215 lines
5.5 KiB
Go
215 lines
5.5 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) AddRolePermissions(ctx context.Context, roleID int64, permissionIDs []int64) error {
|
|
if len(permissionIDs) == 0 {
|
|
return nil
|
|
}
|
|
// Uses ON CONFLICT DO NOTHING at the SQL level (see rbac.sql).
|
|
return s.queries.BulkAssignPermissionsToRole(ctx, dbgen.BulkAssignPermissionsToRoleParams{
|
|
RoleID: roleID,
|
|
Column2: permissionIDs,
|
|
})
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|