Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
be656b2dba
89 files changed
+589
-267
No files matched your search
+50
@@ -0,0 +1,50 @@
|
||||
package org.keycloak.connections.jpa.updater.liquibase.custom;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
import liquibase.exception.CustomChangeException;
|
||||
import liquibase.statement.core.InsertStatement;
|
||||
import liquibase.structure.core.Table;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class JpaUpdate1_2_0_CR1 extends CustomKeycloakTask {
|
||||
|
||||
@Override
|
||||
protected void generateStatementsImpl() throws CustomChangeException {
|
||||
String realmClientTableName = database.correctObjectName("REALM_CLIENT", Table.class);
|
||||
|
||||
try {
|
||||
PreparedStatement statement = jdbcConnection.prepareStatement("select CLIENT.REALM_ID, CLIENT.ID CLIENT_ID from CLIENT where CLIENT.CONSENT_REQUIRED = true");
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
try {
|
||||
while (resultSet.next()) {
|
||||
String realmId = resultSet.getString("REALM_ID");
|
||||
String oauthClientId = resultSet.getString("CLIENT_ID");
|
||||
|
||||
InsertStatement realmClientInsert = new InsertStatement(null, null, realmClientTableName)
|
||||
.addColumnValue("REALM_ID", realmId)
|
||||
.addColumnValue("CLIENT_ID", oauthClientId);
|
||||
statements.add(realmClientInsert);
|
||||
}
|
||||
} finally {
|
||||
resultSet.close();
|
||||
}
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
|
||||
confirmationMessage.append("Inserted " + statements.size() + " OAuth Clients to REALM_CLIENT table");
|
||||
} catch (Exception e) {
|
||||
throw new CustomChangeException(getTaskId() + ": Exception when updating data from previous version", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTaskId() {
|
||||
return "Update 1.2.0.CR1";
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@
|
||||
<addForeignKeyConstraint baseColumnNames="USER_CONSENT_ID" baseTableName="USER_CONSENT_PROT_MAPPER" constraintName="FK_GRNTCSNT_PRM_GR" referencedColumnNames="ID" referencedTableName="USER_CONSENT"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_SESSION_PROT_MAPPER" constraintName="FK_33A8SGQW18I532811V7O2DK89" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
|
||||
|
||||
<renameColumn tableName="CLIENT" newColumnName="CLIENT_ID" oldColumnName="NAME"/>
|
||||
<renameColumn tableName="CLIENT" newColumnName="CLIENT_ID" oldColumnName="NAME" columnDataType="VARCHAR(255)"/>
|
||||
<addColumn tableName="CLIENT">
|
||||
<column name="CONSENT_REQUIRED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
@@ -110,24 +110,36 @@
|
||||
</update>
|
||||
<dropColumn tableName="CLIENT" columnName="DTYPE"/>
|
||||
|
||||
<renameColumn tableName="REALM" newColumnName="MASTER_ADMIN_CLIENT" oldColumnName="MASTER_ADMIN_APP"/>
|
||||
<dropForeignKeyConstraint baseTableName="REALM" constraintName="FK_RSAF444KK6QRKMS7N56AIWQ5Y" />
|
||||
<renameColumn tableName="REALM" newColumnName="MASTER_ADMIN_CLIENT" oldColumnName="MASTER_ADMIN_APP" columnDataType="VARCHAR(36)"/>
|
||||
<addForeignKeyConstraint baseColumnNames="MASTER_ADMIN_CLIENT" baseTableName="REALM" constraintName="FK_TRAF444KK6QRKMS7N56AIWQ5Y" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="REALM_APPLICATION" constraintName="FK_82S3P0DIUXAWWQQSA528UBY2Q" />
|
||||
<renameTable oldTableName="REALM_APPLICATION" newTableName="REALM_CLIENT"/>
|
||||
<renameColumn tableName="REALM_CLIENT" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID"/>
|
||||
<renameColumn tableName="REALM_CLIENT" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID" columnDataType="VARCHAR(36)"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="REALM_CLIENT" constraintName="FK_93S3P0DIUXAWWQQSA528UBY2Q" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="APPLICATION_DEFAULT_ROLES" constraintName="FK_MAYLTS7KLWQW2H8M2B5JOYTKY" />
|
||||
<renameTable oldTableName="APPLICATION_DEFAULT_ROLES" newTableName="CLIENT_DEFAULT_ROLES"/>
|
||||
<renameColumn tableName="CLIENT_DEFAULT_ROLES" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID"/>
|
||||
<renameColumn tableName="CLIENT_DEFAULT_ROLES" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID" columnDataType="VARCHAR(36)"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_DEFAULT_ROLES" constraintName="FK_NUILTS7KLWQW2H8M2B5JOYTKY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
|
||||
<dropForeignKeyConstraint baseTableName="APP_NODE_REGISTRATIONS" constraintName="FK8454723BA992F594" />
|
||||
<renameTable oldTableName="APP_NODE_REGISTRATIONS" newTableName="CLIENT_NODE_REGISTRATIONS"/>
|
||||
<renameColumn tableName="CLIENT_NODE_REGISTRATIONS" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID"/>
|
||||
<renameColumn tableName="CLIENT_NODE_REGISTRATIONS" newColumnName="CLIENT_ID" oldColumnName="APPLICATION_ID" columnDataType="VARCHAR(36)"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_NODE_REGISTRATIONS" constraintName="FK4129723BA992F594" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT" oldColumnName="APPLICATION"/>
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT_ROLE" oldColumnName="APPLICATION_ROLE"/>
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT_REALM_CONSTRAINT" oldColumnName="APP_REALM_CONSTRAINT"/>
|
||||
<dropForeignKeyConstraint baseTableName="KEYCLOAK_ROLE" constraintName="FK_PIMO5LE2C0RAL09FL8CM9WFW9" />
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT" oldColumnName="APPLICATION" columnDataType="VARCHAR(36)"/>
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT_ROLE" oldColumnName="APPLICATION_ROLE" columnDataType="BOOLEAN"/>
|
||||
<renameColumn tableName="KEYCLOAK_ROLE" newColumnName="CLIENT_REALM_CONSTRAINT" oldColumnName="APP_REALM_CONSTRAINT" columnDataType="VARCHAR(36)"/>
|
||||
<addForeignKeyConstraint baseColumnNames="CLIENT" baseTableName="KEYCLOAK_ROLE" constraintName="FK_KJHO5LE2C0RAL09FL8CM9WFW9" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||
|
||||
<dropUniqueConstraint tableName="KEYCLOAK_ROLE" constraintName="UK_J3RWUVD56ONTGSUHOGM184WW2"/>
|
||||
<addUniqueConstraint columnNames="NAME,CLIENT_REALM_CONSTRAINT" constraintName="UK_J3RWUVD56ONTGSUHOGM184WW2-2" tableName="KEYCLOAK_ROLE"/>
|
||||
<addUniqueConstraint columnNames="CLIENT_ID, USER_ID" constraintName="UK_JKUWUVD56ONTGSUHOGM8UEWRT" tableName="USER_CONSENT"/>
|
||||
|
||||
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate1_2_0_CR1"/>
|
||||
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+5
-3
@@ -23,13 +23,15 @@ public class Update1_2_0_RC1 extends Update {
|
||||
convertApplicationsToClients();
|
||||
convertOAuthClientsToClients();
|
||||
|
||||
db.getCollection("realms").update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("adminAppId", "clientId")), false, true);
|
||||
db.getCollection("realms").update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("adminAppId", "masterAdminClient")), false, true);
|
||||
|
||||
ensureIndex("userConsents", new String[]{"clientId", "userId"}, true, false);
|
||||
}
|
||||
|
||||
private void convertApplicationsToClients() {
|
||||
DBCollection applications = db.getCollection("applications");
|
||||
applications.dropIndex("realmId_1_name_1");
|
||||
|
||||
applications.update(new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("consentRequired", false)), false, true);
|
||||
applications.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("name", "clientId")), false, true);
|
||||
renameCollection("applications", "clients");
|
||||
@@ -39,14 +41,14 @@ public class Update1_2_0_RC1 extends Update {
|
||||
roles.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("applicationId", "clientId")), false, true);
|
||||
log.debugv("Renamed roles.applicationId to roles.clientId");
|
||||
|
||||
db.getCollection("clients").dropIndex("realmId_1_name_1");
|
||||
ensureIndex("clients", new String[]{"realmId", "clientId"}, true, false);
|
||||
|
||||
}
|
||||
|
||||
private void convertOAuthClientsToClients() {
|
||||
DBCollection clients = db.getCollection("clients");
|
||||
DBCollection oauthClients = db.getCollection("oauthClients");
|
||||
oauthClients.dropIndex("realmId_1_name_1");
|
||||
|
||||
oauthClients.update(new BasicDBObject(), new BasicDBObject("$rename", new BasicDBObject("name", "clientId")), false, true);
|
||||
oauthClients.update(new BasicDBObject(), new BasicDBObject("$set", new BasicDBObject("consentRequired", true)), false, true);
|
||||
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||
"org.keycloak.models.entities.UserFederationProviderEntity",
|
||||
"org.keycloak.models.entities.ProtocolMapperEntity",
|
||||
"org.keycloak.models.entities.IdentityProviderMapperEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity"
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity",
|
||||
"org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity"
|
||||
};
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
||||
|
||||
@@ -1,28 +1,52 @@
|
||||
package org.keycloak.representations.idm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserConsentRepresentation {
|
||||
|
||||
protected List<String> grantedRoles; // points to roleIds
|
||||
protected List<String> grantedProtocolMappers; // points to protocolMapperIds
|
||||
protected String clientId;
|
||||
|
||||
public List<String> getGrantedRoles() {
|
||||
return grantedRoles;
|
||||
// Key is protocol, Value is list of granted consents for this protocol
|
||||
protected Map<String, List<String>> grantedProtocolMappers;
|
||||
|
||||
protected List<String> grantedRealmRoles;
|
||||
|
||||
// Key is clientId, Value is list of granted roles of this client
|
||||
protected Map<String, List<String>> grantedClientRoles;
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setGrantedRoles(List<String> grantedRoles) {
|
||||
this.grantedRoles = grantedRoles;
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public List<String> getGrantedProtocolMappers() {
|
||||
public Map<String, List<String>> getGrantedProtocolMappers() {
|
||||
return grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public void setGrantedProtocolMappers(List<String> grantedProtocolMappers) {
|
||||
public void setGrantedProtocolMappers(Map<String, List<String>> grantedProtocolMappers) {
|
||||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public List<String> getGrantedRealmRoles() {
|
||||
return grantedRealmRoles;
|
||||
}
|
||||
|
||||
public void setGrantedRealmRoles(List<String> grantedRealmRoles) {
|
||||
this.grantedRealmRoles = grantedRealmRoles;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getGrantedClientRoles() {
|
||||
return grantedClientRoles;
|
||||
}
|
||||
|
||||
public void setGrantedClientRoles(Map<String, List<String>> grantedClientRoles) {
|
||||
this.grantedClientRoles = grantedClientRoles;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public class UserRepresentation {
|
||||
protected List<FederatedIdentityRepresentation> federatedIdentities;
|
||||
protected List<String> realmRoles;
|
||||
protected Map<String, List<String>> clientRoles;
|
||||
protected Map<String, UserConsentRepresentation> clientConsents;
|
||||
protected List<UserConsentRepresentation> clientConsents;
|
||||
|
||||
@Deprecated
|
||||
protected Map<String, List<String>> applicationRoles;
|
||||
@@ -177,11 +177,11 @@ public class UserRepresentation {
|
||||
this.clientRoles = clientRoles;
|
||||
}
|
||||
|
||||
public Map<String, UserConsentRepresentation> getClientConsents() {
|
||||
public List<UserConsentRepresentation> getClientConsents() {
|
||||
return clientConsents;
|
||||
}
|
||||
|
||||
public void setClientConsents(Map<String, UserConsentRepresentation> clientConsents) {
|
||||
public void setClientConsents(List<UserConsentRepresentation> clientConsents) {
|
||||
this.clientConsents = clientConsents;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,27 +10,20 @@
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<includes>
|
||||
<include>net/iharder/base64/**</include>
|
||||
<include>org/apache/httpcomponents/**</include>
|
||||
<include>org/keycloak/keycloak-core/**</include>
|
||||
<include>org/keycloak/keycloak-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-jboss-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-undertow-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-as7-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-as7-subsystem/**</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>org/picketlink/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-undertow-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-adapter/**</exclude>
|
||||
<exclude>org/jboss/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-subsystem/**</exclude>
|
||||
<exclude>**/*.war</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>modules</outputDirectory>
|
||||
<outputDirectory>modules/system/layers/base</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<!--
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useTransitiveDependencies>true</useTransitiveDependencies>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>org.keycloak:keycloak-as7-adapter</include>
|
||||
</includes>
|
||||
<outputDirectory>lib/as7-eap6-adapter</outputDirectory>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
-->
|
||||
</assembly>
|
||||
@@ -10,27 +10,21 @@
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<includes>
|
||||
<include>net/iharder/base64/**</include>
|
||||
<include>org/bouncycastle/**</include>
|
||||
<include>org/apache/httpcomponents/**</include>
|
||||
<include>org/keycloak/keycloak-core/**</include>
|
||||
<include>org/keycloak/keycloak-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-jboss-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-undertow-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-as7-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-subsystem/**</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>org/picketlink/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-undertow-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-wildfly-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-as7-subsystem/**</exclude>
|
||||
<exclude>org/jboss/**</exclude>
|
||||
<exclude>**/*.war</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>modules/system/layers/base</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<!--
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useTransitiveDependencies>true</useTransitiveDependencies>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>org.keycloak:keycloak-as7-adapter</include>
|
||||
</includes>
|
||||
<outputDirectory>lib/as7-eap6-adapter</outputDirectory>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
-->
|
||||
</assembly>
|
||||
+1
-7
@@ -18,7 +18,7 @@
|
||||
<properties>
|
||||
<keycloak.osgi.export>
|
||||
net.iharder;version="${base64.version}",
|
||||
org.apache.http.*;version=${keycloak.apache.httpcomponents.version}
|
||||
org.apache.http.*;version=${apache.httpcomponents.version}
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
*;resolution:=optional
|
||||
@@ -30,15 +30,9 @@
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -10,26 +10,20 @@
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<includes>
|
||||
<include>net/iharder/base64/**</include>
|
||||
<include>org/apache/httpcomponents/**</include>
|
||||
<include>org/keycloak/keycloak-core/**</include>
|
||||
<include>org/keycloak/keycloak-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-jboss-adapter-core/**</include>
|
||||
<include>org/keycloak/keycloak-undertow-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-wildfly-adapter/**</include>
|
||||
<include>org/keycloak/keycloak-subsystem/**</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>org/keycloak/keycloak-as7-adapter/**</exclude>
|
||||
<exclude>org/keycloak/keycloak-as7-subsystem/**</exclude>
|
||||
<exclude>org/bouncycastle/**</exclude>
|
||||
<exclude>org/picketlink/**</exclude>
|
||||
<exclude>**/*.war</exclude>
|
||||
</excludes>
|
||||
<outputDirectory>modules/system/layers/base</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<!--
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<unpack>false</unpack>
|
||||
<useTransitiveDependencies>true</useTransitiveDependencies>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>org.keycloak:keycloak-undertow-adapter</include>
|
||||
</includes>
|
||||
<outputDirectory>lib/wildfly-adapter</outputDirectory>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
-->
|
||||
</assembly>
|
||||
@@ -338,6 +338,13 @@
|
||||
<module-def name="org.keycloak.keycloak-as7-subsystem">
|
||||
<maven-resource group="org.keycloak" artifact="keycloak-as7-subsystem"/>
|
||||
</module-def>
|
||||
|
||||
<module-def name="org.apache.httpcomponents" slot="4.3">
|
||||
<maven-resource group="org.apache.httpcomponents" artifact="httpclient"/>
|
||||
<maven-resource group="org.apache.httpcomponents" artifact="httpcore"/>
|
||||
<maven-resource group="org.apache.httpcomponents" artifact="httpmime"/>
|
||||
</module-def>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="clean-target">
|
||||
|
||||
@@ -67,6 +67,14 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-subsystem</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.apache.httpcomponents" slot="4.3">
|
||||
<resources>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
<module name="org.apache.commons.codec"/>
|
||||
<module name="org.apache.commons.logging"/>
|
||||
<module name="org.apache.james.mime4j"/>
|
||||
</dependencies>
|
||||
</module>
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
<module xmlns="urn:jboss:module:1.1" name="org.bouncycastle">
|
||||
<resources>
|
||||
<resource-root path="bcprov-jdk15on-1.50.jar"/>
|
||||
<resource-root path="bcpkix-jdk15on-1.50.jar"/>
|
||||
<!-- Insert resources here -->
|
||||
</resources>
|
||||
<dependencies>
|
||||
<module name="javax.api"/>
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.keycloak.keycloak-core"/>
|
||||
<module name="net.iharder.base64"/>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
<module name="javax.servlet.api"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.jboss.as.security"/>
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
<module name="org.keycloak.keycloak-login-api"/>
|
||||
<module name="org.keycloak.keycloak-services"/>
|
||||
<module name="org.keycloak.keycloak-forms-common-freemarker"/>
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="javax.ws.rs.api"/>
|
||||
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@
|
||||
<module name="net.iharder.base64"/>
|
||||
<module name="javax.api"/>
|
||||
<module name="javax.activation.api"/>
|
||||
<module name="org.apache.httpcomponents"/>
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
</dependencies>
|
||||
|
||||
</module>
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
<module name="javax.servlet.api"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.jboss.xnio"/>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3" />
|
||||
<module name="javax.servlet.api"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="io.undertow.core"/>
|
||||
|
||||
@@ -18,8 +18,16 @@
|
||||
<exclude>docs/**</exclude>
|
||||
<exclude>standalone/deployments</exclude>
|
||||
<exclude>standalone/deployments/*</exclude>
|
||||
<exclude>standalone/configuration/standalone*.xml</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked</directory>
|
||||
<outputDirectory>standalone/configuration</outputDirectory>
|
||||
<includes>
|
||||
<include>standalone*.xml</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/unpacked/wildfly-${wildfly.version}</directory>
|
||||
<outputDirectory></outputDirectory>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
<includes>
|
||||
<include>standalone*.xml</include>
|
||||
</includes>
|
||||
<outputDir>${project.build.directory}/unpacked/wildfly-${wildfly.version}/standalone/configuration</outputDir>
|
||||
<outputDir>${project.build.directory}/unpacked</outputDir>
|
||||
</transformationSet>
|
||||
</transformationSets>
|
||||
</configuration>
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.events.EventQuery;
|
||||
import org.keycloak.events.EventType;
|
||||
@@ -66,7 +67,9 @@ public class MongoEventQuery implements EventQuery {
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
query.put("time", BasicDBObjectBuilder.start("$gte", from).get());
|
||||
BasicDBObject time = query.containsField("time") ? (BasicDBObject) query.get("time") : new BasicDBObject();
|
||||
time.append("$gte", from);
|
||||
query.put("time", time);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -79,7 +82,9 @@ public class MongoEventQuery implements EventQuery {
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
query.put("time", BasicDBObjectBuilder.start("$lte", to).get());
|
||||
BasicDBObject time = query.containsField("time") ? (BasicDBObject) query.get("time") : new BasicDBObject();
|
||||
time.append("$lte", to);
|
||||
query.put("time", time);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents"/>
|
||||
<module name="org.apache.httpcomponents" slot="4.3"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
||||
@@ -41,7 +41,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents"/>
|
||||
<module name="org.apache.httpcomponents" slot="4.3"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
||||
@@ -47,7 +47,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+14
@@ -1,10 +1,15 @@
|
||||
package org.keycloak.example.oauth;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,10 +19,19 @@ import java.util.List;
|
||||
*/
|
||||
@Path("customers")
|
||||
public class CustomerService {
|
||||
|
||||
@Context
|
||||
private HttpRequest httpRequest;
|
||||
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
@NoCache
|
||||
public List<String> getCustomers() {
|
||||
// Just to show how to user info from access token in REST endpoint
|
||||
KeycloakSecurityContext securityContext = (KeycloakSecurityContext) httpRequest.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
AccessToken accessToken = securityContext.getToken();
|
||||
System.out.println(String.format("User '%s' with email '%s' made request to CustomerService REST endpoint", accessToken.getPreferredUsername(), accessToken.getEmail()));
|
||||
|
||||
ArrayList<String> rtn = new ArrayList<String>();
|
||||
rtn.add("Bill Burke");
|
||||
rtn.add("Stian Thorgersen");
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
||||
@@ -56,7 +56,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
||||
-1
@@ -38,7 +38,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents" slot="4.3"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
||||
@@ -18,7 +18,7 @@
|
||||
<keycloak.osgi.export>
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
org.apache.http.*;version=${keycloak.apache.httpcomponents.version},
|
||||
org.apache.http.*;version=${apache.httpcomponents.version},
|
||||
javax.servlet.*;version="[2.5,4)",
|
||||
org.keycloak.adapters.jetty;version="${project.version}",
|
||||
org.keycloak.adapters;version="${project.version}",
|
||||
@@ -51,7 +51,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+3
-21
@@ -287,29 +287,11 @@ public class ExportUtils {
|
||||
|
||||
// Grants
|
||||
List<UserConsentModel> consents = user.getConsents();
|
||||
Map<String, UserConsentRepresentation> consentReps = new HashMap<String, UserConsentRepresentation>();
|
||||
LinkedList<UserConsentRepresentation> consentReps = new LinkedList<UserConsentRepresentation>();
|
||||
for (UserConsentModel consent : consents) {
|
||||
String clientId = consent.getClient().getClientId();
|
||||
|
||||
List<String> grantedProtocolMappers = new LinkedList<String>();
|
||||
for (ProtocolMapperModel protocolMapper : consent.getGrantedProtocolMappers()) {
|
||||
grantedProtocolMappers.add(protocolMapper.getId());
|
||||
}
|
||||
|
||||
List<String> grantedRoles = new LinkedList<String>();
|
||||
for (RoleModel role : consent.getGrantedRoles()) {
|
||||
grantedRoles.add(role.getId());
|
||||
}
|
||||
|
||||
|
||||
if (grantedRoles.size() > 0 || grantedProtocolMappers.size() > 0) {
|
||||
UserConsentRepresentation consentRep = new UserConsentRepresentation();
|
||||
if (grantedRoles.size() > 0) consentRep.setGrantedRoles(grantedRoles);
|
||||
if (grantedProtocolMappers.size() > 0) consentRep.setGrantedProtocolMappers(grantedProtocolMappers);
|
||||
consentReps.put(clientId, consentRep);
|
||||
}
|
||||
UserConsentRepresentation consentRep = ModelToRepresentation.toRepresentation(consent);
|
||||
consentReps.add(consentRep);
|
||||
}
|
||||
|
||||
if (consentReps.size() > 0) {
|
||||
userRep.setClientConsents(consentReps);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<form action="${url.revokeClientUrl}" method="post">
|
||||
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
|
||||
<input type="hidden" id="referrer" name="referrer" value="${stateChecker}">
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
|
||||
+2
@@ -51,9 +51,11 @@ role_manage-clients=Manage clients
|
||||
role_manage-events=Manage events
|
||||
role_view-profile=View profile
|
||||
role_manage-account=Manage account
|
||||
role_read-token=Read token
|
||||
client_account=Account
|
||||
client_security-admin-console=Security Admin Console
|
||||
client_realm-management=Realm Management
|
||||
client_broker=Broker
|
||||
|
||||
|
||||
requiredFields=Required fields
|
||||
|
||||
@@ -399,6 +399,21 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||
},
|
||||
controller : 'UserFederatedIdentityCtrl'
|
||||
})
|
||||
.when('/realms/:realm/users/:user/consents', {
|
||||
templateUrl : resourceUrl + '/partials/user-consents.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
user : function(UserLoader) {
|
||||
return UserLoader();
|
||||
},
|
||||
userConsents : function(UserConsentsLoader) {
|
||||
return UserConsentsLoader();
|
||||
}
|
||||
},
|
||||
controller : 'UserConsentsCtrl'
|
||||
})
|
||||
.when('/realms/:realm/users', {
|
||||
templateUrl : resourceUrl + '/partials/user-list.html',
|
||||
resolve : {
|
||||
@@ -1418,6 +1433,15 @@ module.directive('kcNavigationClient', function () {
|
||||
}
|
||||
});
|
||||
|
||||
module.directive('kcNavigationUser', function () {
|
||||
return {
|
||||
scope: true,
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: resourceUrl + '/templates/kc-navigation-user.html'
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Used to select the element (invoke $(elem).select()) on specified action list.
|
||||
* Usages kc-select-action="click mouseover"
|
||||
|
||||
+18
@@ -135,6 +135,24 @@ module.controller('UserFederatedIdentityCtrl', function($scope, realm, user, fed
|
||||
$scope.federatedIdentities = federatedIdentities;
|
||||
});
|
||||
|
||||
module.controller('UserConsentsCtrl', function($scope, realm, user, userConsents, UserConsents, Notifications) {
|
||||
$scope.realm = realm;
|
||||
$scope.user = user;
|
||||
$scope.userConsents = userConsents;
|
||||
|
||||
$scope.revokeConsent = function(clientId) {
|
||||
UserConsents.delete({realm : realm.realm, user: user.username, client: clientId }, function () {
|
||||
UserConsents.query({realm: realm.realm, user: user.username}, function(updated) {
|
||||
$scope.userConsents = updated;
|
||||
})
|
||||
Notifications.success('Consent revoked successfully');
|
||||
}, function() {
|
||||
Notifications.error("Consent couldn't be revoked");
|
||||
});
|
||||
console.log("Revoke consent " + clientId);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.controller('UserListCtrl', function($scope, realm, User) {
|
||||
$scope.realm = realm;
|
||||
|
||||
@@ -144,6 +144,14 @@ module.factory('UserFederatedIdentityLoader', function(Loader, UserFederatedIden
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('UserConsentsLoader', function(Loader, UserConsents, $route, $q) {
|
||||
return Loader.query(UserConsents, function() {
|
||||
return {
|
||||
realm : $route.current.params.realm,
|
||||
user : $route.current.params.user
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -268,6 +268,13 @@ module.factory('UserFederatedIdentity', function($resource) {
|
||||
user : '@user'
|
||||
});
|
||||
});
|
||||
module.factory('UserConsents', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/users/:user/consents/:client', {
|
||||
realm : '@realm',
|
||||
user : '@user',
|
||||
client: '@client'
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('UserCredentials', function($resource) {
|
||||
var credentials = {};
|
||||
|
||||
+1
-7
@@ -1,12 +1,6 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/social-links">Federated Identities</a></li>
|
||||
</ul>
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">{{user.username}}</a></li>
|
||||
<li class="active">Consents</li>
|
||||
</ol>
|
||||
<h2>User <span>{{user.username}}</span> Consents <span tooltip-placement="right" tooltip="This page shows you all the consents, which user granted permissions" class="fa fa-info-circle"></span></h2>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th>Granted Roles</th>
|
||||
<th>Granted Protocol Mappers</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr data-ng-repeat="consent in userConsents">
|
||||
<td>{{consent.clientId}}</td>
|
||||
<td>
|
||||
<span data-ng-repeat="realmRole in consent.grantedRealmRoles">
|
||||
<span ng-if="!$first">, </span>{{realmRole}}
|
||||
</span>
|
||||
<span data-ng-repeat="(clientId, clientRoles) in consent.grantedClientRoles">
|
||||
<span data-ng-repeat="clientRole in clientRoles">
|
||||
<span ng-if="!$first || consent.grantedRealmRoles.length > 0">, </span>{{clientRole}} in {{clientId}}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span data-ng-repeat="protocol in consent.grantedProtocolMappers">
|
||||
<span data-ng-repeat="protocolMapper in protocol">
|
||||
<span ng-if="!$first">, </span>{{protocolMapper}}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" ng-click="revokeConsent(consent.clientId)">Revoke consent</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
+1
-8
@@ -1,13 +1,6 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/federated-identity">Federated Identities</a></li>
|
||||
</ul>
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||
|
||||
+1
-8
@@ -1,13 +1,6 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li data-ng-show="access.manageUsers"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/federated-identity">Federated Identities</a></li>
|
||||
</ul>
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="create">
|
||||
<li class="active"><a href="">User List</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/user-federation">Federation</a></li>
|
||||
|
||||
+1
-7
@@ -1,12 +1,6 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<ul class="nav nav-tabs nav-tabs-pf">
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/federated-identity">Federated Identities</a></li>
|
||||
</ul>
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||
|
||||
+1
-7
@@ -1,12 +1,6 @@
|
||||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<ul class="nav nav-tabs nav-tabs-pf">
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/federated-identity">Federated Identities</a></li>
|
||||
</ul>
|
||||
<kc-navigation-user></kc-navigation-user>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/users">Users</a></li>
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-hide="create">
|
||||
<li ng-class="{active: !path[4]}"><a href="#/realms/{{realm.realm}}/users/{{user.username}}">Attributes</a></li>
|
||||
<li ng-class="{active: path[4] == 'user-credentials'}"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/user-credentials">Credentials</a></li>
|
||||
<li ng-class="{active: path[4] == 'role-mappings'}"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/role-mappings">Role Mappings</a></li>
|
||||
<li ng-class="{active: path[4] == 'sessions'}"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/sessions">Sessions</a></li>
|
||||
<li ng-class="{active: path[4] == 'federated-identity'}" data-ng-show="realm.identityFederationEnabled"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/federated-identity">Federated Identities</a></li>
|
||||
<li ng-class="{active: path[4] == 'consents'}"><a href="#/realms/{{realm.realm}}/users/{{user.username}}/consents">Consents</a></li>
|
||||
</ul>
|
||||
+2
@@ -84,9 +84,11 @@ role_manage-clients=Manage clients
|
||||
role_manage-events=Manage events
|
||||
role_view-profile=View profile
|
||||
role_manage-account=Manage account
|
||||
role_read-token=Read token
|
||||
client_account=Account
|
||||
client_security-admin-console=Security Admin Console
|
||||
client_realm-management=Realm Management
|
||||
client_broker=Broker
|
||||
|
||||
invalidUserMessage=Invalid username or password.
|
||||
invalidEmailMessage=Invalid email address.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</keycloak.osgi.export>
|
||||
<keycloak.osgi.import>
|
||||
org.keycloak.*;version="${project.version}",
|
||||
org.apache.http.*;version=${keycloak.apache.httpcomponents.version},
|
||||
org.apache.http.*;version=${apache.httpcomponents.version},
|
||||
org.apache.karaf.jaas.boot.principal;resolution:=optional,
|
||||
org.apache.karaf.jaas.modules;resolution:=optional,
|
||||
*;resolution:=optional
|
||||
@@ -71,7 +71,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
@@ -21,17 +22,33 @@ public class MigrationTo1_2_0_RC1 {
|
||||
if (client == null) {
|
||||
client = KeycloakModelUtils.createClient(realm, Constants.BROKER_SERVICE_CLIENT_ID);
|
||||
client.setEnabled(true);
|
||||
client.setName("${client_" + Constants.BROKER_SERVICE_CLIENT_ID + "}");
|
||||
client.setFullScopeAllowed(false);
|
||||
|
||||
for (String role : Constants.BROKER_SERVICE_ROLES) {
|
||||
client.addRole(role).setDescription("${role_"+role+"}");
|
||||
client.addRole(role).setDescription("${role_"+ role.toLowerCase().replaceAll("_", "-") +"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupClientNames(RealmModel realm) {
|
||||
Map<String, ClientModel> clients = realm.getClientNameMap();
|
||||
|
||||
setupClientName(clients, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||
setupClientName(clients, Constants.ADMIN_CONSOLE_CLIENT_ID);
|
||||
setupClientName(clients, Constants.REALM_MANAGEMENT_CLIENT_ID);
|
||||
}
|
||||
|
||||
private void setupClientName(Map<String, ClientModel> clients, String clientId) {
|
||||
ClientModel client = clients.get(clientId);
|
||||
if (client != null && client.getName() == null) client.setName("${client_" + clientId + "}");
|
||||
}
|
||||
|
||||
public void migrate(KeycloakSession session) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
setupBrokerService(realm);
|
||||
setupClientNames(realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ public interface Constants {
|
||||
|
||||
String ACCOUNT_MANAGEMENT_CLIENT_ID = "account";
|
||||
String BROKER_SERVICE_CLIENT_ID = "broker";
|
||||
String REALM_MANAGEMENT_CLIENT_ID = "realm-management";
|
||||
|
||||
String INSTALLED_APP_URN = "urn:ietf:wg:oauth:2.0:oob";
|
||||
String INSTALLED_APP_URL = "http://localhost";
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
@@ -22,6 +23,7 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserConsentRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||
@@ -325,4 +327,45 @@ public class ModelToRepresentation {
|
||||
return rep;
|
||||
}
|
||||
|
||||
public static UserConsentRepresentation toRepresentation(UserConsentModel model) {
|
||||
String clientId = model.getClient().getClientId();
|
||||
|
||||
Map<String, List<String>> grantedProtocolMappers = new HashMap<String, List<String>>();
|
||||
for (ProtocolMapperModel protocolMapper : model.getGrantedProtocolMappers()) {
|
||||
String protocol = protocolMapper.getProtocol();
|
||||
List<String> currentProtocolMappers = grantedProtocolMappers.get(protocol);
|
||||
if (currentProtocolMappers == null) {
|
||||
currentProtocolMappers = new LinkedList<String>();
|
||||
grantedProtocolMappers.put(protocol, currentProtocolMappers);
|
||||
}
|
||||
currentProtocolMappers.add(protocolMapper.getName());
|
||||
}
|
||||
|
||||
List<String> grantedRealmRoles = new LinkedList<String>();
|
||||
Map<String, List<String>> grantedClientRoles = new HashMap<String, List<String>>();
|
||||
for (RoleModel role : model.getGrantedRoles()) {
|
||||
if (role.getContainer() instanceof RealmModel) {
|
||||
grantedRealmRoles.add(role.getName());
|
||||
} else {
|
||||
ClientModel client2 = (ClientModel) role.getContainer();
|
||||
|
||||
String clientId2 = client2.getClientId();
|
||||
List<String> currentClientRoles = grantedClientRoles.get(clientId2);
|
||||
if (currentClientRoles == null) {
|
||||
currentClientRoles = new LinkedList<String>();
|
||||
grantedClientRoles.put(clientId2, currentClientRoles);
|
||||
}
|
||||
currentClientRoles.add(role.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UserConsentRepresentation consentRep = new UserConsentRepresentation();
|
||||
consentRep.setClientId(clientId);
|
||||
consentRep.setGrantedProtocolMappers(grantedProtocolMappers);
|
||||
consentRep.setGrantedRealmRoles(grantedRealmRoles);
|
||||
consentRep.setGrantedClientRoles(grantedClientRoles);
|
||||
return consentRep;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -788,33 +788,8 @@ public class RepresentationToModel {
|
||||
}
|
||||
}
|
||||
if (userRep.getClientConsents() != null) {
|
||||
for (Map.Entry<String, UserConsentRepresentation> entry : userRep.getClientConsents().entrySet()) {
|
||||
ClientModel client = clientMap.get(entry.getKey());
|
||||
if (client == null) {
|
||||
throw new RuntimeException("Unable to find client consent mappings for client: " + entry.getKey());
|
||||
}
|
||||
|
||||
UserConsentModel consentModel = new UserConsentModel(client);
|
||||
|
||||
UserConsentRepresentation consentRep = entry.getValue();
|
||||
if (consentRep.getGrantedRoles() != null) {
|
||||
for (String roleId : consentRep.getGrantedRoles()) {
|
||||
RoleModel role = newRealm.getRoleById(roleId);
|
||||
if (role == null) {
|
||||
throw new RuntimeException("Unable to find realm role referenced in consent mappings of user " + user.getUsername() + ". Role ID: " + roleId);
|
||||
}
|
||||
consentModel.addGrantedRole(role);
|
||||
}
|
||||
}
|
||||
if (consentRep.getGrantedProtocolMappers() != null) {
|
||||
for (String mapperId : consentRep.getGrantedProtocolMappers()) {
|
||||
ProtocolMapperModel protocolMapper = client.getProtocolMapperById(mapperId);
|
||||
if (protocolMapper == null) {
|
||||
throw new RuntimeException("Unable to find protocol mapper referenced in consent mappings of user " + user.getUsername() + ". Protocol mapper ID: " + mapperId);
|
||||
}
|
||||
consentModel.addGrantedProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
|
||||
UserConsentModel consentModel = toModel(newRealm, consentRep);
|
||||
user.addConsent(consentModel);
|
||||
}
|
||||
}
|
||||
@@ -917,4 +892,53 @@ public class RepresentationToModel {
|
||||
return model;
|
||||
}
|
||||
|
||||
public static UserConsentModel toModel(RealmModel newRealm, UserConsentRepresentation consentRep) {
|
||||
ClientModel client = newRealm.getClientByClientId(consentRep.getClientId());
|
||||
if (client == null) {
|
||||
throw new RuntimeException("Unable to find client consent mappings for client: " + consentRep.getClientId());
|
||||
}
|
||||
|
||||
UserConsentModel consentModel = new UserConsentModel(client);
|
||||
|
||||
if (consentRep.getGrantedRealmRoles() != null) {
|
||||
for (String roleName : consentRep.getGrantedRealmRoles()) {
|
||||
RoleModel role = newRealm.getRole(roleName);
|
||||
if (role == null) {
|
||||
throw new RuntimeException("Unable to find realm role referenced in consent mappings of user. Role name: " + roleName);
|
||||
}
|
||||
consentModel.addGrantedRole(role);
|
||||
}
|
||||
}
|
||||
if (consentRep.getGrantedClientRoles() != null) {
|
||||
for (Map.Entry<String, List<String>> entry : consentRep.getGrantedClientRoles().entrySet()) {
|
||||
String clientId2 = entry.getKey();
|
||||
ClientModel client2 = newRealm.getClientByClientId(clientId2);
|
||||
if (client2 == null) {
|
||||
throw new RuntimeException("Unable to find client referenced in consent mappings. Client ID: " + clientId2);
|
||||
}
|
||||
for (String clientRoleName : entry.getValue()) {
|
||||
RoleModel clientRole = client2.getRole(clientRoleName);
|
||||
if (clientRole == null) {
|
||||
throw new RuntimeException("Unable to find client role referenced in consent mappings of user. Role name: " + clientRole + ", Client: " + clientId2);
|
||||
}
|
||||
consentModel.addGrantedRole(clientRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (consentRep.getGrantedProtocolMappers() != null) {
|
||||
for (Map.Entry<String, List<String>> protocolEntry : consentRep.getGrantedProtocolMappers().entrySet()) {
|
||||
String protocol = protocolEntry.getKey();
|
||||
for (String protocolMapperName : protocolEntry.getValue()) {
|
||||
ProtocolMapperModel protocolMapper = client.getProtocolMapperByName(protocol, protocolMapperName);
|
||||
if (protocolMapper == null) {
|
||||
throw new RuntimeException("Unable to find protocol mapper for protocol " + protocol + ", mapper name " + protocolMapperName);
|
||||
}
|
||||
|
||||
consentModel.addGrantedProtocolMapper(protocolMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
return consentModel;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-2
@@ -15,6 +15,7 @@ import org.keycloak.models.cache.entities.CachedRole;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -196,8 +197,16 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||
|
||||
@Override
|
||||
public List<RealmModel> getRealms() {
|
||||
// we don't cache this for now
|
||||
return getDelegate().getRealms();
|
||||
// Retrieve realms from backend
|
||||
List<RealmModel> backendRealms = getDelegate().getRealms();
|
||||
|
||||
// Return cache delegates to ensure cache invalidated during write operations
|
||||
List<RealmModel> cachedRealms = new LinkedList<RealmModel>();
|
||||
for (RealmModel realm : backendRealms) {
|
||||
RealmModel cached = session.realms().getRealm(realm.getId());
|
||||
cachedRealms.add(cached);
|
||||
}
|
||||
return cachedRealms;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
@@ -1,5 +1,6 @@
|
||||
package org.keycloak.models.mongo.keycloak.entities;
|
||||
|
||||
import org.keycloak.connections.mongo.api.MongoCollection;
|
||||
import org.keycloak.connections.mongo.api.MongoIdentifiableEntity;
|
||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
|
||||
@@ -7,6 +8,7 @@ import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@MongoCollection(collectionName = "migrationModel")
|
||||
public class MongoMigrationModelEntity implements MongoIdentifiableEntity {
|
||||
public static final String MIGRATION_MODEL_ID = "VERSION";
|
||||
private String id = MIGRATION_MODEL_ID;
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
<base64.version>2.3.8</base64.version>
|
||||
<bouncycastle.crypto.version>1.50</bouncycastle.crypto.version>
|
||||
<jackson.version>1.9.9</jackson.version>
|
||||
<keycloak.apache.httpcomponents.version>4.2.1</keycloak.apache.httpcomponents.version>
|
||||
<apache.httpcomponents.version>4.3.6</apache.httpcomponents.version>
|
||||
<apache.httpcomponents.httpcore.version>4.3.3</apache.httpcomponents.httpcore.version>
|
||||
<resteasy.version>3.0.10.Final</resteasy.version>
|
||||
<undertow.version>1.1.1.Final</undertow.version>
|
||||
<picketlink.version>2.7.0.Final</picketlink.version>
|
||||
@@ -427,7 +428,17 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<version>${apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>${apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>${apache.httpcomponents.httpcore.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
@@ -1063,6 +1074,12 @@
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>distribution</id>
|
||||
<modules>
|
||||
<module>distribution</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>jboss-release</id>
|
||||
<modules>
|
||||
|
||||
+1
-28
@@ -32,34 +32,7 @@ public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements
|
||||
property.setHelpText(ProtocolMapperUtils.USER_SESSION_MODEL_NOTE_HELP_TEXT);
|
||||
property.setType(ProviderConfigProperty.STRING_TYPE);
|
||||
configProperties.add(property);
|
||||
property = new ProviderConfigProperty();
|
||||
property.setName(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
|
||||
property.setLabel(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME_LABEL);
|
||||
property.setType(ProviderConfigProperty.STRING_TYPE);
|
||||
property.setHelpText("Name of the claim to insert into the token. This can be a fully qualified name like 'address.street'. In this case, a nested json object will be created.");
|
||||
configProperties.add(property);
|
||||
property = new ProviderConfigProperty();
|
||||
property.setName(OIDCAttributeMapperHelper.JSON_TYPE);
|
||||
property.setLabel(OIDCAttributeMapperHelper.JSON_TYPE);
|
||||
property.setType(ProviderConfigProperty.STRING_TYPE);
|
||||
property.setDefaultValue(ProviderConfigProperty.STRING_TYPE);
|
||||
property.setHelpText("JSON type that should be used to populate the json claim in the token. long, int, boolean, and String are valid values.");
|
||||
configProperties.add(property);
|
||||
property = new ProviderConfigProperty();
|
||||
property.setName(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN);
|
||||
property.setLabel(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN_LABEL);
|
||||
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
|
||||
property.setDefaultValue("true");
|
||||
property.setHelpText(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN_HELP_TEXT);
|
||||
configProperties.add(property);
|
||||
property = new ProviderConfigProperty();
|
||||
property.setName(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN);
|
||||
property.setLabel(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN_LABEL);
|
||||
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
|
||||
property.setDefaultValue("true");
|
||||
property.setHelpText(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN_HELP_TEXT);
|
||||
configProperties.add(property);
|
||||
|
||||
OIDCAttributeMapperHelper.addAttributeConfig(configProperties);
|
||||
}
|
||||
|
||||
public static final String PROVIDER_ID = "oidc-usersessionmodel-note-mapper";
|
||||
|
||||
@@ -113,11 +113,11 @@ public class RealmManager {
|
||||
}
|
||||
|
||||
public String getRealmAdminClientId(RealmModel realm) {
|
||||
return "realm-management";
|
||||
return Constants.REALM_MANAGEMENT_CLIENT_ID;
|
||||
}
|
||||
|
||||
public String getRealmAdminClientId(RealmRepresentation realm) {
|
||||
return "realm-management";
|
||||
return Constants.REALM_MANAGEMENT_CLIENT_ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -223,10 +223,11 @@ public class RealmManager {
|
||||
if (client == null) {
|
||||
client = new ClientManager(this).createClient(realm, Constants.BROKER_SERVICE_CLIENT_ID);
|
||||
client.setEnabled(true);
|
||||
client.setName("${client_" + Constants.BROKER_SERVICE_CLIENT_ID + "}");
|
||||
client.setFullScopeAllowed(false);
|
||||
|
||||
for (String role : Constants.BROKER_SERVICE_ROLES) {
|
||||
client.addRole(role).setDescription("${role_"+role+"}");
|
||||
client.addRole(role).setDescription("${role_"+ role.toLowerCase().replaceAll("_", "-") +"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +531,14 @@ public class AccountService {
|
||||
event.event(EventType.REVOKE_GRANT).client(auth.getClient()).user(auth.getUser()).detail(Details.REVOKED_CLIENT, client.getClientId()).success();
|
||||
setReferrerOnPage();
|
||||
|
||||
return account.setSuccess(Messages.SUCCESS_GRANT_REVOKED).createResponse(AccountPages.APPLICATIONS);
|
||||
UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "applicationsPage");
|
||||
String referrer = uriInfo.getQueryParameters().getFirst("referrer");
|
||||
if (referrer != null) {
|
||||
builder.queryParam("referrer", referrer);
|
||||
|
||||
}
|
||||
URI location = builder.build(realm.getName());
|
||||
return Response.seeOther(location).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.ModelReadOnlyException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
@@ -30,6 +31,7 @@ import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.MappingsRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserConsentRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
@@ -310,6 +312,56 @@ public class UsersResource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List set of consents granted by this user.
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@Path("{username}/consents")
|
||||
@GET
|
||||
@NoCache
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<UserConsentRepresentation> getConsents(final @PathParam("username") String username) {
|
||||
auth.requireView();
|
||||
UserModel user = session.users().getUserByUsername(username, realm);
|
||||
if (user == null) {
|
||||
throw new NotFoundException("User not found");
|
||||
}
|
||||
|
||||
List<UserConsentModel> consents = user.getConsents();
|
||||
List<UserConsentRepresentation> result = new ArrayList<UserConsentRepresentation>();
|
||||
|
||||
for (UserConsentModel consent : consents) {
|
||||
UserConsentRepresentation rep = ModelToRepresentation.toRepresentation(consent);
|
||||
result.add(rep);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke consent for particular client
|
||||
*
|
||||
* @param username
|
||||
* @param clientId
|
||||
*/
|
||||
@Path("{username}/consents/{client}")
|
||||
@DELETE
|
||||
@NoCache
|
||||
public void revokeConsent(final @PathParam("username") String username, final @PathParam("client") String clientId) {
|
||||
auth.requireManage();
|
||||
UserModel user = session.users().getUserByUsername(username, realm);
|
||||
if (user == null) {
|
||||
throw new NotFoundException("User not found");
|
||||
}
|
||||
|
||||
ClientModel client = realm.getClientByClientId(clientId);
|
||||
boolean revoked = user.revokeConsentForClient(client.getId());
|
||||
if (!revoked) {
|
||||
throw new NotFoundException("Consent not found for user " + username + " and client " + clientId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all user sessions associated with this user. And, for all client that have an admin URL, tell
|
||||
* them to invalidate the sessions for this particular user.
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.IdentityProviderResource;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.representations.idm.ErrorRepresentation;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
@@ -43,6 +44,10 @@ public class UserTest extends AbstractClientTest {
|
||||
fail("Expected failure");
|
||||
} catch (ClientErrorException e) {
|
||||
assertEquals(409, e.getResponse().getStatus());
|
||||
|
||||
// Just to show how to retrieve underlying error message
|
||||
ErrorRepresentation error = e.getResponse().readEntity(ErrorRepresentation.class);
|
||||
Assert.assertEquals("User exists with same username", error.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.keycloak.testsuite.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
@@ -32,7 +34,17 @@ public class CacheTest {
|
||||
{
|
||||
// update realm, then get an AppModel and change it. The AppModel would not be a cache adapter
|
||||
KeycloakSession session = kc.startSession();
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
// KEYCLOAK-1240 - obtain the realm via session.realms().getRealms()
|
||||
RealmModel realm = null;
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel current : realms) {
|
||||
if ("test".equals(current.getName())) {
|
||||
realm = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue(realm instanceof org.keycloak.models.cache.RealmAdapter);
|
||||
realm.setAccessCodeLifespanLogin(200);
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
@@ -44,6 +56,7 @@ public class CacheTest {
|
||||
{
|
||||
KeycloakSession session = kc.startSession();
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
Assert.assertEquals(200, realm.getAccessCodeLifespanLogin());
|
||||
ClientModel testApp = session.realms().getClientById(appId, realm);
|
||||
Assert.assertFalse(testApp.isEnabled());
|
||||
kc.stopSession(session, true);
|
||||
|
||||
@@ -75,15 +75,22 @@
|
||||
"Application": [ "app-admin" ],
|
||||
"OtherApp": [ "otherapp-admin" ]
|
||||
},
|
||||
"clientConsents": {
|
||||
"Application": {
|
||||
"grantedRoles": [ "456", "789" ]
|
||||
"clientConsents": [
|
||||
{
|
||||
"clientId": "Application",
|
||||
"grantedRealmRoles": [ "admin" ],
|
||||
"grantedClientRoles": {
|
||||
"Application": [ "app-admin" ]
|
||||
}
|
||||
},
|
||||
"OtherApp": {
|
||||
"grantedProtocolMappers": [ "123" ],
|
||||
"grantedRoles": [ "456" ]
|
||||
{
|
||||
"clientId": "OtherApp",
|
||||
"grantedRealmRoles": [ "admin" ],
|
||||
"grantedProtocolMappers": {
|
||||
"openid-connect": [ "gss delegation credential" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"username": "mySocialUser",
|
||||
@@ -124,7 +131,6 @@
|
||||
"enabled": true,
|
||||
"protocolMappers" : [
|
||||
{
|
||||
"id": "123",
|
||||
"name" : "gss delegation credential",
|
||||
"protocol" : "openid-connect",
|
||||
"protocolMapper" : "oidc-usersessionmodel-note-mapper",
|
||||
@@ -150,14 +156,12 @@
|
||||
"roles" : {
|
||||
"realm" : [
|
||||
{
|
||||
"id": "456",
|
||||
"name": "admin"
|
||||
}
|
||||
],
|
||||
"application" : {
|
||||
"Application" : [
|
||||
{
|
||||
"id": "789",
|
||||
"name": "app-admin"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
@@ -92,7 +92,6 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
||||
Reference in new issue
Block a user