安全修复: - CRITICAL: SSO重定向URL注入漏洞 - 修复redirect_uri白名单验证 - HIGH: SSO ClientSecret未验证 - 使用crypto/subtle.ConstantTimeCompare验证 - HIGH: 邮件验证码熵值过低(3字节) - 提升到6字节(48位熵) - HIGH: 短信验证码熵值过低(4字节) - 提升到6字节 - HIGH: Goroutine使用已取消上下文 - auth_email.go使用独立context+超时 - HIGH: SQL LIKE查询注入风险 - permission/role仓库使用escapeLikePattern 新功能: - Go SDK: sdk/go/user-management/ 完整SDK实现 - CAS SSO框架: internal/auth/cas.go CAS协议支持 其他: - L1Cache实例问题修复 - AuthMiddleware共享l1Cache - 设备指纹XSS防护 - 内存存储替代localStorage - 响应格式协议中间件 - 导出无界查询修复
207 lines
6.2 KiB
Go
207 lines
6.2 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/user-management-system/internal/domain"
|
|
)
|
|
|
|
// PermissionRepository 权限数据访问层
|
|
type PermissionRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewPermissionRepository 创建权限数据访问层
|
|
func NewPermissionRepository(db *gorm.DB) *PermissionRepository {
|
|
return &PermissionRepository{db: db}
|
|
}
|
|
|
|
// Create 创建权限
|
|
func (r *PermissionRepository) Create(ctx context.Context, permission *domain.Permission) error {
|
|
// GORM omits zero values on insert for fields with DB defaults. Explicitly
|
|
// backfill disabled status so callers can persist status=0 permissions.
|
|
requestedStatus := permission.Status
|
|
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
if err := tx.Create(permission).Error; err != nil {
|
|
return err
|
|
}
|
|
if requestedStatus == domain.PermissionStatusDisabled {
|
|
if err := tx.Model(&domain.Permission{}).Where("id = ?", permission.ID).Update("status", requestedStatus).Error; err != nil {
|
|
return err
|
|
}
|
|
permission.Status = requestedStatus
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// Update 更新权限
|
|
func (r *PermissionRepository) Update(ctx context.Context, permission *domain.Permission) error {
|
|
return r.db.WithContext(ctx).Save(permission).Error
|
|
}
|
|
|
|
// Delete 删除权限
|
|
func (r *PermissionRepository) Delete(ctx context.Context, id int64) error {
|
|
return r.db.WithContext(ctx).Delete(&domain.Permission{}, id).Error
|
|
}
|
|
|
|
// GetByID 根据ID获取权限
|
|
func (r *PermissionRepository) GetByID(ctx context.Context, id int64) (*domain.Permission, error) {
|
|
var permission domain.Permission
|
|
err := r.db.WithContext(ctx).First(&permission, id).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &permission, nil
|
|
}
|
|
|
|
// GetByCode 根据代码获取权限
|
|
func (r *PermissionRepository) GetByCode(ctx context.Context, code string) (*domain.Permission, error) {
|
|
var permission domain.Permission
|
|
err := r.db.WithContext(ctx).Where("code = ?", code).First(&permission).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &permission, nil
|
|
}
|
|
|
|
// List 获取权限列表
|
|
func (r *PermissionRepository) List(ctx context.Context, offset, limit int) ([]*domain.Permission, int64, error) {
|
|
var permissions []*domain.Permission
|
|
var total int64
|
|
|
|
query := r.db.WithContext(ctx).Model(&domain.Permission{})
|
|
|
|
// 获取总数
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 获取列表
|
|
if err := query.Offset(offset).Limit(limit).Find(&permissions).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return permissions, total, nil
|
|
}
|
|
|
|
// ListByType 根据类型获取权限列表
|
|
func (r *PermissionRepository) ListByType(ctx context.Context, permissionType domain.PermissionType, offset, limit int) ([]*domain.Permission, int64, error) {
|
|
var permissions []*domain.Permission
|
|
var total int64
|
|
|
|
query := r.db.WithContext(ctx).Model(&domain.Permission{}).Where("type = ?", permissionType)
|
|
|
|
// 获取总数
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 获取列表
|
|
if err := query.Offset(offset).Limit(limit).Find(&permissions).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return permissions, total, nil
|
|
}
|
|
|
|
// ListByStatus 根据状态获取权限列表
|
|
func (r *PermissionRepository) ListByStatus(ctx context.Context, status domain.PermissionStatus, offset, limit int) ([]*domain.Permission, int64, error) {
|
|
var permissions []*domain.Permission
|
|
var total int64
|
|
|
|
query := r.db.WithContext(ctx).Model(&domain.Permission{}).Where("status = ?", status)
|
|
|
|
// 获取总数
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 获取列表
|
|
if err := query.Offset(offset).Limit(limit).Find(&permissions).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return permissions, total, nil
|
|
}
|
|
|
|
// GetByRoleIDs 根据角色ID获取权限列表
|
|
func (r *PermissionRepository) GetByRoleIDs(ctx context.Context, roleIDs []int64) ([]*domain.Permission, error) {
|
|
var permissions []*domain.Permission
|
|
|
|
err := r.db.WithContext(ctx).
|
|
Joins("INNER JOIN role_permissions ON permissions.id = role_permissions.permission_id").
|
|
Where("role_permissions.role_id IN ?", roleIDs).
|
|
Where("permissions.status = ?", domain.PermissionStatusEnabled).
|
|
Find(&permissions).Error
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return permissions, nil
|
|
}
|
|
|
|
// ExistsByCode 检查权限代码是否存在
|
|
func (r *PermissionRepository) ExistsByCode(ctx context.Context, code string) (bool, error) {
|
|
var count int64
|
|
err := r.db.WithContext(ctx).Model(&domain.Permission{}).Where("code = ?", code).Count(&count).Error
|
|
return count > 0, err
|
|
}
|
|
|
|
// UpdateStatus 更新权限状态
|
|
func (r *PermissionRepository) UpdateStatus(ctx context.Context, id int64, status domain.PermissionStatus) error {
|
|
return r.db.WithContext(ctx).Model(&domain.Permission{}).Where("id = ?", id).Update("status", status).Error
|
|
}
|
|
|
|
// Search 搜索权限
|
|
func (r *PermissionRepository) Search(ctx context.Context, keyword string, offset, limit int) ([]*domain.Permission, int64, error) {
|
|
var permissions []*domain.Permission
|
|
var total int64
|
|
|
|
// 转义 LIKE 特殊字符,防止搜索被意外干扰
|
|
escapedKeyword := escapeLikePattern(keyword)
|
|
pattern := "%" + escapedKeyword + "%"
|
|
|
|
query := r.db.WithContext(ctx).Model(&domain.Permission{}).
|
|
Where("name LIKE ? OR code LIKE ? OR description LIKE ?", pattern, pattern, pattern)
|
|
|
|
// 获取总数
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 获取列表
|
|
if err := query.Offset(offset).Limit(limit).Find(&permissions).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return permissions, total, nil
|
|
}
|
|
|
|
// ListByParentID 根据父ID获取权限列表
|
|
func (r *PermissionRepository) ListByParentID(ctx context.Context, parentID int64) ([]*domain.Permission, error) {
|
|
var permissions []*domain.Permission
|
|
err := r.db.WithContext(ctx).Where("parent_id = ?", parentID).Find(&permissions).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return permissions, nil
|
|
}
|
|
|
|
// GetByIDs 根据ID列表批量获取权限
|
|
func (r *PermissionRepository) GetByIDs(ctx context.Context, ids []int64) ([]*domain.Permission, error) {
|
|
if len(ids) == 0 {
|
|
return []*domain.Permission{}, nil
|
|
}
|
|
|
|
var permissions []*domain.Permission
|
|
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&permissions).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return permissions, nil
|
|
}
|