app/auth/api_grp.go

228 lines
5.4 KiB
Go

package auth
import (
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"kumoly.io/kumoly/app/errors"
"kumoly.io/kumoly/app/history"
"kumoly.io/kumoly/app/server"
)
func ApiGrps(c *gin.Context) {
gid := c.Query("id")
if gid != "" {
grp := &Group{}
if err := DB.First(grp, "id = ?", gid).Error; err != nil {
panic(err)
}
server.OK(c, grp)
return
}
grps := []Group{}
var result *gorm.DB
if ACHas(c, SYSTEM) {
result = DB.Find(&grps)
} else {
result = DB.Where("name not like ?", SYS_AUTH_PREFIX+"%").Find(&grps)
}
if result.Error != nil {
panic(result.Error)
}
server.Res(c, &server.Response{Data: grps})
}
type apiGrpNewReq struct {
Name string `json:"name" example:"user" binding:"required"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
Listeners string
GRPF1 string
}
func ApiGrpNew(c *gin.Context) {
var data apiGrpNewReq
if err := c.ShouldBindJSON(&data); err != nil {
panic(err)
}
if (strings.HasPrefix(data.Name, SYS_AUTH_PREFIX) || data.Name == sys_user) &&
!ACHas(c, ADMIN) {
panic(errors.ErrorForbidden)
}
grp := &Group{
Name: data.Name,
Description: data.Description,
DisplayName: data.DisplayName,
Listeners: data.Listeners,
GRPF1: data.GRPF1,
}
if err := DB.Create(grp).Error; err != nil {
panic(err)
}
history.Send(history.Info().Nm("Create").
Bd(data).Grp(data.Name).Scp("grp").
Iss(c.GetString(GinUserKey)).
Msgf("Create group %v", data.Name))
server.Res(c, &server.Response{Data: grp})
}
type apiGrpUpdateReq struct {
ID uint `json:"id" binding:"required"`
Name string `json:"name" binding:"required"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
Listeners string
GRPF1 string
}
func ApiGrpUpdate(c *gin.Context) {
fetch := c.Query("fetch")
var data apiGrpUpdateReq
if err := c.ShouldBindJSON(&data); err != nil {
panic(err)
}
grp := &Group{Name: data.Name}
err := DB.First(grp, data.ID).Error
if err != nil {
panic(errors.NewError(404, err))
}
if strings.HasPrefix(grp.Name, SYS_AUTH_PREFIX) {
panic(errors.ErrorForbidden)
}
if !ACHas(c, ADMIN, grp.Name, SYSTEM) {
panic(errors.ErrorForbidden)
}
result := DB.Model(&grp).Updates(map[string]interface{}{
"name": data.Name,
"display_name": data.DisplayName,
"description": data.Description,
"listeners": data.Listeners,
"grpf1": data.GRPF1,
})
if result.Error != nil {
panic(result.Error)
}
if fetch != "" && ACHas(c, ADMIN, SYSTEM) {
DB.Preload("Users").Preload("Users.Profile").First(grp, data.ID)
}
history.Send(history.Info().Nm("Update").
Bd(data).Grp(data.Name).Scp("grp").
Iss(c.GetString(GinUserKey)).
Msgf("Update group %v", data.Name))
server.Res(c, &server.Response{Data: grp})
}
func ApiGrpDel(c *gin.Context) {
id := c.Param("id")
if id == "" {
panic(errors.ErrorBadRequest)
}
grp := &Group{}
err := DB.First(grp, id).Error
if err != nil {
panic(errors.NewError(404, err))
}
if strings.HasPrefix(grp.Name, SYS_AUTH_PREFIX) && !ACHas(c, ADMIN) {
panic(errors.ErrorForbidden)
}
err = DB.Transaction(func(tx *gorm.DB) error {
err = tx.Model(&grp).Association("Users").Clear()
if err != nil {
return err
}
err = tx.Delete(grp).Error
if err != nil {
return err
}
return nil
})
if err != nil {
panic(err)
}
history.Send(history.Info().Nm("Delete").
Bd(grp).Grp(grp.Name).Scp("grp").
Iss(c.GetString(GinUserKey)).
Msgf("Delete group %v", grp.Name))
server.Res(c, &server.Response{Data: "ok"})
}
func ApiGrpAssign(c *gin.Context) {
uid := c.Param("uid")
gid := c.Param("gid")
if uid == "" || gid == "" {
panic(errors.ErrorBadRequest)
}
usr := &User{}
err := DB.Where("id = ?", uid).First(usr).Error
if err != nil {
panic(errors.NewError(404, err))
}
grp := &Group{}
err = DB.First(grp, gid).Error
if err != nil {
panic(errors.NewError(404, err))
}
// deny access
if !ACHas(c, grp.Name, ADMIN, SYSTEM) {
panic(errors.ErrorForbidden)
}
// only sys can add sys
if grp.Name == SYSTEM {
if !ACHas(c, SYSTEM) {
panic(errors.ErrorForbidden)
}
}
err = DB.Transaction(func(tx *gorm.DB) error {
return tx.Model(usr).Association("Groups").Append(grp)
})
if err != nil {
panic(err)
}
history.Send(history.Info().Nm("Assign").
Bd(map[string]string{"user": usr.Username, "group": grp.Name}).
Grp(grp.Name).Iss(c.GetString(GinUserKey)).Scp("grp").
Msgf("Assigned %v to group %v", usr.Username, grp.Name))
server.Res(c, &server.Response{Data: "ok"})
}
func ApiGrpRemove(c *gin.Context) {
uid := c.Param("uid")
gid := c.Param("gid")
if uid == "" || gid == "" {
panic(errors.ErrorBadRequest)
}
usr := &User{}
err := DB.Where("id = ?", uid).First(usr).Error
if err != nil {
panic(errors.NewError(404, err))
}
grp := &Group{}
err = DB.First(grp, gid).Error
if err != nil {
panic(errors.NewError(404, err))
}
if grp.Name == SYSTEM {
if !ACHas(c, SYSTEM) {
panic(errors.ErrorForbidden)
}
}
if grp.Name == ADMIN && IsLastAdmin() {
panic(ErrorDelLastAdmin)
}
err = DB.Transaction(func(tx *gorm.DB) error {
return tx.Model(usr).Association("Groups").Delete(grp)
})
if err != nil {
panic(err)
}
history.Send(history.Info().Nm("Remove").
Bd(map[string]string{"user": usr.Username, "group": grp.Name}).
Grp(grp.Name).Iss(c.GetString(GinUserKey)).Scp("grp").
Msgf("Remove %v from group %v", usr.Username, grp.Name))
server.Res(c, &server.Response{Data: "ok"})
}