Skip to content

Commit

Permalink
Merge branch 'feature/improve-group-mapper' into 'master'
Browse files Browse the repository at this point in the history
Improve group mapper

See merge request waldur/waldur-keycloak-mapper!13
  • Loading branch information
livenson committed Aug 28, 2024
2 parents cb2f84b + 1fe5ffe commit 4c761cd
Showing 1 changed file with 82 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
import org.apache.http.HttpHeaders;
import org.jboss.logging.Logger;
import org.keycloak.models.ClientSessionContext;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.mappers.AbstractOIDCProtocolMapper;
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
Expand All @@ -25,63 +29,65 @@

import com.fasterxml.jackson.databind.ObjectMapper;

public class WaldurOIDCGroupMapper extends AbstractOIDCProtocolMapper
public class WaldurOIDCOfferingAccessMapper extends AbstractOIDCProtocolMapper
implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper {

private static final String GROUP_NAME = "Viewers";

public static final String PROVIDER_ID = "oidc-waldur-group-mapper";
public static final String PROVIDER_ID = "oidc-waldur-offering-access-mapper";

private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();

private static final Logger LOGGER = Logger.getLogger(WaldurOIDCGroupMapper.class.getName());
private static final Logger LOGGER = Logger.getLogger(WaldurOIDCOfferingAccessMapper.class.getName());

private static final String API_URL_KEY = "url.waldur.api.value";
private static final String API_TOKEN_KEY = "token.waldur.value";
private static final String OFFERING_UUID_KEY = "uuid.waldur.offering.value";
private static final String PROVIDER_UUID_KEY = "uuid.waldur.provider.value";

private static final String GROUP_NAME_KEY = "name.keycloak.group.value";

static {
ProviderConfigProperty property;

property = new ProviderConfigProperty(
API_URL_KEY,
"Waldur API URL",
"URL to the Waldur API including trailing backslash, e.g. https://waldur.example.com/api/",
ProviderConfigProperty.STRING_TYPE,
""
);
API_URL_KEY,
"Waldur API URL",
"URL to the Waldur API including trailing backslash, e.g. https://waldur.example.com/api/",
ProviderConfigProperty.STRING_TYPE,
"");
configProperties.add(property);

property = new ProviderConfigProperty(
PROVIDER_UUID_KEY,
"Waldur provider UUID",
"UUID of the provider in Waldur",
ProviderConfigProperty.STRING_TYPE,
"");
configProperties.add(property);

property = new ProviderConfigProperty(
PROVIDER_UUID_KEY,
"Waldur provider UUID",
"UUID of the provider in Waldur",
ProviderConfigProperty.STRING_TYPE,
""
);
OFFERING_UUID_KEY,
"Waldur offering UUID",
"UUID of the offering in Waldur",
ProviderConfigProperty.STRING_TYPE,
"");
configProperties.add(property);

property = new ProviderConfigProperty(
OFFERING_UUID_KEY,
"Waldur offering UUID",
"UUID of the offering in Waldur",
ProviderConfigProperty.STRING_TYPE,
""
);
API_TOKEN_KEY,
"Waldur API token",
"Token for Waldur API",
ProviderConfigProperty.STRING_TYPE,
"");
configProperties.add(property);

property = new ProviderConfigProperty(
API_TOKEN_KEY,
"Waldur API token",
"Token for Waldur API",
ProviderConfigProperty.STRING_TYPE,
""
);;
GROUP_NAME_KEY,
"Keycloak group name.",
"Name of the precreated group in Keycloak.",
ProviderConfigProperty.STRING_TYPE,
"");
configProperties.add(property);

OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, WaldurOIDCGroupMapper.class);
OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, WaldurOIDCOfferingAccessMapper.class);
}

private boolean hasRelatedOfferingUser(String waldurUrl, String providerUuid, String waldurToken, String username) {
Expand Down Expand Up @@ -119,7 +125,7 @@ private boolean hasRelatedOfferingUser(String waldurUrl, String providerUuid, St
}

private boolean hasAccessToResource(String waldurUrl, String offeringUuid, String waldurToken, String username) {
if (offeringUuid.equals("")){
if (offeringUuid.equals("")) {
LOGGER.error("Offering UUID is empty, skipping resource access check");
return false;
}
Expand Down Expand Up @@ -157,24 +163,52 @@ private boolean hasAccessToResource(String waldurUrl, String offeringUuid, Strin
return false;
}

@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession,
KeycloakSession keycloakSession,
ClientSessionContext clientSessionCtx) {

private void transformToken(IDToken token, Map<String, String> config, KeycloakSession keycloakSession,
UserSessionModel userSession) {
String username = userSession.getUser().getUsername();

final String waldurUrl = mappingModel.getConfig().get(API_URL_KEY);
final String providerUuid = mappingModel.getConfig().get(PROVIDER_UUID_KEY);
final String offeringUuid = mappingModel.getConfig().get(OFFERING_UUID_KEY);
final String waldurToken = mappingModel.getConfig().get(API_TOKEN_KEY);
final String waldurUrl = config.get(API_URL_KEY);
final String providerUuid = config.get(PROVIDER_UUID_KEY);
final String offeringUuid = config.get(OFFERING_UUID_KEY);
final String groupName = config.get(GROUP_NAME_KEY);
final String waldurToken = config.get(API_TOKEN_KEY);

UserModel user = userSession.getUser();
RealmModel realm = keycloakSession.getContext().getRealm();
String groupPath = String.format("/%s", groupName);
GroupModel group = KeycloakModelUtils.findGroupByPath(realm, groupName);

if (group == null) {
LOGGER.error(String.format("The group %s (path %s) does not exist, skipping user processing.",
groupName,
groupPath));
return;
}

boolean hasRelatedOfferingUser = this.hasRelatedOfferingUser(waldurUrl, providerUuid, waldurToken, username);
if (!hasRelatedOfferingUser)
return;
boolean hasAccessToResoure = this.hasAccessToResource(waldurUrl, offeringUuid, waldurToken, username);
if (hasAccessToResoure)
token.getOtherClaims().put("groups", GROUP_NAME);
boolean hasAccessToResource = this.hasAccessToResource(waldurUrl, offeringUuid, waldurToken, username);

if (hasAccessToResource) {
if (!user.isMemberOf(group)) {
LOGGER.info(String.format("The user %s is already in the group %s", user.getUsername(), group.getName()));
}
else {
LOGGER.info(String.format("Adding user %s to group %s", user.getUsername(), group.getName()));
user.joinGroup(group);
}
} else if(user.isMemberOf(group)) {
LOGGER.info(String.format("Removing user %s from group %s", user.getUsername(), group.getName()));
}
}

@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession,
KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) {
Map<String, String> config = mappingModel.getConfig();

this.transformToken(token, config, keycloakSession, userSession);
}

public static ProtocolMapperModel create(
Expand All @@ -183,6 +217,7 @@ public static ProtocolMapperModel create(
String providerUuid,
String offeringUuid,
String apiToken,
String groupName,
boolean accessToken,
boolean idToken,
boolean userInfo) {
Expand All @@ -195,6 +230,7 @@ public static ProtocolMapperModel create(
config.put(API_URL_KEY, url);
config.put(PROVIDER_UUID_KEY, providerUuid);
config.put(API_TOKEN_KEY, apiToken);
config.put(GROUP_NAME_KEY, groupName);

config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(accessToken));
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(accessToken));
Expand All @@ -216,7 +252,7 @@ public String getDisplayCategory() {

@Override
public String getDisplayType() {
return "Waldur group mapper";
return "Waldur offering access mapper";
}

@Override
Expand All @@ -226,6 +262,6 @@ public String getId() {

@Override
public String getHelpText() {
return "Mapper for group from Waldur";
return "Mapper for offering access from Waldur";
}
}

0 comments on commit 4c761cd

Please sign in to comment.