add role based permissions

This commit is contained in:
Aditya Siregar
2025-08-19 21:29:37 +07:00
parent 7d5f061a1b
commit 6da48504fa
12 changed files with 461 additions and 12 deletions
@@ -874,7 +874,6 @@ func transformLetterToResponse(letter *entities.LetterOutgoing) *contract.Outgoi
}
}
// Include Approvals if loaded
if len(letter.Approvals) > 0 {
resp.Approvals = make([]contract.OutgoingLetterApprovalResponse, len(letter.Approvals))
for i, approval := range letter.Approvals {
+160 -2
View File
@@ -28,7 +28,12 @@ func (s *RBACServiceImpl) CreatePermission(ctx context.Context, req *contract.Cr
if err := s.repo.CreatePermission(ctx, p); err != nil {
return nil, err
}
return &contract.PermissionResponse{ID: p.ID, Code: p.Code, Description: &p.Description, CreatedAt: p.CreatedAt, UpdatedAt: p.UpdatedAt}, nil
return &contract.PermissionResponse{
ID: p.ID,
Code: p.Code,
Action: p.Action,
Description: &p.Description,
}, nil
}
func (s *RBACServiceImpl) UpdatePermission(ctx context.Context, id uuid.UUID, req *contract.UpdatePermissionRequest) (*contract.PermissionResponse, error) {
p := &entities.Permission{ID: id}
@@ -48,7 +53,12 @@ func (s *RBACServiceImpl) UpdatePermission(ctx context.Context, id uuid.UUID, re
}
for _, x := range perms {
if x.ID == id {
return &contract.PermissionResponse{ID: x.ID, Code: x.Code, Description: &x.Description, CreatedAt: x.CreatedAt, UpdatedAt: x.UpdatedAt}, nil
return &contract.PermissionResponse{
ID: x.ID,
Code: x.Code,
Action: x.Action,
Description: &x.Description,
}, nil
}
}
return nil, nil
@@ -126,3 +136,151 @@ func (s *RBACServiceImpl) ListRoles(ctx context.Context) (*contract.ListRolesRes
}
return &contract.ListRolesResponse{Roles: out}, nil
}
// New methods for the required API endpoints
func (s *RBACServiceImpl) GetPermissionsGrouped(ctx context.Context) (*contract.PermissionsGroupedResponse, error) {
modules, err := s.repo.ListModules(ctx)
if err != nil {
return nil, err
}
result := make([]contract.ModuleWithPermissionsResponse, 0, len(modules))
for _, module := range modules {
perms, err := s.repo.ListPermissions(ctx)
if err != nil {
return nil, err
}
modulePerms := make([]contract.PermissionResponse, 0)
for _, perm := range perms {
if perm.ModuleID != nil && *perm.ModuleID == module.ID {
modulePerms = append(modulePerms, contract.PermissionResponse{
ID: perm.ID,
Code: perm.Code,
Action: perm.Action,
Description: &perm.Description,
})
}
}
result = append(result, contract.ModuleWithPermissionsResponse{
Module: contract.ModuleResponse{
ID: module.ID,
Name: module.Name,
Code: module.Code,
},
Permissions: modulePerms,
})
}
return &contract.PermissionsGroupedResponse{Data: result}, nil
}
func (s *RBACServiceImpl) CreateOrUpdateRole(ctx context.Context, req *contract.CreateOrUpdateRoleRequest) (*contract.RoleDetailResponse, error) {
// Check if role exists
existingRole, _ := s.repo.GetRoleByCode(ctx, req.Code)
var role *entities.Role
if existingRole != nil {
// Update existing role
role = existingRole
role.Name = req.Name
role.Description = req.Description
if err := s.repo.UpdateRole(ctx, role); err != nil {
return nil, err
}
} else {
// Create new role
role = &entities.Role{
Name: req.Name,
Code: req.Code,
Description: req.Description,
}
if err := s.repo.CreateRole(ctx, role); err != nil {
return nil, err
}
}
// Set permissions based on module and actions
permissionIDs := make([]uuid.UUID, 0)
for _, modPerm := range req.Permissions {
_, err := s.repo.GetModuleByCode(ctx, modPerm.Module)
if err != nil {
continue // Skip if module not found
}
for _, action := range modPerm.Actions {
permCode := modPerm.Module + "_" + action
perm, err := s.repo.GetPermissionByCode(ctx, permCode)
if err == nil && perm != nil {
permissionIDs = append(permissionIDs, perm.ID)
}
}
}
if err := s.repo.SetRolePermissionsByIDs(ctx, role.ID, permissionIDs); err != nil {
return nil, err
}
// Build response
return s.GetRoleDetail(ctx, role.ID)
}
func (s *RBACServiceImpl) GetRoleDetail(ctx context.Context, roleID uuid.UUID) (*contract.RoleDetailResponse, error) {
role, err := s.repo.GetRoleByID(ctx, roleID)
if err != nil {
return nil, err
}
permissions, err := s.repo.GetPermissionsByRoleID(ctx, roleID)
if err != nil {
return nil, err
}
// Group permissions by module
moduleMap := make(map[uuid.UUID]*contract.RolePermissionModuleResponse)
for _, perm := range permissions {
if perm.ModuleID == nil {
continue
}
if _, exists := moduleMap[*perm.ModuleID]; !exists {
if perm.Module != nil {
moduleMap[*perm.ModuleID] = &contract.RolePermissionModuleResponse{
Module: contract.ModuleResponse{
ID: perm.Module.ID,
Name: perm.Module.Name,
Code: perm.Module.Code,
},
Actions: []contract.PermissionActionResponse{},
}
}
}
if modResp, exists := moduleMap[*perm.ModuleID]; exists {
modResp.Actions = append(modResp.Actions, contract.PermissionActionResponse{
ID: perm.ID,
Action: perm.Action,
Code: perm.Code,
Description: perm.Description,
})
}
}
// Convert map to slice
permissionModules := make([]contract.RolePermissionModuleResponse, 0, len(moduleMap))
for _, modResp := range moduleMap {
permissionModules = append(permissionModules, *modResp)
}
return &contract.RoleDetailResponse{
ID: role.ID,
Name: role.Name,
Code: role.Code,
Description: role.Description,
CreatedAt: role.CreatedAt,
UpdatedAt: role.UpdatedAt,
Permissions: permissionModules,
}, nil
}