Skip to content

Commit

Permalink
Merge pull request #9 from HiWay-Media/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
Gregory4297 authored Dec 18, 2024
2 parents 03d3924 + 2144a6b commit b29d9b5
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 20 deletions.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,4 @@ eval "set -- $(
tr '\n' ' '
)" '"$@"'

exec "$JAVACMD" "$@"
exec "$JAVACMD" "$@"
2 changes: 1 addition & 1 deletion gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,4 @@ exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega
:omega
52 changes: 35 additions & 17 deletions src/main/java/media/hiway/provider/DruidIdentityProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider;
import org.keycloak.broker.oidc.OIDCIdentityProvider;
import org.keycloak.broker.oidc.OIDCIdentityProviderConfig;
import org.keycloak.broker.provider.AuthenticationRequest;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.broker.social.SocialIdentityProvider;
Expand All @@ -29,10 +37,27 @@

public class DruidIdentityProvider extends OIDCIdentityProvider implements SocialIdentityProvider<OIDCIdentityProviderConfig> {
private String userJson;
public static final String OAUTH2_PARAMETER_CODE = "code";

private static final Logger logger = Logger.getLogger(DruidIdentityProvider.class);
private static final String AUTH_URL = "https://auth.test.id.sevillafc.es/oauth2/authorize";
private static final String TOKEN_URL = "https://auth.test.id.sevillafc.es/oauth2/token";
private static final String JWKS_URL = "https://auth.test.id.sevillafc.es/oauth2/keys";
private static final String ISSUER = "https://auth.test.id.sevillafc.es";
//
private static final String AUTH_URL_TEST = "https://auth.test.id.sevillafc.es/oauth2/authorize";
private static final String TOKEN_URL_TEST = "https://auth.test.id.sevillafc.es/oauth2/token";
private static final String JWKS_URL_TEST = "https://auth.test.id.sevillafc.es/oauth2/keys";
private static final String ISSUER_TEST = "https://auth.test.id.sevillafc.es";
static final String DRUID_AUTHZ_CODE = "druid-authz-code";


public DruidIdentityProvider(KeycloakSession session, DruidIdentityProviderConfig config) {
super(session, config);
String defaultScope = config.getDefaultScope();
//
logger.debugf("defaultScope ", defaultScope);
//
config.setAuthorizationUrl("https://auth.test.id.sevillafc.es/oauth2/authorize");
config.setTokenUrl("https://auth.test.id.sevillafc.es/oauth2/token");

Expand All @@ -44,6 +69,7 @@ public DruidIdentityProvider(KeycloakSession session, DruidIdentityProviderConfi

@Override
public Object callback(RealmModel realm, AuthenticationCallback callback, EventBuilder event) {
//return new DruidIdentityProviderEndpoint(this, realm, callback, event, session);
return new OIDCEndpoint(callback, realm, event);
}

Expand Down Expand Up @@ -88,7 +114,7 @@ public SimpleHttp authenticateTokenRequest(SimpleHttp tokenRequest) {
token.issuer(config.getTeamId());
token.iat(currentTime);
token.exp(currentTime + 15 * 60);
token.audience("htthttps://sevillafc.ott.es");
token.audience("https://sevillafc.ott.es");
token.subject(config.getClientId());
String clientSecret = new JWSBuilder().jsonContent(token).sign(signer);

Expand All @@ -106,30 +132,22 @@ protected String getDefaultScopes() {
}


/* @Override
@Override
protected UriBuilder createAuthorizationUrl(AuthenticationRequest request) {
UriBuilder uriBuilder = super.createAuthorizationUrl(request);

final DruidIdentityProviderConfig config = (DruidIdentityProviderConfig) getConfig();
//
uriBuilder.queryParam(OAUTH2_PARAMETER_STATE, request.getState().getEncoded())
.queryParam(OAUTH2_PARAMETER_RESPONSE_TYPE, "code")
.queryParam(OAUTH2_PARAMETER_CLIENT_ID, config.getClientId())
.queryParam(OAUTH2_PARAMETER_REDIRECT_URI, request.getRedirectUri());
// final UriBuilder uriBuilder = UriBuilder.fromUri(getConfig().getAuthorizationUrl())
// .queryParam(OAUTH2_PARAMETER_SCOPE, getConfig().getDefaultScope())
// .queryParam(OAUTH2_PARAMETER_STATE, request.getState().getEncoded())
// .queryParam(OAUTH2_PARAMETER_RESPONSE_TYPE, "code")
// .queryParam(OAUTH2_PARAMETER_CLIENT_ID, getConfig().getClientId())
// .queryParam(OAUTH2_PARAMETER_REDIRECT_URI, request.getRedirectUri());
.queryParam(OAUTH2_PARAMETER_RESPONSE_TYPE, "code")
.queryParam(OAUTH2_PARAMETER_CLIENT_ID, config.getClientId())
.queryParam(OAUTH2_PARAMETER_REDIRECT_URI, request.getRedirectUri());
return uriBuilder;
}

protected class OIDCEndpoint extends OIDCIdentityProvider.OIDCEndpoint {
public OIDCEndpoint(AuthenticationCallback callback, RealmModel realm, EventBuilder event) {
super(callback, realm, event);
super(callback, realm, event, DruidIdentityProvider.this);
}

@POST
Expand All @@ -139,9 +157,9 @@ public Response authResponse(
@FormParam("user") String userJson,
@FormParam(OAuth2Constants.ERROR) String error) {
DruidIdentityProvider.this.userJson = userJson;
return super.authResponse(state, authorizationCode, error);
return super.authResponse(state, authorizationCode, error, error);
}
}*/
}



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ class DruidIdentityProviderConfig extends OIDCIdentityProviderConfig {
DruidIdentityProviderConfig(IdentityProviderModel identityProviderModel) {
super(identityProviderModel);
}
private static final String PROD_ENV = "prodEnv";
private static final String DISPLAY_ICON_CLASSES = "fa fa-dragon";
private static final String DISPLAY_NAME = "displayName";
private static final String DEFAULT_DISPLAY_NAME = "Sign in with Druid";
// need to setup if is debug or prod urls
public String getProd() {
return getConfig().get(PROD_ENV);
}

public void setProd(String isProd) {
getConfig().put(PROD_ENV, isProd);
}


public String getKeyId() {
return getConfig().get("keyId");
Expand All @@ -17,4 +30,23 @@ public String getKeyId() {
public String getTeamId() {
return getConfig().get("teamId");
}

@Override
public void setDisplayName(String displayName) {
getConfig().put(DISPLAY_NAME, displayName);
}

@Override
public String getDisplayName() {
var displayName = getConfig().get(DISPLAY_NAME);
if (displayName == null || displayName.isBlank()) {
return DEFAULT_DISPLAY_NAME;
}
return displayName;
}

@Override
public String getDisplayIconClasses() {
return DISPLAY_ICON_CLASSES;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package media.hiway.provider;

import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.core.Response;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.broker.provider.IdentityProvider;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.ErrorPage;
import org.keycloak.services.messages.Messages;

import static media.hiway.provider.DruidIdentityProvider.OAUTH2_PARAMETER_CODE;

public class DruidIdentityProviderEndpoint {

protected static final Logger logger = Logger.getLogger(DruidIdentityProviderEndpoint.class);

private static final String OAUTH2_PARAMETER_STATE = "state";
private static final String OAUTH2_PARAMETER_USER = "user";
private static final String ACCESS_DENIED = "access_denied";
private static final String USER_CANCELLED_AUTHORIZE = "user_cancelled_authorize";

private final DruidIdentityProvider druidIdentityProvider;
private final RealmModel realm;
private final IdentityProvider.AuthenticationCallback callback;
private final EventBuilder event;

protected KeycloakSession session;


public DruidIdentityProviderEndpoint(DruidIdentityProvider druidIdentityProvider, RealmModel realm, IdentityProvider.AuthenticationCallback callback, EventBuilder event, KeycloakSession session) {
this.druidIdentityProvider = druidIdentityProvider;
this.realm = realm;
this.callback = callback;
this.event = event;
this.session = session;
}

@POST
public Response authResponse(@FormParam(OAUTH2_PARAMETER_STATE) String state, @FormParam(OAUTH2_PARAMETER_CODE) String authorizationCode, @FormParam(OAUTH2_PARAMETER_USER) String user, @FormParam(OAuth2Constants.ERROR) String error) {
if (state == null) {
return errorIdentityProviderLogin(Messages.IDENTITY_PROVIDER_MISSING_STATE_ERROR);
}
// TODO
logger.debugf("State is %s", state);
return errorIdentityProviderLogin(Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
}

private Response errorIdentityProviderLogin(String message) {
return errorIdentityProviderLogin(message, Response.Status.BAD_GATEWAY);
}

private Response errorIdentityProviderLogin(String message, Response.Status status) {
sendErrorEvent();
return ErrorPage.error(session, null, status, message);
}

private void sendErrorEvent() {
event.event(EventType.IDENTITY_PROVIDER_LOGIN);
event.detail("idp", druidIdentityProvider.getConfig().getProviderId());
event.error(Errors.IDENTITY_PROVIDER_LOGIN_FAILURE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
import org.keycloak.broker.social.SocialIdentityProviderFactory;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.models.KeycloakSession;
import org.keycloak.provider.ProviderConfigurationBuilder;

import java.util.List;

public class DruidIdentityProviderFactory extends AbstractIdentityProviderFactory<DruidIdentityProvider> implements SocialIdentityProviderFactory<DruidIdentityProvider> {
public static final String PROVIDER_ID = "druid";
Expand All @@ -27,4 +31,14 @@ public DruidIdentityProviderConfig createConfig() {
public String getId() {
return PROVIDER_ID;
}

@Override
public List<ProviderConfigProperty> getConfigProperties() {
return ProviderConfigurationBuilder.create()
.property().name("displayName").label("Display name").helpText("Text that is shown on the login page. Defaults to 'Sign in with Druid'").type(ProviderConfigProperty.STRING_TYPE).add()
.property().name("teamId").label("Team ID").helpText("Your 10-character Team ID obtained from your Druid developer account.").type(ProviderConfigProperty.STRING_TYPE).add()
.property().name("keyId").label("Key ID").helpText("A 10-character key identifier obtained from your Druid developer account.").type(ProviderConfigProperty.STRING_TYPE).add()
.property().name("prodEnv").label("Is Prod").helpText("Is production environment.").type(ProviderConfigProperty.STRING_TYPE).add()
.build();
}
}
34 changes: 34 additions & 0 deletions src/main/java/media/hiway/provider/DruidUserRepresentation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package media.hiway.provider;

import com.fasterxml.jackson.databind.JsonNode;

public class DruidUserRepresentation {
private String firstName;
private String lastName;
private JsonNode profile;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public JsonNode getProfile() {
return profile;
}

public void setProfile(JsonNode profile) {
this.profile = profile;
}

}
17 changes: 17 additions & 0 deletions src/main/java/media/hiway/provider/DruidUserSessionNoteMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package media.hiway.provider;

import org.keycloak.broker.oidc.mappers.ClaimToUserSessionNoteMapper;

public class DruidUserSessionNoteMapper extends ClaimToUserSessionNoteMapper {
private static final String[] cp = new String[] {DruidIdentityProviderFactory.PROVIDER_ID};

@Override
public String[] getCompatibleProviders() {
return cp;
}

@Override
public String getId() {
return "apple-claim-user-session-note-mapper";
}
}
56 changes: 56 additions & 0 deletions src/main/java/media/hiway/provider/TokenExchangeParms.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package media.hiway.provider;

import jakarta.ws.rs.core.MultivaluedMap;
import org.keycloak.OAuth2Constants;

public class TokenExchangeParms {
private String appIdentifier;
private String subjectToken;
private String subjectTokenType;
private String userJson;

public void TokenExchangeParams(MultivaluedMap<String, String> params) {
this.subjectToken = params.getFirst(OAuth2Constants.SUBJECT_TOKEN);
this.subjectTokenType = params.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
this.userJson = params.getFirst("user_profile");
this.appIdentifier = params.getFirst("app_identifier");

this.normalizeAppIdentifier();
this.setTypeDefaultIfNull();
this.normalizeUserJson();
}

private void normalizeAppIdentifier() {
if (this.appIdentifier != null && this.appIdentifier.isBlank()) {
this.appIdentifier = null;
}
}

private void setTypeDefaultIfNull() {
if (this.subjectTokenType == null || this.subjectTokenType.isBlank()) {
this.subjectTokenType = DruidIdentityProvider.DRUID_AUTHZ_CODE;
}
}

private void normalizeUserJson() {
if (this.userJson != null && (this.userJson.isBlank() || this.userJson.equals("null"))) {
this.userJson = null;
}
}

public String getAppIdentifier() {
return this.appIdentifier;
}

public String getSubjectToken() {
return this.subjectToken;
}

public String getSubjectTokenType() {
return this.subjectTokenType;
}

public String getUserJson() {
return this.userJson;
}
}

0 comments on commit b29d9b5

Please sign in to comment.