Yimaru-BackEnd/internal/repository/rbac.go

204 lines
5.2 KiB
Go

package repository
import (
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"Yimaru-Backend/internal/ports"
"context"
"github.com/jackc/pgx/v5/pgtype"
)
func NewRBACStore(s *Store) ports.RBACStore { return s }
func (s *Store) CreateRole(ctx context.Context, name, description string, isSystem bool) (domain.RoleRecord, error) {
r, err := s.queries.CreateRole(ctx, dbgen.CreateRoleParams{
Name: name,
Description: description,
IsSystem: isSystem,
})
if err != nil {
return domain.RoleRecord{}, err
}
return mapRole(r), nil
}
func (s *Store) GetRoleByID(ctx context.Context, id int64) (domain.RoleRecord, error) {
r, err := s.queries.GetRoleByID(ctx, id)
if err != nil {
return domain.RoleRecord{}, err
}
return mapRole(r), nil
}
func (s *Store) GetRoleByName(ctx context.Context, name string) (domain.RoleRecord, error) {
r, err := s.queries.GetRoleByName(ctx, name)
if err != nil {
return domain.RoleRecord{}, err
}
return mapRole(r), nil
}
func (s *Store) ListRoles(ctx context.Context, filter domain.RoleListFilter) ([]domain.RoleRecord, int64, error) {
var queryParam pgtype.Text
if filter.Query != "" {
queryParam = pgtype.Text{String: filter.Query, Valid: true}
}
var isSystemParam pgtype.Bool
if filter.IsSystem != nil {
isSystemParam = pgtype.Bool{Bool: *filter.IsSystem, Valid: true}
}
limit := int32(filter.PageSize)
if limit <= 0 {
limit = 20
}
offset := int32(filter.Page * filter.PageSize)
rows, err := s.queries.ListRoles(ctx, dbgen.ListRolesParams{
Query: queryParam,
IsSystem: isSystemParam,
Limit: pgtype.Int4{Int32: limit, Valid: true},
Offset: pgtype.Int4{Int32: offset, Valid: true},
})
if err != nil {
return nil, 0, err
}
if len(rows) == 0 {
return []domain.RoleRecord{}, 0, nil
}
totalCount := rows[0].TotalCount
roles := make([]domain.RoleRecord, len(rows))
for i, r := range rows {
rec := domain.RoleRecord{
ID: r.ID,
Name: r.Name,
Description: r.Description,
IsSystem: r.IsSystem,
CreatedAt: r.CreatedAt.Time,
}
if r.UpdatedAt.Valid {
rec.UpdatedAt = &r.UpdatedAt.Time
}
roles[i] = rec
}
return roles, totalCount, nil
}
func (s *Store) UpdateRole(ctx context.Context, id int64, name, description string) error {
return s.queries.UpdateRole(ctx, dbgen.UpdateRoleParams{
ID: id,
Name: name,
Description: description,
})
}
func (s *Store) DeleteRole(ctx context.Context, id int64) error {
return s.queries.DeleteRole(ctx, id)
}
func (s *Store) UpsertPermission(ctx context.Context, seed domain.PermissionSeed) (domain.Permission, error) {
p, err := s.queries.UpsertPermission(ctx, dbgen.UpsertPermissionParams{
Key: seed.Key,
Name: seed.Name,
Description: seed.Description,
GroupName: seed.GroupName,
})
if err != nil {
return domain.Permission{}, err
}
return mapPermission(p), nil
}
func (s *Store) ListPermissions(ctx context.Context) ([]domain.Permission, error) {
rows, err := s.queries.ListPermissions(ctx)
if err != nil {
return nil, err
}
perms := make([]domain.Permission, len(rows))
for i, p := range rows {
perms[i] = mapPermission(p)
}
return perms, nil
}
func (s *Store) ListPermissionGroups(ctx context.Context) ([]string, error) {
return s.queries.ListPermissionGroups(ctx)
}
func (s *Store) GetPermissionByKey(ctx context.Context, key string) (domain.Permission, error) {
p, err := s.queries.GetPermissionByKey(ctx, key)
if err != nil {
return domain.Permission{}, err
}
return mapPermission(p), nil
}
func (s *Store) SetRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error {
if err := s.queries.SetRolePermissions(ctx, roleID); err != nil {
return err
}
if len(permissionIDs) > 0 {
return s.queries.BulkAssignPermissionsToRole(ctx, dbgen.BulkAssignPermissionsToRoleParams{
RoleID: roleID,
Column2: permissionIDs,
})
}
return nil
}
func (s *Store) GetRolePermissions(ctx context.Context, roleID int64) ([]domain.Permission, error) {
rows, err := s.queries.GetRolePermissions(ctx, roleID)
if err != nil {
return nil, err
}
perms := make([]domain.Permission, len(rows))
for i, p := range rows {
perms[i] = mapPermission(p)
}
return perms, nil
}
func (s *Store) GetAllRolesWithPermissions(ctx context.Context) (map[string]map[string]struct{}, error) {
rows, err := s.queries.GetAllRolesWithPermissions(ctx)
if err != nil {
return nil, err
}
result := make(map[string]map[string]struct{})
for _, row := range rows {
if _, ok := result[row.RoleName]; !ok {
result[row.RoleName] = make(map[string]struct{})
}
result[row.RoleName][row.PermissionKey] = struct{}{}
}
return result, nil
}
func mapRole(r dbgen.Role) domain.RoleRecord {
rec := domain.RoleRecord{
ID: r.ID,
Name: r.Name,
Description: r.Description,
IsSystem: r.IsSystem,
CreatedAt: r.CreatedAt.Time,
}
if r.UpdatedAt.Valid {
rec.UpdatedAt = &r.UpdatedAt.Time
}
return rec
}
func mapPermission(p dbgen.Permission) domain.Permission {
return domain.Permission{
ID: p.ID,
Key: p.Key,
Name: p.Name,
Description: p.Description,
GroupName: p.GroupName,
CreatedAt: p.CreatedAt.Time,
}
}