121 lines
3.0 KiB
Go
121 lines
3.0 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
|
|
"gateway/internal/model/permission/domain/entity"
|
|
"gateway/internal/model/permission/domain/enum"
|
|
domrepo "gateway/internal/model/permission/domain/repository"
|
|
dom "gateway/internal/model/permission/domain/usecase"
|
|
)
|
|
|
|
// AuthorizationQueryUseCaseParam injects all read-side repos.
|
|
type AuthorizationQueryUseCaseParam struct {
|
|
Roles domrepo.RoleRepository
|
|
Permissions domrepo.PermissionRepository
|
|
RolePermissions domrepo.RolePermissionRepository
|
|
UserRoles domrepo.UserRoleRepository
|
|
}
|
|
|
|
type authorizationQueryUseCase struct {
|
|
roles domrepo.RoleRepository
|
|
perms domrepo.PermissionRepository
|
|
rolePerms domrepo.RolePermissionRepository
|
|
userRoles domrepo.UserRoleRepository
|
|
}
|
|
|
|
// NewAuthorizationQueryUseCase composes Role + RolePermission +
|
|
// Permission to produce the menu/permission map used by GET /me.
|
|
func NewAuthorizationQueryUseCase(param AuthorizationQueryUseCaseParam) dom.AuthorizationQueryUseCase {
|
|
return &authorizationQueryUseCase{
|
|
roles: param.Roles,
|
|
perms: param.Permissions,
|
|
rolePerms: param.RolePermissions,
|
|
userRoles: param.UserRoles,
|
|
}
|
|
}
|
|
|
|
func (uc *authorizationQueryUseCase) Me(
|
|
ctx context.Context,
|
|
tenantID, uid string,
|
|
includeTree bool,
|
|
) (*dom.MePermissionsResponse, error) {
|
|
resp := &dom.MePermissionsResponse{
|
|
UID: uid,
|
|
TenantID: tenantID,
|
|
Roles: []string{},
|
|
Permissions: enum.Permissions{},
|
|
}
|
|
|
|
urs, err := uc.userRoles.ListByUser(ctx, tenantID, uid)
|
|
if err != nil {
|
|
return nil, wrapRepoErr(err)
|
|
}
|
|
if len(urs) == 0 {
|
|
if includeTree {
|
|
resp.Tree = []*dom.PermissionTreeNode{}
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
roleIDs := make([]string, 0, len(urs))
|
|
for _, ur := range urs {
|
|
roleIDs = append(roleIDs, ur.RoleID)
|
|
}
|
|
roles, err := uc.roles.ListByTenantAndIDs(ctx, tenantID, roleIDs)
|
|
if err != nil {
|
|
return nil, wrapRepoErr(err)
|
|
}
|
|
roleByID := make(map[string]*entity.Role, len(roles))
|
|
for _, role := range roles {
|
|
roleByID[role.ID.Hex()] = role
|
|
if role.Status == enum.StatusOpen {
|
|
resp.Roles = append(resp.Roles, role.Key)
|
|
}
|
|
}
|
|
|
|
rps, err := uc.rolePerms.ListByRoles(ctx, tenantID, roleIDs)
|
|
if err != nil {
|
|
return nil, wrapRepoErr(err)
|
|
}
|
|
if len(rps) == 0 {
|
|
if includeTree {
|
|
resp.Tree = []*dom.PermissionTreeNode{}
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
permIDSet := make(map[string]struct{}, len(rps))
|
|
for _, rp := range rps {
|
|
role, ok := roleByID[rp.RoleID]
|
|
if !ok || role.Status != enum.StatusOpen {
|
|
continue
|
|
}
|
|
permIDSet[rp.PermissionID] = struct{}{}
|
|
}
|
|
if len(permIDSet) == 0 {
|
|
if includeTree {
|
|
resp.Tree = []*dom.PermissionTreeNode{}
|
|
}
|
|
return resp, nil
|
|
}
|
|
ids := make([]string, 0, len(permIDSet))
|
|
for id := range permIDSet {
|
|
ids = append(ids, id)
|
|
}
|
|
perms, err := uc.perms.GetByIDs(ctx, ids)
|
|
if err != nil {
|
|
return nil, wrapRepoErr(err)
|
|
}
|
|
for _, perm := range perms {
|
|
resp.Permissions[perm.Name] = perm.Status
|
|
}
|
|
|
|
if includeTree {
|
|
resp.Tree = filterOpenNodes(buildPermissionTree(perms))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
var _ dom.AuthorizationQueryUseCase = (*authorizationQueryUseCase)(nil)
|