Skip to content

Commit

Permalink
Get matched roles and permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
asafshen committed Dec 20, 2023
1 parent 38dd4d4 commit 2e5bb69
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,10 @@ try {
// Handle the error
}

// Or get the matched roles/permissions
List<String> matchedPermissions = as.getMatchedPermissions(sessionToken, "my-tenant-ID", Arrays.asList("Permission1", "Permission2"));

List<String> matchedRoles = as.getMatchedRoles(sessionToken, "my-tenant-ID", Arrays.asList("Role1", "Role2"));
```

When not using tenants use:
Expand All @@ -539,6 +543,10 @@ try {
// Handle the error
}

// Or get the matched roles/permissions
List<String> matchedPermissions = as.getMatchedPermissions(sessionToken, Arrays.asList("Permission1", "Permission2"));

List<String> matchedRoles = as.getMatchedRoles(sessionToken, Arrays.asList("Role1", "Role2"));
```

### Logging Out
Expand Down
51 changes: 49 additions & 2 deletions src/main/java/com/descope/sdk/auth/AuthenticationService.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Token validateAndRefreshSessionWithTokens(String sessionToken, String refreshTok

/**
* Use to ensure that a validated session token has been granted the specified permissions. This
* is a shortcut for ValidateTenantPermissions(token, "", permissions)
* is a shortcut for validatePermissions(token, "", permissions)
*
* @param token - {@link Token Token}
* @param permissions - List of permissions.
Expand All @@ -72,9 +72,33 @@ Token validateAndRefreshSessionWithTokens(String sessionToken, String refreshTok
boolean validatePermissions(Token token, String tenant, List<String> permissions)
throws DescopeException;

/**
* Use to retrieves the permissions from top level token's claims that match the specified permissions list. This
* is a shortcut for getMatchedPermissions(token, "", permissions)
*
* @param token - {@link Token Token}
* @param permissions - List of permissions.
* @return is valid permissions.
* @throws DescopeException if there is an error
*/
List<String> getMatchedPermissions(Token token, List<String> permissions) throws DescopeException;

/**
* Use to retrieves the permissions from token's claims of a specific tenant
* that match the specified permissions list.
* This is a shortcut for getMatchedPermissions(token, "", permissions)
*
* @param token - {@link Token Token}
* @param tenant - Tenant ID.
* @param permissions - List of permissions.
* @return is valid permissions.
* @throws DescopeException if there is an error
*/
List<String> getMatchedPermissions(Token token, String tenant, List<String> permissions) throws DescopeException;

/**
* Use to ensure that a validated session token has been granted the specified roles. This is a
* shortcut for ValidateTenantRoles(token, "", roles)
* shortcut for validateRoles(token, "", roles)
*
* @param token - {@link Token Token}
* @param roles - List of roles.
Expand All @@ -95,6 +119,29 @@ boolean validatePermissions(Token token, String tenant, List<String> permissions
*/
boolean validateRoles(Token token, String tenant, List<String> roles) throws DescopeException;

/**
* Use to retrieves the roles from top level token's claims that match the specified roles list. This
* is a shortcut for getMatchedRoles(token, "", roles)
*
* @param token - {@link Token Token}
* @param roles - List of roles.
* @return is valid roles.
* @throws DescopeException if there is an error
*/
List<String> getMatchedRoles(Token token, List<String> roles) throws DescopeException;

/**
* Use to retrieves the roles from token's claims of a specific tenant
* that match the specified roles list.
*
* @param token - {@link Token Token}
* @param tenant - Tenant ID.
* @param roles - List of roles.
* @return is valid permissions.
* @throws DescopeException if there is an error
*/
List<String> getMatchedRoles(Token token, String tenant, List<String> roles) throws DescopeException;

/**
* Return the list of roles granted to the validated session token in the given tenant.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import com.descope.model.jwt.response.JWTResponse;
import com.descope.proxy.ApiProxy;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -89,6 +92,22 @@ public boolean validatePermissions(Token token, String tenant, List<String> perm
return CollectionUtils.isSubCollection(permissions, grantedPermissions);
}

@Override
public List<String> getMatchedPermissions(Token token, List<String> permissions) throws DescopeException {
return getMatchedPermissions(token, "", permissions);
}

@Override
public List<String> getMatchedPermissions(Token token, String tenant, List<String> permissions)
throws DescopeException {
if (CollectionUtils.isEmpty(permissions) || StringUtils.isNotBlank(tenant) && !isTenantAssociated(token, tenant)) {
return Collections.emptyList();
}
List<String> grantedPermissions = getPermissions(token, tenant);
Collection<String> intersection = CollectionUtils.intersection(permissions, grantedPermissions);
return new ArrayList<>(intersection);
}

@Override
public boolean validateRoles(Token token, List<String> roles) throws DescopeException {
return validateRoles(token, "", roles);
Expand All @@ -104,6 +123,21 @@ public boolean validateRoles(Token token, String tenant, List<String> roles)
return CollectionUtils.isSubCollection(roles, grantedRoles);
}

@Override
public List<String> getMatchedRoles(Token token, List<String> roles) throws DescopeException {
return getMatchedRoles(token, "", roles);
}

@Override
public List<String> getMatchedRoles(Token token, String tenant, List<String> roles) throws DescopeException {
if (CollectionUtils.isEmpty(roles) || StringUtils.isNotBlank(tenant) && !isTenantAssociated(token, tenant)) {
return Collections.emptyList();
}
List<String> grantedRoles = getRoles(token, tenant);
Collection<String> intersection = CollectionUtils.intersection(roles, grantedRoles);
return new ArrayList<>(intersection);
}

@Override
public List<String> getRoles(Token token, String tenant) throws DescopeException {
return getAuthorizationClaimItems(token, tenant, ROLES_CLAIM_KEY);
Expand All @@ -130,7 +164,7 @@ public void logout(String refreshToken) throws DescopeException {
throw ServerCommonException.missingArguments("Request doesn't contain refresh token");
}
ApiProxy apiProxy = getApiProxy(refreshToken);
URI logOutURL = composeLogOutLinkURL();
URI logOutURL = composeLogOutLinkURL();
apiProxy.post(logOutURL, null, JWTResponse.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.descope.sdk.TestUtils.MOCK_TOKEN;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -63,6 +64,22 @@ void testPermissionsAndRoles() {
assertFalse(authenticationService.validateRoles(MOCK_TOKEN, Arrays.asList("r2", "r3")));
}

@Test
void textGetMatchedPermissionsAndRoles() {
assertEquals(Arrays.asList("tp1", "tp2"),
authenticationService.getMatchedPermissions(MOCK_TOKEN, "someTenant", Arrays.asList("tp1", "tp2")));
assertEquals(Arrays.asList(),
authenticationService.getMatchedPermissions(MOCK_TOKEN, "someTenant", null));
assertEquals(Arrays.asList("tp1", "tp2"),
authenticationService.getMatchedPermissions(MOCK_TOKEN, "someTenant", Arrays.asList("tp1", "tp2", "tp3")));
assertEquals(Arrays.asList("p1", "p2"),
authenticationService.getMatchedPermissions(MOCK_TOKEN, Arrays.asList("p1", "p2")));
assertEquals(Arrays.asList(),
authenticationService.getMatchedPermissions(MOCK_TOKEN, null));
assertEquals(Arrays.asList("p1", "p2"),
authenticationService.getMatchedPermissions(MOCK_TOKEN, Arrays.asList("p1", "p2", "p3")));
}

@RetryingTest(value = 3, suspendForMs = 30000, onExceptions = RateLimitExceededException.class)
void testFunctionalPermissions() {
String roleName = TestUtils.getRandomName("r-").substring(0, 20);
Expand Down

0 comments on commit 2e5bb69

Please sign in to comment.