Skip to content

Commit

Permalink
KEYCLOAK-1187 First round: Combined ApplicationModel and OAuthClientM…
Browse files Browse the repository at this point in the history
…odel into ClientModel. Removed OAuth Clients from Admin console and renamed Applications to Clients.
  • Loading branch information
stianst committed Apr 9, 2015
1 parent b92a178 commit 6fbc097
Show file tree
Hide file tree
Showing 196 changed files with 6,069 additions and 9,521 deletions.
@@ -0,0 +1,84 @@
package org.keycloak.connections.jpa.updater.liquibase.custom;

import liquibase.change.custom.CustomSqlChange;
import liquibase.database.Database;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.CustomChangeException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;
import liquibase.snapshot.SnapshotGeneratorFactory;
import liquibase.statement.SqlStatement;
import liquibase.statement.core.UpdateStatement;
import liquibase.structure.core.Table;
import org.keycloak.models.utils.KeycloakModelUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;

/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class SetConsentRequiredOnOAuthClients implements CustomSqlChange {

private String confirmationMessage;

@Override
public SqlStatement[] generateStatements(Database database) throws CustomChangeException {
try {
StringBuilder sb = new StringBuilder();
sb.append("Set consent required for: ");

Connection connection = ((JdbcConnection) (database.getConnection())).getWrappedConnection();
ArrayList<SqlStatement> statements = new ArrayList<SqlStatement>();

String correctedTableName = database.correctObjectName("CLIENT", Table.class);
if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) {
ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM CLIENT");
while (resultSet.next()) {
String id = resultSet.getString(1);

UpdateStatement statement = new UpdateStatement(null, null, correctedTableName)
.addNewColumnValue("CONSENT_REQUIRED", true)
.setWhereClause("ID='" + id + "'");
statements.add(statement);

if (!resultSet.isFirst()) {
sb.append(", ");
}
sb.append(id);
}

if (!statements.isEmpty()) {
confirmationMessage = sb.toString();
}
}

return statements.toArray(new SqlStatement[statements.size()]);
} catch (Exception e) {
throw new CustomChangeException("Failed to add realm code secret", e);
}
}

@Override
public String getConfirmationMessage() {
return confirmationMessage;
}

@Override
public void setUp() throws SetupException {

}

@Override
public void setFileOpener(ResourceAccessor resourceAccessor) {

}

@Override
public ValidationErrors validate(Database database) {
return null;
}

}
Expand Up @@ -36,5 +36,12 @@
<addPrimaryKey columnNames="IDP_MAPPER_ID, NAME" constraintName="CONSTRAINT_IDPMConfig" tableName="IDP_MAPPER_CONFIG"/>
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="IDENTITY_PROVIDER_MAPPER" constraintName="FK_IDPM_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
<addForeignKeyConstraint baseColumnNames="IDP_MAPPER_ID" baseTableName="IDP_MAPPER_CONFIG" constraintName="FK_IDPMConfig" referencedColumnNames="ID" referencedTableName="IDENTITY_PROVIDER_MAPPER"/>

<addColumn tableName="CLIENT">
<column name="CONSENT_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/>
</column>
</addColumn>
<dropColumn tableName="CLIENT" columnName="DTYPE"/>
</changeSet>
</databaseChangeLog>
3 changes: 1 addition & 2 deletions connections/jpa/src/main/resources/META-INF/persistence.xml
Expand Up @@ -3,9 +3,8 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="keycloak-default" transaction-type="RESOURCE_LOCAL">
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
<class>org.keycloak.models.jpa.entities.ClientEntity</class>
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
Expand Down
Expand Up @@ -33,8 +33,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
"org.keycloak.models.entities.RequiredCredentialEntity",
"org.keycloak.models.entities.CredentialEntity",
"org.keycloak.models.entities.FederatedIdentityEntity",
"org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity",
"org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity",
"org.keycloak.models.mongo.keycloak.entities.MongoClientEntity",
"org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
"org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
Expand Down
Expand Up @@ -22,6 +22,8 @@ public class ApplicationRepresentation {
protected ClaimRepresentation claims;
protected Integer notBefore;
protected Boolean bearerOnly;
protected Boolean consentRequired;
protected Boolean directGrantsOnly;
protected Boolean publicClient;
protected Boolean frontchannelLogout;
protected String protocol;
Expand Down Expand Up @@ -136,6 +138,22 @@ public void setBearerOnly(Boolean bearerOnly) {
this.bearerOnly = bearerOnly;
}

public Boolean isConsentRequired() {
return consentRequired;
}

public void setConsentRequired(Boolean consentRequired) {
this.consentRequired = consentRequired;
}

public Boolean getDirectGrantsOnly() {
return directGrantsOnly;
}

public void setDirectGrantsOnly(Boolean directGrantsOnly) {
this.directGrantsOnly = directGrantsOnly;
}

public Boolean isPublicClient() {
return publicClient;
}
Expand Down
Expand Up @@ -6,10 +6,8 @@
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
Expand All @@ -18,9 +16,7 @@
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.RolesRepresentation;
Expand Down Expand Up @@ -58,24 +54,14 @@ public static RealmRepresentation exportRealm(KeycloakSession session, RealmMode
}

// Applications
List<ApplicationModel> applications = realm.getApplications();
List<ClientModel> applications = realm.getClients();
List<ApplicationRepresentation> appReps = new ArrayList<ApplicationRepresentation>();
for (ApplicationModel app : applications) {
for (ClientModel app : applications) {
ApplicationRepresentation appRep = exportApplication(app);
appReps.add(appRep);
}
rep.setApplications(appReps);

// OAuth clients
List<OAuthClientModel> oauthClients = realm.getOAuthClients();
List<OAuthClientRepresentation> oauthClientReps = new ArrayList<OAuthClientRepresentation>();
for (OAuthClientModel oauthClient : oauthClients) {
OAuthClientRepresentation clientRep = ModelToRepresentation.toRepresentation(oauthClient);
clientRep.setSecret(oauthClient.getSecret());
oauthClientReps.add(clientRep);
}
rep.setOauthClients(oauthClientReps);

// Roles
List<RoleRepresentation> realmRoleReps = null;
Map<String, List<RoleRepresentation>> appRolesReps = new HashMap<String, List<RoleRepresentation>>();
Expand All @@ -84,10 +70,10 @@ public static RealmRepresentation exportRealm(KeycloakSession session, RealmMode
if (realmRoles != null && realmRoles.size() > 0) {
realmRoleReps = exportRoles(realmRoles);
}
for (ApplicationModel app : applications) {
for (ClientModel app : applications) {
Set<RoleModel> currentAppRoles = app.getRoles();
List<RoleRepresentation> currentAppRoleReps = exportRoles(currentAppRoles);
appRolesReps.put(app.getName(), currentAppRoleReps);
appRolesReps.put(app.getClientId(), currentAppRoleReps);
}

RolesRepresentation rolesRep = new RolesRepresentation();
Expand All @@ -100,9 +86,8 @@ public static RealmRepresentation exportRealm(KeycloakSession session, RealmMode
rep.setRoles(rolesRep);

// Scopes
List<ClientModel> allClients = new ArrayList<ClientModel>(applications);
allClients.addAll(realm.getOAuthClients());
Map<String, List<ScopeMappingRepresentation>> appScopeReps = new HashMap<String, List<ScopeMappingRepresentation>>();
List<ClientModel> allClients = new ArrayList<>(applications);
Map<String, List<ScopeMappingRepresentation>> appScopeReps = new HashMap<>();

for (ClientModel client : allClients) {
Set<RoleModel> clientScopes = client.getScopeMappings();
Expand All @@ -114,11 +99,11 @@ public static RealmRepresentation exportRealm(KeycloakSession session, RealmMode
}
scopeMappingRep.role(scope.getName());
} else {
ApplicationModel app = (ApplicationModel)scope.getContainer();
String appName = app.getName();
ClientModel app = (ClientModel)scope.getContainer();
String appName = app.getClientId();
List<ScopeMappingRepresentation> currentAppScopes = appScopeReps.get(appName);
if (currentAppScopes == null) {
currentAppScopes = new ArrayList<ScopeMappingRepresentation>();
currentAppScopes = new ArrayList<>();
appScopeReps.put(appName, currentAppScopes);
}

Expand Down Expand Up @@ -165,7 +150,7 @@ public static RealmRepresentation exportRealm(KeycloakSession session, RealmMode
* @param app
* @return full ApplicationRepresentation
*/
public static ApplicationRepresentation exportApplication(ApplicationModel app) {
public static ApplicationRepresentation exportApplication(ClientModel app) {
ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app);

appRep.setSecret(app.getSecret());
Expand Down Expand Up @@ -216,8 +201,8 @@ public static RoleRepresentation exportRole(RoleModel role) {
compositeAppRoles = new HashMap<String, List<String>>();
}

ApplicationModel app = (ApplicationModel)crContainer;
String appName = app.getName();
ClientModel app = (ClientModel)crContainer;
String appName = app.getClientId();
List<String> currentAppComposites = compositeAppRoles.get(appName);
if (currentAppComposites == null) {
currentAppComposites = new ArrayList<String>();
Expand Down Expand Up @@ -269,8 +254,8 @@ public static UserRepresentation exportUser(KeycloakSession session, RealmModel
if (role.getContainer() instanceof RealmModel) {
realmRoleNames.add(role.getName());
} else {
ApplicationModel app = (ApplicationModel)role.getContainer();
String appName = app.getName();
ClientModel app = (ClientModel)role.getContainer();
String appName = app.getClientId();
List<String> currentAppRoles = appRoleNames.get(appName);
if (currentAppRoles == null) {
currentAppRoles = new ArrayList<String>();
Expand Down
Expand Up @@ -8,7 +8,7 @@
import org.keycloak.Config;
import org.keycloak.exportimport.Strategy;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
Expand Down Expand Up @@ -81,7 +81,7 @@ private static void refreshMasterAdminApps(RealmProvider model, RealmModel realm
// We just imported master realm. All 'masterAdminApps' need to be refreshed
RealmModel adminRealm = realm;
for (RealmModel currentRealm : model.getRealms()) {
ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm));
ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(currentRealm));
if (masterApp != null) {
currentRealm.setMasterAdminApp(masterApp);
} else {
Expand All @@ -91,7 +91,7 @@ private static void refreshMasterAdminApps(RealmProvider model, RealmModel realm
} else {
// Need to refresh masterApp for current realm
RealmModel adminRealm = model.getRealm(adminRealmId);
ApplicationModel masterApp = adminRealm.getApplicationByName(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
ClientModel masterApp = adminRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
if (masterApp != null) {
realm.setMasterAdminApp(masterApp);
} else {
Expand Down Expand Up @@ -119,7 +119,7 @@ public static void setupMasterAdminManagement(RealmProvider model, RealmModel re
}
adminRole.setDescription("${role_"+AdminRoles.ADMIN+"}");

ApplicationModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
ClientModel realmAdminApp = KeycloakModelUtils.createApplication(adminRealm, KeycloakModelUtils.getMasterRealmAdminApplicationName(realm));
realmAdminApp.setBearerOnly(true);
realm.setMasterAdminApp(realmAdminApp);

Expand Down Expand Up @@ -220,7 +220,7 @@ public static void importUsersFromStream(KeycloakSession session, String realmNa

private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
RealmModel realm = model.getRealmByName(realmName);
Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
Map<String, ClientModel> apps = realm.getClientNameMap();
for (UserRepresentation user : userReps) {
RepresentationToModel.createUser(session, realm, user, apps);
}
Expand Down
@@ -1,14 +1,11 @@
package org.keycloak.account.freemarker.model;

import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.util.Time;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -63,23 +60,14 @@ public Date getExpires() {
return Time.toDate(max);
}

public Set<String> getApplications() {
Set<String> apps = new HashSet<String>();
public Set<String> getClients() {
Set<String> clients = new HashSet<String>();
for (ClientSessionModel clientSession : session.getClientSessions()) {
ClientModel client = clientSession.getClient();
if (client instanceof ApplicationModel) apps.add(client.getClientId());
clients.add(client.getClientId());
}
return apps;
return clients;
}
public List<String> getClients() {
List<String> apps = new ArrayList<String>();
for (ClientSessionModel clientSession : session.getClientSessions()) {
ClientModel client = clientSession.getClient();
if (client instanceof OAuthClientModel) apps.add(client.getClientId());
}
return apps;
}

}

}
Expand Up @@ -14,7 +14,6 @@
<td>${msg("started")}</td>
<td>${msg("lastAccess")}</td>
<td>${msg("expires")}</td>
<td>${msg("applications")}</td>
<td>${msg("clients")}</td>
</tr>
</thead>
Expand All @@ -26,11 +25,6 @@
<td>${session.started?datetime}</td>
<td>${session.lastAccess?datetime}</td>
<td>${session.expires?datetime}</td>
<td>
<#list session.applications as app>
${app}<br/>
</#list>
</td>
<td>
<#list session.clients as client>
${client}<br/>
Expand Down

0 comments on commit 6fbc097

Please sign in to comment.