template-monorepo/internal/model/permission/usecase/authorization_query_usecase.go

121 lines
3.0 KiB
Go
Raw Permalink Normal View History

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)