From 06c8bf09640248930a289c1a6abae0f6a75f2420 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Thu, 5 Mar 2015 11:54:51 -0500 Subject: [PATCH] add oauth mappers --- .../theme/admin/base/resources/js/app.js | 70 ++++++- .../resources/js/controllers/oauth-clients.js | 194 ++++++++++++++++++ .../theme/admin/base/resources/js/loaders.js | 10 + .../theme/admin/base/resources/js/services.js | 24 +++ .../partials/application-mappers-add.html | 2 +- .../partials/oauth-client-mappers-add.html | 49 +++++ .../partials/oauth-client-mappers.html | 47 +++++ .../oauth-client-protocol-mapper-detail.html | 103 ++++++++++ .../templates/kc-navigation-oauth-client.html | 2 +- .../mongo/keycloak/adapters/RealmAdapter.java | 26 ++- 10 files changed, 521 insertions(+), 6 deletions(-) create mode 100755 forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers-add.html create mode 100755 forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers.html create mode 100755 forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-protocol-mapper-detail.html diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js index 3f39818c19..820048677e 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js @@ -491,6 +491,72 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'ApplicationProtocolMapperCreateCtrl' }) + + .when('/realms/:realm/oauth-clients/:oauth/mappers', { + templateUrl : resourceUrl + '/partials/oauth-client-mappers.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + oauth : function(OAuthClientLoader) { + return OAuthClientLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + } + }, + controller : 'OAuthClientProtocolMapperListCtrl' + }) + .when('/realms/:realm/oauth-clients/:oauth/add-mappers', { + templateUrl : resourceUrl + '/partials/oauth-client-mappers-add.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + oauth : function(OAuthClientLoader) { + return OAuthClientLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + } + }, + controller : 'OAuthClientAddBuiltinProtocolMapperCtrl' + }) + .when('/realms/:realm/oauth-clients/:oauth/mappers/:id', { + templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + oauth : function(OAuthClientLoader) { + return OAuthClientLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + }, + mapper : function(OAuthClientProtocolMapperLoader) { + return OAuthClientProtocolMapperLoader(); + } + + }, + controller : 'OAuthClientProtocolMapperCtrl' + }) + .when('/create/oauth-client/:realm/:oauth/mappers', { + templateUrl : resourceUrl + '/partials/oauth-client-protocol-mapper-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + }, + oauth : function(OAuthClientLoader) { + return OAuthClientLoader(); + } + }, + controller : 'OAuthClientProtocolMapperCreateCtrl' + }) + .when('/realms/:realm/applications/:application/sessions', { templateUrl : resourceUrl + '/partials/application-sessions.html', resolve : { @@ -1411,7 +1477,7 @@ module.directive('kcNavigationApplication', function () { scope: true, restrict: 'E', replace: true, - templateUrl: resourceUrl + '/templates/kc-navigation-application.html', + templateUrl: resourceUrl + '/templates/kc-navigation-application.html' } }); @@ -1420,7 +1486,7 @@ module.directive('kcNavigationOauthClient', function () { scope: true, restrict: 'E', replace: true, - templateUrl: resourceUrl + '/templates/kc-navigation-oauth-client.html', + templateUrl: resourceUrl + '/templates/kc-navigation-oauth-client.html' } }); diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js index 1237f57301..a55b9e3754 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/oauth-clients.js @@ -415,3 +415,197 @@ module.controller('OAuthClientIdentityProviderCtrl', function($scope, $route, re }, true); }); +module.controller('OAuthClientProtocolMapperListCtrl', function($scope, realm, oauth, serverInfo, + OAuthClientProtocolMappersByProtocol, + $http, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.oauth = oauth; + if (oauth.protocol == null) { + oauth.protocol = 'openid-connect'; + } + + var protocolMappers = serverInfo.protocolMapperTypes[oauth.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + + var updateMappers = function() { + $scope.mappers = OAuthClientProtocolMappersByProtocol.query({realm : realm.realm, oauth : oauth.id, protocol : oauth.protocol}); + }; + + updateMappers(); +}); + +module.controller('OAuthClientAddBuiltinProtocolMapperCtrl', function($scope, realm, oauth, serverInfo, + OAuthClientProtocolMappersByProtocol, + $http, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.oauth = oauth; + if (oauth.protocol == null) { + oauth.protocol = 'openid-connect'; + } + + var protocolMappers = serverInfo.protocolMapperTypes[oauth.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + + + + var updateMappers = function() { + var appMappers = OAuthClientProtocolMappersByProtocol.query({realm : realm.realm, oauth : oauth.id, protocol : oauth.protocol}, function() { + var builtinMappers = serverInfo.builtinProtocolMappers[oauth.protocol]; + for (var i = 0; i < appMappers.length; i++) { + 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; + } + } + } + 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(); + + $scope.add = function() { + var toAdd = []; + for (var i = 0; i < $scope.mappers.length; i++) { + if ($scope.mappers[i].isChecked) { + delete $scope.mappers[i].isChecked; + toAdd.push($scope.mappers[i]); + } + } + $http.post(authUrl + '/admin/realms/' + realm.realm + '/oauth-clients-by-id/' + oauth.id + '/protocol-mappers/add-models', + toAdd).success(function() { + Notifications.success("Mappers added"); + $location.url('/realms/' + realm.realm + '/oauth-clients/' + oauth.id + '/mappers'); + }).error(function() { + Notifications.error("Error adding mappers"); + $location.url('/realms/' + realm.realm + '/oauth-clients/' + oauth.id + '/mappers'); + }); + }; + +}); + +module.controller('OAuthClientProtocolMapperCtrl', function($scope, realm, serverInfo, oauth, mapper, OAuthClientProtocolMapper, Notifications, Dialog, $location) { + if (oauth.protocol == null) { + oauth.protocol = 'openid-connect'; + } + $scope.realm = realm; + $scope.oauth = oauth; + $scope.create = false; + var protocol = oauth.protocol; + $scope.protocol = oauth.protocol; + $scope.mapper = angular.copy(mapper); + var oldCopy = angular.copy($scope.realm); + $scope.changed = false; + + 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() { + OAuthClientProtocolMapper.update({ + realm : realm.realm, + oauth: oauth.id, + id : mapper.id + }, $scope.mapper, function() { + $scope.changed = false; + mapper = angular.copy($scope.mapper); + $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.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() { + OAuthClientProtocolMapper.remove({ realm: realm.realm, oauth: oauth.id, id : $scope.mapper.id }, function() { + Notifications.success("The mapper has been deleted."); + $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.id + "/mappers"); + }); + }); + }; + +}); + +module.controller('OAuthClientProtocolMapperCreateCtrl', function($scope, realm, serverInfo, oauth, OAuthClientProtocolMapper, Notifications, Dialog, $location) { + if (oauth.protocol == null) { + oauth.protocol = 'openid-connect'; + } + $scope.realm = realm; + $scope.oauth = oauth; + $scope.create = true; + var protocol = oauth.protocol; + $scope.protocol = protocol; + $scope.mapper = { protocol : oauth.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; + OAuthClientProtocolMapper.save({ + realm : realm.realm, oauth: oauth.id + }, $scope.mapper, function(data, headers) { + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + $location.url("/realms/" + realm.realm + '/oauth-clients/' + oauth.id + "/mappers/" + id); + Notifications.success("Mapper has been created."); + }); + }; + + $scope.cancel = function() { + //$location.url("/realms"); + window.history.back(); + }; + + +}); + + diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js index decbbff93e..e5db07fa07 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js @@ -89,6 +89,16 @@ module.factory('ApplicationProtocolMapperLoader', function(Loader, ApplicationPr }); }); +module.factory('OAuthClientProtocolMapperLoader', function(Loader, OAuthClientProtocolMapper, $route, $q) { + return Loader.get(OAuthClientProtocolMapper, function() { + return { + realm : $route.current.params.realm, + oauth : $route.current.params.oauth, + id: $route.current.params.id + } + }); +}); + module.factory('UserLoader', function(Loader, User, $route, $q) { return Loader.get(User, function() { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js index b6e306b896..b3b0edfcee 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js @@ -188,6 +188,8 @@ module.factory('ServerInfo', function($resource) { return $resource(authUrl + '/admin/serverinfo'); }); + + module.factory('ApplicationProtocolMapper', function($resource) { return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/protocol-mappers/models/:id', { realm : '@realm', @@ -200,6 +202,28 @@ module.factory('ApplicationProtocolMapper', function($resource) { }); }); +module.factory('OAuthClientProtocolMapper', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/models/:id', { + realm : '@realm', + oauth: '@oauth', + id : "@id" + }, { + update : { + method : 'PUT' + } + }); +}); + +module.factory('OAuthClientProtocolMappersByProtocol', function($resource) { + return $resource(authUrl + '/admin/realms/:realm/oauth-clients-by-id/:oauth/protocol-mappers/protocol/:protocol', { + realm : '@realm', + oauth : "@oauth", + protocol : "@protocol" + }); +}); + + + module.factory('User', function($resource) { return $resource(authUrl + '/admin/realms/:realm/users/:userId', { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-mappers-add.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-mappers-add.html index 95c4eead09..07ec62c626 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-mappers-add.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-mappers-add.html @@ -35,7 +35,7 @@ - {{mapper.name}} + {{mapper.name}} {{mapperTypes[mapper.protocolMapper].category}} {{mapperTypes[mapper.protocolMapper].name}} diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers-add.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers-add.html new file mode 100755 index 0000000000..0b0284e060 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers-add.html @@ -0,0 +1,49 @@ +
+
+ +
+ +

Add Builtin Protocol Mappers

+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
NameCategoryTypeAdd
{{mapper.name}}{{mapperTypes[mapper.protocolMapper].category}}{{mapperTypes[mapper.protocolMapper].name}}
No mappers available
+
+
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers.html new file mode 100755 index 0000000000..83a722e7e9 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-mappers.html @@ -0,0 +1,47 @@ +
+
+ +
+ +

{{realm.realm}} {{oauth.name}} {{oauth.protocol}} Protocol Mappers

+ + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
NameCategoryType
{{mapper.name}}{{mapperTypes[mapper.protocolMapper].category}}{{mapperTypes[mapper.protocolMapper].name}}
No mappers available
+
+
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-protocol-mapper-detail.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-protocol-mapper-detail.html new file mode 100755 index 0000000000..a98bbe7cf6 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/oauth-client-protocol-mapper-detail.html @@ -0,0 +1,103 @@ +
+
+ +
+ + + +

{{mapper.name}} Protocol Mapper

+

Create Protocol Mapper

+

* Required fields

+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ + + +
+
+
+
\ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html index db40ee5582..8c35518959 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-oauth-client.html @@ -1,7 +1,7 @@