Skip to content

Commit 600c15a

Browse files
committed
use algebraic data type for response and add additional check
Signed-off-by: Josh Hootman <[email protected]>
1 parent 8de1120 commit 600c15a

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

UnityAuth/src/main/java/io/unityfoundation/auth/AuthController.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import io.micronaut.http.HttpStatus;
77
import io.micronaut.http.annotation.Body;
88
import io.micronaut.http.annotation.Controller;
9-
import io.micronaut.http.annotation.Get;
109
import io.micronaut.http.annotation.Post;
1110
import io.micronaut.http.exceptions.HttpStatusException;
1211
import io.micronaut.security.annotation.Secured;
@@ -41,19 +40,22 @@ public AuthController(UserRepo userRepo, ServiceRepo serviceRepo, TenantRepo ten
4140
this.tenantRepo = tenantRepo;
4241
}
4342

44-
@Get("/permissions")
45-
public HttpResponse<UserPermissionsResponse> permissions(@Body UserPermissionsRequest requestDTO,
43+
@Post("/principal/permissions")
44+
public UserPermissionsResponse permissions(@Body UserPermissionsRequest requestDTO,
4645
Authentication authentication) {
47-
Tenant tenant = tenantRepo.findById(requestDTO.tenantId())
48-
.orElseThrow(() -> new HttpStatusException(HttpStatus.NOT_FOUND, "No tenant found."));
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();
4951

5052
if (!tenant.getStatus().equals(TenantStatus.ENABLED)){
51-
throw new HttpStatusException(HttpStatus.FORBIDDEN, "The tenant is not enabled.");
53+
return new UserPermissionsResponse.Failure("The tenant is not enabled.");
5254
}
5355

5456
User user = userRepo.findByEmail(authentication.getName()).orElse(null);
5557
if (checkUserStatus(user)) {
56-
throw new HttpStatusException(HttpStatus.FORBIDDEN, "The user's account has been disabled.");
58+
return new UserPermissionsResponse.Failure("The users account has been disabled.");
5759
}
5860

5961
Service service = serviceRepo.findById(requestDTO.serviceId())
@@ -62,11 +64,17 @@ public HttpResponse<UserPermissionsResponse> permissions(@Body UserPermissionsRe
6264
if (service.getStatus() == ServiceStatus.DISABLED) {
6365
throw new HttpStatusException(HttpStatus.FORBIDDEN, "The service is disabled.");
6466
} else if (service.getStatus() == ServiceStatus.DOWN_FOR_MAINTENANCE) {
67+
6568
throw new HttpStatusException(HttpStatus.SERVICE_UNAVAILABLE,
6669
"The service is down for maintenance.");
6770
}
6871

69-
return HttpResponse.ok(new UserPermissionsResponse(getPermissionsFor(user, tenant)));
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));
7078
}
7179

7280
@Post("/hasPermission")
@@ -169,13 +177,18 @@ public record TenantPermission(
169177

170178
}
171179

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+
172188
@Serdeable
173189
public record UserPermissionsRequest(@NotNull Long tenantId,
174190
@NotNull Long serviceId) {
175191

176192
}
177193

178-
@Serdeable
179-
public record UserPermissionsResponse(List<String> permissions){}
180-
181194
}

UnityAuth/src/test/java/io/unityfoundation/UnityIamTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.micronaut.security.token.render.BearerAccessRefreshToken;
1515
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
1616
import io.unityfoundation.auth.AuthController.HasPermissionResponse;
17+
import io.unityfoundation.auth.AuthController.UserPermissionsRequest;
18+
import io.unityfoundation.auth.AuthController.UserPermissionsResponse;
1719
import io.unityfoundation.auth.HasPermissionRequest;
1820
import jakarta.inject.Inject;
1921
import java.util.List;
@@ -120,6 +122,31 @@ void testHasNoSubtenantPermission() {
120122
assertNull(response.getBody().get().permissions());
121123
}
122124

125+
126+
@Test
127+
void testGetUserPermissionsDisabled() {
128+
String accessToken = login("[email protected]");
129+
HttpRequest<?> hasPermissionRequest = HttpRequest.POST("/api/principal/permissions",
130+
new UserPermissionsRequest(1L, 1L))
131+
.bearerAuth(accessToken);
132+
HttpResponse<UserPermissionsResponse.Failure> response = client.toBlocking()
133+
.exchange(hasPermissionRequest, UserPermissionsResponse.Failure.class);
134+
UserPermissionsResponse.Failure failure = response.getBody().orElseThrow();
135+
assertEquals("The user's account has been disabled.", failure.errorMessage());
136+
}
137+
138+
@Test
139+
void testGetUserPermissionsHappyPath() {
140+
String accessToken = login("[email protected]");
141+
HttpRequest<?> hasPermissionRequest = HttpRequest.POST("/api/principal/permissions",
142+
new UserPermissionsRequest(1L, 1L))
143+
.bearerAuth(accessToken);
144+
HttpResponse<UserPermissionsResponse.Success> response = client.toBlocking()
145+
.exchange(hasPermissionRequest, UserPermissionsResponse.Success.class);
146+
147+
assertEquals(response.getBody().get().permissions(), List.of("AUTH_SERVICE_EDIT-SYSTEM"));
148+
}
149+
123150
private String login(String username) {
124151
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, "test");
125152
HttpRequest<?> request = HttpRequest.POST("/api/login", creds);

0 commit comments

Comments
 (0)