package auth import ( "encoding/base64" "github.com/gin-gonic/gin" "gorm.io/gorm" "kumoly.io/kumoly/app/errors" "kumoly.io/kumoly/app/history" "kumoly.io/kumoly/app/server" ) func ApiUsers(c *gin.Context) { users := []User{} result := DB.Preload("Groups").Preload("Profile").Find(&users) if result.Error != nil { panic(result.Error) } server.Res(c, &server.Response{Data: users}) } type apiUserNewReq struct { Name string `json:"username" example:"user" binding:"required"` PwdB64 string `json:"password" example:"YWRtaW4=" binding:"required,base64"` } func ApiUserNew(c *gin.Context) { var data apiUserNewReq if err := c.ShouldBindJSON(&data); err != nil { panic(err) } pwd, err := base64.URLEncoding.DecodeString(data.PwdB64) if err != nil { panic(err) } usr := &User{ Username: data.Name, Password: string(pwd), } err = NewUser(usr) if err != nil { panic(err) } history.Send(history.Info().Nm("Create"). Grp(data.Name).Scp("usr"). Iss(c.GetString(GinUserKey)). Msgf("Create user %v", data.Name)) server.Res(c, &server.Response{Data: usr}) } func ApiUserDelete(c *gin.Context) { var err error id := c.Param("id") if id == "" { panic(errors.ErrorBadRequest) } usr := &User{ ID: id, } err = DB.First(usr, "id = ?", id).Error if err != nil { panic(errors.NewError(404, err)) } if IsLastAdminUser(id) { panic(ErrorDelLastAdmin) } prof := &Profile{} profExist := true err = DB.First(prof, "user_id = ?", id).Error if err != nil { profExist = false } grp := &Group{} grpExist := false err = DB.Where("name = ?", usr.Username).First(grp).Error if err == nil { grpExist = true } err = DB.Transaction(func(tx *gorm.DB) error { if grpExist { err = tx.Model(&grp).Association("Users").Clear() if err != nil { return err } } err = tx.Model(&usr).Association("Groups").Clear() if err != nil { return err } err = tx.Model(&usr).Association("Profile").Clear() if err != nil { return err } if profExist { err = tx.Delete(&prof).Error if err != nil { return err } } err = tx.Delete(usr).Error if err != nil { return err } err = tx.Delete(grp).Error return err }) if err != nil { panic(err) } history.Send(history.Info().Nm("Delete"). Grp(usr.Username).Scp("usr"). Iss(c.GetString(GinUserKey)). Msgf("Delete user %v", usr.Username)) server.Res(c, &server.Response{Data: "ok"}) } type apiUserChangePasswdReq struct { UserID string `json:"uid" example:"c35icut3sbav3gg5j1b0" binding:"required"` PwdB64 string `json:"old" ` NewPwdB64 string `json:"new" example:"YWRtaW4=" binding:"required,base64"` } func ApiUserChangePasswd(c *gin.Context) { var err error var data apiUserChangePasswdReq if err = c.ShouldBindJSON(&data); err != nil { panic(err) } usr := &User{} err = DB.First(usr, "id = ?", data.UserID).Error if err != nil { panic(errors.NewError(404, err)) } if !ACHas(c, ADMIN) { if !ACHas(c, usr.Username) { panic(errors.ErrorForbidden) } old_pwd, err := base64.URLEncoding.DecodeString(data.PwdB64) if err != nil { panic(err) } err = usr.ValidatePassword(string(old_pwd)) if err != nil { panic(err) } } new_pwd, err := base64.URLEncoding.DecodeString(data.NewPwdB64) if err != nil { panic(err) } err = usr.ChangePassword(DB, string(new_pwd)) if err != nil { panic(err) } history.Send(history.Info().Nm("ChangePassword"). Grp(usr.Username).Scp("usr"). Iss(c.GetString(GinUserKey)). Msgf("User %v password changed", usr.Username)) server.Res(c, &server.Response{Data: "ok"}) } func ApiUserActivate(c *gin.Context) { usr := &User{} uid := c.Param("id") if uid == "" { panic(errors.ErrorBadRequest) } err := DB.Where("id = ?", uid).First(usr).Error if err != nil { panic(errors.NewError(404, err)) } err = DB.Model(&usr).Update("activated", true).Error if err != nil { panic(err) } history.Send(history.Info().Nm("Activate"). Grp(usr.Username).Scp("usr"). Iss(c.GetString(GinUserKey)). Msgf("User %v activated", usr.Username)) server.Res(c, &server.Response{Data: "ok"}) } func ApiUserDeactivate(c *gin.Context) { usr := &User{} uid := c.Param("id") if uid == "" { panic(errors.ErrorBadRequest) } err := DB.Where("id = ?", uid).First(usr).Error if err != nil { panic(errors.NewError(404, err)) } if IsLastAdminUser(uid) { panic(ErrorDelLastAdmin) } err = DB.Model(&usr).Update("activated", false).Error if err != nil { panic(err) } history.Send(history.Info().Nm("Deactivate"). Grp(usr.Username).Scp("usr"). Iss(c.GetString(GinUserKey)). Msgf("User %v deactivated", usr.Username)) server.Res(c, &server.Response{Data: "ok"}) }