app/auth/api_user.go

212 lines
4.6 KiB
Go

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"})
}