3
3
import io .micronaut .core .annotation .Introspected ;
4
4
import io .micronaut .core .annotation .Nullable ;
5
5
import io .micronaut .http .HttpResponse ;
6
+ import io .micronaut .http .HttpStatus ;
6
7
import io .micronaut .http .annotation .Body ;
7
8
import io .micronaut .http .annotation .Controller ;
8
9
import io .micronaut .http .annotation .Post ;
10
+ import io .micronaut .http .exceptions .HttpStatusException ;
9
11
import io .micronaut .security .annotation .Secured ;
10
12
import io .micronaut .security .authentication .Authentication ;
11
13
import io .micronaut .security .rules .SecurityRule ;
15
17
import io .unityfoundation .auth .entities .Service .ServiceStatus ;
16
18
import io .unityfoundation .auth .entities .ServiceRepo ;
17
19
import io .unityfoundation .auth .entities .Tenant ;
20
+ import io .unityfoundation .auth .entities .Tenant .TenantStatus ;
18
21
import io .unityfoundation .auth .entities .TenantRepo ;
19
22
import io .unityfoundation .auth .entities .User ;
20
23
import io .unityfoundation .auth .entities .UserRepo ;
24
+ import jakarta .validation .constraints .NotNull ;
21
25
import java .util .List ;
22
26
import java .util .Optional ;
27
+ import java .util .function .BiPredicate ;
23
28
24
29
@ Secured (SecurityRule .IS_AUTHENTICATED )
25
30
@ Controller ("/api" )
@@ -35,6 +40,43 @@ public AuthController(UserRepo userRepo, ServiceRepo serviceRepo, TenantRepo ten
35
40
this .tenantRepo = tenantRepo ;
36
41
}
37
42
43
+ @ Post ("/principal/permissions" )
44
+ public UserPermissionsResponse permissions (@ Body UserPermissionsRequest requestDTO ,
45
+ Authentication authentication ) {
46
+ Optional <Tenant > maybeTenant = tenantRepo .findById (requestDTO .tenantId ());
47
+ if (maybeTenant .isEmpty ()){
48
+ return new UserPermissionsResponse .Failure ("No tenant found." );
49
+ }
50
+ Tenant tenant = maybeTenant .get ();
51
+
52
+ if (!tenant .getStatus ().equals (TenantStatus .ENABLED )){
53
+ return new UserPermissionsResponse .Failure ("The tenant is not enabled." );
54
+ }
55
+
56
+ User user = userRepo .findByEmail (authentication .getName ()).orElse (null );
57
+ if (checkUserStatus (user )) {
58
+ return new UserPermissionsResponse .Failure ("The users account has been disabled." );
59
+ }
60
+
61
+ Service service = serviceRepo .findById (requestDTO .serviceId ())
62
+ .orElseThrow (() -> new HttpStatusException (HttpStatus .NOT_FOUND , "Service not found." ));
63
+
64
+ if (service .getStatus () == ServiceStatus .DISABLED ) {
65
+ throw new HttpStatusException (HttpStatus .FORBIDDEN , "The service is disabled." );
66
+ } else if (service .getStatus () == ServiceStatus .DOWN_FOR_MAINTENANCE ) {
67
+
68
+ throw new HttpStatusException (HttpStatus .SERVICE_UNAVAILABLE ,
69
+ "The service is down for maintenance." );
70
+ }
71
+
72
+ if (!userRepo .isServiceAvailable (user .getId (), service .getId ())) {
73
+ return new UserPermissionsResponse .Failure (
74
+ "The Tenant and/or Service is not available for this user" );
75
+ }
76
+
77
+ return new UserPermissionsResponse .Success (getPermissionsFor (user , tenant ));
78
+ }
79
+
38
80
@ Post ("/hasPermission" )
39
81
public HttpResponse <HasPermissionResponse > hasPermission (@ Body HasPermissionRequest requestDTO ,
40
82
Authentication authentication ) {
@@ -86,20 +128,26 @@ private String checkServiceStatus(Optional<Service> service) {
86
128
return null ;
87
129
}
88
130
131
+ private final BiPredicate <TenantPermission , Tenant > isTenantOrSystemOrSubtenantScopeAndBelongsToTenant = (tp , t ) ->
132
+ PermissionScope .SYSTEM .equals (tp .permissionScope ()) || (
133
+ (PermissionScope .TENANT .equals (tp .permissionScope ())
134
+ || PermissionScope .SUBTENANT .equals (tp .permissionScope ()))
135
+ && tp .tenantId == t .getId ());
136
+
137
+
89
138
private List <String > checkUserPermission (User user , Tenant tenant , List <String > permissions ) {
90
- List <TenantPermission > userPermissions = userRepo .getTenantPermissionsFor (user .getId ()).stream ()
91
- .filter (tenantPermission ->
92
- PermissionScope .SYSTEM .equals (tenantPermission .permissionScope ()) ||
93
- ((PermissionScope .TENANT .equals (tenantPermission .permissionScope ()) || PermissionScope .SUBTENANT .equals (tenantPermission .permissionScope ()))
94
- && tenantPermission .tenantId == tenant .getId ()))
95
- .toList ();
139
+ List <String > commonPermissions = getPermissionsFor (user , tenant ).stream ()
140
+ .filter (permissions ::contains ).toList ();
96
141
97
- List <String > commonPermissions = userPermissions .stream ()
142
+ return commonPermissions ;
143
+ }
144
+
145
+ private List <String > getPermissionsFor (User user , Tenant tenant ) {
146
+ return userRepo .getTenantPermissionsFor (user .getId ()).stream ()
147
+ .filter (tenantPermission ->
148
+ isTenantOrSystemOrSubtenantScopeAndBelongsToTenant .test (tenantPermission , tenant ))
98
149
.map (TenantPermission ::permissionName )
99
- .filter (permissions ::contains )
100
150
.toList ();
101
-
102
- return commonPermissions ;
103
151
}
104
152
105
153
private HttpResponse <HasPermissionResponse > createHasPermissionResponse (boolean hasPermission ,
@@ -129,4 +177,18 @@ public record TenantPermission(
129
177
130
178
}
131
179
180
+
181
+ public sealed interface UserPermissionsResponse {
182
+ @ Serdeable
183
+ record Success (List <String > permissions ) implements UserPermissionsResponse {}
184
+ @ Serdeable
185
+ record Failure (String errorMessage ) implements UserPermissionsResponse {}
186
+ }
187
+
188
+ @ Serdeable
189
+ public record UserPermissionsRequest (@ NotNull Long tenantId ,
190
+ @ NotNull Long serviceId ) {
191
+
192
+ }
193
+
132
194
}
0 commit comments