mirror of https://github.com/veypi/OneAuth.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
package user
|
|
|
|
import (
|
|
"github.com/veypi/vbase/cfg"
|
|
"github.com/veypi/vbase/models"
|
|
"github.com/veypi/vigo"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type GetRolesReq struct {
|
|
UserID string `src:"path@user_id" desc:"User ID"`
|
|
Scope *string `json:"scope" src:"query" desc:"Scope"`
|
|
}
|
|
|
|
func getRoles(x *vigo.X, req *GetRolesReq) ([]models.Role, error) {
|
|
var userRoles []models.UserRole
|
|
query := cfg.DB().Preload("Role").Where("user_id = ?", req.UserID)
|
|
|
|
if req.Scope != nil {
|
|
query = query.Joins("JOIN roles ON roles.id = user_roles.role_id").Where("roles.scope = ?", *req.Scope)
|
|
}
|
|
|
|
if err := query.Find(&userRoles).Error; err != nil {
|
|
return nil, vigo.ErrDatabase.WithError(err)
|
|
}
|
|
|
|
roles := make([]models.Role, 0, len(userRoles))
|
|
for _, ur := range userRoles {
|
|
roles = append(roles, ur.Role)
|
|
}
|
|
return roles, nil
|
|
}
|
|
|
|
type UpdateRolesReq struct {
|
|
UserID string `src:"path@user_id" desc:"User ID"`
|
|
RoleIDs []string `json:"role_ids" src:"json" desc:"Role IDs"`
|
|
Scope string `json:"scope" src:"json" default:"default" desc:"Scope"`
|
|
}
|
|
|
|
func updateRoles(x *vigo.X, req *UpdateRolesReq) error {
|
|
var user models.User
|
|
if err := cfg.DB().First(&user, "id = ?", req.UserID).Error; err != nil {
|
|
return vigo.ErrNotFound
|
|
}
|
|
|
|
return cfg.DB().Transaction(func(tx *gorm.DB) error {
|
|
// Find all roles in the target scope to identify which UserRoles to delete
|
|
var scopeRoleIDs []string
|
|
if err := tx.Model(&models.Role{}).Where("scope = ?", req.Scope).Pluck("id", &scopeRoleIDs).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// If there are roles in this scope, delete the user's association with them
|
|
if len(scopeRoleIDs) > 0 {
|
|
if err := tx.Where("user_id = ? AND role_id IN ?", req.UserID, scopeRoleIDs).Delete(&models.UserRole{}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if len(req.RoleIDs) > 0 {
|
|
// Verify that all provided RoleIDs belong to the requested scope
|
|
var count int64
|
|
if err := tx.Model(&models.Role{}).Where("id IN ? AND scope = ?", req.RoleIDs, req.Scope).Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count != int64(len(req.RoleIDs)) {
|
|
return vigo.ErrInvalidArg.WithString("One or more roles do not belong to the specified scope")
|
|
}
|
|
|
|
userRoles := make([]models.UserRole, 0, len(req.RoleIDs))
|
|
for _, rid := range req.RoleIDs {
|
|
userRoles = append(userRoles, models.UserRole{
|
|
UserID: req.UserID,
|
|
RoleID: rid,
|
|
})
|
|
}
|
|
if err := tx.Create(&userRoles).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|