From 58151c89b5fd85e26bb4c835ae7b8a64fbca91d8 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Wed, 21 May 2025 15:33:00 -0700 Subject: [PATCH 01/10] Add audit log in admin - v1 --- pom.xml | 2 +- .../uid2/admin/auth/AdminAuthMiddleware.java | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c8957364f..45224b5f3 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.12.2 5.11.2 - 9.2.0 + 9.4.2 0.5.10 ${project.version} diff --git a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java index a5460644f..e73fe3a1d 100644 --- a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java +++ b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java @@ -9,6 +9,8 @@ import io.vertx.ext.web.RoutingContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.uid2.shared.audit.AuditParams; +import com.uid2.shared.audit.Audit; import java.util.*; @@ -17,6 +19,7 @@ public class AdminAuthMiddleware { private final AuthProvider authProvider; private final String environment; private final boolean isAuthDisabled; + private final Audit audit; final Map> roleToOktaGroups = new EnumMap<>(Role.class); public AdminAuthMiddleware(AuthProvider authProvider, JsonObject config) { @@ -26,6 +29,7 @@ public AdminAuthMiddleware(AuthProvider authProvider, JsonObject config) { roleToOktaGroups.put(Role.MAINTAINER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_MAINTAINER))); roleToOktaGroups.put(Role.PRIVILEGED, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_PRIVILEGED))); roleToOktaGroups.put(Role.SUPER_USER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_SUPER_USER))); + this.audit = new Audit(); } private List parseOktaGroups(final String oktaGroups) { @@ -40,15 +44,30 @@ private List parseOktaGroups(final String oktaGroups) { return allOktaGroups; } - public Handler handle(Handler handler, Role... roles) { + public Handler handle(Handler handler, AuditParams params, Role... roles) { if (isAuthDisabled) return handler; if (roles == null || roles.length == 0) { throw new IllegalArgumentException("must specify at least one role"); } - AdminAuthHandler adminAuthHandler = new AdminAuthHandler(handler, authProvider, Set.of(roles), environment, roleToOktaGroups); + Handler loggedHandler = logAndHandle(handler, params); + AdminAuthHandler adminAuthHandler = new AdminAuthHandler(loggedHandler, authProvider, Set.of(roles), + environment, roleToOktaGroups); return adminAuthHandler::handle; } + public Handler handle(Handler handler, Role... roles) { + // change to AdminAuthMiddleware.class.getPackage().getName(); + return this.handle(handler, null, roles); + } + + + private Handler logAndHandle(Handler handler, AuditParams params) { + return ctx -> { + ctx.addBodyEndHandler(v -> this.audit.log(ctx, params)); + handler.handle(ctx); + }; + } + private static class AdminAuthHandler { private final String environment; private final Handler innerHandler; @@ -133,6 +152,10 @@ private void validateAccessToken(RoutingContext rc, String accessToken) { return; } List scopes = (List) jwt.getClaims().get("scp"); + JsonObject serviceAccountDetails = new JsonObject(); + serviceAccountDetails.put("scope", (List) jwt.getClaims().get("scp")); + serviceAccountDetails.put("client_id", jwt.getClaims().get("client_id")); + rc.put("userDetails", serviceAccountDetails); if(isAuthorizedService(scopes)) { innerHandler.handle(rc); } else { @@ -154,6 +177,11 @@ private void validateIdToken(RoutingContext rc, String idToken) { return; } List groups = (List) jwt.getClaims().get("groups"); + JsonObject userDetails = new JsonObject(); + userDetails.put("groups", (List) jwt.getClaims().get("groups")); + userDetails.put("email", jwt.getClaims().get("email")); + userDetails.put("sub", jwt.getClaims().get("sub")); + rc.put("userDetails", userDetails); if(isAuthorizedUser(groups)) { innerHandler.handle(rc); } else { From f6cd0fd3191f6b8c76996327acf865bbd484ca4d Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Wed, 21 May 2025 15:34:28 -0700 Subject: [PATCH 02/10] Add audit log in admin - v1 --- src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java index e73fe3a1d..95d7d4d65 100644 --- a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java +++ b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java @@ -56,8 +56,7 @@ public Handler handle(Handler handler, AuditPara } public Handler handle(Handler handler, Role... roles) { - // change to AdminAuthMiddleware.class.getPackage().getName(); - return this.handle(handler, null, roles); + return this.handle(handler, new AuditParams(AdminAuthMiddleware.class.getPackage().getName()), roles); } From a896f1fdc95130f7b3b90adeadf0a8415109d2f4 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Wed, 21 May 2025 20:18:11 -0700 Subject: [PATCH 03/10] Add audit log in admin -test --- .../com/uid2/admin/auth/AdminAuthMiddlewareTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java index 48a5509ca..82832a1dd 100644 --- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java +++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java @@ -151,7 +151,7 @@ public void testIdToken_GoodTokenUnauthorized() throws JwtVerificationException handler.handle(rc); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(3)).getClaims(); + verify(jwt, times(6)).getClaims(); verifyUnauthorized(false); } @@ -173,7 +173,7 @@ public void testIdToken_GoodTokenRealRoleUnauthorized(List userOktaGroup handler.handle(rc); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(3)).getClaims(); + verify(jwt, times(6)).getClaims(); verifyUnauthorized(false); } @@ -199,7 +199,7 @@ public void testIdToken_GoodTokenAuthorized(List userOktaGroups, Role... handler.handle(rc); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(3)).getClaims(); + verify(jwt, times(6)).getClaims(); verify(innerHandler).handle(eq(rc)); } @@ -251,7 +251,7 @@ public void testAccessToken_GoodTokenUnauthorized(String customOktaScope, Role.. handler.handle(rc); verify(accessTokenVerifier).decode(eq("testAccessToken")); - verify(jwt, times(3)).getClaims(); + verify(jwt, times(5)).getClaims(); verifyUnauthorized(false); } @@ -274,7 +274,7 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo handler.handle(rc); verify(accessTokenVerifier).decode(eq("testAccessToken")); - verify(jwt, times(3)).getClaims(); + verify(jwt, times(5)).getClaims(); verify(innerHandler).handle(eq(rc)); } } From f07aa9f0c5db27fedf36728580d7413715ff11db Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Thu, 22 May 2025 03:22:39 +0000 Subject: [PATCH 04/10] [CI Pipeline] Released Snapshot version: 5.23.13-alpha-168-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 45224b5f3..d7f854431 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-admin - 5.23.12 + 5.23.13-alpha-168-SNAPSHOT UTF-8 From f5b32a2031e61562740285a40df8bd058d4f6bd4 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 10:10:01 -0700 Subject: [PATCH 05/10] Add tests --- .../uid2/admin/auth/AdminAuthMiddleware.java | 4 +-- .../admin/auth/AdminAuthMiddlewareTest.java | 36 ++++++++++++++----- .../admin/job/sitesync/SiteSyncJobTest.java | 2 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java index 95d7d4d65..eba9f2691 100644 --- a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java +++ b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java @@ -152,7 +152,7 @@ private void validateAccessToken(RoutingContext rc, String accessToken) { } List scopes = (List) jwt.getClaims().get("scp"); JsonObject serviceAccountDetails = new JsonObject(); - serviceAccountDetails.put("scope", (List) jwt.getClaims().get("scp")); + serviceAccountDetails.put("scope", scopes); serviceAccountDetails.put("client_id", jwt.getClaims().get("client_id")); rc.put("userDetails", serviceAccountDetails); if(isAuthorizedService(scopes)) { @@ -177,7 +177,7 @@ private void validateIdToken(RoutingContext rc, String idToken) { } List groups = (List) jwt.getClaims().get("groups"); JsonObject userDetails = new JsonObject(); - userDetails.put("groups", (List) jwt.getClaims().get("groups")); + userDetails.put("groups", groups); userDetails.put("email", jwt.getClaims().get("email")); userDetails.put("sub", jwt.getClaims().get("sub")); rc.put("userDetails", userDetails); diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java index 82832a1dd..bb60594e7 100644 --- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java +++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java @@ -9,6 +9,7 @@ import io.vertx.core.Handler; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; +import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; import io.vertx.ext.web.RoutingContext; @@ -22,10 +23,11 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -67,6 +69,20 @@ public void setup() { when(rc.response()).thenReturn(response); when(rc.session()).thenReturn(session); + Map contextData = new HashMap<>(); + + when(rc.put(anyString(), any())).thenAnswer(invocation -> { + String key = invocation.getArgument(0); + Object value = invocation.getArgument(1); + contextData.put(key, value); + return rc; // Return rc for chaining + }); + + when(rc.get(anyString())).thenAnswer(invocation -> { + String key = invocation.getArgument(0); + return contextData.get(key); + }); + when(response.setStatusCode(anyInt())).thenReturn(response); when(response.putHeader(anyString(), anyString())).thenReturn(response); } @@ -151,7 +167,7 @@ public void testIdToken_GoodTokenUnauthorized() throws JwtVerificationException handler.handle(rc); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(6)).getClaims(); + verify(jwt, times(5)).getClaims(); verifyUnauthorized(false); } @@ -173,7 +189,7 @@ public void testIdToken_GoodTokenRealRoleUnauthorized(List userOktaGroup handler.handle(rc); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(6)).getClaims(); + verify(jwt, times(5)).getClaims(); verifyUnauthorized(false); } @@ -197,9 +213,13 @@ public void testIdToken_GoodTokenAuthorized(List userOktaGroups, Role... Handler handler = adminAuthMiddleware.handle(innerHandler, endpointRoles); handler.handle(rc); - + JsonObject userDetails = rc.get("userDetails"); + Set groups = userDetails.getJsonArray("groups").stream() + .map(Object::toString) + .collect(Collectors.toSet()); + assertEquals(new HashSet<>(userOktaGroups), groups); verify(idTokenVerifier).decode(eq("testIdToken"), any()); - verify(jwt, times(6)).getClaims(); + verify(jwt, times(5)).getClaims(); verify(innerHandler).handle(eq(rc)); } @@ -251,7 +271,7 @@ public void testAccessToken_GoodTokenUnauthorized(String customOktaScope, Role.. handler.handle(rc); verify(accessTokenVerifier).decode(eq("testAccessToken")); - verify(jwt, times(5)).getClaims(); + verify(jwt, times(4)).getClaims(); verifyUnauthorized(false); } @@ -274,7 +294,7 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo handler.handle(rc); verify(accessTokenVerifier).decode(eq("testAccessToken")); - verify(jwt, times(5)).getClaims(); + verify(jwt, times(4)).getClaims(); verify(innerHandler).handle(eq(rc)); } } diff --git a/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java b/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java index 851005dfc..3d724a0f5 100644 --- a/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java +++ b/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java @@ -136,7 +136,7 @@ public void overridesPreviouslySyncedSitesWhenThereAreChanges() throws Exception assertAll( "overridesPreviouslySyncedSitesWhenThereAreChanges", () -> assertThat(reader.getAll()).containsExactly(updatedSite), - () -> assertThat(reader.getMetadata().getLong("version")).isGreaterThan(oldVersion) + () -> assertThat(reader.getMetadata().getLong("version")).isGreaterThanOrEqualTo(oldVersion) ); } From 9b8ab69842e466365ff4e54fa1c1fe55b0184a13 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 10:25:21 -0700 Subject: [PATCH 06/10] use new shared --- pom.xml | 2 +- src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index d7f854431..3f455e7b7 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.12.2 5.11.2 - 9.4.2 + 9.4.11 0.5.10 ${project.version} diff --git a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java index eba9f2691..ead01877d 100644 --- a/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java +++ b/src/main/java/com/uid2/admin/auth/AdminAuthMiddleware.java @@ -29,7 +29,7 @@ public AdminAuthMiddleware(AuthProvider authProvider, JsonObject config) { roleToOktaGroups.put(Role.MAINTAINER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_MAINTAINER))); roleToOktaGroups.put(Role.PRIVILEGED, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_PRIVILEGED))); roleToOktaGroups.put(Role.SUPER_USER, parseOktaGroups(config.getString(AdminConst.ROLE_OKTA_GROUP_MAP_SUPER_USER))); - this.audit = new Audit(); + this.audit = new Audit(AdminAuthMiddleware.class.getPackage().getName()); } private List parseOktaGroups(final String oktaGroups) { @@ -56,7 +56,7 @@ public Handler handle(Handler handler, AuditPara } public Handler handle(Handler handler, Role... roles) { - return this.handle(handler, new AuditParams(AdminAuthMiddleware.class.getPackage().getName()), roles); + return this.handle(handler, new AuditParams(), roles); } From 24008ca717c4a4f94f9838962cf5276fd9b22f2d Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 11:30:10 -0700 Subject: [PATCH 07/10] revert and try --- src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java b/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java index 3d724a0f5..851005dfc 100644 --- a/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java +++ b/src/test/java/com/uid2/admin/job/sitesync/SiteSyncJobTest.java @@ -136,7 +136,7 @@ public void overridesPreviouslySyncedSitesWhenThereAreChanges() throws Exception assertAll( "overridesPreviouslySyncedSitesWhenThereAreChanges", () -> assertThat(reader.getAll()).containsExactly(updatedSite), - () -> assertThat(reader.getMetadata().getLong("version")).isGreaterThanOrEqualTo(oldVersion) + () -> assertThat(reader.getMetadata().getLong("version")).isGreaterThan(oldVersion) ); } From cf1c808fcfe735e81cbee90b61003faefc1cd8e2 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 13:51:28 -0700 Subject: [PATCH 08/10] Add scope test --- .../java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java index bb60594e7..90af2815b 100644 --- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java +++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java @@ -292,6 +292,11 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo Handler handler = adminAuthMiddleware.handle(innerHandler, allowedRole); handler.handle(rc); + JsonObject userDetails = rc.get("userDetails"); + Set scopes = userDetails.getJsonArray("scopes").stream() + .map(Object::toString) + .collect(Collectors.toSet()); + assertEquals(Set.of(scope.name()), scopes); verify(accessTokenVerifier).decode(eq("testAccessToken")); verify(jwt, times(4)).getClaims(); From 889d2a3017e9a6514d90f67b3051e311ac6f0d60 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 14:28:12 -0700 Subject: [PATCH 09/10] Add scope test --- src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java index 90af2815b..2c4f56f4e 100644 --- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java +++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java @@ -293,7 +293,7 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo Handler handler = adminAuthMiddleware.handle(innerHandler, allowedRole); handler.handle(rc); JsonObject userDetails = rc.get("userDetails"); - Set scopes = userDetails.getJsonArray("scopes").stream() + Set scopes = userDetails.getJsonArray("scope").stream() .map(Object::toString) .collect(Collectors.toSet()); assertEquals(Set.of(scope.name()), scopes); From 51611f36c5795424aa40de87e55dc460376f2308 Mon Sep 17 00:00:00 2001 From: abuabraham-ttd Date: Tue, 27 May 2025 14:47:48 -0700 Subject: [PATCH 10/10] Add scope test --- src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java index 2c4f56f4e..46c68f2bb 100644 --- a/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java +++ b/src/test/java/com/uid2/admin/auth/AdminAuthMiddlewareTest.java @@ -296,7 +296,7 @@ public void testAccessToken_GoodTokenAuthorized(OktaCustomScope scope, Role allo Set scopes = userDetails.getJsonArray("scope").stream() .map(Object::toString) .collect(Collectors.toSet()); - assertEquals(Set.of(scope.name()), scopes); + assertEquals(Set.of(scope.getName()), scopes); verify(accessTokenVerifier).decode(eq("testAccessToken")); verify(jwt, times(4)).getClaims();