Skip to content

Commit

Permalink
Use userId to filter users returned by Kessel (#3219)
Browse files Browse the repository at this point in the history
* Use userId to filter users returned by Kessel
  • Loading branch information
g-duval authored Dec 18, 2024
1 parent c7e4ecf commit 706b9f0
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 18 deletions.
4 changes: 4 additions & 0 deletions .rhcicd/clowdapp-recipients-resolver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ objects:
key: relations-api.client.secret
- name: RELATIONS_API_IS_SECURE_CLIENTS
value: ${NOTIFICATIONS_KESSEL_RELATIONS_SECURE_CLIENTS}
- name: KESSEL_DOMAIN
value: ${KESSEL_DOMAIN}
parameters:
- name: CLOUDWATCH_ENABLED
description: Enable Cloudwatch (or not)
Expand Down Expand Up @@ -285,3 +287,5 @@ parameters:
- name: NOTIFICATIONS_KESSEL_OIDC_ISSUER
description: Specifies the issuer of the OIDC authentication tokens.
value: "https://redhat.com/realms/redhat-external"
- name: KESSEL_DOMAIN
value: "redhat"
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class RecipientsResolverConfig {
private static final String KESSEL_CLIENT_SECRET = "relations-api.authn.client.secret";
private static final String KESSEL_CLIENT_ISSUER = "relations-api.authn.client.issuer";
private static final String KESSEL_CLIENT_MODE = "relations-api.authn.mode";
private static final String KESSEL_DOMAIN = "notifications.kessel.domain";

/*
* Unleash configuration
Expand Down Expand Up @@ -118,6 +119,9 @@ public class RecipientsResolverConfig {
@ConfigProperty(name = "quarkus.rest-client.it-s2s.key-store-password")
Optional<String> quarkusItServicePassword;

@ConfigProperty(name = KESSEL_DOMAIN, defaultValue = "redhat")
String kesselDomain;

@PostConstruct
void postConstruct() {
fetchUsersWithMbopToggle = toggleRegistry.register("fetch-users-with-mbop", true);
Expand All @@ -140,6 +144,7 @@ void logConfigAtStartup(@Observes Startup event) {
config.put(useKesselToggle, isUseKesselEnabled(null));
config.put(KESSEL_TARGET_URL, getKesselTargetUrl());
config.put(KESSEL_USE_SECURE_CLIENT, isKesselUseSecureClient());
config.put(KESSEL_DOMAIN, getKesselDomain());

Log.info("=== Startup configuration ===");
config.forEach((key, value) -> {
Expand Down Expand Up @@ -244,4 +249,8 @@ public Optional<String> getKesselClientIssuer() {
public AuthenticationConfig.AuthMode getKesselClientMode() {
return kesselClientMode;
}

public String getKesselDomain() {
return kesselDomain;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ private Set<User> recipientUsers(String orgId, RecipientSettings request, Option
fetchedUsers = fetchingUsers.getGroupUsers(orgId, request.isAdminsOnly(), request.getGroupUUID());
}

final Set<String> authorizedUsers = new HashSet<>();
final Set<String> authorizedUserIds = new HashSet<>();
if (recipientsResolverConfig.isUseKesselEnabled(orgId) && !fetchedUsers.isEmpty() && null != recipientsAuthorizationCriterion) {
authorizedUsers.addAll(findAuthorizedUsersWithCriterion(recipientsAuthorizationCriterion));
authorizedUserIds.addAll(findAuthorizedUsersWithCriterion(recipientsAuthorizationCriterion));
Log.infof("Found %d authorized users in Kessel for orgId %s and criterion %s", authorizedUserIds.size(), orgId, recipientsAuthorizationCriterion);
}

// The fetched users are cached, so we need to create a new Set to avoid altering the cached data.
Expand All @@ -86,7 +87,7 @@ private Set<User> recipientUsers(String orgId, RecipientSettings request, Option
return true;
}

if (recipientsResolverConfig.isUseKesselEnabled(orgId) && null != recipientsAuthorizationCriterion && !authorizedUsers.contains(lowerCaseUsername)) {
if (recipientsResolverConfig.isUseKesselEnabled(orgId) && null != recipientsAuthorizationCriterion && !authorizedUserIds.contains(user.getId())) {
return true;
}

Expand Down Expand Up @@ -145,11 +146,7 @@ private static Optional<Set<String>> extractRequestUsersIntersection(Set<Recipie
private Set<String> findAuthorizedUsersWithCriterion(RecipientsAuthorizationCriterion externalAuthorizationCriteria) {
Set<String> authorizedUsers = new HashSet<>();
if (externalAuthorizationCriteria != null) {
try {
authorizedUsers = kesselLookupService.lookupSubjects(externalAuthorizationCriteria);
} catch (Exception ex) {
Log.error("Error calling Kessel relationship Api", ex);
}
authorizedUsers = kesselLookupService.lookupSubjects(externalAuthorizationCriteria);
}
return authorizedUsers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ public Optional<String> oidcClientCredentialsMinterImplementation() {
}

public Set<String> lookupSubjects(RecipientsAuthorizationCriterion recipientsAuthorizationCriterion) {
Set<String> userNames = new HashSet<>();
Set<String> userIds = new HashSet<>();
LookupSubjectsRequest request = getLookupSubjectsRequest(recipientsAuthorizationCriterion);

for (Iterator<LookupSubjectsResponse> it = lookupClient.lookupSubjects(request); it.hasNext();) {
LookupSubjectsResponse response = it.next();
Log.infof("Kessel response: %s", response);
userNames.add(response.getSubject().getSubject().getId());

userIds.add(response.getSubject().getSubject().getId().replaceAll(recipientsResolverConfig.getKesselDomain(), ""));
}
return userNames;
return userIds;
}

private static LookupSubjectsRequest getLookupSubjectsRequest(RecipientsAuthorizationCriterion recipientsAuthorizationCriterion) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ public class RecipientsResolverTest {
@CacheName("find-recipients")
Cache recipientsCache;

User user1 = createUser("user1", false);
User user2 = createUser("user2", false);
User user3 = createUser("user3", false);
User admin1 = createUser("admin1", true);
User admin2 = createUser("admin2", true);
User user1 = createUser("userId1", "user1", false);
User user2 = createUser("userId2", "user2", false);
User user3 = createUser("userId3", "user3", false);
User admin1 = createUser("adminId1", "admin1", true);
User admin2 = createUser("adminId2", "admin2", true);

UUID group1 = UUID.randomUUID();
UUID group2 = UUID.randomUUID();
Expand Down Expand Up @@ -146,7 +146,7 @@ void testNotSubscribedByDefaultAndAdminsOnlyWithOrWithoutKessel(boolean useKesse
externalAuthorizationCriteria.setId("defaultId");
externalAuthorizationCriteria.setRelation("relationship");
externalAuthorizationCriteria.setType(kesselAssetType);
when(kesselService.lookupSubjects(any())).thenReturn(Set.of("user1", "admin1"));
when(kesselService.lookupSubjects(any())).thenReturn(Set.of("userId1", "adminId1"));
}
Set<User> recipients = recipientsResolver.findRecipients(
ORG_ID,
Expand Down Expand Up @@ -620,10 +620,11 @@ void testRequestUsersIntersectionAndDisjointSets() {
verifyNoMoreInteractions(fetchUsersFromExternalServices);
}

public User createUser(String username, boolean isAdmin) {
public User createUser(String userId, String username, boolean isAdmin) {
User user = new User();
user.setUsername(username);
user.setAdmin(isAdmin);
user.setId(userId);
return user;
}
}

0 comments on commit 706b9f0

Please sign in to comment.