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 b46b13f5c3..6ebea5fa8a 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 @@ -476,8 +476,8 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'ApplicationClusteringNodeCtrl' }) - .when('/realms/:realm/applications/:application/certificate', { - templateUrl : 'partials/application-keys.html', + .when('/realms/:realm/applications/:application/saml/keys', { + templateUrl : 'partials/application-saml-keys.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); @@ -486,7 +486,31 @@ module.config([ '$routeProvider', function($routeProvider) { return ApplicationLoader(); } }, - controller : 'ApplicationCertificateCtrl' + controller : 'ApplicationSamlKeyCtrl' + }) + .when('/realms/:realm/applications/:application/saml/:keyType/import/:attribute', { + templateUrl : 'partials/application-saml-key-import.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + application : function(ApplicationLoader) { + return ApplicationLoader(); + } + }, + controller : 'ApplicationCertificateImportCtrl' + }) + .when('/realms/:realm/applications/:application/saml/:keyType/export/:attribute', { + templateUrl : 'partials/application-saml-key-export.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + application : function(ApplicationLoader) { + return ApplicationLoader(); + } + }, + controller : 'ApplicationCertificateExportCtrl' }) .when('/realms/:realm/applications/:application/roles', { templateUrl : 'partials/application-role-list.html', @@ -553,6 +577,9 @@ module.config([ '$routeProvider', function($routeProvider) { }, application : function() { return {}; + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); } }, controller : 'ApplicationDetailCtrl' @@ -568,6 +595,9 @@ module.config([ '$routeProvider', function($routeProvider) { }, application : function(ApplicationLoader) { return ApplicationLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); } }, controller : 'ApplicationDetailCtrl' @@ -580,10 +610,26 @@ module.config([ '$routeProvider', function($routeProvider) { }, applications : function(ApplicationListLoader) { return ApplicationListLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); } + }, controller : 'ApplicationListCtrl' }) + .when('/import/application/:realm', { + templateUrl : 'partials/application-import.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + } + }, + controller : 'ApplicationImportCtrl' + }) // OAUTH Client diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js index e1efcba147..3d80c2b2bc 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/applications.js @@ -43,16 +43,82 @@ module.controller('ApplicationCredentialsCtrl', function($scope, $location, real }); }); -module.controller('ApplicationCertificateCtrl', function($scope, $location, $http, $upload, realm, application, +module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $upload, realm, application, ApplicationCertificate, ApplicationCertificateGenerate, ApplicationCertificateDownload, Notifications) { $scope.realm = realm; $scope.application = application; - var jks = { - keyAlias: application.name, - realmAlias: realm.realm + + var signingKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.signing' }, + function() { + $scope.signingKeyInfo = signingKeyInfo; + } + ); + + $scope.generateSigningKey = function() { + var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.signing' }, + function() { + Notifications.success('Signing key has been regenerated.'); + $scope.signingKeyInfo = keyInfo; + }, + function() { + Notifications.error("Signing key was not regenerated."); + } + ); }; + $scope.importSigningKey = function() { + $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/import/saml.signing"); + }; + + $scope.exportSigningKey = function() { + $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Signing/export/saml.signing"); + }; + + var encryptionKeyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' }, + function() { + $scope.encryptionKeyInfo = encryptionKeyInfo; + } + ); + + $scope.generateEncryptionKey = function() { + var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id, attribute: 'saml.encryption' }, + function() { + Notifications.success('Encryption key has been regenerated.'); + $scope.encryptionKeyInfo = keyInfo; + }, + function() { + Notifications.error("Encryption key was not regenerated."); + } + ); + }; + + $scope.importEncryptionKey = function() { + $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/import/saml.encryption"); + }; + + $scope.exportEncryptionKey = function() { + $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/Encryption/export/saml.encryption"); + }; + + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); + +module.controller('ApplicationCertificateImportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams, + ApplicationCertificate, ApplicationCertificateGenerate, + ApplicationCertificateDownload, Notifications) { + + var keyType = $routeParams.keyType; + var attribute = $routeParams.attribute; + $scope.realm = realm; + $scope.application = application; + $scope.keyType = keyType; + $scope.files = []; $scope.onFileSelect = function($files) { @@ -68,8 +134,6 @@ module.controller('ApplicationCertificateCtrl', function($scope, $location, $htt "PKCS12" ]; - $scope.jks = jks; - $scope.jks.format = $scope.keyFormats[0]; $scope.uploadKeyFormat = $scope.keyFormats[0]; $scope.uploadFile = function() { @@ -77,13 +141,13 @@ module.controller('ApplicationCertificateCtrl', function($scope, $location, $htt for (var i = 0; i < $scope.files.length; i++) { var $file = $scope.files[i]; $scope.upload = $upload.upload({ - url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/upload/jks', + url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/upload', // method: POST or PUT, // headers: {'headerKey': 'headerValue'}, withCredential: true, data: {keystoreFormat: $scope.uploadKeyFormat, - keyAlias: $scope.uploadKeyAlias, - keyPassword: $scope.uploadKeyPassword, - storePassword: $scope.uploadStorePassword + keyAlias: $scope.uploadKeyAlias, + keyPassword: $scope.uploadKeyPassword, + storePassword: $scope.uploadStorePassword }, file: $file /* set file formData name for 'Content-Desposition' header. Default: 'file' */ @@ -93,8 +157,8 @@ module.controller('ApplicationCertificateCtrl', function($scope, $location, $htt }).progress(function(evt) { console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers) { - $scope.keyInfo = data; Notifications.success("Keystore uploaded successfully."); + $location.url("/realms/" + realm.realm + "/applications/" + application.id + "/saml/keys"); }) .error(function() { Notifications.error("The key store can not be uploaded. Please verify the file."); @@ -104,30 +168,42 @@ module.controller('ApplicationCertificateCtrl', function($scope, $location, $htt } }; + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); +module.controller('ApplicationCertificateExportCtrl', function($scope, $location, $http, $upload, realm, application, $routeParams, + ApplicationCertificate, ApplicationCertificateGenerate, + ApplicationCertificateDownload, Notifications) { + var keyType = $routeParams.keyType; + var attribute = $routeParams.attribute; + $scope.realm = realm; + $scope.application = application; + $scope.keyType = keyType; + var jks = { + keyAlias: application.name, + realmAlias: realm.realm + }; + $scope.keyFormats = [ + "JKS", + "PKCS12" + ]; - var keyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id }, + var keyInfo = ApplicationCertificate.get({ realm : realm.realm, application : application.id, attribute: attribute }, function() { $scope.keyInfo = keyInfo; } ); + $scope.jks = jks; + $scope.jks.format = $scope.keyFormats[0]; - $scope.generate = function() { - var keyInfo = ApplicationCertificateGenerate.generate({ realm : realm.realm, application : application.id }, - function() { - Notifications.success('Client keypair and cert has been changed.'); - $scope.keyInfo = keyInfo; - }, - function() { - Notifications.error("Client keypair and cert was not changed due to a problem."); - } - ); - }; - - $scope.downloadJKS = function() { + $scope.download = function() { $http({ - url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/download', + url: authUrl + '/admin/realms/' + realm.realm + '/applications-by-id/' + application.id + '/certificates/' + attribute + '/download', method: 'POST', responseType: 'arraybuffer', data: $scope.jks, @@ -290,9 +366,62 @@ module.controller('ApplicationRoleDetailCtrl', function($scope, realm, applicati }); -module.controller('ApplicationListCtrl', function($scope, realm, applications, Application, $location) { +module.controller('ApplicationImportCtrl', function($scope, $location, $upload, realm, serverInfo, Notifications) { + + $scope.realm = realm; + $scope.configFormats = serverInfo.applicationImporters; + $scope.configFormat = null; + + $scope.files = []; + + $scope.onFileSelect = function($files) { + $scope.files = $files; + }; + + $scope.clearFileSelect = function() { + $scope.files = null; + } + + $scope.uploadFile = function() { + //$files: an array of files selected, each file has name, size, and type. + for (var i = 0; i < $scope.files.length; i++) { + var $file = $scope.files[i]; + $scope.upload = $upload.upload({ + url: authUrl + '/admin/realms/' + realm.realm + '/application-importers/' + $scope.configFormat.id + '/upload', + // method: POST or PUT, + // headers: {'headerKey': 'headerValue'}, withCredential: true, + data: {myObj: ""}, + file: $file + /* set file formData name for 'Content-Desposition' header. Default: 'file' */ + //fileFormDataName: myFile, + /* customize how data is added to formData. See #40#issuecomment-28612000 for example */ + //formDataAppender: function(formData, key, val){} + }).progress(function(evt) { + console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); + }).success(function(data, status, headers) { + Notifications.success("Uploaded successfully."); + $location.url("/realms/" + realm.realm + "/applications"); + }) + .error(function() { + Notifications.error("The file can not be uploaded. Please verify the file."); + + }); + //.then(success, error, progress); + } + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); + + +module.controller('ApplicationListCtrl', function($scope, realm, applications, Application, serverInfo, $location) { $scope.realm = realm; $scope.applications = applications; + $scope.importButton = serverInfo.applicationImporters.length > 0; $scope.$watch(function() { return $location.path(); }, function() { @@ -335,7 +464,7 @@ module.controller('ApplicationInstallationCtrl', function($scope, realm, applica } }); -module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) { +module.controller('ApplicationDetailCtrl', function($scope, realm, application, serverInfo, Application, $location, Dialog, Notifications) { console.log('ApplicationDetailCtrl'); $scope.accessTypes = [ @@ -344,10 +473,8 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, "bearer-only" ]; - $scope.protocols = [ - "openid-connect", - "saml" - ]; + $scope.protocols = serverInfo.protocols; + $scope.signatureAlgorithms = [ "RSA_SHA1", "RSA_SHA256", @@ -375,11 +502,9 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application, } else if (application.publicClient) { $scope.accessType = $scope.accessTypes[1]; } - if (application.protocol == 'openid-connect') { - $scope.protocol = $scope.protocols[0]; - } else if (application.protocol == 'saml') { - $scope.protocol = $scope.protocols[1]; - } else { // protocol could be null due to older keycloak installs + if (application.protocol) { + $scope.protocol = $scope.protocols[$scope.protocols.indexOf(application.protocol)]; + } else { $scope.protocol = $scope.protocols[0]; } if (application.attributes['saml.signature.algorithm'] == 'RSA_SHA1') { 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 ee4d635ccf..d47e3abbce 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 @@ -708,16 +708,18 @@ module.factory('ApplicationTestNodesAvailable', function($resource) { }); module.factory('ApplicationCertificate', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates', { + return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute', { realm : '@realm', - application : "@application" + application : "@application", + attribute: "@attribute" }); }); module.factory('ApplicationCertificateGenerate', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/generate', { + return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/generate', { realm : '@realm', - application : "@application" + application : "@application", + attribute: "@attribute" }, { generate : { @@ -727,9 +729,10 @@ module.factory('ApplicationCertificateGenerate', function($resource) { }); module.factory('ApplicationCertificateDownload', function($resource) { - return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/download', { + return $resource(authUrl + '/admin/realms/:realm/applications-by-id/:application/certificates/:attribute/download', { realm : '@realm', - application : "@application" + application : "@application", + attribute: "@attribute" }, { download : { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-import.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-import.html new file mode 100755 index 0000000000..723bf011b3 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-import.html @@ -0,0 +1,42 @@ +
+
+ +

+
+

{{application.name}} Application Import

+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ + + {{files[0].name}} + +
+
+
+ + +
+
+
+
+
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-list.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-list.html index f6eec65ed4..364b4c7c53 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-list.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-list.html @@ -19,7 +19,8 @@
- Add Application + Import + Create
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-export.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-export.html new file mode 100755 index 0000000000..692080a70f --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-export.html @@ -0,0 +1,62 @@ +
+
+ +
+ +

{{application.name}} SAML {{keyType}} Key Export

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-import.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-import.html new file mode 100755 index 0000000000..e72583ea8b --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-key-import.html @@ -0,0 +1,59 @@ +
+
+ +
+ +

{{application.name}} SAML {{keyType}} Key Import

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + {{files[0].name}} + +
+
+
+ + +
+
+
+
+
\ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-keys.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-keys.html new file mode 100755 index 0000000000..f871bb9c4a --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/application-saml-keys.html @@ -0,0 +1,66 @@ +
+
+ +
+ +

{{application.name}} SAML Keys

+
+
+ Signing Key +
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + +
+
+
+
+ Encryption Key +
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+ + + +
+
+
+
+
+
\ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-application.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-application.html index 8e3a96305a..02343270d4 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-application.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/templates/kc-navigation-application.html @@ -1,7 +1,7 @@