55import edu .stanford .protege .webprotege .common .ProjectId ;
66import edu .stanford .protege .webprotege .ipc .EventDispatcher ;
77import org .bson .Document ;
8+ import org .keycloak .common .VerificationException ;
89import org .slf4j .Logger ;
910import org .slf4j .LoggerFactory ;
1011import org .springframework .data .mongodb .core .MongoTemplate ;
@@ -49,19 +50,29 @@ public class AccessManagerImpl implements AccessManager {
4950
5051 private final EventDispatcher eventDispatcher ;
5152
53+ private final TokenValidator tokenValidator ;
54+
55+ private final BuiltInRoleOracle builtInRoleOracle ;
56+
5257 /**
5358 * Constructs an {@link AccessManager} that is backed by MongoDb.
5459 *
5560 * @param mongoTemplate A {@link MongoTemplate} that is used to access MongoDb.
5661 */
5762 public AccessManagerImpl (ObjectMapper objectMapper ,
5863 MongoTemplate mongoTemplate ,
59- ProjectRoleDefinitionsManager projectRoleDefinitionsManager , RoleDefinitionsManager roleDefinitionsManager , EventDispatcher eventDispatcher ) {
64+ ProjectRoleDefinitionsManager projectRoleDefinitionsManager ,
65+ RoleDefinitionsManager roleDefinitionsManager ,
66+ EventDispatcher eventDispatcher ,
67+ TokenValidator tokenValidator ,
68+ BuiltInRoleOracle builtInRoleOracle ) {
6069 this .objectMapper = objectMapper ;
6170 this .mongoTemplate = mongoTemplate ;
6271 this .projectRoleDefinitionsManager = projectRoleDefinitionsManager ;
6372 this .roleDefinitionsManager = roleDefinitionsManager ;
6473 this .eventDispatcher = eventDispatcher ;
74+ this .tokenValidator = tokenValidator ;
75+ this .builtInRoleOracle = builtInRoleOracle ;
6576 }
6677
6778 /**
@@ -241,12 +252,31 @@ public Set<Capability> getCapabilityClosure(@Nonnull Subject subject, @Nonnull R
241252 }
242253
243254 @ Override
244- public boolean hasPermission (@ Nonnull Subject subject , @ Nonnull Resource resource , @ Nonnull Capability capability ) {
255+ public boolean hasPermission (@ Nonnull Subject subject , @ Nonnull Resource resource , @ Nonnull Capability capability , String jwt ) {
256+ logger .info ("Checking permission for subject {} and resource {} with capability: {}" , subject , resource , capability );
257+
245258 lock .readLock ().lock ();
246259 try {
247- return find (withUserOrAnyUserAndTarget (subject , resource ))
260+ List < Capability > capabilities = new ArrayList <>( find (withUserOrAnyUserAndTarget (subject , resource ))
248261 .map (d -> objectMapper .convertValue (d , RoleAssignment .class ))
249- .anyMatch (roleAssignment -> roleAssignment .getCapabilityClosure ().contains (capability ));
262+ .flatMap (roleAssignment -> roleAssignment .getCapabilityClosure ().stream ())
263+ .toList ());
264+
265+ if (jwt != null && !jwt .isEmpty ()) {
266+ try {
267+ List <RoleId > roleIds = tokenValidator .extractClaimsWithoutVerification (jwt ).stream ()
268+ .map (RoleId ::new )
269+ .toList ();
270+ capabilities .addAll (builtInRoleOracle .getCapabilitiesAssociatedToRoles (roleIds ));
271+ } catch (VerificationException e ) {
272+ logger .error ("Error getting token claims" , e );
273+ throw new RuntimeException (e );
274+ }
275+ }
276+
277+
278+ return capabilities .contains (capability );
279+
250280 } finally {
251281 lock .readLock ().unlock ();
252282 }
@@ -285,7 +315,8 @@ public Collection<Resource> getResourcesAccessibleToSubject(Subject subject, Cap
285315 lock .readLock ().lock ();
286316 try {
287317 var userName = toUserName (subject );
288- var query = query (where (USER_NAME ).is (userName ).and (CAPABILITY_CLOSURE ).is (capability .id ()));
318+ logger .info ("Trying to fetch resources {} and capability {}" , userName , capability .id ());
319+ var query = query (where (USER_NAME ).is (userName ).and (CAPABILITY_CLOSURE + ".id" ).is (capability .id ()));
289320 return find (query )
290321 .map (f -> objectMapper .convertValue (f , RoleAssignment .class ))
291322 .map (ra -> {
@@ -331,7 +362,7 @@ public void rebuild() {
331362 public void rebuild (ProjectId projectId ) {
332363 lock .writeLock ().lock ();
333364 try {
334- logger .info ("Rebuilding permissions for project: {}" , projectId );
365+ logger .info ("Rebuilding permissions for project: {}" , projectId );
335366 var criteria = where (PROJECT_ID ).is (projectId .value ());
336367 var queryObject = new Query (criteria ).getQueryObject ();
337368 rebuildMatchingRoleAssignments (queryObject );
@@ -345,7 +376,7 @@ private void rebuildMatchingRoleAssignments(Document queryObject) {
345376 var collection = mongoTemplate .getCollection (COLLECTION_NAME );
346377 collection .find (queryObject )
347378 .forEach (roleAssignmentDoc -> {
348- final var roleAssignmentId = roleAssignmentDoc .get ("_id" );
379+ final var roleAssignmentId = roleAssignmentDoc .get ("_id" );
349380 var roleAssignment = objectMapper .convertValue (roleAssignmentDoc , RoleAssignment .class );
350381
351382 // For each role assignment we compute the role closure and then
@@ -373,8 +404,8 @@ private void rebuildMatchingRoleAssignments(Document queryObject) {
373404 sortedCapabilityClosure );
374405
375406 var updatedRoleAssignmentDoc = objectMapper .convertValue (updatedRoleAssignment , Document .class );
376- updatedRoleAssignmentDoc .put ("_id" , roleAssignmentId );
377- collection .replaceOne (new Document ("_id" , roleAssignmentId ), updatedRoleAssignmentDoc );
407+ updatedRoleAssignmentDoc .put ("_id" , roleAssignmentId );
408+ collection .replaceOne (new Document ("_id" , roleAssignmentId ), updatedRoleAssignmentDoc );
378409 });
379410 }
380411
0 commit comments