package org.keycloak.social.openshift;
import com.fasterxml.jackson.databind.JsonNode;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper;
import org.keycloak.broker.oidc.util.JsonSimpleHttp;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.IdentityBrokerException;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.social.SocialIdentityProvider;
import org.keycloak.models.KeycloakSession;
import java.io.IOException;
import java.util.Optional;
/**
* Identity provider for Openshift V3. Check <a href="https://docs.openshift.com/enterprise/3.0/architecture/additional_concepts/authentication.html">official documentation</a> for more details.
*/
public class OpenshiftV3IdentityProvider extends AbstractOAuth2IdentityProvider<OpenshiftV3IdentityProviderConfig> implements SocialIdentityProvider<OpenshiftV3IdentityProviderConfig> {
public static final String BASE_URL = "https://api.preview.openshift.com";
private static final String AUTH_RESOURCE = "/oauth/authorize";
private static final String TOKEN_RESOURCE = "/oauth/token";
private static final String PROFILE_RESOURCE = "/oapi/v1/users/~";
private static final String DEFAULT_SCOPE = "user:info";
public OpenshiftV3IdentityProvider(KeycloakSession session, OpenshiftV3IdentityProviderConfig config) {
super(session, config);
final String baseUrl = Optional.ofNullable(config.getBaseUrl()).orElse(BASE_URL);
config.setAuthorizationUrl(baseUrl + AUTH_RESOURCE);
config.setTokenUrl(baseUrl + TOKEN_RESOURCE);
config.setUserInfoUrl(baseUrl + PROFILE_RESOURCE);
}
@Override
protected String getDefaultScopes() {
return DEFAULT_SCOPE;
}
@Override
protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
try {
final JsonNode profile = fetchProfile(accessToken);
final BrokeredIdentityContext user = extractUserContext(profile.get("metadata"));
AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias());
return user;
} catch (Exception e) {
throw new IdentityBrokerException("Could not obtain user profile from Openshift.", e);
}
}
private BrokeredIdentityContext extractUserContext(JsonNode metadata) {
final BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(metadata, "uid"));
user.setUsername(getJsonProperty(metadata, "name"));
user.setName(getJsonProperty(metadata, "fullName"));
user.setIdpConfig(getConfig());
user.setIdp(this);
return user;
}
private JsonNode fetchProfile(String accessToken) throws IOException {
return JsonSimpleHttp.asJson(SimpleHttp.doGet(getConfig().getUserInfoUrl(), this.session)
.header("Authorization", "Bearer " + accessToken));
}
}