Merge pull request #1015 from patriot1burke/master

refactor mapper
This commit is contained in:
Bill Burke 2015-03-03 21:21:42 -05:00
commit d7860420d6
59 changed files with 640 additions and 1583 deletions

View file

@ -17,7 +17,7 @@
<column name="APPLIED_BY_DEFAULT" type="BOOLEAN(1)"/>
<column name="CONSENT_REQUIRED" type="BOOLEAN(1)"/>
<column name="CONSENT_TEXT" type="VARCHAR(255)"/>
<column name="REALM_ID" type="VARCHAR(36)">
<column name="CLIENT_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
</createTable>
@ -30,15 +30,6 @@
<constraints nullable="false"/>
</column>
</createTable>
<createTable tableName="CLAIM_TYPE">
<column name="ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="NAME" type="VARCHAR(255)"/>
<column name="BUILT_IN" type="BOOLEAN(1)"/>
<column name="VALUE_TYPE" type="VARCHAR(255)"/>
<column name="REALM_ID" type="VARCHAR(36)"/>
</createTable>
<createTable tableName="FEDERATED_IDENTITY">
<column name="IDENTITY_PROVIDER" type="VARCHAR(255)">
<constraints nullable="false"/>
@ -82,33 +73,21 @@
</column>
<column name="RETRIEVE_TOKEN" type="BOOLEAN(1)"/>
</createTable>
<createTable tableName="CLIENT_PROTOCOL_MAPPER">
<column name="CLIENT_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="MAPPING_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
</createTable>
<addColumn tableName="CLIENT">
<column name="FRONTCHANNEL_LOGOUT" type="BOOLEAN" defaultValueBoolean="false"/>
</addColumn>
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_CT" tableName="CLAIM_TYPE"/>
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_PCM" tableName="PROTOCOL_MAPPER"/>
<addPrimaryKey columnNames="INTERNAL_ID" constraintName="CONSTRAINT_2B" tableName="IDENTITY_PROVIDER"/>
<addPrimaryKey columnNames="IDENTITY_PROVIDER, USER_ID" constraintName="CONSTRAINT_40" tableName="FEDERATED_IDENTITY"/>
<addPrimaryKey columnNames="IDENTITY_PROVIDER_ID, NAME" constraintName="CONSTRAINT_D" tableName="IDENTITY_PROVIDER_CONFIG"/>
<addPrimaryKey columnNames="PROTOCOL_MAPPER_ID, NAME" constraintName="CONSTRAINT_PMConfig" tableName="PROTOCOL_MAPPER_CONFIG"/>
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="IDENTITY_PROVIDER" constraintName="FK2B4EBC52AE5C3B34" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="CLAIM_TYPE" constraintName="FK_CT_REALM" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="PROTOCOL_MAPPER" constraintName="FK_PCM_REALM" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="REALM"/>
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="PROTOCOL_MAPPER" constraintName="FK_PCM_REALM" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="CLIENT"/>
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="FEDERATED_IDENTITY" constraintName="FK404288B92EF007A6" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
<addForeignKeyConstraint baseColumnNames="IDENTITY_PROVIDER_ID" baseTableName="IDENTITY_PROVIDER_CONFIG" constraintName="FKDC4897CF864C4E43" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="PROTOCOL_MAPPER_ID" baseTableName="PROTOCOL_MAPPER_CONFIG" constraintName="FK_PMConfig" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="PROTOCOL_MAPPER"/>
<addForeignKeyConstraint baseColumnNames="IDENTITY_PROVIDER_ID" baseTableName="CLIENT_IDENTITY_PROVIDER_MAPPING" constraintName="FK_7CELWNIBJI49AVXSRTUF6XJ12" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_IDENTITY_PROVIDER_MAPPING" constraintName="FK_56ELWNIBJI49AVXSRTUF6XJ23" referencedColumnNames="ID" referencedTableName="CLIENT"/>
<addForeignKeyConstraint baseColumnNames="MAPPING_ID" baseTableName="CLIENT_PROTOCOL_MAPPER" constraintName="FK_CPCM" referencedColumnNames="ID" referencedTableName="PROTOCOL_MAPPER"/>
<addUniqueConstraint columnNames="CLIENT_ID,MAPPING_ID" constraintName="UK_CPCM" tableName="CLIENT_PROTOCOL_MAPPER"/>
<addUniqueConstraint columnNames="PROVIDER_NONIMAL_ID" constraintName="UK_2DAELWNIBJI49AVXSRTUF6XJ33" tableName="IDENTITY_PROVIDER"/>
<addUniqueConstraint columnNames="IDENTITY_PROVIDER_ID,CLIENT_ID" constraintName="UK_7CAELWNIBJI49AVXSRTUF6XJ12" tableName="CLIENT_IDENTITY_PROVIDER_MAPPING"/>
</changeSet>

View file

@ -19,7 +19,6 @@
<class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
<class>org.keycloak.models.jpa.entities.IdentityProviderEntity</class>
<class>org.keycloak.models.jpa.entities.ClientIdentityProviderMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ClaimTypeEntity</class>
<class>org.keycloak.models.jpa.entities.ProtocolMapperEntity</class>
<!-- JpaUserSessionProvider -->

View file

@ -29,7 +29,7 @@ public class ApplicationRepresentation {
protected Integer nodeReRegistrationTimeout;
protected Map<String, Integer> registeredNodes;
protected List<ClientIdentityProviderMappingRepresentation> identityProviders;
protected List<ClientProtocolMappingRepresentation> protocolMappers;
protected List<ProtocolMapperRepresentation> protocolMappers;
public String getId() {
return id;
@ -199,11 +199,11 @@ public class ApplicationRepresentation {
this.identityProviders = identityProviders;
}
public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
public List<ProtocolMapperRepresentation> getProtocolMappers() {
return protocolMappers;
}
public void setProtocolMappers(List<ClientProtocolMappingRepresentation> protocolMappers) {
public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}

View file

@ -1,45 +0,0 @@
package org.keycloak.representations.idm;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClaimTypeRepresentation {
private String id;
private String name;
private Boolean builtIn;
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean isBuiltIn() {
return builtIn;
}
public void setBuiltIn(Boolean builtIn) {
this.builtIn = builtIn;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View file

@ -1,26 +0,0 @@
package org.keycloak.representations.idm;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClientProtocolMappingRepresentation {
protected String protocol;
protected String name;
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View file

@ -22,7 +22,7 @@ public class OAuthClientRepresentation {
protected Boolean directGrantsOnly;
protected Boolean fullScopeAllowed;
protected Boolean frontchannelLogout;
protected List<ClientProtocolMappingRepresentation> protocolMappers;
protected List<ProtocolMapperRepresentation> protocolMappers;
private List<ClientIdentityProviderMappingRepresentation> identityProviders;
@ -146,11 +146,11 @@ public class OAuthClientRepresentation {
this.identityProviders = identityProviders;
}
public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
public List<ProtocolMapperRepresentation> getProtocolMappers() {
return protocolMappers;
}
public void setProtocolMappers(List<ClientProtocolMappingRepresentation> protocolMappers) {
public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}

View file

@ -12,7 +12,6 @@ public class ProtocolMapperRepresentation {
protected String name;
protected String protocol;
protected String protocolMapper;
protected boolean appliedByDefault;
protected boolean consentRequired;
protected String consentText;
protected Map<String, String> config = new HashMap<String, String>();
@ -42,14 +41,6 @@ public class ProtocolMapperRepresentation {
this.protocol = protocol;
}
public boolean isAppliedByDefault() {
return appliedByDefault;
}
public void setAppliedByDefault(boolean appliedByDefault) {
this.appliedByDefault = appliedByDefault;
}
public String getProtocolMapper() {
return protocolMapper;
}

View file

@ -64,7 +64,6 @@ public class RealmRepresentation {
protected Long eventsExpiration;
protected List<String> eventsListeners;
private List<IdentityProviderRepresentation> identityProviders;
private List<ClaimTypeRepresentation> claimTypes;
private List<ProtocolMapperRepresentation> protocolMappers;
private Boolean identityFederationEnabled;
@ -484,15 +483,6 @@ public class RealmRepresentation {
return !getIdentityProviders().isEmpty();
}
public List<ClaimTypeRepresentation> getClaimTypes() {
if (claimTypes == null) claimTypes = new ArrayList<ClaimTypeRepresentation>();
return claimTypes;
}
public void setClaimTypes(List<ClaimTypeRepresentation> claimTypes) {
this.claimTypes = claimTypes;
}
public List<ProtocolMapperRepresentation> getProtocolMappers() {
return protocolMappers;
}

View file

@ -33,7 +33,6 @@
<script src="${resourceUrl}/js/controllers/applications.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/oauth-clients.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/users.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/controllers/protocols.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/loaders.js" type="text/javascript"></script>
<script src="${resourceUrl}/js/services.js" type="text/javascript"></script>

View file

@ -440,7 +440,7 @@ module.config([ '$routeProvider', function($routeProvider) {
return ServerInfoLoader();
}
},
controller : 'ApplicationProtocolMapperCtrl'
controller : 'ApplicationProtocolMapperListCtrl'
})
.when('/realms/:realm/applications/:application/add-mappers', {
templateUrl : resourceUrl + '/partials/application-mappers-add.html',
@ -455,7 +455,41 @@ module.config([ '$routeProvider', function($routeProvider) {
return ServerInfoLoader();
}
},
controller : 'AddApplicationProtocolMapperCtrl'
controller : 'AddBuiltinProtocolMapperCtrl'
})
.when('/realms/:realm/applications/:application/mappers/:id', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
mapper : function(ApplicationProtocolMapperLoader) {
return ApplicationProtocolMapperLoader();
}
},
controller : 'ApplicationProtocolMapperCtrl'
})
.when('/create/application/:realm/:application/mappers', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
application : function(ApplicationLoader) {
return ApplicationLoader();
}
},
controller : 'ApplicationProtocolMapperCreateCtrl'
})
.when('/realms/:realm/applications/:application/sessions', {
templateUrl : resourceUrl + '/partials/application-sessions.html',
@ -974,59 +1008,7 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'ProtocolListCtrl'
})
.when('/realms/:realm/protocols/:protocol/mappers', {
templateUrl : resourceUrl + '/partials/protocol-mapper-list.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
protocol : function($route) {
return $route.current.params.protocol;
},
mappers : function(RealmProtocolMappersByProtocolLoader) {
return RealmProtocolMappersByProtocolLoader();
}
},
controller : 'ProtocolMapperListCtrl'
})
.when('/realms/:realm/protocols/:protocol/mappers/:id', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
protocol : function($route) {
return $route.current.params.protocol;
},
mapper : function(RealmProtocolMapperLoader) {
return RealmProtocolMapperLoader();
}
},
controller : 'ProtocolMapperCtrl'
})
.when('/create/protocols/:protocol/realms/:realm/mappers', {
templateUrl : resourceUrl + '/partials/protocol-mapper-detail.html',
resolve : {
realm : function(RealmLoader) {
return RealmLoader();
},
serverInfo : function(ServerInfoLoader) {
return ServerInfoLoader();
},
protocol : function($route) {
return $route.current.params.protocol;
}
},
controller : 'ProtocolMapperCreateCtrl'
})
.when('/server-info', {
templateUrl : resourceUrl + '/partials/server-info.html'

View file

@ -1086,7 +1086,7 @@ module.controller('ApplicationClusteringNodeCtrl', function($scope, application,
}
});
module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, application, serverInfo,
module.controller('ApplicationProtocolMapperListCtrl', function($scope, realm, application, serverInfo,
ApplicationProtocolMappersByProtocol,
$http, $location, Dialog, Notifications) {
$scope.realm = realm;
@ -1105,35 +1105,12 @@ module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, appli
var updateMappers = function() {
$scope.mappers = ApplicationProtocolMappersByProtocol.query({realm : realm.realm, application : application.id, protocol : application.protocol});
for (var i = 0; i < $scope.mappers.length; i++) {
$scope.mappers[i].isChecked = false;
}
};
updateMappers();
$scope.remove = function() {
var toDelete = [];
for (var i = 0; i < $scope.mappers.length; i++) {
if ($scope.mappers[i].isChecked) {
toDelete.push($scope.mappers[i].id);
}
}
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/protocol-mappers/models',
{data : toDelete, headers : {"content-type" : "application/json"}}).success(function() {
Notifications.success("Mappers removed");
updateMappers();
}).error(function() {
updateMappers();
Notifications.error("Error removing mappers");
});
};
});
module.controller('AddApplicationProtocolMapperCtrl', function($scope, realm, application, serverInfo,
RealmProtocolMappersByProtocol,
module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, application, serverInfo,
ApplicationProtocolMappersByProtocol,
$http, $location, Dialog, Notifications) {
$scope.realm = realm;
@ -1150,27 +1127,31 @@ module.controller('AddApplicationProtocolMapperCtrl', function($scope, realm, ap
$scope.mapperTypes = mapperTypes;
var updateMappers = function() {
var mappers = RealmProtocolMappersByProtocol.query({realm : realm.realm, protocol : application.protocol}, function() {
var appMappers = ApplicationProtocolMappersByProtocol.query({realm : realm.realm, application : application.id, protocol : application.protocol}, function() {
var builtinMappers = serverInfo.builtinProtocolMappers[application.protocol];
for (var i = 0; i < appMappers.length; i++) {
for (var j = 0; j < mappers.length; j++) {
if (mappers[j].id == appMappers[i].id) {
mappers.remove(j);
for (var j = 0; j < builtinMappers.length; j++) {
if (builtinMappers[j].name == appMappers[i].name
&& builtinMappers[j].protocolMapper == appMappers[i].protocolMapper) {
console.log('removing: ' + builtinMappers[j].name);
builtinMappers.splice(j, 1);
break;
}
}
}
$scope.mappers = mappers;
for (var j = 0; j < builtinMappers.length; j++) {
console.log('builtin left: ' + builtinMappers[j].name);
}
$scope.mappers = builtinMappers;
for (var i = 0; i < $scope.mappers.length; i++) {
$scope.mappers[i].isChecked = false;
}
})
})
});
};
updateMappers();
@ -1179,10 +1160,11 @@ module.controller('AddApplicationProtocolMapperCtrl', function($scope, realm, ap
var toAdd = [];
for (var i = 0; i < $scope.mappers.length; i++) {
if ($scope.mappers[i].isChecked) {
toAdd.push($scope.mappers[i].id);
delete $scope.mappers[i].isChecked;
toAdd.push($scope.mappers[i]);
}
}
$http.post(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/protocol-mappers/models',
$http.post(authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/protocol-mappers/add-models',
toAdd).success(function() {
Notifications.success("Mappers added");
$location.url('/realms/' + realm.realm + '/applications/' + application.id + '/mappers');
@ -1194,5 +1176,106 @@ module.controller('AddApplicationProtocolMapperCtrl', function($scope, realm, ap
});
module.controller('ApplicationProtocolMapperCtrl', function($scope, realm, serverInfo, application, mapper, ApplicationProtocolMapper, Notifications, Dialog, $location) {
$scope.realm = realm;
$scope.application = application;
$scope.create = false;
var protocol = application.protocol;
$scope.protocol = application.protocol;
$scope.mapper = angular.copy(mapper);
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
$scope.boolval = true;
$scope.boolvalId = 'boolval';
console.log('protocol: ' + protocol);
var protocolMappers = serverInfo.protocolMapperTypes[protocol];
for (var i = 0; i < protocolMappers.length; i++) {
if (protocolMappers[i].id == mapper.protocolMapper) {
$scope.mapperType = protocolMappers[i];
}
}
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.$watch('mapper', function() {
if (!angular.equals($scope.mapper, mapper)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
ApplicationProtocolMapper.update({
realm : realm.realm,
application: application.id,
id : mapper.id
}, $scope.mapper, function() {
$scope.changed = false;
mapper = angular.copy($scope.mapper);
$location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers/" + mapper.id);
Notifications.success("Your changes have been saved.");
});
};
$scope.reset = function() {
$scope.mapper = angular.copy(mapper);
$scope.changed = false;
};
$scope.cancel = function() {
//$location.url("/realms");
window.history.back();
};
$scope.remove = function() {
Dialog.confirmDelete($scope.mapper.name, 'mapper', function() {
ApplicationProtocolMapper.remove({ realm: realm.realm, application: application.id, id : $scope.mapper.id }, function() {
Notifications.success("The mapper has been deleted.");
$location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers");
});
});
};
});
module.controller('ApplicationProtocolMapperCreateCtrl', function($scope, realm, serverInfo, application, ApplicationProtocolMapper, Notifications, Dialog, $location) {
$scope.realm = realm;
$scope.application = application;
$scope.create = true;
var protocol = application.protocol;
$scope.protocol = protocol;
$scope.mapper = { protocol : application.protocol, config: {}};
$scope.mapperTypes = serverInfo.protocolMapperTypes[protocol];
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.save = function() {
$scope.mapper.protocolMapper = $scope.mapperType.id;
ApplicationProtocolMapper.save({
realm : realm.realm, application: application.id
}, $scope.mapper, function(data, headers) {
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/realms/" + realm.realm + '/applications/' + application.id + "/mappers/" + id);
Notifications.success("Mapper has been created.");
});
};
$scope.cancel = function() {
//$location.url("/realms");
window.history.back();
};
});

View file

@ -1,125 +0,0 @@
module.controller('ProtocolListCtrl', function($scope, realm, serverInfo, $location) {
$scope.realm = realm;
$scope.protocols = serverInfo.protocols;
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ProtocolMapperListCtrl', function($scope, realm, serverInfo, protocol, mappers, $location) {
$scope.realm = realm;
$scope.protocol = protocol;
var protocolMappers = serverInfo.protocolMapperTypes[protocol];
var mapperTypes = {};
for (var i = 0; i < protocolMappers.length; i++) {
mapperTypes[protocolMappers[i].id] = protocolMappers[i];
}
$scope.mapperTypes = mapperTypes;
$scope.mappers = mappers;
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
});
module.controller('ProtocolMapperCtrl', function($scope, realm, serverInfo, protocol, mapper, RealmProtocolMapper, Notifications, Dialog, $location) {
$scope.realm = realm;
$scope.create = false;
$scope.protocol = protocol;
$scope.mapper = angular.copy(mapper);
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
$scope.boolval = true;
$scope.boolvalId = 'boolval';
console.log('protocol: ' + protocol);
var protocolMappers = serverInfo.protocolMapperTypes[protocol];
for (var i = 0; i < protocolMappers.length; i++) {
if (protocolMappers[i].id == mapper.protocolMapper) {
$scope.mapperType = protocolMappers[i];
}
}
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.$watch('mapper', function() {
if (!angular.equals($scope.mapper, mapper)) {
$scope.changed = true;
}
}, true);
$scope.save = function() {
RealmProtocolMapper.update({
realm : realm.realm,
id : mapper.id
}, $scope.mapper, function() {
$scope.changed = false;
mapper = angular.copy($scope.mapper);
$location.url("/realms/" + realm.realm + "/protocols/" + protocol + "/mappers/" + mapper.id);
Notifications.success("Your changes have been saved.");
});
};
$scope.reset = function() {
$scope.mapper = angular.copy(mapper);
$scope.changed = false;
};
$scope.cancel = function() {
//$location.url("/realms");
window.history.back();
};
$scope.remove = function() {
Dialog.confirmDelete($scope.mapper.name, 'mapper', function() {
RealmProtocolMapper.remove({ realm: realm.realm, id : $scope.mapper.id }, function() {
Notifications.success("The mapper has been deleted.");
$location.url("/realms/" + realm.realm + "/protocols/" + protocol + "/mappers");
});
});
};
});
module.controller('ProtocolMapperCreateCtrl', function($scope, realm, serverInfo, protocol, RealmProtocolMapper, Notifications, Dialog, $location) {
$scope.realm = realm;
$scope.create = true;
$scope.protocol = protocol;
$scope.mapper = { protocol : protocol, config: {}};
$scope.mapperTypes = serverInfo.protocolMapperTypes[protocol];
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.save = function() {
$scope.mapper.protocolMapper = $scope.mapperType.id;
RealmProtocolMapper.save({
realm : realm.realm
}, $scope.mapper, function(data, headers) {
var l = headers().location;
var id = l.substring(l.lastIndexOf("/") + 1);
$location.url("/realms/" + realm.realm + "/protocols/" + protocol + "/mappers/" + id);
Notifications.success("Mapper has been created.");
});
};
$scope.cancel = function() {
//$location.url("/realms");
window.history.back();
};
});

View file

@ -79,19 +79,11 @@ module.factory('RealmApplicationSessionStatsLoader', function(Loader, RealmAppli
});
});
module.factory('RealmProtocolMappersByProtocolLoader', function(Loader, RealmProtocolMappersByProtocol, $route, $q) {
return Loader.query(RealmProtocolMappersByProtocol, function() {
return {
realm : $route.current.params.realm,
protocol: $route.current.params.protocol
}
});
});
module.factory('RealmProtocolMapperLoader', function(Loader, RealmProtocolMapper, $route, $q) {
return Loader.get(RealmProtocolMapper, function() {
module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationProtocolMapper, $route, $q) {
return Loader.get(ApplicationProtocolMapper, function() {
return {
realm : $route.current.params.realm,
application : $route.current.params.application,
id: $route.current.params.id
}
});

View file

@ -188,15 +188,10 @@ module.factory('ServerInfo', function($resource) {
return $resource(authUrl + '/admin/serverinfo');
});
module.factory('RealmProtocolMappersByProtocol', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/protocol-mappers/protocol/:protocol', {
realm : '@realm',
protocol : "@protocol"
});
});
module.factory('RealmProtocolMapper', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/protocol-mappers/models/:id', {
module.factory('ApplicationProtocolMapper', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/models/:id', {
realm : '@realm',
application: '@application',
id : "@id"
}, {
update : {

View file

@ -6,9 +6,9 @@
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">{{application.name}} Mappers</a></li>
<li class="active">Add Protocol Mappers</li>
<li class="active">Add Builtin Protocol Mappers</li>
</ol>
<h2><span>{{realm.realm}} </span>Add {{application.name}} {{application.protocol}} Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the application and auth server." class="fa fa-info-circle"></span></h2>
<h2><span>{{realm.realm}} </span>Add Builtin Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the application and auth server." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>

View file

@ -21,9 +21,8 @@
</button>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="#/create/protocols/{{application.protocol}}/realms/{{realm.realm}}/mappers">Create</a>
<a class="btn btn-primary" href="#/create/application/{{realm.realm}}/{{application.id}}/mappers">Create</a>
<a class="btn btn-primary" href="#/realms/{{realm.realm}}/applications/{{application.id}}/add-mappers">Add Builtin</a>
<button class="btn btn-primary" data-ng-click="remove()">Remove Selected</button>
</div>
</th>
</tr>
@ -31,15 +30,13 @@
<th>Name</th>
<th>Category</th>
<th>Type</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="mapper in mappers | filter:search">
<td><a href="#/realms/{{realm.realm}}/protocols/{{application.protocol}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
<td><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
<td>{{mapperTypes[mapper.protocolMapper].category}}</td>
<td>{{mapperTypes[mapper.protocolMapper].name}}</td>
<td><input type="checkbox" ng-model="mapper.isChecked"></td>
</tr>
<tr data-ng-show="mappers.length == 0">
<td>No mappers available</td>

View file

@ -1,22 +0,0 @@
<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">
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}}</span> Client Protocols <span tooltip-placement="right" tooltip="This section allows you to manage settings for the protocols clients and applications use to login and interact with the auth server.." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr data-ng-hide="applications.length == 0">
<th>Protocol Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="protocol in protocols">
<td><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers">{{protocol}}</a></td>
</tr>
<tr data-ng-show="applications.length == 0">
<td>No protocols available</td>
</tr>
</tbody>
</table>
</div>
</div>

View file

@ -1,20 +1,22 @@
<div class="bs-sidebar col-sm-3 " data-ng-include data-src="resourceUrl + '/partials/realm-menu.html'"></div>
<div id="content-area" class="col-sm-9" role="main">
<ul class="nav nav-tabs nav-tabs-pf">
<li><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers">Mappers</a></li>
</ul>
<kc-navigation-application></kc-navigation-application>
<div id="content">
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers">Protocol Mappers</a></li>
<li><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers/{{mapper.id}}">{{mapper.name}}</a></li>
<li class="active">Protocol Mapper</li>
</ol>
<ol class="breadcrumb" data-ng-show="create">
<li><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers">Protocol Mappers</a></li>
<li class="active">Add Protocol Mapper</li>
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">Protocol Mappers</a></li>
<li class="active">Create Protocol Mapper</li>
</ol>
<h2 class="pull-left" data-ng-hide="create">Protocol Mapper Settings</h2>
<h2 class="pull-left" data-ng-show="create">Add Protocol Mapper</h2>
<ol class="breadcrumb" data-ng-hide="create">
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}">{{application.name}}</a></li>
<li><a href="#/realms/{{realm.realm}}/applications/{{application.id}}/mappers">Protocol Mappers</a></li>
<li class="active">{{mapper.name}}</li>
</ol>
<h2 class="pull-left" data-ng-hide="create">{{mapper.name}} Protocol Mapper</h2>
<h2 class="pull-left" data-ng-show="create">Create Protocol Mapper</h2>
<p class="subtitle"><span class="required">*</span> Required fields</p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">

View file

@ -1,41 +0,0 @@
<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">
<h2></h2>
<div id="content">
<h2><span>{{realm.realm}} </span> {{protocol}} Protocol Mappers <span tooltip-placement="right" tooltip="Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the application and auth server." class="fa fa-info-circle"></span></h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="kc-table-actions" colspan="3">
<div class="search-comp clearfix">
<input type="text" placeholder="Search..." class="form-control search" data-ng-model="search.name"
onkeyup="if(event.keyCode == 13){$(this).next('button').click();}">
<button type="submit" class="kc-icon-search" tooltip-placement="right"
tooltip="Search by mapper name.">
Icon: search
</button>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="#/create/protocols/{{protocol}}/realms/{{realm.realm}}/mappers">Create</a>
</div>
</th>
</tr>
<tr data-ng-hide="mappers.length == 0">
<th>Name</th>
<th>Category</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="mapper in mappers | filter:search">
<td><a href="#/realms/{{realm.realm}}/protocols/{{protocol}}/mappers/{{mapper.id}}">{{mapper.name}}</a></td>
<td>{{mapperTypes[mapper.protocolMapper].category}}</td>
<td>{{mapperTypes[mapper.protocolMapper].name}}</td>
</tr>
<tr data-ng-show="mappers.length == 0">
<td>No mappers available</td>
</tr>
</tbody>
</table>
</div>
</div>

View file

@ -14,7 +14,6 @@
<li data-ng-show="access.viewApplications" data-ng-class="(path[2] == 'applications' || path[1] == 'application' || path[3] == 'applications') && 'active'"><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'oauth-clients' || path[1] == 'oauth-client') && 'active'"><a href="#/realms/{{realm.realm}}/oauth-clients">OAuth Clients</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'sessions' || path[2] == 'token-settings') && 'active'"><a href="#/realms/{{realm.realm}}/sessions/realm">Sessions and Tokens</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'protocols') && 'active'"><a href="#/realms/{{realm.realm}}/protocols">Protocol Settings</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'defense') && 'active'"><a href="#/realms/{{realm.realm}}/defense/headers">Security Defenses</a></li>
<li data-ng-show="access.viewEvents" data-ng-class="(path[2] == 'events' || path[2] == 'events-settings') && 'active'"><a href="#/realms/{{realm.realm}}/events">Events</a></li>
</ul>

View file

@ -104,7 +104,9 @@ public interface ClientModel {
boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId);
Set<ProtocolMapperModel> getProtocolMappers();
void addProtocolMappers(Set<String> mapperIds);
void removeProtocolMappers(Set<String> mapperIds);
void setProtocolMappers(Set<String> mapperIds);
ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model);
void removeProtocolMapper(ProtocolMapperModel mapping);
void updateProtocolMapper(ProtocolMapperModel mapping);
public ProtocolMapperModel getProtocolMapperById(String id);
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name);
}

View file

@ -18,7 +18,6 @@ public class ProtocolMapperModel {
protected String protocolMapper;
protected boolean consentRequired;
protected String consentText;
protected boolean appliedByDefault;
protected Map<String, String> config;
@ -46,14 +45,6 @@ public class ProtocolMapperModel {
this.protocol = protocol;
}
public boolean isAppliedByDefault() {
return appliedByDefault;
}
public void setAppliedByDefault(boolean appliedByDefault) {
this.appliedByDefault = appliedByDefault;
}
public String getProtocolMapper() {
return protocolMapper;
}

View file

@ -20,7 +20,6 @@ public interface RealmModel extends RoleContainerModel {
RealmModel getCreatedRealm();
}
interface ClientCreationEvent extends ProviderEvent {
RealmModel getCreatedRealm();
ClientModel getCreatedClient();
}
interface ApplicationCreationEvent extends ClientCreationEvent {
@ -237,19 +236,4 @@ public interface RealmModel extends RoleContainerModel {
ClientModel findClientById(String id);
boolean isIdentityFederationEnabled();
Set<ClaimTypeModel> getClaimTypes();
ClaimTypeModel addClaimType(ClaimTypeModel model);
void removeClaimType(ClaimTypeModel claimType);
ClaimTypeModel getClaimType(String name);
void updateClaimType(ClaimTypeModel claimType);
Set<ProtocolMapperModel> getProtocolMappers();
ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model);
void removeProtocolMapper(ProtocolMapperModel mapping);
void updateProtocolMapper(ProtocolMapperModel mapping);
public ProtocolMapperModel getProtocolMapperById(String id);
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name);
}

View file

@ -1,53 +0,0 @@
package org.keycloak.models.entities;
import org.keycloak.models.ClaimTypeModel;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClaimTypeEntity {
protected String id;
private String name;
protected boolean builtIn;
protected ClaimTypeModel.ValueType type;
private String realmId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isBuiltIn() {
return builtIn;
}
public void setBuiltIn(boolean builtIn) {
this.builtIn = builtIn;
}
public ClaimTypeModel.ValueType getType() {
return type;
}
public void setType(ClaimTypeModel.ValueType type) {
this.type = type;
}
}

View file

@ -30,7 +30,7 @@ public class ClientEntity extends AbstractIdentifiableEntity {
private List<String> redirectUris = new ArrayList<String>();
private List<String> scopeIds = new ArrayList<String>();
private List<ClientIdentityProviderMappingEntity> identityProviders = new ArrayList<ClientIdentityProviderMappingEntity>();
private Set<String> protocolMappers = new HashSet<String>();
private List<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
public String getName() {
return name;
@ -152,11 +152,11 @@ public class ClientEntity extends AbstractIdentifiableEntity {
this.identityProviders = identityProviders;
}
public Set<String> getProtocolMappers() {
public List<ProtocolMapperEntity> getProtocolMappers() {
return protocolMappers;
}
public void setProtocolMappers(Set<String> protocolMappers) {
public void setProtocolMappers(List<ProtocolMapperEntity> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}

View file

@ -13,7 +13,6 @@ public class ProtocolMapperEntity {
protected String name;
protected String protocol;
protected String protocolMapper;
protected boolean appliedByDefault;
protected boolean consentRequired;
protected String consentText;
protected Map<String, String> config;
@ -42,14 +41,6 @@ public class ProtocolMapperEntity {
this.protocol = protocol;
}
public boolean isAppliedByDefault() {
return appliedByDefault;
}
public void setAppliedByDefault(boolean appliedByDefault) {
this.appliedByDefault = appliedByDefault;
}
public String getProtocolMapper() {
return protocolMapper;
}

View file

@ -52,8 +52,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
private List<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
private List<UserFederationProviderEntity> userFederationProviders = new ArrayList<UserFederationProviderEntity>();
private List<IdentityProviderEntity> identityProviders = new ArrayList<IdentityProviderEntity>();
private List<ClaimTypeEntity> claimTypes = new ArrayList<ClaimTypeEntity>();
private List<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
@ -392,22 +390,6 @@ public class RealmEntity extends AbstractIdentifiableEntity {
public void setCertificatePem(String certificatePem) {
this.certificatePem = certificatePem;
}
public List<ClaimTypeEntity> getClaimTypes() {
return claimTypes;
}
public void setClaimTypes(List<ClaimTypeEntity> claimTypes) {
this.claimTypes = claimTypes;
}
public List<ProtocolMapperEntity> getProtocolMappers() {
return protocolMappers;
}
public void setProtocolMappers(List<ProtocolMapperEntity> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}

View file

@ -2,7 +2,6 @@ package org.keycloak.models.utils;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClaimTypeModel;
import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
@ -19,9 +18,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClaimTypeRepresentation;
import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation;
import org.keycloak.representations.idm.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@ -156,14 +153,6 @@ public class ModelToRepresentation {
rep.addIdentityProvider(toRepresentation(provider));
}
for (ClaimTypeModel claimType : realm.getClaimTypes()) {
rep.getClaimTypes().add(toRepresentation(claimType));
}
for (ProtocolMapperModel mapping : realm.getProtocolMappers()) {
rep.addProtocolMapper(toRepresentation(mapping));
}
return rep;
}
@ -269,11 +258,9 @@ public class ModelToRepresentation {
}
if (!applicationModel.getProtocolMappers().isEmpty()) {
List<ClientProtocolMappingRepresentation> mappings = new LinkedList<ClientProtocolMappingRepresentation>();
List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel model : applicationModel.getProtocolMappers()) {
ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
map.setProtocol(model.getProtocol());
map.setName(model.getName());
mappings.add(toRepresentation(model));
}
rep.setProtocolMappers(mappings);
}
@ -323,11 +310,9 @@ public class ModelToRepresentation {
}
if (!model.getProtocolMappers().isEmpty()) {
List<ClientProtocolMappingRepresentation> mappings = new LinkedList<ClientProtocolMappingRepresentation>();
for (ProtocolMapperModel mapping : model.getProtocolMappers()) {
ClientProtocolMappingRepresentation map = new ClientProtocolMappingRepresentation();
map.setProtocol(mapping.getProtocol());
map.setName(mapping.getName());
List<ProtocolMapperRepresentation> mappings = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
mappings.add(toRepresentation(mapper));
}
rep.setProtocolMappers(mappings);
}
@ -373,18 +358,9 @@ public class ModelToRepresentation {
rep.setConfig(config);
rep.setName(model.getName());
rep.setProtocolMapper(model.getProtocolMapper());
rep.setAppliedByDefault(model.isAppliedByDefault());
rep.setConsentText(model.getConsentText());
rep.setConsentRequired(model.isConsentRequired());
return rep;
}
public static ClaimTypeRepresentation toRepresentation(ClaimTypeModel claimType) {
ClaimTypeRepresentation rep = new ClaimTypeRepresentation();
rep.setId(claimType.getId());
rep.setName(claimType.getName());
rep.setBuiltIn(claimType.isBuiltIn());
rep.setType(claimType.getType().name().toLowerCase());
return rep;
}
}

View file

@ -6,7 +6,6 @@ import org.keycloak.enums.SslRequired;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.BrowserSecurityHeaders;
import org.keycloak.models.ClaimMask;
import org.keycloak.models.ClaimTypeModel;
import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.FederatedIdentityModel;
@ -23,9 +22,7 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.ClaimRepresentation;
import org.keycloak.representations.idm.ClaimTypeRepresentation;
import org.keycloak.representations.idm.ClientIdentityProviderMappingRepresentation;
import org.keycloak.representations.idm.ClientProtocolMappingRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@ -120,8 +117,6 @@ public class RepresentationToModel {
if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
importIdentityProviders(rep, newRealm);
importClaimTypes(rep, newRealm);
importProtocolMappers(rep, newRealm);
if (rep.getApplications() != null) {
Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
@ -458,15 +453,13 @@ public class RepresentationToModel {
}
if (resourceRep.getProtocolMappers() != null) {
Set<String> ids = new HashSet<String>();
for (ClientProtocolMappingRepresentation map : resourceRep.getProtocolMappers()) {
ProtocolMapperModel mapperModel = applicationModel.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
if (mapperModel != null) {
ids.add(mapperModel.getId());
}
// first, remove all default/built in mappers
Set<ProtocolMapperModel> mappers = applicationModel.getProtocolMappers();
for (ProtocolMapperModel mapper : mappers) applicationModel.removeProtocolMapper(mapper);
for (ProtocolMapperRepresentation mapper : resourceRep.getProtocolMappers()) {
applicationModel.addProtocolMapper(toModel(mapper));
}
applicationModel.setProtocolMappers(ids);
}
applicationModel.updateAllowedIdentityProviders(toModel(resourceRep.getIdentityProviders(), realm));
@ -636,15 +629,13 @@ public class RepresentationToModel {
updateClientIdentityProvides(rep.getIdentityProviders(), model);
if (rep.getProtocolMappers() != null) {
Set<String> ids = new HashSet<String>();
for (ClientProtocolMappingRepresentation map : rep.getProtocolMappers()) {
ProtocolMapperModel mapperModel = model.getRealm().getProtocolMapperByName(map.getProtocol(), map.getName());
if (mapperModel != null) {
ids.add(mapperModel.getId());
}
// first, remove all default/built in mappers
Set<ProtocolMapperModel> mappers = model.getProtocolMappers();
for (ProtocolMapperModel mapper : mappers) model.removeProtocolMapper(mapper);
for (ProtocolMapperRepresentation mapper : rep.getProtocolMappers()) {
model.addProtocolMapper(toModel(mapper));
}
model.setProtocolMappers(ids);
}
}
@ -770,31 +761,6 @@ public class RepresentationToModel {
}
}
}
private static void importClaimTypes(RealmRepresentation rep, RealmModel newRealm) {
if (rep.getClaimTypes() != null) {
for (ClaimTypeRepresentation representation : rep.getClaimTypes()) {
newRealm.addClaimType(toModel(representation));
}
}
}
private static void importProtocolMappers(RealmRepresentation rep, RealmModel newRealm) {
if (rep.getProtocolMappers() != null) {
// we make sure we don't recreate mappers that are automatically created by the protocol providers.
Set<ProtocolMapperModel> mappers = newRealm.getProtocolMappers();
for (ProtocolMapperRepresentation representation : rep.getProtocolMappers()) {
ProtocolMapperModel existing = newRealm.getProtocolMapperByName(representation.getProtocol(), representation.getName());
if (existing == null) {
newRealm.addProtocolMapper(toModel(representation));
} else {
ProtocolMapperModel mapping = toModel(representation);
mapping.setId(existing.getId());
newRealm.updateProtocolMapper(mapping);
}
}
}
}
public static IdentityProviderModel toModel(IdentityProviderRepresentation representation) {
IdentityProviderModel identityProviderModel = new IdentityProviderModel();
@ -811,20 +777,10 @@ public class RepresentationToModel {
return identityProviderModel;
}
public static ClaimTypeModel toModel(ClaimTypeRepresentation rep) {
ClaimTypeModel model = new ClaimTypeModel();
model.setId(rep.getId());
model.setType(ClaimTypeModel.ValueType.valueOf(rep.getType()));
model.setBuiltIn(rep.isBuiltIn());
model.setName(rep.getName());
return model;
}
public static ProtocolMapperModel toModel(ProtocolMapperRepresentation rep) {
ProtocolMapperModel model = new ProtocolMapperModel();
model.setId(rep.getId());
model.setName(rep.getName());
model.setAppliedByDefault(rep.isAppliedByDefault());
model.setConsentRequired(rep.isConsentRequired());
model.setConsentText(rep.getConsentText());
model.setProtocol(rep.getProtocol());

View file

@ -290,26 +290,42 @@ public abstract class ClientAdapter implements ClientModel {
@Override
public Set<ProtocolMapperModel> getProtocolMappers() {
if (updatedClient != null) return updatedClient.getProtocolMappers();
return cachedClient.getProtocolClaimMappings(); }
return cachedClient.getProtocolMappers();
}
@Override
public void addProtocolMappers(Set<String> mapperNames) {
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
getDelegateForUpdate();
updatedClient.addProtocolMappers(mapperNames);
return updatedClient.addProtocolMapper(model);
}
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
getDelegateForUpdate();
updatedClient.removeProtocolMapper(mapping);
}
@Override
public void removeProtocolMappers(Set<String> mapperNames) {
public void updateProtocolMapper(ProtocolMapperModel mapping) {
getDelegateForUpdate();
updatedClient.removeProtocolMappers(mapperNames);
updatedClient.updateProtocolMapper(mapping);
}
@Override
public void setProtocolMappers(Set<String> mapperNames) {
getDelegateForUpdate();
updatedClient.setProtocolMappers(mapperNames);
public ProtocolMapperModel getProtocolMapperById(String id) {
for (ProtocolMapperModel mapping : cachedClient.getProtocolMappers()) {
if (mapping.getId().equals(id)) return mapping;
}
return null;
}
@Override
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
for (ProtocolMapperModel mapping : cachedClient.getProtocolMappers()) {
if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
}
return null;
}
}

View file

@ -850,82 +850,6 @@ public class RealmAdapter implements RealmModel {
return cached.isIdentityFederationEnabled();
}
@Override
public Set<ClaimTypeModel> getClaimTypes() {
if (updated != null) return updated.getClaimTypes();
return cached.getClaimTypes();
}
@Override
public ClaimTypeModel addClaimType(ClaimTypeModel claimType) {
getDelegateForUpdate();
return updated.addClaimType(claimType);
}
@Override
public void removeClaimType(ClaimTypeModel claimType) {
getDelegateForUpdate();
updated.removeClaimType(claimType);
}
@Override
public ClaimTypeModel getClaimType(String name) {
for (ClaimTypeModel claimType : getClaimTypes()) {
if (claimType.getName().equals(name)) return claimType;
}
return null;
}
@Override
public void updateClaimType(ClaimTypeModel claimType) {
getDelegateForUpdate();
updated.updateClaimType(claimType);
}
@Override
public Set<ProtocolMapperModel> getProtocolMappers() {
if (updated != null) return updated.getProtocolMappers();
return cached.getProtocolMappers();
}
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
getDelegateForUpdate();
return updated.addProtocolMapper(model);
}
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
getDelegateForUpdate();
updated.removeProtocolMapper(mapping);
}
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
getDelegateForUpdate();
updated.updateProtocolMapper(mapping);
}
@Override
public ProtocolMapperModel getProtocolMapperById(String id) {
for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
if (mapping.getId().equals(id)) return mapping;
}
return null;
}
@Override
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
for (ProtocolMapperModel mapping : cached.getProtocolMappers()) {
if (mapping.getProtocol().equals(protocol) && mapping.getName().equals(name)) return mapping;
}
return null;
}
@Override
public boolean equals(Object o) {

View file

@ -37,7 +37,7 @@ public class CachedClient {
protected Set<String> scope = new HashSet<String>();
protected Set<String> webOrigins = new HashSet<String>();
private List<ClientIdentityProviderMappingModel> identityProviders = new ArrayList<ClientIdentityProviderMappingModel>();
private Set<ProtocolMapperModel> protocolClaimMappings = new HashSet<ProtocolMapperModel>();
private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
public CachedClient(RealmCache cache, RealmProvider delegate, RealmModel realm, ClientModel model) {
id = model.getId();
@ -59,7 +59,9 @@ public class CachedClient {
scope.add(role.getId());
}
this.identityProviders = model.getIdentityProviders();
protocolClaimMappings.addAll(model.getProtocolMappers());
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper);
}
}
public String getId() {
@ -140,8 +142,8 @@ public class CachedClient {
return false;
}
public Set<ProtocolMapperModel> getProtocolClaimMappings() {
return protocolClaimMappings;
public Set<ProtocolMapperModel> getProtocolMappers() {
return protocolMappers;
}
public boolean isAllowedRetrieveTokenFromIdentityProvider(String providerId) {

View file

@ -70,8 +70,6 @@ public class CachedRealm {
private List<RequiredCredentialModel> requiredCredentials = new ArrayList<RequiredCredentialModel>();
private List<UserFederationProviderModel> userFederationProviders = new ArrayList<UserFederationProviderModel>();
private List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
private Set<ClaimTypeModel> claimTypes = new HashSet<ClaimTypeModel>();
private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
private Map<String, String> browserSecurityHeaders = new HashMap<String, String>();
private Map<String, String> smtpConfig = new HashMap<String, String>();
@ -135,13 +133,6 @@ public class CachedRealm {
this.identityProviders.add(new IdentityProviderModel(identityProviderModel));
}
for (ClaimTypeModel claimType : model.getClaimTypes()) {
this.claimTypes.add(new ClaimTypeModel(claimType));
}
for (ProtocolMapperModel mapper : model.getProtocolMappers()) {
this.protocolMappers.add(mapper);
}
smtpConfig.putAll(model.getSmtpConfig());
browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders());
@ -351,12 +342,4 @@ public class CachedRealm {
public List<IdentityProviderModel> getIdentityProviders() {
return identityProviders;
}
public Set<ClaimTypeModel> getClaimTypes() {
return claimTypes;
}
public Set<ProtocolMapperModel> getProtocolMappers() {
return protocolMappers;
}
}

View file

@ -1,7 +1,9 @@
package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientIdentityProviderMappingModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
@ -12,6 +14,7 @@ import org.keycloak.models.jpa.entities.IdentityProviderEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RoleEntity;
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
@ -412,7 +415,6 @@ public abstract class ClientAdapter implements ClientModel {
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
@ -425,71 +427,98 @@ public abstract class ClientAdapter implements ClientModel {
return mappings;
}
protected ProtocolMapperEntity findProtocolMapperByName(String protocol, String name) {
TypedQuery<ProtocolMapperEntity> query = em.createNamedQuery("getProtocolMapperByNameProtocol", ProtocolMapperEntity.class);
query.setParameter("name", name);
query.setParameter("protocol", protocol);
query.setParameter("realm", entity.getRealm());
List<ProtocolMapperEntity> entities = query.getResultList();
if (entities.size() == 0) return null;
if (entities.size() > 1) throw new IllegalStateException("Should not be more than one protocol mapper with same name");
return query.getResultList().get(0);
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol");
}
String id = KeycloakModelUtils.generateId();
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(id);
entity.setName(model.getName());
entity.setProtocol(model.getProtocol());
entity.setProtocolMapper(model.getProtocolMapper());
entity.setClient(this.entity);
entity.setConfig(model.getConfig());
entity.setConsentRequired(model.isConsentRequired());
entity.setConsentText(model.getConsentText());
em.persist(entity);
this.entity.getProtocolMappers().add(entity);
return entityToModel(entity);
}
protected ProtocolMapperEntity getProtocolMapperEntity(String id) {
for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
@Override
public void addProtocolMappers(Set<String> mappings) {
Collection<ProtocolMapperEntity> entities = entity.getProtocolMappers();
Set<String> already = new HashSet<String>();
for (ProtocolMapperEntity rel : entities) {
already.add(rel.getId());
public void removeProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity toDelete = getProtocolMapperEntity(mapping.getId());
if (toDelete != null) {
this.entity.getProtocolMappers().remove(toDelete);
em.remove(toDelete);
}
for (String id : mappings) {
if (!already.contains(id)) {
ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
if (mapping != null) {
entities.add(mapping);
}
}
}
em.flush();
}
@Override
public void removeProtocolMappers(Set<String> mappings) {
Collection<ProtocolMapperEntity> entities = entity.getProtocolMappers();
List<ProtocolMapperEntity> remove = new LinkedList<ProtocolMapperEntity>();
for (ProtocolMapperEntity rel : entities) {
if (mappings.contains(rel.getId())) remove.add(rel);
}
for (ProtocolMapperEntity entity : remove) {
entities.remove(entity);
public void updateProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setConsentRequired(mapping.isConsentRequired());
entity.setConsentText(mapping.getConsentText());
if (entity.getConfig() == null) {
entity.setConfig(mapping.getConfig());
} else {
entity.getConfig().clear();
entity.getConfig().putAll(mapping.getConfig());
}
em.flush();
}
@Override
public void setProtocolMappers(Set<String> mappings) {
Collection<ProtocolMapperEntity> entities = entity.getProtocolMappers();
Iterator<ProtocolMapperEntity> it = entities.iterator();
Set<String> already = new HashSet<String>();
while (it.hasNext()) {
ProtocolMapperEntity mapper = it.next();
if (mappings.contains(mapper.getId())) {
already.add(mapper.getId());
continue;
}
it.remove();
}
for (String id : mappings) {
if (!already.contains(id)) {
ProtocolMapperEntity mapping = em.find(ProtocolMapperEntity.class, id);
if (mapping != null) {
entities.add(mapping);
}
}
}
em.flush();
public ProtocolMapperModel getProtocolMapperById(String id) {
ProtocolMapperEntity entity = getProtocolMapperEntity(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapping.setConfig(config);
return mapping;
}
}

View file

@ -2,22 +2,18 @@ package org.keycloak.models.jpa;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClaimTypeModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.jpa.entities.ApplicationEntity;
import org.keycloak.models.jpa.entities.ClaimTypeEntity;
import org.keycloak.models.jpa.entities.IdentityProviderEntity;
import org.keycloak.models.jpa.entities.OAuthClientEntity;
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
import org.keycloak.models.jpa.entities.RealmAttributeEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
@ -628,17 +624,6 @@ public class RealmAdapter implements RealmModel {
return this.addApplication(KeycloakModelUtils.generateId(), name);
}
public void addDefaultClientProtocolMappers(ClientModel client) {
Set<String> adding = new HashSet<String>();
for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
if (mapper.isAppliedByDefault()) {
adding.add(mapper.getId());
}
}
client.setProtocolMappers(adding);
}
@Override
public ApplicationModel addApplication(String id, String name) {
ApplicationEntity applicationData = new ApplicationEntity();
@ -649,9 +634,19 @@ public class RealmAdapter implements RealmModel {
realm.getApplications().add(applicationData);
em.persist(applicationData);
em.flush();
ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
addDefaultClientProtocolMappers(resource);
final ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
em.flush();
session.getKeycloakSessionFactory().publish(new ApplicationCreationEvent() {
@Override
public ApplicationModel getCreatedApplication() {
return resource;
}
@Override
public ClientModel getCreatedClient() {
return resource;
}
});
return resource;
}
@ -714,9 +709,19 @@ public class RealmAdapter implements RealmModel {
data.setRealm(realm);
em.persist(data);
em.flush();
OAuthClientModel model = new OAuthClientAdapter(this, data, em);
addDefaultClientProtocolMappers(model);
final OAuthClientModel model = new OAuthClientAdapter(this, data, em);
em.flush();
session.getKeycloakSessionFactory().publish(new OAuthClientCreationEvent() {
@Override
public OAuthClientModel getCreatedOAuthClient() {
return model;
}
@Override
public ClientModel getCreatedClient() {
return model;
}
});
return model;
}
@ -1211,191 +1216,4 @@ public class RealmAdapter implements RealmModel {
return !this.realm.getIdentityProviders().isEmpty();
}
@Override
public Set<ClaimTypeModel> getClaimTypes() {
Set<ClaimTypeModel> claimTypes = new HashSet<ClaimTypeModel>();
for (ClaimTypeEntity claimTypeEntity : realm.getClaimTypes()) {
claimTypes.add(new ClaimTypeModel(claimTypeEntity.getId(), claimTypeEntity.getName(), claimTypeEntity.isBuiltIn(), ClaimTypeModel.ValueType.valueOf(claimTypeEntity.getType())));
}
return claimTypes;
}
@Override
public ClaimTypeModel addClaimType(ClaimTypeModel model) {
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
ClaimTypeEntity claimEntity = new ClaimTypeEntity();
claimEntity.setId(id);
claimEntity.setType(model.getType().name());
claimEntity.setBuiltIn(model.isBuiltIn());
claimEntity.setRealm(realm);
em.persist(claimEntity);
realm.getClaimTypes().add(claimEntity);
return new ClaimTypeModel(claimEntity.getId(), model.getName(), model.isBuiltIn(), model.getType());
}
protected ClaimTypeEntity getClaimTypeEntity(ClaimTypeModel claim) {
for (ClaimTypeEntity claimTypeEntity : realm.getClaimTypes()) {
if (claimTypeEntity.getId().equals(claim.getId())) {
return claimTypeEntity;
}
}
return null;
}
@Override
public void removeClaimType(ClaimTypeModel claimType) {
ClaimTypeEntity toDelete = getClaimTypeEntity(claimType);
if (toDelete != null) {
realm.getClaimTypes().remove(toDelete);
em.remove(toDelete);
}
}
@Override
public ClaimTypeModel getClaimType(String name) {
for (ClaimTypeModel model : getClaimTypes()) {
if (model.getName().equals(name)) {
return model;
}
}
return null;
}
@Override
public void updateClaimType(ClaimTypeModel claimType) {
ClaimTypeEntity updated = getClaimTypeEntity(claimType);
updated.setName(claimType.getName());
updated.setBuiltIn(claimType.isBuiltIn());
updated.setType(claimType.getType().name());
em.flush();
}
@Override
public Set<ProtocolMapperModel> getProtocolMappers() {
Set<ProtocolMapperModel> mappings = new HashSet<ProtocolMapperModel>();
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
mappings.add(mapping);
}
return mappings;
}
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol");
}
String id = KeycloakModelUtils.generateId();
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(id);
entity.setName(model.getName());
entity.setProtocol(model.getProtocol());
entity.setProtocolMapper(model.getProtocolMapper());
entity.setAppliedByDefault(model.isAppliedByDefault());
entity.setRealm(realm);
entity.setConfig(model.getConfig());
entity.setConsentRequired(model.isConsentRequired());
entity.setConsentText(model.getConsentText());
em.persist(entity);
realm.getProtocolMappers().add(entity);
return entityToModel(entity);
}
protected ProtocolMapperEntity getProtocolMapperEntity(String id) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity toDelete = getProtocolMapperEntity(mapping.getId());
if (toDelete != null) {
realm.getProtocolMappers().remove(toDelete);
Set<String> removeId = new HashSet<String>();
removeId.add(mapping.getId());
for (ApplicationModel app : getApplications()) {
app.removeProtocolMappers(removeId);
}
for (OAuthClientModel app : getOAuthClients()) {
app.removeProtocolMappers(removeId);
}
em.remove(toDelete);
}
}
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setAppliedByDefault(mapping.isAppliedByDefault());
entity.setConsentRequired(mapping.isConsentRequired());
entity.setConsentText(mapping.getConsentText());
if (entity.getConfig() == null) {
entity.setConfig(mapping.getConfig());
} else {
entity.getConfig().clear();
entity.getConfig().putAll(mapping.getConfig());
}
em.flush();
}
@Override
public ProtocolMapperModel getProtocolMapperById(String id) {
ProtocolMapperEntity entity = getProtocolMapperEntity(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapping.setConfig(config);
return mapping;
}
}

View file

@ -1,82 +0,0 @@
package org.keycloak.models.jpa.entities;
import org.keycloak.models.ClaimTypeModel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@Entity
@NamedQueries({
@NamedQuery(name="deleteClaimTypesByRealm", query="delete from ClaimTypeEntity attr where attr.realm = :realm")
})
@Table(name="CLAIM_TYPE")
public class ClaimTypeEntity {
@Id
@Column(name="ID", length = 36)
protected String id;
@Column(name = "NAME")
private String name;
@Column(name = "BUILT_IN")
protected boolean builtIn;
@Column(name = "VALUE_TYPE")
protected String type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REALM_ID")
protected RealmEntity realm;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isBuiltIn() {
return builtIn;
}
public void setBuiltIn(boolean builtIn) {
this.builtIn = builtIn;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public RealmEntity getRealm() {
return realm;
}
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
}

View file

@ -76,8 +76,7 @@ public abstract class ClientEntity {
@OneToMany(fetch = FetchType.LAZY, mappedBy = "client", cascade = CascadeType.REMOVE)
Collection<ClientIdentityProviderMappingEntity> identityProviders = new ArrayList<ClientIdentityProviderMappingEntity>();
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(name="CLIENT_PROTOCOL_MAPPER", joinColumns = { @JoinColumn(name="CLIENT_ID")}, inverseJoinColumns = { @JoinColumn(name="MAPPING_ID")})
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "client")
Collection<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
public RealmEntity getRealm() {

View file

@ -19,9 +19,6 @@ import java.util.Map;
* @version $Revision: 1 $
*/
@Entity
@NamedQueries({
@NamedQuery(name="getProtocolMapperByNameProtocol", query="select mapper from ProtocolMapperEntity mapper where mapper.protocol = :protocol and mapper.name = :name and mapper.realm = :realm")
})
@Table(name="PROTOCOL_MAPPER")
public class ProtocolMapperEntity {
@ -36,8 +33,6 @@ public class ProtocolMapperEntity {
protected String protocol;
@Column(name = "PROTOCOL_MAPPER_NAME")
protected String protocolMapper;
@Column(name = "APPLIED_BY_DEFAULT")
protected boolean appliedByDefault;
@Column(name="CONSENT_REQUIRED")
protected boolean consentRequired;
@Column(name="CONSENT_TEXT")
@ -50,8 +45,8 @@ public class ProtocolMapperEntity {
private Map<String, String> config;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REALM_ID")
protected RealmEntity realm;
@JoinColumn(name = "CLIENT_ID")
private ClientEntity client;
public String getId() {
return id;
@ -85,14 +80,6 @@ public class ProtocolMapperEntity {
this.protocolMapper = protocolMapper;
}
public boolean isAppliedByDefault() {
return appliedByDefault;
}
public void setAppliedByDefault(boolean appliedByDefault) {
this.appliedByDefault = appliedByDefault;
}
public Map<String, String> getConfig() {
return config;
}
@ -101,12 +88,12 @@ public class ProtocolMapperEntity {
this.config = config;
}
public RealmEntity getRealm() {
return realm;
public ClientEntity getClient() {
return client;
}
public void setRealm(RealmEntity realm) {
this.realm = realm;
public void setClient(ClientEntity client) {
this.client = client;
}
public boolean isConsentRequired() {

View file

@ -92,12 +92,6 @@ public class RealmEntity {
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<RealmAttributeEntity> attributes = new ArrayList<RealmAttributeEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<ClaimTypeEntity> claimTypes = new ArrayList<ClaimTypeEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<ProtocolMapperEntity> protocolMappers = new ArrayList<ProtocolMapperEntity>();
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
Collection<RequiredCredentialEntity> requiredCredentials = new ArrayList<RequiredCredentialEntity>();
@ -439,20 +433,5 @@ public class RealmEntity {
getIdentityProviders().add(entity);
}
public Collection<ClaimTypeEntity> getClaimTypes() {
return claimTypes;
}
public void setClaimTypes(Collection<ClaimTypeEntity> claimTypes) {
this.claimTypes = claimTypes;
}
public Collection<ProtocolMapperEntity> getProtocolMappers() {
return protocolMappers;
}
public void setProtocolMappers(Collection<ProtocolMapperEntity> protocolMappers) {
this.protocolMappers = protocolMappers;
}
}

View file

@ -11,8 +11,10 @@ import org.keycloak.models.RealmProvider;
import org.keycloak.models.RoleModel;
import org.keycloak.models.entities.ClientEntity;
import org.keycloak.models.entities.ClientIdentityProviderMappingEntity;
import org.keycloak.models.entities.ProtocolMapperEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
import org.keycloak.models.mongo.utils.MongoModelUtils;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.ArrayList;
import java.util.HashMap;
@ -295,33 +297,117 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
@Override
public Set<ProtocolMapperModel> getProtocolMappers() {
Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
for (String id : getMongoEntityAsClient().getProtocolMappers()) {
ProtocolMapperModel model = getRealm().getProtocolMapperById(id);
if (model != null) result.add(model);
for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
}
return result;
}
@Override
public void addProtocolMappers(Set<String> mapperIds) {
getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol");
}
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(KeycloakModelUtils.generateId());
entity.setProtocol(model.getProtocol());
entity.setName(model.getName());
entity.setProtocolMapper(model.getProtocolMapper());
entity.setConfig(model.getConfig());
entity.setConsentRequired(model.isConsentRequired());
entity.setConsentText(model.getConsentText());
getMongoEntityAsClient().getProtocolMappers().add(entity);
updateMongoEntity();
return entityToModel(entity);
}
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
if (entity.getId().equals(mapping.getId())) {
getMongoEntityAsClient().getProtocolMappers().remove(entity);
updateMongoEntity();
break;
}
}
}
protected ProtocolMapperEntity getProtocolMapperyEntityById(String id) {
for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : getMongoEntityAsClient().getProtocolMappers()) {
if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity entity = getProtocolMapperyEntityById(mapping.getId());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setConsentRequired(mapping.isConsentRequired());
entity.setConsentText(mapping.getConsentText());
if (entity.getConfig() != null) {
entity.getConfig().clear();
entity.getConfig().putAll(mapping.getConfig());
} else {
entity.setConfig(mapping.getConfig());
}
updateMongoEntity();
}
@Override
public void removeProtocolMappers(Set<String> mapperIds) {
getMongoEntityAsClient().getProtocolMappers().removeAll(mapperIds);
updateMongoEntity();
public ProtocolMapperModel getProtocolMapperById(String id) {
ProtocolMapperEntity entity = getProtocolMapperyEntityById(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public void setProtocolMappers(Set<String> mapperIds) {
getMongoEntityAsClient().getProtocolMappers().clear();
getMongoEntityAsClient().getProtocolMappers().addAll(mapperIds);
updateMongoEntity();
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapping.setConfig(config);
return mapping;
}
@Override
public void updateAllowedIdentityProviders(List<ClientIdentityProviderMappingModel> identityProviders) {
List<ClientIdentityProviderMappingEntity> stored = new ArrayList<ClientIdentityProviderMappingEntity>();

View file

@ -5,21 +5,17 @@ import com.mongodb.QueryBuilder;
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClaimTypeModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.entities.ClaimTypeEntity;
import org.keycloak.models.entities.IdentityProviderEntity;
import org.keycloak.models.entities.ProtocolMapperEntity;
import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.models.entities.UserFederationProviderEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
@ -616,14 +612,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
return result;
}
public void addDefaultClientProtocolMappers(ClientModel client) {
Set<String> adding = new HashSet<String>();
for (ProtocolMapperEntity mapper : realm.getProtocolMappers()) {
if (mapper.isAppliedByDefault()) adding.add(mapper.getId());
}
client.setProtocolMappers(adding);
}
@Override
public ApplicationModel addApplication(String name) {
return this.addApplication(null, name);
@ -639,7 +627,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
getMongoStore().insertEntity(appData, invocationContext);
ApplicationModel model = new ApplicationAdapter(session, this, appData, invocationContext);
addDefaultClientProtocolMappers(model);
return model;
}
@ -662,7 +649,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
getMongoStore().insertEntity(oauthClient, invocationContext);
OAuthClientAdapter model = new OAuthClientAdapter(session, this, oauthClient, invocationContext);
addDefaultClientProtocolMappers(model);
return model;
}
@ -798,178 +784,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
updateRealm();
}
@Override
public Set<ProtocolMapperModel> getProtocolMappers() {
Set<ProtocolMapperModel> result = new HashSet<ProtocolMapperModel>();
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) {
config.putAll(entity.getConfig());
}
mapping.setConfig(config);
}
return result;
}
@Override
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
throw new RuntimeException("protocol mapper name must be unique per protocol");
}
ProtocolMapperEntity entity = new ProtocolMapperEntity();
entity.setId(KeycloakModelUtils.generateId());
entity.setProtocol(model.getProtocol());
entity.setName(model.getName());
entity.setAppliedByDefault(model.isAppliedByDefault());
entity.setProtocolMapper(model.getProtocolMapper());
entity.setConfig(model.getConfig());
entity.setConsentRequired(model.isConsentRequired());
entity.setConsentText(model.getConsentText());
realm.getProtocolMappers().add(entity);
updateRealm();
return entityToModel(entity);
}
@Override
public void removeProtocolMapper(ProtocolMapperModel mapping) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getId().equals(mapping.getId())) {
realm.getProtocolMappers().remove(entity);
updateRealm();
break;
}
}
}
protected ProtocolMapperEntity getProtocolMapperyEntityById(String id) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getId().equals(id)) {
return entity;
}
}
return null;
}
protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
for (ProtocolMapperEntity entity : realm.getProtocolMappers()) {
if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
return entity;
}
}
return null;
}
@Override
public void updateProtocolMapper(ProtocolMapperModel mapping) {
ProtocolMapperEntity entity = getProtocolMapperyEntityById(mapping.getId());
entity.setAppliedByDefault(mapping.isAppliedByDefault());
entity.setProtocolMapper(mapping.getProtocolMapper());
entity.setConsentRequired(mapping.isConsentRequired());
entity.setConsentText(mapping.getConsentText());
if (entity.getConfig() != null) {
entity.getConfig().clear();
entity.getConfig().putAll(mapping.getConfig());
} else {
entity.setConfig(mapping.getConfig());
}
updateRealm();
}
@Override
public ProtocolMapperModel getProtocolMapperById(String id) {
ProtocolMapperEntity entity = getProtocolMapperyEntityById(id);
if (entity == null) return null;
return entityToModel(entity);
}
@Override
public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) {
ProtocolMapperEntity entity = getProtocolMapperEntityByName(protocol, name);
if (entity == null) return null;
return entityToModel(entity);
}
protected ProtocolMapperModel entityToModel(ProtocolMapperEntity entity) {
ProtocolMapperModel mapping = new ProtocolMapperModel();
mapping.setId(entity.getId());
mapping.setName(entity.getName());
mapping.setProtocol(entity.getProtocol());
mapping.setAppliedByDefault(entity.isAppliedByDefault());
mapping.setProtocolMapper(entity.getProtocolMapper());
mapping.setConsentRequired(entity.isConsentRequired());
mapping.setConsentText(entity.getConsentText());
Map<String, String> config = new HashMap<String, String>();
if (entity.getConfig() != null) config.putAll(entity.getConfig());
mapping.setConfig(config);
return mapping;
}
@Override
public Set<ClaimTypeModel> getClaimTypes() {
Set<ClaimTypeModel> result = new HashSet<ClaimTypeModel>();
for (ClaimTypeEntity entity : realm.getClaimTypes()) {
result.add(new ClaimTypeModel(entity.getId(), entity.getName(), entity.isBuiltIn(), entity.getType()));
}
return result;
}
@Override
public ClaimTypeModel addClaimType(ClaimTypeModel model) {
String id = model.getId() == null ? KeycloakModelUtils.generateId() : model.getId();
ClaimTypeModel claim = new ClaimTypeModel(id, model.getName(), model.isBuiltIn(), model.getType());
ClaimTypeEntity entity = new ClaimTypeEntity();
entity.setId(claim.getId());
entity.setType(model.getType());
entity.setBuiltIn(model.isBuiltIn());
entity.setName(model.getName());
realm.getClaimTypes().add(entity);
updateRealm();
return claim;
}
@Override
public void removeClaimType(ClaimTypeModel claimType) {
for (ClaimTypeEntity entity : realm.getClaimTypes()) {
if (entity.getId().equals(claimType.getId())) {
realm.getClaimTypes().remove(entity);
updateRealm();
break;
}
}
}
@Override
public ClaimTypeModel getClaimType(String name) {
for (ClaimTypeModel claimType : getClaimTypes()) {
if (claimType.getName().equals(name)) return claimType;
}
return null;
}
@Override
public void updateClaimType(ClaimTypeModel claimType) {
for (ClaimTypeEntity entity : realm.getClaimTypes()) {
if (entity.getId().equals(claimType.getId())) {
entity.setName(claimType.getName());
entity.setBuiltIn(claimType.isBuiltIn());
entity.setType(claimType.getType());
updateRealm();
break;
}
}
}
@Override
public List<IdentityProviderModel> getIdentityProviders() {

View file

@ -2,6 +2,7 @@ package org.keycloak.protocol.saml;
import org.keycloak.Config;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ProtocolMapperModel;
@ -19,7 +20,9 @@ import org.keycloak.services.managers.AuthenticationManager;
import org.picketlink.identity.federation.core.saml.v2.constants.X500SAMLProfileConstants;
import org.picketlink.identity.federation.core.sts.PicketLinkCoreSTS;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -50,22 +53,37 @@ public class SamlProtocolFactory extends AbstractLoginProtocolFactory {
}
@Override
protected void addDefaults(RealmModel realm) {
UserModelUriReferenceAttributeStatementMapper.addAttributeMapper(realm, "X500 email",
public List<ProtocolMapperModel> getBuiltinMappers() {
return builtins;
}
static List<ProtocolMapperModel> builtins = new ArrayList<>();
static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
static {
ProtocolMapperModel model;
model = UserModelUriReferenceAttributeStatementMapper.createAttributeMapper("X500 email",
"email",
X500SAMLProfileConstants.EMAIL.get(), X500SAMLProfileConstants.EMAIL.getFriendlyName(),
true, "email",
false);
UserModelUriReferenceAttributeStatementMapper.addAttributeMapper(realm, "X500 givenName",
true, "email");
builtins.add(model);
model = UserModelUriReferenceAttributeStatementMapper.createAttributeMapper("X500 givenName",
"firstName",
X500SAMLProfileConstants.GIVEN_NAME.get(), X500SAMLProfileConstants.GIVEN_NAME.getFriendlyName(),
true, "given name",
false);
UserModelUriReferenceAttributeStatementMapper.addAttributeMapper(realm, "X500 surname",
true, "given name");
builtins.add(model);
model = UserModelUriReferenceAttributeStatementMapper.createAttributeMapper("X500 surname",
"lastName",
X500SAMLProfileConstants.SURNAME.get(), X500SAMLProfileConstants.SURNAME.getFriendlyName(),
true, "family name",
false);
true, "family name");
builtins.add(model);
}
@Override
protected void addDefaults(ClientModel client) {
for (ProtocolMapperModel model : defaultBuiltins) client.addProtocolMapper(model);
}

View file

@ -74,16 +74,13 @@ public class AttributeStatementHelper {
configProperties.add(property);
}
public static void addAttributeMapper(RealmModel realm, String name, String userAttribute, String samlAttributeName, String friendlyName, boolean consentRequired, String consentText, boolean appliedByDefault, String mapperId) {
ProtocolMapperModel mapper = realm.getProtocolMapperByName(SamlProtocol.LOGIN_PROTOCOL, name);
if (mapper != null) return;
mapper = new ProtocolMapperModel();
public static ProtocolMapperModel createAttributeMapper(String name, String userAttribute, String samlAttributeName, String friendlyName, boolean consentRequired, String consentText, String mapperId) {
ProtocolMapperModel mapper = mapper = new ProtocolMapperModel();
mapper.setName(name);
mapper.setProtocolMapper(mapperId);
mapper.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
mapper.setConsentRequired(consentRequired);
mapper.setConsentText(consentText);
mapper.setAppliedByDefault(appliedByDefault);
Map<String, String> config = new HashMap<String, String>();
config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
config.put(SAML_ATTRIBUTE_NAME, samlAttributeName);
@ -91,6 +88,6 @@ public class AttributeStatementHelper {
config.put(FRIENDLY_NAME, friendlyName);
}
mapper.setConfig(config);
realm.addProtocolMapper(mapper);
return mapper;
}
}

View file

@ -67,14 +67,13 @@ public class UserAttributeBasicAttributeStatementMapper extends AbstractSAMLProt
}
public static void addAttributeMapper(RealmModel realm, String name,
public static ProtocolMapperModel createAttributeMapper(String name,
String userAttribute,
String samlAttributeName,
String friendlyName,
boolean consentRequired, String consentText,
boolean appliedByDefault) {
boolean consentRequired, String consentText) {
String mapperId = PROVIDER_ID;
AttributeStatementHelper.addAttributeMapper(realm, name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, appliedByDefault, mapperId);
return AttributeStatementHelper.createAttributeMapper(name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, mapperId);
}

View file

@ -66,14 +66,13 @@ public class UserAttributeUriReferenceAttributeStatementMapper extends AbstractS
AttributeStatementHelper.addUriReferenceAttribute(attributeStatement, mappingModel, attributeValue);
}
public static void addAttributeMapper(RealmModel realm, String name,
public static ProtocolMapperModel createAttributeMapper(String name,
String userAttribute,
String samlAttributeName,
String friendlyName,
boolean consentRequired, String consentText,
boolean appliedByDefault) {
boolean consentRequired, String consentText) {
String mapperId = PROVIDER_ID;
AttributeStatementHelper.addAttributeMapper(realm, name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, appliedByDefault, mapperId);
return AttributeStatementHelper.createAttributeMapper(name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, mapperId);
}

View file

@ -67,14 +67,13 @@ public class UserModelBasicAttributeStatementMapper extends AbstractSAMLProtocol
}
public static void addAttributeMapper(RealmModel realm, String name,
public static ProtocolMapperModel createAttributeMapper(String name,
String userAttribute,
String samlAttributeName,
String friendlyName,
boolean consentRequired, String consentText,
boolean appliedByDefault) {
boolean consentRequired, String consentText) {
String mapperId = PROVIDER_ID;
AttributeStatementHelper.addAttributeMapper(realm, name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, appliedByDefault, mapperId);
return AttributeStatementHelper.createAttributeMapper(name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, mapperId);
}
}

View file

@ -3,7 +3,6 @@ package org.keycloak.protocol.saml.mappers;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.ProtocolMapperUtils;
@ -67,14 +66,13 @@ public class UserModelUriReferenceAttributeStatementMapper extends AbstractSAMLP
}
public static void addAttributeMapper(RealmModel realm, String name,
public static ProtocolMapperModel createAttributeMapper(String name,
String userAttribute,
String samlAttributeName,
String friendlyName,
boolean consentRequired, String consentText,
boolean appliedByDefault) {
boolean consentRequired, String consentText) {
String mapperId = PROVIDER_ID;
AttributeStatementHelper.addAttributeMapper(realm, name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, appliedByDefault, mapperId);
return AttributeStatementHelper.createAttributeMapper(name, userAttribute, samlAttributeName, friendlyName, consentRequired, consentText, mapperId);
}
}

View file

@ -2,6 +2,7 @@ package org.keycloak.protocol;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
@ -24,25 +25,12 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
@Override
public void postInit(KeycloakSessionFactory factory) {
KeycloakSession session = factory.create();
session.getTransaction().begin();
try {
List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) addDefaults(realm);
session.getTransaction().commit();
} catch (Exception e) {
logger.error("Can't add default mappers to realm", e);
session.getTransaction().rollback();
} finally {
session.close();
}
factory.register(new ProviderEventListener() {
@Override
public void onEvent(ProviderEvent event) {
if (event instanceof RealmModel.RealmCreationEvent) {
RealmModel realm = ((RealmModel.RealmCreationEvent)event).getCreatedRealm();
addDefaults(realm);
if (event instanceof RealmModel.ClientCreationEvent) {
ClientModel client = ((RealmModel.ClientCreationEvent)event).getCreatedClient();
addDefaults(client);
}
}
});
@ -50,7 +38,7 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
}
protected abstract void addDefaults(RealmModel realm);
protected abstract void addDefaults(ClientModel realm);
@Override
public void close() {

View file

@ -13,5 +13,11 @@ import java.util.List;
* @version $Revision: 1 $
*/
public interface LoginProtocolFactory extends ProviderFactory<LoginProtocol> {
/**
* List of built in protocol mappers that can be used to apply to clients.
*
* @return
*/
List<ProtocolMapperModel> getBuiltinMappers();
Object createProtocolEndpoint(RealmModel realm, EventBuilder event, AuthenticationManager authManager);
}

View file

@ -1,6 +1,7 @@
package org.keycloak.protocol.oidc;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
@ -13,7 +14,9 @@ import org.keycloak.protocol.oidc.mappers.OIDCFullNameMapper;
import org.keycloak.protocol.oidc.mappers.OIDCUserModelMapper;
import org.keycloak.services.managers.AuthenticationManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -27,71 +30,80 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory {
}
@Override
protected void addDefaults(RealmModel realm) {
int counter = 0;
// the ids must never change!!!! So if you add more default mappers, then add to end with higher counter.
OIDCUserModelMapper.addClaimMapper(realm, "username",
public List<ProtocolMapperModel> getBuiltinMappers() {
return builtins;
}
static List<ProtocolMapperModel> builtins = new ArrayList<>();
static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
static {
ProtocolMapperModel model;
model = OIDCUserModelMapper.createClaimMapper("username",
"username",
"preferred_username", "String",
true, "username",
true,
true, true);
OIDCUserModelMapper.addClaimMapper(realm, "email",
builtins.add(model);
defaultBuiltins.add(model);
model = OIDCUserModelMapper.createClaimMapper("email",
"email",
"email", "String",
true, "email",
true,
true, true);
OIDCUserModelMapper.addClaimMapper(realm, "given name",
builtins.add(model);
defaultBuiltins.add(model);
model = OIDCUserModelMapper.createClaimMapper("given name",
"firstName",
"given_name", "String",
true, "given name",
true,
true, true);
OIDCUserModelMapper.addClaimMapper(realm, "family name",
builtins.add(model);
defaultBuiltins.add(model);
model = OIDCUserModelMapper.createClaimMapper("family name",
"lastName",
"family_name", "String",
true, "family name",
true,
true, true);
OIDCUserModelMapper.addClaimMapper(realm, "email verified",
builtins.add(model);
defaultBuiltins.add(model);
model = OIDCUserModelMapper.createClaimMapper("email verified",
"emailVerified",
"email_verified", "boolean",
false, null,
false,
true, true);
builtins.add(model);
ProtocolMapperModel fullName = new ProtocolMapperModel();
if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "full name") == null) {
fullName.setName("full name");
fullName.setProtocolMapper(OIDCFullNameMapper.PROVIDER_ID);
fullName.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
fullName.setConsentRequired(true);
fullName.setConsentText("full name");
fullName.setAppliedByDefault(true);
Map<String, String> config = new HashMap<String, String>();
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
fullName.setConfig(config);
realm.addProtocolMapper(fullName);
}
builtins.add(fullName);
defaultBuiltins.add(fullName);
ProtocolMapperModel address = new ProtocolMapperModel();
if (realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, "address") == null) {
address.setName("address");
address.setProtocolMapper(OIDCAddressMapper.PROVIDER_ID);
address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
address.setConsentRequired(true);
address.setConsentText("address");
address.setAppliedByDefault(false);
Map<String, String> config = new HashMap<String, String>();
config = new HashMap<String, String>();
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
address.setConfig(config);
realm.addProtocolMapper(address);
builtins.add(address);
}
@Override
protected void addDefaults(ClientModel client) {
for (ProtocolMapperModel model : defaultBuiltins) client.addProtocolMapper(model);
}
@Override

View file

@ -67,22 +67,18 @@ public class OIDCAttributeMapperHelper {
}
}
public static void addClaimMapper(RealmModel realm, String name,
public static ProtocolMapperModel createClaimMapper(String name,
String userAttribute,
String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
boolean appliedByDefault,
boolean accessToken, boolean idToken,
String mapperId) {
ProtocolMapperModel mapper = realm.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, name);
if (mapper != null) return;
mapper = new ProtocolMapperModel();
ProtocolMapperModel mapper = new ProtocolMapperModel();
mapper.setName(name);
mapper.setProtocolMapper(mapperId);
mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
mapper.setConsentRequired(consentRequired);
mapper.setConsentText(consentText);
mapper.setAppliedByDefault(appliedByDefault);
Map<String, String> config = new HashMap<String, String>();
config.put(ProtocolMapperUtils.USER_ATTRIBUTE, userAttribute);
config.put(TOKEN_CLAIM_NAME, tokenClaimName);
@ -90,7 +86,7 @@ public class OIDCAttributeMapperHelper {
if (accessToken) config.put(INCLUDE_IN_ACCESS_TOKEN, "true");
if (idToken) config.put(INCLUDE_IN_ID_TOKEN, "true");
mapper.setConfig(config);
realm.addProtocolMapper(mapper);
return mapper;
}
public static boolean includeInIDToken(ProtocolMapperModel mappingModel) {

View file

@ -114,16 +114,15 @@ public class OIDCUserAttributeMapper extends AbstractOIDCProtocolMapper implemen
return token;
}
public static void addClaimMapper(RealmModel realm, String name,
public static ProtocolMapperModel createClaimMapper(String name,
String userAttribute,
String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
boolean appliedByDefault,
boolean accessToken, boolean idToken) {
OIDCAttributeMapperHelper.addClaimMapper(realm, name, userAttribute,
return OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
tokenClaimName, claimType,
consentRequired, consentText,
appliedByDefault, accessToken, idToken,
accessToken, idToken,
PROVIDER_ID);
}

View file

@ -112,16 +112,15 @@ public class OIDCUserModelMapper extends AbstractOIDCProtocolMapper implements O
OIDCAttributeMapperHelper.mapClaim(token, mappingModel, propertyValue);
}
public static void addClaimMapper(RealmModel realm, String name,
public static ProtocolMapperModel createClaimMapper(String name,
String userAttribute,
String tokenClaimName, String claimType,
boolean consentRequired, String consentText,
boolean appliedByDefault,
boolean accessToken, boolean idToken) {
OIDCAttributeMapperHelper.addClaimMapper(realm, name, userAttribute,
return OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute,
tokenClaimName, claimType,
consentRequired, consentText,
appliedByDefault, accessToken, idToken,
accessToken, idToken,
PROVIDER_ID);
}

View file

@ -89,8 +89,8 @@ public class ApplicationResource {
}
@Path("protocol-mappers")
public ClientProtocolMappersResource getProtocolMappers() {
ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, application);
public ProtocolMappersResource getProtocolMappers() {
ProtocolMappersResource mappers = new ProtocolMappersResource(application, auth);
ResteasyProviderFactory.getInstance().injectProperties(mappers);
//resourceContext.initResource(mappers);
return mappers;

View file

@ -1,120 +0,0 @@
package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Base resource for managing users
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ClientProtocolMappersResource {
protected static final Logger logger = Logger.getLogger(ClientProtocolMappersResource.class);
protected ClientModel client;
protected RealmModel realm;
protected RealmAuth auth;
@Context
protected UriInfo uriInfo;
@Context
protected KeycloakSession session;
public ClientProtocolMappersResource(RealmModel realm, RealmAuth auth, ClientModel client) {
this.auth = auth;
this.realm = realm;
this.client = client;
auth.init(RealmAuth.Resource.USER);
}
/**
* Map of mappers by name for a specific protocol attached to the client
*
* @param protocol
* @return
*/
@GET
@NoCache
@Path("protocol/{protocol}")
@Produces("application/json")
public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
return mappers;
}
/**
* Add mappers to client.
*
* @param mapperIds List of mapper ids
*/
@Path("models")
@POST
@NoCache
@Consumes("application/json")
public void addMappers(Set<String> mapperIds) {
auth.requireManage();
client.addProtocolMappers(mapperIds);
}
/**
* remove client mappers.
*
* @param mapperIds List of mapper ids
*/
@Path("models")
@DELETE
@NoCache
@Consumes("application/json")
public void removeMappers(Set<String> mapperIds) {
auth.requireManage();
client.removeProtocolMappers(mapperIds);
}
@GET
@NoCache
@Path("models")
@Produces("application/json")
public List<ProtocolMapperRepresentation> getMappers() {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
return mappers;
}
}

View file

@ -80,8 +80,8 @@ public class OAuthClientResource {
* @return
*/
@Path("protocol-mappers")
public ClientProtocolMappersResource getProtocolMappers() {
ClientProtocolMappersResource mappers = new ClientProtocolMappersResource(realm, auth, oauthClient);
public ProtocolMappersResource getProtocolMappers() {
ProtocolMappersResource mappers = new ProtocolMappersResource(oauthClient, auth);
ResteasyProviderFactory.getInstance().injectProperties(mappers);
//resourceContext.initResource(mappers);
return mappers;

View file

@ -3,6 +3,7 @@ package org.keycloak.services.resources.admin;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KerberosConstants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
@ -47,7 +48,7 @@ import java.util.Map;
public class ProtocolMappersResource {
protected static final Logger logger = Logger.getLogger(ProtocolMappersResource.class);
protected RealmModel realm;
protected ClientModel client;
protected RealmAuth auth;
@ -57,9 +58,9 @@ public class ProtocolMappersResource {
@Context
protected KeycloakSession session;
public ProtocolMappersResource(RealmModel realm, RealmAuth auth) {
public ProtocolMappersResource(ClientModel client, RealmAuth auth) {
this.auth = auth;
this.realm = realm;
this.client = client;
auth.init(RealmAuth.Resource.USER);
}
@ -77,14 +78,14 @@ public class ProtocolMappersResource {
public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
if (mapper.getProtocol().equals(protocol)) mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
return mappers;
}
/**
* createa mapper
* creates mapper
*
* @param rep
*/
@ -95,9 +96,24 @@ public class ProtocolMappersResource {
public Response createMapper(ProtocolMapperRepresentation rep) {
auth.requireManage();
ProtocolMapperModel model = RepresentationToModel.toModel(rep);
model = realm.addProtocolMapper(model);
model = client.addProtocolMapper(model);
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
}
/**
* creates multiple mapper
*
*/
@Path("add-models")
@POST
@NoCache
@Consumes("application/json")
public void createMapper(List<ProtocolMapperRepresentation> reps) {
auth.requireManage();
for (ProtocolMapperRepresentation rep : reps) {
ProtocolMapperModel model = RepresentationToModel.toModel(rep);
model = client.addProtocolMapper(model);
}
}
@GET
@NoCache
@ -106,7 +122,7 @@ public class ProtocolMappersResource {
public List<ProtocolMapperRepresentation> getMappers() {
auth.requireView();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : realm.getProtocolMappers()) {
for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
return mappers;
@ -118,7 +134,7 @@ public class ProtocolMappersResource {
@Produces("application/json")
public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
auth.requireView();
ProtocolMapperModel model = realm.getProtocolMapperById(id);
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
return ModelToRepresentation.toRepresentation(model);
}
@ -129,10 +145,10 @@ public class ProtocolMappersResource {
@Consumes("application/json")
public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
auth.requireManage();
ProtocolMapperModel model = realm.getProtocolMapperById(id);
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
model = RepresentationToModel.toModel(rep);
realm.updateProtocolMapper(model);
client.updateProtocolMapper(model);
}
@DELETE
@ -140,9 +156,9 @@ public class ProtocolMappersResource {
@Path("models/{id}")
public void delete(@PathParam("id") String id) {
auth.requireManage();
ProtocolMapperModel model = realm.getProtocolMapperById(id);
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
realm.removeProtocolMapper(model);
client.removeProtocolMapper(model);
}

View file

@ -12,6 +12,7 @@ import org.keycloak.exportimport.ApplicationImporter;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserSessionModel;
@ -19,8 +20,12 @@ import org.keycloak.models.cache.CacheRealmProvider;
import org.keycloak.models.cache.CacheUserProvider;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.LoginProtocolFactory;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.LDAPConnectionTestManager;
@ -273,18 +278,6 @@ public class RealmAdminResource {
return new ResourceAdminManager().pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
}
/**
* Protocol mappers
*
*/
@Path("protocol-mappers")
public ProtocolMappersResource protocolMappers() {
ProtocolMappersResource mappers = new ProtocolMappersResource(realm, auth);
ResteasyProviderFactory.getInstance().injectProperties(mappers);
//resourceContext.initResource(mappers);
return mappers;
}
/**
* Removes all user sessions. Any application that has an admin url will also be told to invalidate any sessions
* they have.

View file

@ -1,6 +1,5 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.Cache;
import org.keycloak.Version;
import org.keycloak.broker.provider.IdentityProvider;
import org.keycloak.broker.provider.IdentityProviderFactory;
@ -10,11 +9,15 @@ import org.keycloak.exportimport.ApplicationImporterFactory;
import org.keycloak.freemarker.Theme;
import org.keycloak.freemarker.ThemeProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.LoginProtocolFactory;
import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.Spi;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
import org.keycloak.social.SocialIdentityProvider;
@ -55,7 +58,8 @@ public class ServerInfoAdminResource {
setProtocols(info);
setApplicationImporters(info);
setProviders(info);
setProtocolMappers(info);
setProtocolMapperTypes(info);
setBuiltinProtocolMappers(info);
return info;
}
@ -131,7 +135,7 @@ public class ServerInfoAdminResource {
Collections.sort(info.protocols);
}
private void setProtocolMappers(ServerInfoRepresentation info) {
private void setProtocolMapperTypes(ServerInfoRepresentation info) {
info.protocolMapperTypes = new HashMap<String, List<ProtocolMapperTypeRepresentation>>();
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ProtocolMapper.class)) {
ProtocolMapper mapper = (ProtocolMapper)p;
@ -159,6 +163,18 @@ public class ServerInfoAdminResource {
}
}
private void setBuiltinProtocolMappers(ServerInfoRepresentation info) {
info.builtinProtocolMappers = new HashMap<>();
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) {
LoginProtocolFactory factory = (LoginProtocolFactory)p;
List<ProtocolMapperRepresentation> mappers = new LinkedList<>();
for (ProtocolMapperModel mapper : factory.getBuiltinMappers()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
info.builtinProtocolMappers.put(p.getId(), mappers);
}
}
private void setApplicationImporters(ServerInfoRepresentation info) {
info.applicationImporters = new LinkedList<Map<String, String>>();
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ApplicationImporter.class)) {
@ -187,6 +203,7 @@ public class ServerInfoAdminResource {
private List<String> eventListeners;
private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
private Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers;
public ServerInfoRepresentation() {
}
@ -230,6 +247,14 @@ public class ServerInfoAdminResource {
public Map<String, List<ProtocolMapperTypeRepresentation>> getProtocolMapperTypes() {
return protocolMapperTypes;
}
public Map<String, List<ProtocolMapperRepresentation>> getBuiltinProtocolMappers() {
return builtinProtocolMappers;
}
public void setBuiltinProtocolMappers(Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers) {
this.builtinProtocolMappers = builtinProtocolMappers;
}
}
}