60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
package aeusadmin
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"slices"
|
|
"time"
|
|
|
|
"git.nobla.cn/golang/aeus-admin/models"
|
|
"git.nobla.cn/golang/aeus-admin/pkg/dbcache"
|
|
"git.nobla.cn/golang/aeus/middleware/auth"
|
|
"git.nobla.cn/golang/aeus/pkg/errors"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type PermissionChecker struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func (p *PermissionChecker) getUserPermissions(ctx context.Context, uid string) (permissions []string, err error) {
|
|
permissions, err = dbcache.TryCache(ctx, fmt.Sprintf("user:permissions:%s", uid), func(tx *gorm.DB) ([]string, error) {
|
|
var ss []string
|
|
err = tx.Select("permission").Model(&models.RolePermission{}).
|
|
Joins("LEFT JOIN users on users.role = role_permissions.role").
|
|
Where("users.uid = ?", uid).
|
|
Pluck("permission", &ss).
|
|
Error
|
|
return ss, err
|
|
}, dbcache.WithCacheDuration(time.Minute), dbcache.WithDB(p.db))
|
|
return
|
|
}
|
|
|
|
|
|
func (p *PermissionChecker) CheckPermission(ctx context.Context, permission string) (err error) {
|
|
var (
|
|
uid string
|
|
ps []string
|
|
)
|
|
if claims, ok := auth.FromContext(ctx); !ok {
|
|
return errors.ErrAccessDenied
|
|
} else {
|
|
if uid, err = claims.GetSubject(); err != nil {
|
|
return
|
|
}
|
|
}
|
|
if ps, err = p.getUserPermissions(ctx, uid); err != nil {
|
|
return
|
|
}
|
|
if !slices.Contains(ps, permission) {
|
|
err = errors.ErrPermissionDenied
|
|
}
|
|
return
|
|
}
|
|
|
|
func NewPermissionChecker(db *gorm.DB) *PermissionChecker {
|
|
return &PermissionChecker{
|
|
db: db,
|
|
}
|
|
}
|