diff options
Diffstat (limited to 'admin/resources/js/controllers/clients.js')
-rw-r--r-- | admin/resources/js/controllers/clients.js | 3456 |
1 files changed, 3456 insertions, 0 deletions
diff --git a/admin/resources/js/controllers/clients.js b/admin/resources/js/controllers/clients.js new file mode 100644 index 0000000..7768762 --- /dev/null +++ b/admin/resources/js/controllers/clients.js @@ -0,0 +1,3456 @@ +Array.prototype.remove = function(from, to) { + var rest = this.slice((to || from) + 1 || this.length); + this.length = from < 0 ? this.length + from : from; + return this.push.apply(this, rest); +}; + +module.controller('ClientTabCtrl', function(Dialog, $scope, Current, Notifications, $location) { + $scope.removeClient = function() { + Dialog.confirmDelete($scope.client.clientId, 'client', function() { + $scope.client.$remove({ + realm : Current.realm.realm, + client : $scope.client.id + }, function() { + $location.url("/realms/" + Current.realm.realm + "/clients"); + Notifications.success("The client has been deleted."); + }); + }); + }; +}); + +module.controller('ClientRoleListCtrl', function($scope, $route, realm, client, ClientRoleList, RoleById, Notifications, Dialog) { + $scope.realm = realm; + $scope.roles = []; + $scope.client = client; + + $scope.query = { + realm: realm.realm, + client: $scope.client.id, + search : null, + max : 20, + first : 0 + } + + $scope.$watch('query.search', function (newVal, oldVal) { + if($scope.query.search && $scope.query.search.length >= 3) { + $scope.firstPage(); + } + }, true); + + $scope.firstPage = function() { + $scope.query.first = 0; + $scope.searchQuery(); + } + + $scope.previousPage = function() { + $scope.query.first -= parseInt($scope.query.max); + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.searchQuery(); + } + + $scope.nextPage = function() { + $scope.query.first += parseInt($scope.query.max); + $scope.searchQuery(); + } + + $scope.searchQuery = function() { + $scope.searchLoaded = false; + + $scope.roles = ClientRoleList.query($scope.query, function() { + $scope.searchLoaded = true; + $scope.lastSearch = $scope.query.search; + }); + }; + + $scope.searchQuery(); + + $scope.removeRole = function(role) { + Dialog.confirmDelete(role.name, 'role', function() { + RoleById.remove({ + realm: realm.realm, + role: role.id + }, function () { + $route.reload(); + Notifications.success("The role has been deleted."); + }); + }); + }; +}); + +module.controller('ClientCredentialsCtrl', function($scope, $location, realm, client, clientAuthenticatorProviders, clientConfigProperties, Client, ClientRegistrationAccessToken, Notifications) { + $scope.realm = realm; + $scope.client = angular.copy(client); + $scope.clientAuthenticatorProviders = clientAuthenticatorProviders; + + var updateCurrentPartial = function(val) { + $scope.clientAuthenticatorConfigPartial; + switch(val) { + case 'client-secret': + $scope.clientAuthenticatorConfigPartial = 'client-credentials-secret.html'; + break; + case 'client-jwt': + $scope.clientAuthenticatorConfigPartial = 'client-credentials-jwt.html'; + break; + case 'client-secret-jwt': + $scope.clientAuthenticatorConfigPartial = 'client-credentials-secret-jwt.html'; + break; + case 'client-x509': + $scope.clientAuthenticatorConfigPartial = 'client-credentials-x509.html'; + break; + default: + $scope.currentAuthenticatorConfigProperties = clientConfigProperties[val]; + $scope.clientAuthenticatorConfigPartial = 'client-credentials-generic.html'; + break; + } + }; + + updateCurrentPartial(client.clientAuthenticatorType); + + $scope.$watch('client.clientAuthenticatorType', function() { + if (!angular.equals($scope.client.clientAuthenticatorType, client.clientAuthenticatorType)) { + + Client.update({ + realm : realm.realm, + client : client.id + }, $scope.client, function() { + $scope.changed = false; + client = angular.copy($scope.client); + updateCurrentPartial(client.clientAuthenticatorType) + }); + + } + }, true); + + $scope.regenerateRegistrationAccessToken = function() { + var secret = ClientRegistrationAccessToken.update({ realm : $scope.realm.realm, client : $scope.client.id }, + function(data) { + Notifications.success('The registration access token has been updated.'); + $scope.client['registrationAccessToken'] = data.registrationAccessToken; + }, + function() { + Notifications.error('Failed to update the registration access token'); + } + ); + }; +}); + +module.controller('ClientSecretCtrl', function($scope, $location, ClientSecret, Notifications) { + var secret = ClientSecret.get({ realm : $scope.realm.realm, client : $scope.client.id }, + function() { + $scope.secret = secret.value; + } + ); + + $scope.changePassword = function() { + var secret = ClientSecret.update({ realm : $scope.realm.realm, client : $scope.client.id }, + function() { + Notifications.success('The secret has been changed.'); + $scope.secret = secret.value; + }, + function() { + Notifications.error("The secret was not changed due to a problem."); + $scope.secret = "error"; + } + ); + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.cancel = function() { + $location.url("/realms/" + $scope.realm.realm + "/clients/" + $scope.client.id + "/credentials"); + }; +}); + +module.controller('ClientX509Ctrl', function($scope, $location, Client, Notifications) { + console.log('ClientX509Ctrl invoked'); + + $scope.clientCopy = angular.copy($scope.client); + $scope.changed = false; + + $scope.$watch('client', function() { + if (!angular.equals($scope.client, $scope.clientCopy)) { + $scope.changed = true; + } + }, true); + + $scope.save = function() { + if (!$scope.client.attributes["x509.subjectdn"]) { + Notifications.error("The SubjectDN must not be empty."); + } else { + Client.update({ + realm : $scope.realm.realm, + client : $scope.client.id + }, $scope.client, function() { + $scope.changed = false; + $scope.clientCopy = angular.copy($scope.client); + Notifications.success("Client authentication configuration has been saved to the client."); + }, function() { + Notifications.error("The SubjectDN was not changed due to a problem."); + $scope.subjectdn = "error"; + }); + } + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.reset = function() { + $scope.client.attributes["x509.subjectdn"] = $scope.clientCopy.attributes["x509.subjectdn"]; + $location.url("/realms/" + $scope.realm.realm + "/clients/" + $scope.client.id + "/credentials"); + }; +}); + +module.controller('ClientSignedJWTCtrl', function($scope, $location, Client, ClientCertificate, Notifications, $route) { + var signingKeyInfo = ClientCertificate.get({ realm : $scope.realm.realm, client : $scope.client.id, attribute: 'jwt.credential' }, + function() { + $scope.signingKeyInfo = signingKeyInfo; + } + ); + + console.log('ClientSignedJWTCtrl invoked'); + + $scope.clientCopy = angular.copy($scope.client); + $scope.changed = false; + + $scope.$watch('client', function() { + if (!angular.equals($scope.client, $scope.clientCopy)) { + $scope.changed = true; + } + }, true); + + if ($scope.client.attributes["use.jwks.url"]) { + if ($scope.client.attributes["use.jwks.url"] == "true") { + $scope.useJwksUrl = true; + } else { + $scope.useJwksUrl = false; + } + } + + $scope.switchChange = function() { + $scope.changed = true; + } + + $scope.save = function() { + + if ($scope.useJwksUrl == true) { + $scope.client.attributes["use.jwks.url"] = "true"; + } else { + $scope.client.attributes["use.jwks.url"] = "false"; + } + + Client.update({ + realm : $scope.realm.realm, + client : $scope.client.id + }, $scope.client, function() { + $scope.changed = false; + $scope.clientCopy = angular.copy($scope.client); + Notifications.success("Client authentication configuration has been saved to the client."); + }); + }; + + $scope.importCertificate = function() { + $location.url("/realms/" + $scope.realm.realm + "/clients/" + $scope.client.id + "/credentials/client-jwt/Signing/import/jwt.credential"); + }; + + $scope.generateSigningKey = function() { + $location.url("/realms/" + $scope.realm.realm + "/clients/" + $scope.client.id + "/credentials/client-jwt/Signing/export/jwt.credential"); + }; + + $scope.reset = function() { + $route.reload(); + }; +}); + +module.controller('ClientGenericCredentialsCtrl', function($scope, $location, Client, Notifications) { + + console.log('ClientGenericCredentialsCtrl invoked'); + + $scope.clientCopy = angular.copy($scope.client); + $scope.changed = false; + + $scope.$watch('client', function() { + if (!angular.equals($scope.client, $scope.clientCopy)) { + $scope.changed = true; + } + }, true); + + $scope.save = function() { + + Client.update({ + realm : $scope.realm.realm, + client : $scope.client.id + }, $scope.client, function() { + $scope.changed = false; + $scope.clientCopy = angular.copy($scope.client); + Notifications.success("Client authentication configuration has been saved to the client."); + }); + }; + + $scope.reset = function() { + $scope.client = angular.copy($scope.clientCopy); + $scope.changed = false; + }; +}); + +module.controller('ClientIdentityProviderCtrl', function($scope, $location, $route, realm, client, Client, $location, Notifications) { + $scope.realm = realm; + $scope.client = angular.copy(client); + var length = 0; + + if ($scope.client.identityProviders) { + length = $scope.client.identityProviders.length; + + for (i = 0; i < $scope.client.identityProviders.length; i++) { + var clientProvider = $scope.client.identityProviders[i]; + if (clientProvider.retrieveToken) { + clientProvider.retrieveToken = clientProvider.retrieveToken.toString(); + } + } + + } else { + $scope.client.identityProviders = []; + } + + $scope.identityProviders = []; + var providersMissingInClient = []; + + for (j = 0; j < realm.identityProviders.length; j++) { + var identityProvider = realm.identityProviders[j]; + var clientProvider = null; + + for (i = 0; i < $scope.client.identityProviders.length; i++) { + clientProvider = $scope.client.identityProviders[i]; + + if (clientProvider) { + + if (clientProvider.id == identityProvider.id) { + $scope.identityProviders[i] = {}; + $scope.identityProviders[i].identityProvider = identityProvider; + $scope.identityProviders[i].retrieveToken = clientProvider.retrieveToken; + break; + } + + clientProvider = null; + } + } + + if (clientProvider == null) { + providersMissingInClient.push(identityProvider); + } + } + + for (j = 0; j < providersMissingInClient.length; j++) { + var identityProvider = providersMissingInClient[j]; + + var currentProvider = {}; + currentProvider.identityProvider = identityProvider; + currentProvider.retrieveToken = "false"; + $scope.identityProviders.push(currentProvider); + + var currentClientProvider = {}; + currentClientProvider.id = identityProvider.id; + currentClientProvider.retrieveToken = "false"; + $scope.client.identityProviders.push(currentClientProvider); + } + + var oldCopy = angular.copy($scope.client); + + $scope.save = function() { + + Client.update({ + realm : realm.realm, + client : client.id + }, $scope.client, function() { + $scope.changed = false; + $route.reload(); + Notifications.success("Your changes have been saved to the client."); + }); + }; + + $scope.reset = function() { + $scope.client = angular.copy(oldCopy); + $scope.changed = false; + }; + + $scope.$watch('client', function() { + if (!angular.equals($scope.client, oldCopy)) { + $scope.changed = true; + } + }, true); +}); + +module.controller('ClientSamlKeyCtrl', function($scope, $location, $http, $upload, realm, client, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { + $scope.realm = realm; + $scope.client = client; + + var signingKeyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: 'saml.signing' }, + function() { + $scope.signingKeyInfo = signingKeyInfo; + } + ); + + $scope.generateSigningKey = function() { + var keyInfo = ClientCertificateGenerate.generate({ realm : realm.realm, client : client.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 + "/clients/" + client.id + "/saml/Signing/import/saml.signing"); + }; + + $scope.exportSigningKey = function() { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Signing/export/saml.signing"); + }; + + var encryptionKeyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: 'saml.encryption' }, + function() { + $scope.encryptionKeyInfo = encryptionKeyInfo; + } + ); + + $scope.generateEncryptionKey = function() { + var keyInfo = ClientCertificateGenerate.generate({ realm : realm.realm, client : client.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 + "/clients/" + client.id + "/saml/Encryption/import/saml.encryption"); + }; + + $scope.exportEncryptionKey = function() { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/Encryption/export/saml.encryption"); + }; + + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); + +module.controller('ClientCertificateImportCtrl', function($scope, $location, $http, $upload, realm, client, callingContext, $routeParams, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { + + console.log("callingContext: " + callingContext); + + var keyType = $routeParams.keyType; + var attribute = $routeParams.attribute; + $scope.realm = realm; + $scope.client = client; + $scope.keyType = keyType; + + if (callingContext == 'saml') { + var uploadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/upload'; + var redirectLocation = "/realms/" + realm.realm + "/clients/" + client.id + "/saml/keys"; + } else if (callingContext == 'jwt-credentials') { + var uploadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/upload-certificate'; + var redirectLocation = "/realms/" + realm.realm + "/clients/" + client.id + "/credentials"; + } + + $scope.files = []; + + $scope.onFileSelect = function($files) { + $scope.files = $files; + }; + + $scope.cancel = function() { + $location.url(redirectLocation); + } + + $scope.keyFormats = [ + "JKS", + "PKCS12", + "Certificate PEM" + ]; + + if (callingContext == 'jwt-credentials') { + $scope.keyFormats.push('Public Key PEM'); + $scope.keyFormats.push('JSON Web Key Set'); + } + + $scope.hideKeystoreSettings = function() { + return $scope.uploadKeyFormat == 'Certificate PEM' || $scope.uploadKeyFormat == 'Public Key PEM' || $scope.uploadKeyFormat == 'JSON Web Key Set'; + } + + $scope.uploadKeyFormat = $scope.keyFormats[0]; + + $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: uploadUrl, + // method: POST or PUT, + // headers: {'headerKey': 'headerValue'}, withCredential: true, + data: {keystoreFormat: $scope.uploadKeyFormat, + keyAlias: $scope.uploadKeyAlias, + keyPassword: $scope.uploadKeyPassword, + storePassword: $scope.uploadStorePassword + }, + 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){} + }).then(function(data, status, headers) { + Notifications.success("Keystore uploaded successfully."); + $location.url(redirectLocation); + }) + //.then(success, error, progress); + } + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); +}); + +module.controller('ClientCertificateExportCtrl', function($scope, $location, $http, $upload, realm, client, callingContext, $routeParams, + ClientCertificate, ClientCertificateGenerate, + ClientCertificateDownload, Notifications) { + var keyType = $routeParams.keyType; + var attribute = $routeParams.attribute; + $scope.realm = realm; + $scope.client = client; + $scope.keyType = keyType; + + if (callingContext == 'saml') { + var downloadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/download'; + var realmCertificate = true; + } else if (callingContext == 'jwt-credentials') { + var downloadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/generate-and-download' + var realmCertificate = false; + } + + var jks = { + keyAlias: client.clientId, + realmAlias: realm.realm, + realmCertificate: realmCertificate + }; + + $scope.keyFormats = [ + "JKS", + "PKCS12" + ]; + + var keyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: attribute }, + function() { + $scope.keyInfo = keyInfo; + } + ); + $scope.jks = jks; + $scope.jks.format = $scope.keyFormats[0]; + + $scope.download = function() { + $http({ + url: downloadUrl, + method: 'POST', + responseType: 'arraybuffer', + data: $scope.jks, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/octet-stream' + } + }).then(function(response){ + var blob = new Blob([response.data], { + type: 'application/octet-stream' + }); + var ext = ".jks"; + if ($scope.jks.format == 'PKCS12') ext = ".p12"; + + if (callingContext == 'jwt-credentials') { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials"); + Notifications.success("New keypair and certificate generated successfully. Download keystore file") + } + + saveAs(blob, 'keystore' + ext); + }).catch(function(response) { + var errorMsg = 'Error downloading'; + try { + var error = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(response.data))); + errorMsg = error['error_description'] ? error['error_description'] : errorMsg; + } catch (err) { + } + Notifications.error(errorMsg); + }); + } + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.cancel = function() { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials"); + } +}); + +module.controller('ClientSessionsCtrl', function($scope, realm, sessionCount, client, + ClientUserSessions) { + $scope.realm = realm; + $scope.count = sessionCount.count; + $scope.sessions = []; + $scope.client = client; + + $scope.page = 0; + + $scope.query = { + realm : realm.realm, + client: $scope.client.id, + max : 5, + first : 0 + } + + $scope.firstPage = function() { + $scope.query.first = 0; + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.loadUsers(); + } + + $scope.previousPage = function() { + $scope.query.first -= parseInt($scope.query.max); + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.loadUsers(); + } + + $scope.nextPage = function() { + $scope.query.first += parseInt($scope.query.max); + $scope.loadUsers(); + } + + $scope.toDate = function(val) { + return new Date(val); + }; + + $scope.loadUsers = function() { + ClientUserSessions.query($scope.query, function(updated) { + $scope.sessions = updated; + }) + }; +}); + +module.controller('ClientOfflineSessionsCtrl', function($scope, realm, offlineSessionCount, client, + ClientOfflineSessions) { + $scope.realm = realm; + $scope.count = offlineSessionCount.count; + $scope.sessions = []; + $scope.client = client; + + $scope.page = 0; + + $scope.query = { + realm : realm.realm, + client: $scope.client.id, + max : 5, + first : 0 + } + + $scope.firstPage = function() { + $scope.query.first = 0; + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.loadUsers(); + } + + $scope.previousPage = function() { + $scope.query.first -= parseInt($scope.query.max); + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.loadUsers(); + } + + $scope.nextPage = function() { + $scope.query.first += parseInt($scope.query.max); + $scope.loadUsers(); + } + + $scope.toDate = function(val) { + return new Date(val); + }; + + $scope.loadUsers = function() { + ClientOfflineSessions.query($scope.query, function(updated) { + $scope.sessions = updated; + }) + }; +}); + +module.controller('ClientRoleDetailCtrl', function($scope, $route, realm, client, role, roles, Client, + Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, + $http, $location, Dialog, Notifications, ComponentUtils) { + $scope.realm = realm; + $scope.client = client; + $scope.role = angular.copy(role); + $scope.create = !role.name; + + $scope.changed = $scope.create; + + $scope.save = function() { + convertAttributeValuesToLists(); + if ($scope.create) { + ClientRole.save({ + realm: realm.realm, + client : client.id + }, $scope.role, function (data, headers) { + $scope.changed = false; + convertAttributeValuesToString($scope.role); + role = angular.copy($scope.role); + + ClientRole.get({ realm: realm.realm, client : client.id, role: role.name }, function(role) { + var id = role.id; + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles/" + id); + Notifications.success("The role has been created."); + }); + }); + } else { + $scope.update(); + } + }; + + $scope.remove = function() { + Dialog.confirmDelete($scope.role.name, 'role', function() { + $scope.role.$remove({ + realm : realm.realm, + client : client.id, + role : $scope.role.id + }, function() { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles"); + Notifications.success("The role has been deleted."); + }); + }); + }; + + $scope.cancel = function () { + $location.url("/realms/" + realm.realm + "/clients/" + client.id + "/roles"); + }; + + $scope.addAttribute = function() { + $scope.role.attributes[$scope.newAttribute.key] = $scope.newAttribute.value; + delete $scope.newAttribute; + } + + $scope.removeAttribute = function(key) { + delete $scope.role.attributes[key]; + } + + function convertAttributeValuesToLists() { + var attrs = $scope.role.attributes; + for (var attribute in attrs) { + if (typeof attrs[attribute] === "string") { + var attrVals = attrs[attribute].split("##"); + attrs[attribute] = attrVals; + } + } + } + + function convertAttributeValuesToString(role) { + var attrs = role.attributes; + for (var attribute in attrs) { + if (typeof attrs[attribute] === "object") { + var attrVals = attrs[attribute].join("##"); + attrs[attribute] = attrVals; + } + } + } + + roleControl($scope, $route, realm, role, roles, Client, + ClientRole, RoleById, RoleRealmComposites, RoleClientComposites, + $http, $location, Notifications, Dialog, ComponentUtils); + +}); + +module.controller('ClientRoleMembersCtrl', function($scope, realm, client, role, ClientRoleMembership, Dialog, Notifications, $location) { + $scope.realm = realm; + $scope.page = 0; + $scope.role = role; + $scope.client = client; + + $scope.query = { + realm: realm.realm, + role: role.name, + client: client.id, + max : 5, + first : 0 + } + + $scope.firstPage = function() { + $scope.query.first = 0; + $scope.searchQuery(); + } + + $scope.previousPage = function() { + $scope.query.first -= parseInt($scope.query.max); + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.searchQuery(); + } + + $scope.nextPage = function() { + $scope.query.first += parseInt($scope.query.max); + $scope.searchQuery(); + } + + $scope.searchQuery = function() { + $scope.searchLoaded = false; + + $scope.users = ClientRoleMembership.query($scope.query, function() { + console.log('search loaded'); + $scope.searchLoaded = true; + $scope.lastSearch = $scope.query.search; + }); + }; + + $scope.searchQuery(); +}); + +module.controller('ClientImportCtrl', function($scope, $location, $upload, realm, serverInfo, Notifications) { + + $scope.realm = realm; + + $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 + '/client-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){} + }).success(function(data, status, headers) { + Notifications.success("Uploaded successfully."); + $location.url("/realms/" + realm.realm + "/clients"); + }) + .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('ClientListCtrl', function($scope, realm, Client, ClientListSearchState, $route, Dialog, Notifications) { + $scope.init = function() { + $scope.realm = realm; + $scope.searchLoaded = true; + + ClientListSearchState.query.realm = realm.realm; + $scope.query = ClientListSearchState.query; + + if (!ClientListSearchState.isFirstSearch) { + $scope.searchQuery(); + } else { + $scope.query.clientId = null; + $scope.firstPage(); + } + }; + + $scope.searchQuery = function() { + console.log("query.search: ", $scope.query); + $scope.searchLoaded = false; + + $scope.clients = Client.query($scope.query, function() { + $scope.searchLoaded = true; + $scope.lastSearch = $scope.query.search; + ClientListSearchState.isFirstSearch = false; + }); + }; + + $scope.firstPage = function() { + $scope.query.first = 0; + $scope.searchQuery(); + } + + $scope.previousPage = function() { + $scope.query.first -= parseInt($scope.query.max); + if ($scope.query.first < 0) { + $scope.query.first = 0; + } + $scope.searchQuery(); + } + + $scope.nextPage = function() { + $scope.query.first += parseInt($scope.query.max); + $scope.searchQuery(); + } + + $scope.removeClient = function(client) { + Dialog.confirmDelete(client.clientId, 'client', function() { + Client.remove({ + realm : realm.realm, + client : client.id + }, function() { + $route.reload(); + Notifications.success("The client has been deleted."); + }); + }); + }; + + $scope.exportClient = function(client) { + var clientCopy = angular.copy(client); + delete clientCopy.id; + + if (clientCopy.protocolMappers) { + for (var i = 0; i < clientCopy.protocolMappers.length; i++) { + delete clientCopy.protocolMappers[i].id; + } + } + + saveAs(new Blob([angular.toJson(clientCopy, 4)], { type: 'application/json' }), clientCopy.clientId + '.json'); + } +}); + +module.controller('ClientInstallationCtrl', function($scope, realm, client, serverInfo, ClientInstallation,$http, $routeParams) { + $scope.realm = realm; + $scope.client = client; + $scope.installation = null; + $scope.download = null; + $scope.configFormat = null; + $scope.filename = null; + + var protocol = client.protocol; + if (!protocol) protocol = 'openid-connect'; + $scope.configFormats = serverInfo.clientInstallations[protocol]; + console.log('configFormats.length: ' + $scope.configFormats.length); + + $scope.changeFormat = function() { + var url = ClientInstallation.url({ realm: $routeParams.realm, client: $routeParams.client, provider: $scope.configFormat.id }); + if ($scope.configFormat.mediaType == 'application/zip') { + $http({ + url: url, + method: 'GET', + responseType: 'arraybuffer', + cache: false + }).then(function(response) { + var installation = response.data; + $scope.installation = installation; + } + ); + } else { + $http.get(url).then(function (response) { + var installation = response.data; + if ($scope.configFormat.mediaType == 'application/json') { + installation = angular.fromJson(response.data); + installation = angular.toJson(installation, true); + } + $scope.installation = installation; + }); + } + + }; + $scope.download = function() { + saveAs(new Blob([$scope.installation], { type: $scope.configFormat.mediaType }), $scope.configFormat.filename); + } +}); + + +module.controller('ClientDetailCtrl', function($scope, realm, client, flows, $route, serverInfo, Client, ClientDescriptionConverter, Components, ClientStorageOperations, $location, $modal, Dialog, Notifications, TimeUnit2) { + $scope.serverInfo = serverInfo; + $scope.flows = []; + $scope.clientFlows = []; + var emptyFlow = { + id: "", + alias: "" + } + for (var i=0 ; i<flows.length ; i++) { + if (flows[i].providerId == 'client-flow') { + $scope.clientFlows.push(flows[i]); + } else { + $scope.flows.push(flows[i]); + } + } + $scope.flows.push(emptyFlow) + $scope.clientFlows.push(emptyFlow) + + + + $scope.accessTypes = [ + "confidential", + "public", + "bearer-only" + ]; + + $scope.protocols = serverInfo.listProviderIds('login-protocol'); + + $scope.signatureAlgorithms = [ + "RSA_SHA1", + "RSA_SHA256", + "RSA_SHA512", + "DSA_SHA1" + ]; + $scope.nameIdFormats = [ + "username", + "email", + "transient", + "persistent" + ]; + $scope.xmlKeyNameTranformers = [ + "NONE", + "KEY_ID", + "CERT_SUBJECT" + ]; + + $scope.canonicalization = [ + {name: "EXCLUSIVE", value: "http://www.w3.org/2001/10/xml-exc-c14n#" }, + {name: "EXCLUSIVE_WITH_COMMENTS", value: "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"}, + {name: "INCLUSIVE", value: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" }, + {name: "INCLUSIVE_WITH_COMMENTS", value: "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"} + ]; + + $scope.requestObjectRequiredOptions = [ + "not required", + "request or request_uri", + "request only", + "request_uri only" + ]; + + $scope.changePkceCodeChallengeMethodOptions = [ + "S256", + "plain", + "" + ]; + + $scope.realm = realm; + $scope.samlAuthnStatement = false; + $scope.samlOneTimeUseCondition = false; + $scope.samlMultiValuedRoles = false; + $scope.samlServerSignature = false; + $scope.samlServerSignatureEnableKeyInfoExtension = false; + $scope.samlAssertionSignature = false; + $scope.samlClientSignature = false; + $scope.samlEncrypt = false; + $scope.samlForcePostBinding = false; + $scope.samlForceNameIdFormat = false; + $scope.samlXmlKeyNameTranformer = $scope.xmlKeyNameTranformers[1]; + $scope.disableAuthorizationTab = !client.authorizationServicesEnabled; + $scope.disableServiceAccountRolesTab = !client.serviceAccountsEnabled; + $scope.disableCredentialsTab = client.publicClient; + // KEYCLOAK-6771 Certificate Bound Token + // https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3 + $scope.tlsClientCertificateBoundAccessTokens = false; + + $scope.accessTokenLifespan = TimeUnit2.asUnit(client.attributes['access.token.lifespan']); + $scope.samlAssertionLifespan = TimeUnit2.asUnit(client.attributes['saml.assertion.lifespan']); + $scope.clientSessionIdleTimeout = TimeUnit2.asUnit(client.attributes['client.session.idle.timeout']); + $scope.clientSessionMaxLifespan = TimeUnit2.asUnit(client.attributes['client.session.max.lifespan']); + + if(client.origin) { + if ($scope.access.viewRealm) { + Components.get({realm: realm.realm, componentId: client.origin}, function (link) { + $scope.originName = link.name; + //$scope.originLink = "#/realms/" + realm.realm + "/user-storage/providers/" + link.providerId + "/" + link.id; + }) + } + else { + // KEYCLOAK-4328 + ClientStorageOperations.simpleName.get({realm: realm.realm, componentId: client.origin}, function (link) { + $scope.originName = link.name; + //$scope.originLink = $location.absUrl(); + }) + } + } else { + console.log("origin is null"); + } + + + function updateProperties() { + if (!$scope.client.attributes) { + $scope.client.attributes = {}; + } + $scope.accessType = $scope.accessTypes[0]; + if ($scope.client.bearerOnly) { + $scope.accessType = $scope.accessTypes[2]; + } else if ($scope.client.publicClient) { + $scope.accessType = $scope.accessTypes[1]; + } + if ($scope.client.protocol) { + $scope.protocol = $scope.protocols[$scope.protocols.indexOf($scope.client.protocol)]; + } else { + $scope.protocol = $scope.protocols[0]; + } + if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA1') { + $scope.signatureAlgorithm = $scope.signatureAlgorithms[0]; + } else if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA256') { + $scope.signatureAlgorithm = $scope.signatureAlgorithms[1]; + } else if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA512') { + $scope.signatureAlgorithm = $scope.signatureAlgorithms[2]; + } else if ($scope.client.attributes['saml.signature.algorithm'] == 'DSA_SHA1') { + $scope.signatureAlgorithm = $scope.signatureAlgorithms[3]; + } + if ($scope.client.attributes['saml_name_id_format'] == 'username') { + $scope.nameIdFormat = $scope.nameIdFormats[0]; + } else if ($scope.client.attributes['saml_name_id_format'] == 'email') { + $scope.nameIdFormat = $scope.nameIdFormats[1]; + } else if ($scope.client.attributes['saml_name_id_format'] == 'transient') { + $scope.nameIdFormat = $scope.nameIdFormats[2]; + } else if ($scope.client.attributes['saml_name_id_format'] == 'persistent') { + $scope.nameIdFormat = $scope.nameIdFormats[3]; + } + if ($scope.client.attributes["saml.server.signature"]) { + if ($scope.client.attributes["saml.server.signature"] == "true") { + $scope.samlServerSignature = true; + } else { + $scope.samlServerSignature = false; + + } + } + if ($scope.client.attributes["saml.server.signature.keyinfo.ext"]) { + if ($scope.client.attributes["saml.server.signature.keyinfo.ext"] == "true") { + $scope.samlServerSignatureEnableKeyInfoExtension = true; + } else { + $scope.samlServerSignatureEnableKeyInfoExtension = false; + } + } + if ($scope.client.attributes['saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer'] === 'NONE') { + $scope.samlXmlKeyNameTranformer = $scope.xmlKeyNameTranformers[0]; + } else if ($scope.client.attributes['saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer'] === 'KEY_ID') { + $scope.samlXmlKeyNameTranformer = $scope.xmlKeyNameTranformers[1]; + } else if ($scope.client.attributes['saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer'] === 'CERT_SUBJECT') { + $scope.samlXmlKeyNameTranformer = $scope.xmlKeyNameTranformers[2]; + } + if ($scope.client.attributes["saml.assertion.signature"]) { + if ($scope.client.attributes["saml.assertion.signature"] == "true") { + $scope.samlAssertionSignature = true; + } else { + $scope.samlAssertionSignature = false; + } + } + if ($scope.client.attributes["saml.client.signature"]) { + if ($scope.client.attributes["saml.client.signature"] == "true") { + $scope.samlClientSignature = true; + } else { + $scope.samlClientSignature = false; + } + } + if ($scope.client.attributes["saml.encrypt"]) { + if ($scope.client.attributes["saml.encrypt"] == "true") { + $scope.samlEncrypt = true; + } else { + $scope.samlEncrypt = false; + } + } + if ($scope.client.attributes["saml.authnstatement"]) { + if ($scope.client.attributes["saml.authnstatement"] == "true") { + $scope.samlAuthnStatement = true; + } else { + $scope.samlAuthnStatement = false; + } + } + if ($scope.client.attributes["saml.onetimeuse.condition"]) { + if ($scope.client.attributes["saml.onetimeuse.condition"] == "true") { + $scope.samlOneTimeUseCondition = true; + } else { + $scope.samlOneTimeUseCondition = false; + } + } + if ($scope.client.attributes["saml_force_name_id_format"]) { + if ($scope.client.attributes["saml_force_name_id_format"] == "true") { + $scope.samlForceNameIdFormat = true; + } else { + $scope.samlForceNameIdFormat = false; + } + } + if ($scope.client.attributes["saml.multivalued.roles"]) { + if ($scope.client.attributes["saml.multivalued.roles"] == "true") { + $scope.samlMultiValuedRoles = true; + } else { + $scope.samlMultiValuedRoles = false; + } + } + if ($scope.client.attributes["saml.force.post.binding"]) { + if ($scope.client.attributes["saml.force.post.binding"] == "true") { + $scope.samlForcePostBinding = true; + } else { + $scope.samlForcePostBinding = false; + } + } + + $scope.accessTokenSignedResponseAlg = $scope.client.attributes['access.token.signed.response.alg']; + $scope.idTokenSignedResponseAlg = $scope.client.attributes['id.token.signed.response.alg']; + $scope.idTokenEncryptedResponseAlg = $scope.client.attributes['id.token.encrypted.response.alg']; + $scope.idTokenEncryptedResponseEnc = $scope.client.attributes['id.token.encrypted.response.enc']; + + var attrVal1 = $scope.client.attributes['user.info.response.signature.alg']; + $scope.userInfoSignedResponseAlg = attrVal1==null ? 'unsigned' : attrVal1; + + var attrVal2 = $scope.client.attributes['request.object.signature.alg']; + $scope.requestObjectSignatureAlg = attrVal2==null ? 'any' : attrVal2; + + var attrVal3 = $scope.client.attributes['request.object.required']; + $scope.requestObjectRequired = attrVal3==null ? 'not required' : attrVal3; + + var attrVal4 = $scope.client.attributes['pkce.code.challenge.method']; + $scope.pkceCodeChallengeMethod = attrVal4==null ? 'none' : attrVal4; + + if ($scope.client.attributes["exclude.session.state.from.auth.response"]) { + if ($scope.client.attributes["exclude.session.state.from.auth.response"] == "true") { + $scope.excludeSessionStateFromAuthResponse = true; + } else { + $scope.excludeSessionStateFromAuthResponse = false; + } + } + + // KEYCLOAK-6771 Certificate Bound Token + // https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3 + if ($scope.client.attributes["tls.client.certificate.bound.access.tokens"]) { + if ($scope.client.attributes["tls.client.certificate.bound.access.tokens"] == "true") { + $scope.tlsClientCertificateBoundAccessTokens = true; + } else { + $scope.tlsClientCertificateBoundAccessTokens = false; + } + } + + if ($scope.client.attributes["display.on.consent.screen"]) { + if ($scope.client.attributes["display.on.consent.screen"] == "true") { + $scope.displayOnConsentScreen = true; + } else { + $scope.displayOnConsentScreen = false; + } + } + } + + if (!$scope.create) { + $scope.client = client; + updateProperties(); + + $scope.clientEdit = angular.copy(client); + } + + + $scope.samlIdpInitiatedUrl = function(ssoName) { + return encodeURI($location.absUrl().replace(/\/admin.*/, "/realms/") + realm.realm + "/protocol/saml/clients/") + encodeURIComponent(ssoName) + } + + $scope.importFile = function(fileContent){ + console.debug(fileContent); + ClientDescriptionConverter.save({ + realm: realm.realm + }, fileContent, function (data) { + $scope.client = data; + updateProperties(); + $scope.importing = true; + + $scope.clientEdit = angular.copy(client); + }); + }; + + $scope.viewImportDetails = function() { + $modal.open({ + templateUrl: resourceUrl + '/partials/modal/view-object.html', + controller: 'ObjectModalCtrl', + resolve: { + object: function () { + return $scope.client; + } + } + }) + }; + + $scope.switchChange = function() { + $scope.changed = true; + } + + $scope.changeAccessType = function() { + if ($scope.accessType == "confidential") { + $scope.clientEdit.bearerOnly = false; + $scope.clientEdit.publicClient = false; + } else if ($scope.accessType == "public") { + $scope.clientEdit.bearerOnly = false; + $scope.clientEdit.publicClient = true; + } else if ($scope.accessType == "bearer-only") { + $scope.clientEdit.bearerOnly = true; + $scope.clientEdit.publicClient = false; + $scope.clientEdit.alwaysDisplayInConsole = false; + } + }; + + $scope.changeProtocol = function() { + if ($scope.protocol == "openid-connect") { + $scope.clientEdit.protocol = "openid-connect"; + } else if ($scope.protocol == "saml") { + $scope.clientEdit.protocol = "saml"; + } + }; + + $scope.changeAlgorithm = function() { + $scope.clientEdit.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; + }; + + $scope.changeNameIdFormat = function() { + $scope.clientEdit.attributes['saml_name_id_format'] = $scope.nameIdFormat; + }; + + $scope.changeSamlSigKeyNameTranformer = function() { + $scope.clientEdit.attributes['saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer'] = $scope.samlXmlKeyNameTranformer; + }; + + $scope.changeAccessTokenSignedResponseAlg = function() { + $scope.clientEdit.attributes['access.token.signed.response.alg'] = $scope.accessTokenSignedResponseAlg; + }; + + $scope.changeIdTokenSignedResponseAlg = function() { + $scope.clientEdit.attributes['id.token.signed.response.alg'] = $scope.idTokenSignedResponseAlg; + }; + + $scope.changeIdTokenEncryptedResponseAlg = function() { + $scope.clientEdit.attributes['id.token.encrypted.response.alg'] = $scope.idTokenEncryptedResponseAlg; + }; + + $scope.changeIdTokenEncryptedResponseEnc = function() { + $scope.clientEdit.attributes['id.token.encrypted.response.enc'] = $scope.idTokenEncryptedResponseEnc; + }; + + $scope.changeUserInfoSignedResponseAlg = function() { + if ($scope.userInfoSignedResponseAlg === 'unsigned') { + $scope.clientEdit.attributes['user.info.response.signature.alg'] = null; + } else { + $scope.clientEdit.attributes['user.info.response.signature.alg'] = $scope.userInfoSignedResponseAlg; + } + }; + + $scope.changeRequestObjectSignatureAlg = function() { + if ($scope.requestObjectSignatureAlg === 'any') { + $scope.clientEdit.attributes['request.object.signature.alg'] = null; + } else { + $scope.clientEdit.attributes['request.object.signature.alg'] = $scope.requestObjectSignatureAlg; + } + }; + + $scope.changeRequestObjectRequired = function() { + if ($scope.requestObjectRequired === 'not required') { + $scope.clientEdit.attributes['request.object.required'] = null; + } else { + $scope.clientEdit.attributes['request.object.required'] = $scope.requestObjectRequired; + } + }; + + $scope.changePkceCodeChallengeMethod = function() { + $scope.clientEdit.attributes['pkce.code.challenge.method'] = $scope.pkceCodeChallengeMethod; + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + function isChanged() { + if (!angular.equals($scope.client, $scope.clientEdit)) { + return true; + } + if ($scope.newRedirectUri && $scope.newRedirectUri.length > 0) { + return true; + } + if ($scope.newWebOrigin && $scope.newWebOrigin.length > 0) { + return true; + } + return false; + } + + $scope.updateTimeouts = function() { + if ($scope.accessTokenLifespan.time) { + if ($scope.accessTokenLifespan.time === -1) { + $scope.clientEdit.attributes['access.token.lifespan'] = -1; + } else { + $scope.clientEdit.attributes['access.token.lifespan'] = $scope.accessTokenLifespan.toSeconds(); + } + } else { + $scope.clientEdit.attributes['access.token.lifespan'] = null; + } + } + + $scope.updateAssertionLifespan = function() { + if ($scope.samlAssertionLifespan.time) { + $scope.clientEdit.attributes['saml.assertion.lifespan'] = $scope.samlAssertionLifespan.toSeconds(); + } else { + $scope.clientEdit.attributes['saml.assertion.lifespan'] = null; + } + } + + $scope.updateClientSessionIdleTimeout = function() { + if ($scope.clientSessionIdleTimeout.time) { + $scope.clientEdit.attributes['client.session.idle.timeout'] = $scope.clientSessionIdleTimeout.toSeconds(); + } else { + $scope.clientEdit.attributes['client.session.idle.timeout'] = null; + } + } + + $scope.updateClientSessionMaxLifespan = function() { + if ($scope.clientSessionMaxLifespan.time) { + $scope.clientEdit.attributes['client.session.max.lifespan'] = $scope.clientSessionMaxLifespan.toSeconds(); + } else { + $scope.clientEdit.attributes['client.session.max.lifespan'] = null; + } + } + + function configureAuthorizationServices() { + if ($scope.clientEdit.authorizationServicesEnabled) { + if ($scope.accessType == 'public') { + $scope.accessType = 'confidential'; + } + $scope.clientEdit.publicClient = false; + $scope.clientEdit.serviceAccountsEnabled = true; + } else if ($scope.clientEdit.bearerOnly) { + $scope.clientEdit.serviceAccountsEnabled = false; + } + if ($scope.client.authorizationServicesEnabled && !$scope.clientEdit.authorizationServicesEnabled) { + Dialog.confirm("Disable Authorization Settings", "Are you sure you want to disable authorization ? Once you save your changes, all authorization settings associated with this client will be removed. This operation can not be reverted.", function () { + }, function () { + $scope.clientEdit.authorizationServicesEnabled = true; + }); + } + } + + $scope.$watch('clientEdit', function() { + $scope.changed = isChanged(); + configureAuthorizationServices(); + }, true); + + $scope.$watch('newRedirectUri', function() { + $scope.changed = isChanged(); + }, true); + + + $scope.$watch('newWebOrigin', function() { + $scope.changed = isChanged(); + }, true); + + $scope.deleteWebOrigin = function(index) { + $scope.clientEdit.webOrigins.splice(index, 1); + } + $scope.addWebOrigin = function() { + $scope.clientEdit.webOrigins.push($scope.newWebOrigin); + $scope.newWebOrigin = ""; + } + $scope.deleteRedirectUri = function(index) { + $scope.clientEdit.redirectUris.splice(index, 1); + } + + $scope.addRedirectUri = function() { + $scope.clientEdit.redirectUris.push($scope.newRedirectUri); + $scope.newRedirectUri = ""; + } + + $scope.save = function() { + if ($scope.newRedirectUri && $scope.newRedirectUri.length > 0) { + $scope.addRedirectUri(); + } + + if ($scope.newWebOrigin && $scope.newWebOrigin.length > 0) { + $scope.addWebOrigin(); + } + + if ($scope.samlServerSignature == true) { + $scope.clientEdit.attributes["saml.server.signature"] = "true"; + } else { + $scope.clientEdit.attributes["saml.server.signature"] = "false"; + } + if ($scope.samlServerSignatureEnableKeyInfoExtension == true) { + $scope.clientEdit.attributes["saml.server.signature.keyinfo.ext"] = "true"; + } else { + $scope.clientEdit.attributes["saml.server.signature.keyinfo.ext"] = "false"; + } + if ($scope.samlAssertionSignature == true) { + $scope.clientEdit.attributes["saml.assertion.signature"] = "true"; + } else { + $scope.clientEdit.attributes["saml.assertion.signature"] = "false"; + } + if ($scope.samlClientSignature == true) { + $scope.clientEdit.attributes["saml.client.signature"] = "true"; + } else { + $scope.clientEdit.attributes["saml.client.signature"] = "false"; + + } + if ($scope.samlEncrypt == true) { + $scope.clientEdit.attributes["saml.encrypt"] = "true"; + } else { + $scope.clientEdit.attributes["saml.encrypt"] = "false"; + + } + if ($scope.samlAuthnStatement == true) { + $scope.clientEdit.attributes["saml.authnstatement"] = "true"; + } else { + $scope.clientEdit.attributes["saml.authnstatement"] = "false"; + + } + if ($scope.samlOneTimeUseCondition == true) { + $scope.clientEdit.attributes["saml.onetimeuse.condition"] = "true"; + } else { + $scope.clientEdit.attributes["saml.onetimeuse.condition"] = "false"; + + } + if ($scope.samlForceNameIdFormat == true) { + $scope.clientEdit.attributes["saml_force_name_id_format"] = "true"; + } else { + $scope.clientEdit.attributes["saml_force_name_id_format"] = "false"; + + } + if ($scope.samlMultiValuedRoles == true) { + $scope.clientEdit.attributes["saml.multivalued.roles"] = "true"; + } else { + $scope.clientEdit.attributes["saml.multivalued.roles"] = "false"; + + } + if ($scope.samlForcePostBinding == true) { + $scope.clientEdit.attributes["saml.force.post.binding"] = "true"; + } else { + $scope.clientEdit.attributes["saml.force.post.binding"] = "false"; + + } + + if ($scope.excludeSessionStateFromAuthResponse == true) { + $scope.clientEdit.attributes["exclude.session.state.from.auth.response"] = "true"; + } else { + $scope.clientEdit.attributes["exclude.session.state.from.auth.response"] = "false"; + + } + + // KEYCLOAK-6771 Certificate Bound Token + // https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3 + if ($scope.tlsClientCertificateBoundAccessTokens == true) { + $scope.clientEdit.attributes["tls.client.certificate.bound.access.tokens"] = "true"; + } else { + $scope.clientEdit.attributes["tls.client.certificate.bound.access.tokens"] = "false"; + } + + if ($scope.displayOnConsentScreen == true) { + $scope.clientEdit.attributes["display.on.consent.screen"] = "true"; + } else { + $scope.clientEdit.attributes["display.on.consent.screen"] = "false"; + } + + $scope.clientEdit.protocol = $scope.protocol; + $scope.clientEdit.attributes['saml.signature.algorithm'] = $scope.signatureAlgorithm; + $scope.clientEdit.attributes['saml_name_id_format'] = $scope.nameIdFormat; + + if ($scope.clientEdit.protocol != 'saml' && !$scope.clientEdit.bearerOnly && ($scope.clientEdit.standardFlowEnabled || $scope.clientEdit.implicitFlowEnabled) && (!$scope.clientEdit.redirectUris || $scope.clientEdit.redirectUris.length == 0)) { + Notifications.error("You must specify at least one redirect uri"); + } else { + Client.update({ + realm : realm.realm, + client : client.id + }, $scope.clientEdit, function() { + $route.reload(); + Notifications.success("Your changes have been saved to the client."); + }); + } + }; + + $scope.reset = function() { + $route.reload(); + }; + + $scope.cancel = function() { + $location.url("/realms/" + realm.realm + "/clients"); + }; +}); + +module.controller('CreateClientCtrl', function($scope, realm, client, $route, serverInfo, Client, ClientDescriptionConverter, $location, $modal, Dialog, Notifications) { + $scope.protocols = serverInfo.listProviderIds('login-protocol'); + $scope.create = true; + + $scope.realm = realm; + + $scope.client = { + enabled: true, + attributes: {} + }; + $scope.client.redirectUris = []; + $scope.protocol = $scope.protocols[0]; + + + $scope.importFile = function(fileContent){ + console.debug(fileContent); + ClientDescriptionConverter.save({ + realm: realm.realm + }, fileContent, function (data) { + $scope.client = data; + if (data.protocol) { + $scope.protocol = data.protocol; + } + $scope.importing = true; + }); + }; + + $scope.viewImportDetails = function() { + $modal.open({ + templateUrl: resourceUrl + '/partials/modal/view-object.html', + controller: 'ObjectModalCtrl', + resolve: { + object: function () { + return $scope.client; + } + } + }) + }; + + $scope.switchChange = function() { + $scope.changed = true; + } + + $scope.changeProtocol = function() { + if ($scope.protocol == "openid-connect") { + $scope.client.protocol = "openid-connect"; + } else if ($scope.protocol == "saml") { + $scope.client.protocol = "saml"; + } + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + function isChanged() { + if (!angular.equals($scope.client, client)) { + return true; + } + return false; + } + + $scope.$watch('client', function() { + $scope.changed = isChanged(); + }, true); + + + $scope.save = function() { + $scope.client.protocol = $scope.protocol; + + Client.save({ + realm: realm.realm, + client: '' + }, $scope.client, function (data, headers) { + $scope.changed = false; + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + $location.url("/realms/" + realm.realm + "/clients/" + id); + Notifications.success("The client has been created."); + }); + }; + + $scope.reset = function() { + $route.reload(); + }; + + $scope.cancel = function() { + $location.url("/realms/" + realm.realm + "/clients"); + }; +}); + +module.controller('ClientScopeMappingCtrl', function($scope, $http, realm, $route, client, clients, Notifications, + Client, ClientScope, + ClientRealmScopeMapping, ClientClientScopeMapping, ClientRole, + ClientAvailableRealmScopeMapping, ClientAvailableClientScopeMapping, + ClientCompositeRealmScopeMapping, ClientCompositeClientScopeMapping) { + $scope.realm = realm; + $scope.client = angular.copy(client); + $scope.selectedRealmRoles = []; + $scope.selectedRealmMappings = []; + $scope.realmMappings = []; + $scope.clients = clients; + $scope.clientRoles = []; + $scope.clientComposite = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; + $scope.clientMappings = []; + $scope.dummymodel = []; + + $scope.hideRoleSelector = function() { + return $scope.client.fullScopeAllowed; + } + + $scope.changeFlag = function() { + console.log('changeFlag'); + Client.update({ + realm : realm.realm, + client : client.id + }, $scope.client, function() { + $scope.changed = false; + client = angular.copy($scope.client); + updateRealmRoles(); + Notifications.success("Scope mappings updated."); + }); + } + + + $scope.selectedClient = null; + + $scope.selectClient = function(client) { + if (!client || !client.id) { + $scope.selectedClient = null; + return; + } + + $scope.selectedClient = client; + updateClientRoles(); + } + + function updateRealmRoles() { + $scope.realmRoles = ClientAvailableRealmScopeMapping.query({realm : realm.realm, client : client.id}); + $scope.realmMappings = ClientRealmScopeMapping.query({realm : realm.realm, client : client.id}); + $scope.realmComposite = ClientCompositeRealmScopeMapping.query({realm : realm.realm, client : client.id}); + } + + function updateClientRoles() { + if ($scope.selectedClient) { + $scope.clientRoles = ClientAvailableClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.selectedClient.id}); + $scope.clientMappings = ClientClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.selectedClient.id}); + $scope.clientComposite = ClientCompositeClientScopeMapping.query({realm : realm.realm, client : client.id, targetClient : $scope.selectedClient.id}); + } else { + $scope.clientRoles = null; + $scope.clientMappings = null; + $scope.clientComposite = null; + } + } + + $scope.addRealmRole = function() { + $scope.selectedRealmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']'); + $scope.selectedRealmRoles = []; + $http.post(authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/scope-mappings/realm', + $scope.selectedRealmRolesToAdd).then(function() { + updateRealmRoles(); + $scope.selectedRealmRolesToAdd = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.deleteRealmRole = function() { + $scope.selectedRealmMappingsToRemove = JSON.parse('[' + $scope.selectedRealmMappings + ']'); + $scope.selectedRealmMappings = []; + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/scope-mappings/realm', + {data : $scope.selectedRealmMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function () { + updateRealmRoles(); + $scope.selectedRealmMappingsToRemove = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.addClientRole = function() { + $scope.selectedClientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']'); + $scope.selectedClientRoles = []; + $http.post(authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/scope-mappings/clients/' + $scope.selectedClient.id, + $scope.selectedClientRolesToAdd).then(function () { + updateClientRoles(); + $scope.selectedClientRolesToAdd = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.deleteClientRole = function() { + $scope.selectedClientMappingsToRemove = JSON.parse('[' + $scope.selectedClientMappings + ']'); + $scope.selectedClientMappings = []; + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/scope-mappings/clients/' + $scope.selectedClient.id, + {data : $scope.selectedClientMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function () { + updateClientRoles(); + $scope.selectedClientMappingsToRemove = []; + Notifications.success("Scope mappings updated."); + }); + }; + + clientSelectControl($scope, $route.current.params.realm, Client); + updateRealmRoles(); +}); + +module.controller('ClientRevocationCtrl', function($scope, realm, client, Client, ClientPushRevocation, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.client = client; + + var setNotBefore = function() { + if ($scope.client.notBefore == 0) { + $scope.notBefore = "None"; + } else { + $scope.notBefore = new Date($scope.client.notBefore * 1000); + } + }; + + setNotBefore(); + + var refresh = function() { + Client.get({ realm : realm.realm, client: $scope.client.id }, function(updated) { + $scope.client = updated; + setNotBefore(); + }) + + }; + + $scope.clear = function() { + $scope.client.notBefore = 0; + Client.update({ realm : realm.realm, client: client.id}, $scope.client, function () { + $scope.notBefore = "None"; + Notifications.success('Not Before cleared for client.'); + refresh(); + }); + } + $scope.setNotBeforeNow = function() { + $scope.client.notBefore = new Date().getTime()/1000; + Client.update({ realm : realm.realm, client: $scope.client.id}, $scope.client, function () { + Notifications.success('Not Before set for client.'); + refresh(); + }); + } + $scope.pushRevocation = function() { + ClientPushRevocation.save({realm : realm.realm, client: $scope.client.id}, function (globalReqResult) { + var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0; + var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0; + + if (successCount==0 && failedCount==0) { + Notifications.warn('No push sent. No admin URI configured or no registered cluster nodes available'); + } else if (failedCount > 0) { + var msgStart = successCount>0 ? 'Successfully push notBefore to: ' + globalReqResult.successRequests + ' . ' : ''; + Notifications.error(msgStart + 'Failed to push notBefore to: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again'); + } else { + Notifications.success('Successfully push notBefore to: ' + globalReqResult.successRequests); + } + }); + } + +}); + +module.controller('ClientClusteringCtrl', function($scope, client, Client, ClientTestNodesAvailable, ClientClusterNode, realm, $location, $route, Dialog, Notifications, TimeUnit) { + $scope.client = client; + $scope.realm = realm; + + var oldCopy = angular.copy($scope.client); + $scope.changed = false; + + $scope.$watch('client', function() { + if (!angular.equals($scope.client, oldCopy)) { + $scope.changed = true; + } + }, true); + + $scope.client.nodeReRegistrationTimeoutUnit = TimeUnit.autoUnit(client.nodeReRegistrationTimeout); + $scope.client.nodeReRegistrationTimeout = TimeUnit.toUnit(client.nodeReRegistrationTimeout, $scope.client.nodeReRegistrationTimeoutUnit); + + $scope.save = function() { + var clientCopy = angular.copy($scope.client); + delete clientCopy['nodeReRegistrationTimeoutUnit']; + clientCopy.nodeReRegistrationTimeout = TimeUnit.toSeconds($scope.client.nodeReRegistrationTimeout, $scope.client.nodeReRegistrationTimeoutUnit) + Client.update({ realm : realm.realm, client : client.id }, clientCopy, function () { + $route.reload(); + Notifications.success('Your changes have been saved to the client.'); + }); + }; + + $scope.reset = function() { + $route.reload(); + }; + + $scope.testNodesAvailable = function() { + ClientTestNodesAvailable.get({ realm : realm.realm, client : client.id }, function(globalReqResult) { + $route.reload(); + + var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0; + var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0; + + if (successCount==0 && failedCount==0) { + Notifications.warn('No requests sent. No admin URI configured or no registered cluster nodes available'); + } else if (failedCount > 0) { + var msgStart = successCount>0 ? 'Successfully verify availability for ' + globalReqResult.successRequests + ' . ' : ''; + Notifications.error(msgStart + 'Failed to verify availability for: ' + globalReqResult.failedRequests + '. Fix or unregister failed cluster nodes and try again'); + } else { + Notifications.success('Successfully sent requests to: ' + globalReqResult.successRequests); + } + }); + }; + + if (client.registeredNodes) { + var nodeRegistrations = []; + for (node in client.registeredNodes) { + reg = { + host: node, + lastRegistration: new Date(client.registeredNodes[node] * 1000) + } + nodeRegistrations.push(reg); + } + + $scope.nodeRegistrations = nodeRegistrations; + }; + + $scope.removeNode = function(node) { + Dialog.confirmDelete(node.host, 'node', function() { + ClientClusterNode.remove({ realm : realm.realm, client : client.id , node: node.host }, function() { + Notifications.success('Node ' + node.host + ' unregistered successfully.'); + $route.reload(); + }); + }); + }; +}); + +module.controller('ClientClusteringNodeCtrl', function($scope, client, Client, ClientClusterNode, realm, + $location, $routeParams, Notifications, Dialog) { + $scope.client = client; + $scope.realm = realm; + $scope.create = !$routeParams.node; + + $scope.save = function() { + ClientClusterNode.save({ realm : realm.realm, client : client.id , node: $scope.node.host }, function() { + Notifications.success('Node ' + $scope.node.host + ' registered successfully.'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/clustering'); + }); + } + + $scope.unregisterNode = function() { + Dialog.confirmDelete($scope.node.host, 'node', function() { + ClientClusterNode.remove({ realm : realm.realm, client : client.id , node: $scope.node.host }, function() { + Notifications.success('Node ' + $scope.node.host + ' unregistered successfully.'); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/clustering'); + }); + }); + } + + if ($scope.create) { + $scope.node = {} + $scope.registered = false; + } else { + var lastRegTime = client.registeredNodes[$routeParams.node]; + + if (lastRegTime) { + $scope.registered = true; + $scope.node = { + host: $routeParams.node, + lastRegistration: new Date(lastRegTime * 1000) + } + + } else { + $scope.registered = false; + $scope.node = { + host: $routeParams.node + } + } + } +}); + +module.controller('AddBuiltinProtocolMapperCtrl', function($scope, realm, client, serverInfo, + ClientProtocolMappersByProtocol, + $http, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.client = client; + if (client.protocol == null) { + client.protocol = 'openid-connect'; + } + + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + + + + var updateMappers = function() { + var clientMappers = ClientProtocolMappersByProtocol.query({realm : realm.realm, client : client.id, protocol : client.protocol}, function() { + var builtinMappers = serverInfo.builtinProtocolMappers[client.protocol]; + for (var i = 0; i < clientMappers.length; i++) { + for (var j = 0; j < builtinMappers.length; j++) { + if (builtinMappers[j].name == clientMappers[i].name + && builtinMappers[j].protocolMapper == clientMappers[i].protocolMapper) { + builtinMappers.splice(j, 1); + break; + } + } + } + $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 + '/clients/' + client.id + '/protocol-mappers/add-models', + toAdd).then(function() { + Notifications.success("Mappers added"); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/mappers'); + }).catch(function() { + Notifications.error("Error adding mappers"); + $location.url('/realms/' + realm.realm + '/clients/' + client.id + '/mappers'); + }); + }; + +}); + +module.controller('ClientProtocolMapperListCtrl', function($scope, realm, client, serverInfo, + Client, + ClientProtocolMappersByProtocol, ClientProtocolMapper, + $route, Dialog, Notifications) { + $scope.realm = realm; + $scope.client = client; + if (client.protocol == null) { + client.protocol = 'openid-connect'; + } + + $scope.changeFlag = function() { + Client.update({ + realm : realm.realm, + client : client.id + }, $scope.client, function() { + $scope.changed = false; + client = angular.copy($scope.client); + Notifications.success("Client updated."); + }); + } + + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + $scope.removeMapper = function(mapper) { + console.debug(mapper); + Dialog.confirmDelete(mapper.name, 'mapper', function() { + ClientProtocolMapper.remove({ realm: realm.realm, client: client.id, id : mapper.id }, function() { + Notifications.success("The mapper has been deleted."); + $route.reload(); + }); + }); + }; + + $scope.sortMappersByPriority = function(mapper) { + return $scope.mapperTypes[mapper.protocolMapper].priority; + } + + var updateMappers = function() { + $scope.mappers = ClientProtocolMappersByProtocol.query({realm : realm.realm, client : client.id, protocol : client.protocol}); + }; + + updateMappers(); +}); + +module.controller('ClientProtocolMapperCtrl', function($scope, realm, serverInfo, client, clients, mapper, ClientProtocolMapper, Notifications, Dialog, $location) { + $scope.realm = realm; + $scope.clients = clients; + + /* + $scope.client = client; + $scope.create = false; + $scope.protocol = client.protocol; + $scope.mapper = angular.copy(mapper); + $scope.changed = false; + */ + + if (client.protocol == null) { + client.protocol = 'openid-connect'; + } + + $scope.model = { + realm: realm, + client: client, + create: false, + protocol: client.protocol, + mapper: angular.copy(mapper), + changed: false + }; + + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; + for (var i = 0; i < protocolMappers.length; i++) { + if (protocolMappers[i].id === mapper.protocolMapper) { + $scope.model.mapperType = protocolMappers[i]; + } + } + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.$watch('model.mapper', function() { + if (!angular.equals($scope.model.mapper, mapper)) { + $scope.model.changed = true; + } + }, true); + + $scope.save = function() { + ClientProtocolMapper.update({ + realm : realm.realm, + client: client.id, + id : $scope.model.mapper.id + }, $scope.model.mapper, function() { + $scope.model.changed = false; + mapper = angular.copy($scope.mapper); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers/" + $scope.model.mapper.id); + Notifications.success("Your changes have been saved."); + }); + }; + + $scope.reset = function() { + $scope.model.mapper = angular.copy(mapper); + $scope.model.changed = false; + }; + + $scope.cancel = function() { + //$location.url("/realms"); + window.history.back(); + }; + + $scope.remove = function() { + Dialog.confirmDelete($scope.model.mapper.name, 'mapper', function() { + ClientProtocolMapper.remove({ realm: realm.realm, client: client.id, id : $scope.model.mapper.id }, function() { + Notifications.success("The mapper has been deleted."); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers"); + }); + }); + }; + +}); + +module.controller('ClientProtocolMapperCreateCtrl', function($scope, realm, serverInfo, client, clients, ClientProtocolMapper, Notifications, Dialog, $location) { + $scope.realm = realm; + $scope.clients = clients; + + if (client.protocol == null) { + client.protocol = 'openid-connect'; + } + var protocol = client.protocol; + /* + $scope.client = client; + $scope.create = true; + $scope.protocol = protocol; + $scope.mapper = { protocol : client.protocol, config: {}}; + $scope.mapperTypes = serverInfo.protocolMapperTypes[protocol]; + */ + $scope.model = { + realm: realm, + client: client, + create: true, + protocol: client.protocol, + mapper: { protocol : client.protocol, config: {}}, + changed: false, + mapperTypes: serverInfo.protocolMapperTypes[protocol] + }; + console.log("mapper types: ", $scope.model.mapperTypes); + + // apply default configurations on change for selected protocolmapper type. + $scope.$watch('model.mapperType', function() { + var currentMapperType = $scope.model.mapperType; + var defaultConfig = {}; + + if (currentMapperType && Array.isArray(currentMapperType.properties)) { + for (var i = 0; i < currentMapperType.properties.length; i++) { + var property = currentMapperType.properties[i]; + if (property && property.name && property.defaultValue) { + defaultConfig[property.name] = property.defaultValue; + } + } + } + + $scope.model.mapper.config = defaultConfig; + }, true); + + $scope.model.mapperType = $scope.model.mapperTypes[0]; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.save = function() { + $scope.model.mapper.protocolMapper = $scope.model.mapperType.id; + ClientProtocolMapper.save({ + realm : realm.realm, client: client.id + }, $scope.model.mapper, function(data, headers) { + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + $location.url("/realms/" + realm.realm + '/clients/' + client.id + "/mappers/" + id); + Notifications.success("Mapper has been created."); + }); + }; + + $scope.cancel = function() { + //$location.url("/realms"); + window.history.back(); + }; + + +}); + + +module.controller('ClientClientScopesSetupCtrl', function($scope, realm, Realm, client, clientScopes, serverInfo, + clientDefaultClientScopes, ClientDefaultClientScopes, clientOptionalClientScopes, ClientOptionalClientScopes, $route, Notifications, $location) { + console.log('ClientClientScopesSetupCtrl'); + + $scope.realm = realm; + $scope.client = client; + + $scope.clientDefaultClientScopes = clientDefaultClientScopes; + $scope.clientOptionalClientScopes = clientOptionalClientScopes; + + $scope.availableClientScopes = []; + $scope.selectedDefaultClientScopes = []; + $scope.selectedDefDefaultClientScopes = []; + + $scope.selectedOptionalClientScopes = []; + $scope.selectedDefOptionalClientScopes = []; + + // Populate available client scopes. Available client scopes are neither already assigned to 'default' or 'optional' + for (var i = 0; i < clientScopes.length; i++) { + var clientScope = clientScopes[i]; + var scopeName = clientScopes[i].name; + + var available = true; + if (clientScope.protocol != client.protocol) { + available = false; + } + + for (var j = 0; j < $scope.clientDefaultClientScopes.length; j++) { + if (scopeName === $scope.clientDefaultClientScopes[j].name) { + available = false; + } + } + for (var j = 0; j < $scope.clientOptionalClientScopes.length; j++) { + if (scopeName === $scope.clientOptionalClientScopes[j].name) { + available = false; + } + } + + if (available) { + $scope.availableClientScopes.push(clientScope); + } + } + + $scope.addDefaultClientScope = function () { + $scope.selectedDefaultClientScopesToAdd = JSON.parse('[' + $scope.selectedDefaultClientScopes + ']'); + toAdd = $scope.selectedDefaultClientScopesToAdd.length; + + for (var i = 0; i < $scope.selectedDefaultClientScopesToAdd.length; i++) { + var currentScope = $scope.selectedDefaultClientScopesToAdd[i]; + + ClientDefaultClientScopes.update({ + realm : realm.realm, + client : client.id, + clientScopeId : currentScope.id + }, function () { + toAdd = toAdd - 1; + if (toAdd === 0) { + $route.reload(); + Notifications.success("Default scopes updated."); + } + }); + } + $scope.selectedDefaultClientScopesToAdd = []; + }; + + $scope.deleteDefaultClientScope = function () { + $scope.selectedDefDefaultClientScopesToRemove = JSON.parse('[' + $scope.selectedDefDefaultClientScopes + ']'); + toRemove = $scope.selectedDefDefaultClientScopesToRemove.length; + + for (var i = 0; i < $scope.selectedDefDefaultClientScopesToRemove.length; i++) { + var currentScope = $scope.selectedDefDefaultClientScopesToRemove[i]; + + ClientDefaultClientScopes.remove({ + realm : realm.realm, + client : client.id, + clientScopeId : currentScope.id + }, function () { + toRemove = toRemove - 1; + if (toRemove === 0) { + $route.reload(); + Notifications.success("Default scopes updated."); + } + }); + } + $scope.selectedDefDefaultClientScopesToRemove = []; + }; + + $scope.addOptionalClientScope = function () { + $scope.selectedOptionalClientScopesToAdd = JSON.parse('[' + $scope.selectedOptionalClientScopes + ']'); + toAdd = $scope.selectedOptionalClientScopesToAdd.length; + + for (var i = 0; i < $scope.selectedOptionalClientScopesToAdd.length; i++) { + var currentScope = $scope.selectedOptionalClientScopesToAdd[i]; + + ClientOptionalClientScopes.update({ + realm : realm.realm, + client : client.id, + clientScopeId : currentScope.id + }, function () { + toAdd = toAdd - 1; + if (toAdd === 0) { + $route.reload(); + Notifications.success("Optional scopes updated."); + } + }); + } + }; + + $scope.deleteOptionalClientScope = function () { + $scope.selectedDefOptionalClientScopesToRemove = JSON.parse('[' + $scope.selectedDefOptionalClientScopes + ']'); + toRemove = $scope.selectedDefOptionalClientScopesToRemove.length; + + for (var i = 0; i < $scope.selectedDefOptionalClientScopesToRemove.length; i++) { + var currentScope = $scope.selectedDefOptionalClientScopesToRemove[i]; + + ClientOptionalClientScopes.remove({ + realm : realm.realm, + client : client.id, + clientScopeId : currentScope.id + }, function () { + toRemove = toRemove - 1; + if (toRemove === 0) { + $route.reload(); + Notifications.success("Optional scopes updated."); + } + }); + } + $scope.selectedDefOptionalClientScopesToRemove = []; + }; + +}); + +module.controller('ClientClientScopesEvaluateCtrl', function($scope, Realm, User, ClientEvaluateProtocolMappers, ClientEvaluateGrantedRoles, + ClientEvaluateNotGrantedRoles, ClientEvaluateGenerateExampleToken, realm, client, clients, clientScopes, serverInfo, + ComponentUtils, clientOptionalClientScopes, clientDefaultClientScopes, $route, $routeParams, $http, Notifications, $location, + Client) { + + console.log('ClientClientScopesEvaluateCtrl'); + + var protocolMappers = serverInfo.protocolMapperTypes[client.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + $scope.realm = realm; + $scope.client = client; + $scope.clients = clients; + $scope.userId = null; + + $scope.availableClientScopes = []; + $scope.assignedClientScopes = []; + $scope.selectedClientScopes = []; + $scope.selectedDefClientScopes = []; + $scope.effectiveClientScopes = []; + + // Populate available client scopes. Available client scopes are neither already assigned to 'default' or 'optional' + for (var i = 0; i < clientOptionalClientScopes.length; i++) { + $scope.availableClientScopes.push(clientOptionalClientScopes[i]); + } + + function clearEvalResponse() { + $scope.protocolMappers = null; + $scope.grantedRealmRoles = null; + $scope.notGrantedRealmRoles = null; + $scope.grantedClientRoles = null; + $scope.notGrantedClientRoles = null; + $scope.targetClient = null; + $scope.oidcAccessToken = null; + + $scope.selectedTab = 0; + } + + function updateState() { + // Compute scope parameter + $scope.scopeParam = 'openid'; + for (var i = 0; i < $scope.assignedClientScopes.length; i++) { + var currentScopeParam = $scope.assignedClientScopes[i].name; + $scope.scopeParam = $scope.scopeParam + ' ' + currentScopeParam; + } + + // Compute effective scopes + $scope.effectiveClientScopes = []; + + for (var i = 0; i < clientDefaultClientScopes.length; i++) { + var currentScope = clientDefaultClientScopes[i]; + $scope.effectiveClientScopes.push(currentScope); + } + for (var i = 0; i < $scope.assignedClientScopes.length; i++) { + var currentScope = $scope.assignedClientScopes[i]; + $scope.effectiveClientScopes.push(currentScope); + } + + // Clear the evaluation response + clearEvalResponse(); + } + + updateState(); + + + $scope.addAppliedClientScope = function () { + $scope.selectedClientScopesToAdd = JSON.parse('[' + $scope.selectedClientScopes + ']'); + for (var i = 0; i < $scope.selectedClientScopesToAdd.length; i++) { + var currentScope = $scope.selectedClientScopesToAdd[i]; + + $scope.assignedClientScopes.push(currentScope); + + var index = ComponentUtils.findIndexById($scope.availableClientScopes, currentScope.id); + if (index > -1) { + $scope.availableClientScopes.splice(index, 1); + } + } + + $scope.selectedClientScopes = []; + $scope.selectedClientScopesToAdd = []; + updateState(); + }; + + $scope.deleteAppliedClientScope = function () { + $scope.selectedDefClientScopesToRemove = JSON.parse('[' + $scope.selectedDefClientScopes + ']'); + for (var i = 0; i < $scope.selectedDefClientScopesToRemove.length; i++) { + var currentScope = $scope.selectedDefClientScopesToRemove[i]; + + $scope.availableClientScopes.push(currentScope); + + var index = ComponentUtils.findIndexById($scope.assignedClientScopes, currentScope.id); + if (index > -1) { + $scope.assignedClientScopes.splice(index, 1); + } + } + + $scope.selectedDefClientScopes = []; + $scope.selectedDefClientScopesToRemove = []; + + updateState(); + }; + + $scope.usersUiSelect = { + minimumInputLength: 1, + delay: 500, + allowClear: true, + query: function (query) { + var data = {results: []}; + if ('' == query.term.trim()) { + query.callback(data); + return; + } + User.query({realm: $route.current.params.realm, search: query.term.trim(), max: 20}, function(response) { + data.results = response; + query.callback(data); + }); + }, + formatResult: function(object, container, query) { + object.text = object.username; + return object.username; + } + }; + + $scope.selectedUser = null; + + $scope.selectUser = function(user) { + clearEvalResponse(); + + if (!user || !user.id) { + $scope.selectedUser = null; + $scope.userId = ''; + return; + } + + $scope.userId = user.id; + } + + clientSelectControl($scope, $route.current.params.realm, Client); + + $scope.selectedClient = null; + + $scope.selectClient = function(client) { + console.log("selected client: ", client); + if (!client || !client.id) { + $scope.selectedClient = null; + return; + } + + $scope.selectedClient = client; + updateScopeClientRoles(); + } + + + $scope.sendEvaluationRequest = function () { + + // Send request for retrieve protocolMappers + $scope.protocolMappers = ClientEvaluateProtocolMappers.query({ + realm: realm.realm, + client: client.id, + scopeParam: $scope.scopeParam + }); + + // Send request for retrieve realmRoles + updateScopeRealmRoles(); + + // Send request for retrieve accessToken (in case user was selected) + if (client.protocol === 'openid-connect' && $scope.userId != null && $scope.userId !== '') { + var url = ClientEvaluateGenerateExampleToken.url({ + realm: realm.realm, + client: client.id, + userId: $scope.userId, + scopeParam: $scope.scopeParam + }); + + $http.get(url).then(function (response) { + if (response.data) { + var oidcAccessToken = angular.fromJson(response.data); + oidcAccessToken = angular.toJson(oidcAccessToken, true); + $scope.oidcAccessToken = oidcAccessToken; + } else { + $scope.oidcAccessToken = null; + } + }); + } + + $scope.showTab(1); + }; + + + $scope.isResponseAvailable = function () { + return $scope.protocolMappers != null; + } + + $scope.isTokenAvailable = function () { + return $scope.oidcAccessToken != null; + } + + $scope.showTab = function (tab) { + $scope.selectedTab = tab; + + // Check if there is more clever way to do it... :/ + if (tab === 1) { + $scope.tabCss = { tab1: 'active', tab2: '', tab3: '' } + } else if (tab === 2) { + $scope.tabCss = { tab1: '', tab2: 'active', tab3: '' } + } else if (tab === 3) { + $scope.tabCss = { tab1: '', tab2: '', tab3: 'active' } + } + } + + $scope.protocolMappersShown = function () { + return $scope.selectedTab === 1; + } + + $scope.rolesShown = function () { + return $scope.selectedTab === 2; + } + + $scope.tokenShown = function () { + return $scope.selectedTab === 3; + } + + $scope.sortMappersByPriority = function(mapper) { + return $scope.mapperTypes[mapper.protocolMapper].priority; + } + + + // Roles + + function updateScopeRealmRoles() { + $scope.grantedRealmRoles = ClientEvaluateGrantedRoles.query({ + realm: realm.realm, + client: client.id, + roleContainer: realm.realm, + scopeParam: $scope.scopeParam + }); + $scope.notGrantedRealmRoles = ClientEvaluateNotGrantedRoles.query({ + realm: realm.realm, + client: client.id, + roleContainer: realm.realm, + scopeParam: $scope.scopeParam + }); + } + + function updateScopeClientRoles() { + if ($scope.selectedClient) { + $scope.grantedClientRoles = ClientEvaluateGrantedRoles.query({ + realm: realm.realm, + client: client.id, + roleContainer: $scope.selectedClient.id, + scopeParam: $scope.scopeParam + }); + $scope.notGrantedClientRoles = ClientEvaluateNotGrantedRoles.query({ + realm: realm.realm, + client: client.id, + roleContainer: $scope.selectedClient.id, + scopeParam: $scope.scopeParam + }); + } else { + $scope.grantedClientRoles = null; + $scope.notGrantedClientRoles = null; + } + } +}); + + +module.controller('ClientScopeTabCtrl', function(Dialog, $scope, Current, Notifications, $location) { + $scope.removeClientScope = function() { + Dialog.confirmDelete($scope.clientScope.name, 'client scope', function() { + $scope.clientScope.$remove({ + realm : Current.realm.realm, + clientScope : $scope.clientScope.id + }, function() { + $location.url("/realms/" + Current.realm.realm + "/client-scopes"); + Notifications.success("The client scope has been deleted."); + }); + }); + }; +}); + + + +module.controller('ClientScopeListCtrl', function($scope, realm, clientScopes, ClientScope, serverInfo, $route, Dialog, Notifications, $location) { + $scope.realm = realm; + $scope.clientScopes = clientScopes; + + $scope.removeClientScope = function(clientScope) { + Dialog.confirmDelete(clientScope.name, 'client scope', function() { + ClientScope.remove({ + realm : realm.realm, + clientScope : clientScope.id + }, function() { + $route.reload(); + Notifications.success("The client scope been deleted."); + }); + }); + }; +}); + +module.controller('ClientScopesRealmDefaultCtrl', function($scope, realm, Realm, clientScopes, realmDefaultClientScopes, RealmDefaultClientScopes, + realmOptionalClientScopes, RealmOptionalClientScopes, serverInfo, $route, Dialog, Notifications, $location) { + + console.log('ClientScopesRealmDefaultCtrl'); + + $scope.realm = realm; + $scope.realmDefaultClientScopes = realmDefaultClientScopes; + $scope.realmOptionalClientScopes = realmOptionalClientScopes; + + $scope.availableClientScopes = []; + $scope.selectedDefaultClientScopes = []; + $scope.selectedDefDefaultClientScopes = []; + + $scope.selectedOptionalClientScopes = []; + $scope.selectedDefOptionalClientScopes = []; + + // Populate available client scopes. Available client scopes are neither already assigned to 'default' or 'optional' + for (var i = 0; i < clientScopes.length; i++) { + var scopeName = clientScopes[i].name; + + var available = true; + for (var j = 0; j < $scope.realmDefaultClientScopes.length; j++) { + if (scopeName === $scope.realmDefaultClientScopes[j].name) { + available = false; + } + } + for (var j = 0; j < $scope.realmOptionalClientScopes.length; j++) { + if (scopeName === $scope.realmOptionalClientScopes[j].name) { + available = false; + } + } + + if (available) { + $scope.availableClientScopes.push(clientScopes[i]); + } + } + + $scope.addDefaultClientScope = function () { + $scope.selectedDefaultClientScopesToAdd = JSON.parse('[' + $scope.selectedDefaultClientScopes + ']'); + toAdd = $scope.selectedDefaultClientScopesToAdd.length; + + for (var i = 0; i < $scope.selectedDefaultClientScopesToAdd.length; i++) { + var currentScope = $scope.selectedDefaultClientScopesToAdd[i]; + + RealmDefaultClientScopes.update({ + realm : realm.realm, + clientScopeId : currentScope.id + }, function () { + toAdd = toAdd - 1; + console.log('toAdd: ' + toAdd); + if (toAdd === 0) { + $route.reload(); + Notifications.success("Realm default scopes updated."); + } + }); + } + $scope.selectedDefaultClientScopesToAdd = []; + }; + + $scope.deleteDefaultClientScope = function () { + $scope.selectedDefDefaultClientScopesToRemove = JSON.parse('[' + $scope.selectedDefDefaultClientScopes + ']'); + toRemove = $scope.selectedDefDefaultClientScopesToRemove.length; + + for (var i = 0; i < $scope.selectedDefDefaultClientScopesToRemove.length; i++) { + var currentScope = $scope.selectedDefDefaultClientScopesToRemove[i]; + + RealmDefaultClientScopes.remove({ + realm : realm.realm, + clientScopeId : currentScope.id + }, function () { + toRemove = toRemove - 1; + if (toRemove === 0) { + $route.reload(); + Notifications.success("Realm default scopes updated."); + } + }); + } + $scope.selectedDefDefaultClientScopesToRemove = []; + }; + + $scope.addOptionalClientScope = function () { + $scope.selectedOptionalClientScopesToAdd = JSON.parse('[' + $scope.selectedOptionalClientScopes + ']'); + toAdd = $scope.selectedOptionalClientScopesToAdd.length; + + for (var i = 0; i < $scope.selectedOptionalClientScopesToAdd.length; i++) { + var currentScope = $scope.selectedOptionalClientScopesToAdd[i]; + + RealmOptionalClientScopes.update({ + realm : realm.realm, + clientScopeId : currentScope.id + }, function () { + toAdd = toAdd - 1; + console.log('toAdd: ' + toAdd); + if (toAdd === 0) { + $route.reload(); + Notifications.success("Realm optional scopes updated."); + } + }); + } + $scope.selectedOptionalClientScopesToAdd = []; + }; + + $scope.deleteOptionalClientScope = function () { + $scope.selectedDefOptionalClientScopesToRemove = JSON.parse('[' + $scope.selectedDefOptionalClientScopes + ']'); + toRemove = $scope.selectedDefOptionalClientScopesToRemove.length; + + for (var i = 0; i < $scope.selectedDefOptionalClientScopesToRemove.length; i++) { + var currentScope = $scope.selectedDefOptionalClientScopesToRemove[i]; + + RealmOptionalClientScopes.remove({ + realm : realm.realm, + clientScopeId : currentScope.id + }, function () { + toRemove = toRemove - 1; + if (toRemove === 0) { + $route.reload(); + Notifications.success("Realm optional scopes updated."); + } + }); + } + $scope.selectedDefOptionalClientScopesToRemove = []; + }; +}); + +module.controller('ClientScopeDetailCtrl', function($scope, realm, clientScope, $route, serverInfo, ClientScope, $location, $modal, Dialog, Notifications) { + $scope.protocols = serverInfo.listProviderIds('login-protocol'); + + $scope.realm = realm; + $scope.create = !clientScope.name; + + function updateProperties() { + if (!$scope.clientScope.attributes) { + $scope.clientScope.attributes = {}; + } + + if ($scope.clientScope.protocol) { + $scope.protocol = $scope.protocols[$scope.protocols.indexOf($scope.clientScope.protocol)]; + } else { + $scope.protocol = $scope.protocols[0]; + } + + if ($scope.clientScope.attributes["display.on.consent.screen"]) { + if ($scope.clientScope.attributes["display.on.consent.screen"] == "true") { + $scope.displayOnConsentScreen = true; + } else { + $scope.displayOnConsentScreen = false; + } + } else { + $scope.displayOnConsentScreen = true; + } + + if ($scope.clientScope.attributes["include.in.token.scope"]) { + if ($scope.clientScope.attributes["include.in.token.scope"] == "true") { + $scope.includeInTokenScope = true; + } else { + $scope.includeInTokenScope = false; + } + } else { + $scope.includeInTokenScope = true; + } + } + + if (!$scope.create) { + $scope.clientScope = angular.copy(clientScope); + } else { + $scope.clientScope = {}; + } + + updateProperties(); + + + $scope.switchChange = function() { + $scope.changed = true; + } + + $scope.changeProtocol = function() { + if ($scope.protocol == "openid-connect") { + $scope.clientScope.protocol = "openid-connect"; + } else if ($scope.protocol == "saml") { + $scope.clientScope.protocol = "saml"; + } + }; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + function isChanged() { + if (!angular.equals($scope.clientScope, clientScope)) { + return true; + } + return false; + } + + $scope.$watch('clientScope', function() { + $scope.changed = isChanged(); + }, true); + + $scope.save = function() { + $scope.clientScope.protocol = $scope.protocol; + + if ($scope.displayOnConsentScreen == true) { + $scope.clientScope.attributes["display.on.consent.screen"] = "true"; + } else { + $scope.clientScope.attributes["display.on.consent.screen"] = "false"; + } + + if ($scope.includeInTokenScope == true) { + $scope.clientScope.attributes["include.in.token.scope"] = "true"; + } else { + $scope.clientScope.attributes["include.in.token.scope"] = "false"; + } + + if ($scope.create) { + ClientScope.save({ + realm: realm.realm, + clientScope: '' + }, $scope.clientScope, function (data, headers) { + $scope.changed = false; + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + $location.url("/realms/" + realm.realm + "/client-scopes/" + id); + Notifications.success("The client scope has been created."); + }); + } else { + ClientScope.update({ + realm : realm.realm, + clientScope : clientScope.id + }, $scope.clientScope, function() { + $scope.changed = false; + clientScope = angular.copy($scope.clientScope); + $location.url("/realms/" + realm.realm + "/client-scopes/" + clientScope.id); + Notifications.success("Your changes have been saved to the client scope."); + }); + } + }; + + $scope.reset = function() { + $route.reload(); + }; + + $scope.cancel = function() { + $location.url("/realms/" + realm.realm + "/client-scopes"); + }; +}); + +module.controller('ClientScopeProtocolMapperListCtrl', function($scope, realm, clientScope, serverInfo, + ClientScopeProtocolMappersByProtocol, ClientScopeProtocolMapper, + $route, Dialog, Notifications) { + $scope.realm = realm; + $scope.clientScope = clientScope; + if (clientScope.protocol == null) { + clientScope.protocol = 'openid-connect'; + } + + var protocolMappers = serverInfo.protocolMapperTypes[clientScope.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + $scope.removeMapper = function(mapper) { + console.debug(mapper); + Dialog.confirmDelete(mapper.name, 'mapper', function() { + ClientScopeProtocolMapper.remove({ realm: realm.realm, clientScope: clientScope.id, id : mapper.id }, function() { + Notifications.success("The mapper has been deleted."); + $route.reload(); + }); + }); + }; + + $scope.sortMappersByPriority = function(mapper) { + return $scope.mapperTypes[mapper.protocolMapper].priority; + } + + var updateMappers = function() { + $scope.mappers = ClientScopeProtocolMappersByProtocol.query({realm : realm.realm, clientScope : clientScope.id, protocol : clientScope.protocol}); + }; + + updateMappers(); +}); + +module.controller('ClientScopeProtocolMapperCtrl', function($scope, realm, serverInfo, clientScope, mapper, clients, ClientScopeProtocolMapper, Notifications, Dialog, $location, $route) { + $scope.realm = realm; + $scope.clients = clients; + + if (clientScope.protocol == null) { + clientScope.protocol = 'openid-connect'; + } + + $scope.model = { + realm: realm, + clientScope: clientScope, + create: false, + protocol: clientScope.protocol, + mapper: angular.copy(mapper), + changed: false + } + + var protocolMappers = serverInfo.protocolMapperTypes[clientScope.protocol]; + for (var i = 0; i < protocolMappers.length; i++) { + if (protocolMappers[i].id == mapper.protocolMapper) { + $scope.model.mapperType = protocolMappers[i]; + } + } + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.$watch('model.mapper', function() { + if (!angular.equals($scope.model.mapper, mapper)) { + $scope.model.changed = true; + } + }, true); + + $scope.save = function() { + ClientScopeProtocolMapper.update({ + realm : realm.realm, + clientScope: clientScope.id, + id : mapper.id + }, $scope.model.mapper, function() { + $route.reload(); + Notifications.success("Your changes have been saved."); + }); + }; + + $scope.reset = function() { + $scope.model.mapper = angular.copy(mapper); + $scope.model.changed = false; + }; + + $scope.cancel = function() { + //$location.url("/realms"); + window.history.back(); + }; + + $scope.remove = function() { + Dialog.confirmDelete($scope.model.mapper.name, 'mapper', function() { + ClientScopeProtocolMapper.remove({ realm: realm.realm, clientScope: clientScope.id, id : $scope.model.mapper.id }, function() { + Notifications.success("The mapper has been deleted."); + $location.url("/realms/" + realm.realm + '/client-scopes/' + clientScope.id + "/mappers"); + }); + }); + }; + +}); + +module.controller('ClientScopeProtocolMapperCreateCtrl', function($scope, realm, serverInfo, clientScope, clients, ClientScopeProtocolMapper, Notifications, Dialog, $location) { + $scope.realm = realm; + $scope.clients = clients; + + if (clientScope.protocol == null) { + clientScope.protocol = 'openid-connect'; + } + var protocol = clientScope.protocol; + $scope.model = { + realm: realm, + clientScope: clientScope, + create: true, + protocol: clientScope.protocol, + mapper: { protocol : clientScope.protocol, config: {}}, + changed: false, + mapperTypes: serverInfo.protocolMapperTypes[protocol] + } + + // apply default configurations on change for selected protocolmapper type. + $scope.$watch('model.mapperType', function() { + var currentMapperType = $scope.model.mapperType; + var defaultConfig = {}; + + if (currentMapperType && Array.isArray(currentMapperType.properties)) { + for (var i = 0; i < currentMapperType.properties.length; i++) { + var property = currentMapperType.properties[i]; + if (property && property.name && property.defaultValue) { + defaultConfig[property.name] = property.defaultValue; + } + } + } + + $scope.model.mapper.config = defaultConfig; + }, true); + + $scope.model.mapperType = $scope.model.mapperTypes[0]; + + $scope.$watch(function() { + return $location.path(); + }, function() { + $scope.path = $location.path().substring(1).split("/"); + }); + + $scope.save = function() { + $scope.model.mapper.protocolMapper = $scope.model.mapperType.id; + ClientScopeProtocolMapper.save({ + realm : realm.realm, clientScope: clientScope.id + }, $scope.model.mapper, function(data, headers) { + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + $location.url("/realms/" + realm.realm + '/client-scopes/' + clientScope.id + "/mappers/" + id); + Notifications.success("Mapper has been created."); + }); + }; + + $scope.cancel = function() { + //$location.url("/realms"); + window.history.back(); + }; + + +}); + +module.controller('ClientScopeAddBuiltinProtocolMapperCtrl', function($scope, realm, clientScope, serverInfo, + ClientScopeProtocolMappersByProtocol, + $http, $location, Dialog, Notifications) { + $scope.realm = realm; + $scope.clientScope = clientScope; + if (clientScope.protocol == null) { + clientScope.protocol = 'openid-connect'; + } + + var protocolMappers = serverInfo.protocolMapperTypes[clientScope.protocol]; + var mapperTypes = {}; + for (var i = 0; i < protocolMappers.length; i++) { + mapperTypes[protocolMappers[i].id] = protocolMappers[i]; + } + $scope.mapperTypes = mapperTypes; + + + + + var updateMappers = function() { + var clientMappers = ClientScopeProtocolMappersByProtocol.query({realm : realm.realm, clientScope : clientScope.id, protocol : clientScope.protocol}, function() { + var builtinMappers = serverInfo.builtinProtocolMappers[clientScope.protocol]; + for (var i = 0; i < clientMappers.length; i++) { + for (var j = 0; j < builtinMappers.length; j++) { + if (builtinMappers[j].name == clientMappers[i].name + && builtinMappers[j].protocolMapper == clientMappers[i].protocolMapper) { + builtinMappers.splice(j, 1); + break; + } + } + } + $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 + '/client-scopes/' + clientScope.id + '/protocol-mappers/add-models', + toAdd).then(function() { + Notifications.success("Mappers added"); + $location.url('/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/mappers'); + }).catch(function() { + Notifications.error("Error adding mappers"); + $location.url('/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/mappers'); + }); + }; + +}); + + +module.controller('ClientScopeScopeMappingCtrl', function($scope, $http, $route, realm, clientScope, Notifications, + ClientScope, Client, + ClientScopeRealmScopeMapping, ClientScopeClientScopeMapping, ClientRole, + ClientScopeAvailableRealmScopeMapping, ClientScopeAvailableClientScopeMapping, + ClientScopeCompositeRealmScopeMapping, ClientScopeCompositeClientScopeMapping) { + $scope.realm = realm; + $scope.clientScope = angular.copy(clientScope); + $scope.selectedRealmRoles = []; + $scope.selectedRealmMappings = []; + $scope.realmMappings = []; + $scope.clientRoles = []; + $scope.clientComposite = []; + $scope.selectedClientRoles = []; + $scope.selectedClientMappings = []; + $scope.clientMappings = []; + $scope.dummymodel = []; + $scope.selectedClient = null; + + function updateScopeRealmRoles() { + $scope.realmRoles = ClientScopeAvailableRealmScopeMapping.query({realm : realm.realm, clientScope : clientScope.id}); + $scope.realmMappings = ClientScopeRealmScopeMapping.query({realm : realm.realm, clientScope : clientScope.id}); + $scope.realmComposite = ClientScopeCompositeRealmScopeMapping.query({realm : realm.realm, clientScope : clientScope.id}); + } + + function updateScopeClientRoles() { + if ($scope.selectedClient) { + $scope.clientRoles = ClientScopeAvailableClientScopeMapping.query({realm : realm.realm, clientScope : clientScope.id, targetClient : $scope.selectedClient.id}); + $scope.clientMappings = ClientScopeClientScopeMapping.query({realm : realm.realm, clientScope : clientScope.id, targetClient : $scope.selectedClient.id}); + $scope.clientComposite = ClientScopeCompositeClientScopeMapping.query({realm : realm.realm, clientScope : clientScope.id, targetClient : $scope.selectedClient.id}); + } else { + $scope.clientRoles = null; + $scope.clientMappings = null; + $scope.clientComposite = null; + } + } + + $scope.changeClient = function(client) { + if (!client || !client.id) { + $scope.selectedClient = null; + return; + } + $scope.selectedClient = client; + updateScopeClientRoles(); + }; + + $scope.addRealmRole = function() { + $scope.selectedRealmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']'); + $scope.selectedRealmRoles = []; + $http.post(authUrl + '/admin/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/scope-mappings/realm', + $scope.selectedRealmRolesToAdd).then(function() { + updateScopeRealmRoles(); + $scope.selectedRealmRolesToAdd = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.deleteRealmRole = function() { + $scope.selectedRealmMappingsToRemove = JSON.parse('[' + $scope.selectedRealmMappings + ']'); + $scope.selectedRealmMappings = []; + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/scope-mappings/realm', + {data : $scope.selectedRealmMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function () { + updateScopeRealmRoles(); + $scope.selectedRealmMappingsToRemove = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.addClientRole = function() { + $scope.selectedClientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']'); + $scope.selectedClientRoles = []; + $http.post(authUrl + '/admin/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/scope-mappings/clients/' + $scope.selectedClient.id, + $scope.selectedClientRolesToAdd).then(function () { + updateScopeClientRoles(); + $scope.selectedClientRolesToAdd = []; + Notifications.success("Scope mappings updated."); + }); + }; + + $scope.deleteClientRole = function() { + $scope.selectedClientMappingsToRemove = JSON.parse('[' + $scope.selectedClientMappings + ']'); + $scope.selectedClientMappings = []; + $http.delete(authUrl + '/admin/realms/' + realm.realm + '/client-scopes/' + clientScope.id + '/scope-mappings/clients/' + $scope.selectedClient.id, + {data : $scope.selectedClientMappingsToRemove, headers : {"content-type" : "application/json"}}).then(function () { + updateScopeClientRoles(); + $scope.selectedClientMappingsToRemove = []; + Notifications.success("Scope mappings updated."); + }); + }; + + clientSelectControl($scope, $route.current.params.realm, Client); + updateScopeRealmRoles(); +}); + +module.controller('ClientStoresCtrl', function($scope, $location, $route, realm, serverInfo, Components, Notifications, Dialog) { + console.log('ClientStoresCtrl ++++****'); + $scope.realm = realm; + $scope.providers = serverInfo.componentTypes['org.keycloak.storage.client.ClientStorageProvider']; + $scope.clientStorageProviders = serverInfo.componentTypes['org.keycloak.storage.client.ClientStorageProvider']; + $scope.instancesLoaded = false; + + if (!$scope.providers) $scope.providers = []; + + $scope.addProvider = function(provider) { + console.log('Add provider: ' + provider.id); + $location.url("/create/client-storage/" + realm.realm + "/providers/" + provider.id); + }; + + $scope.getInstanceLink = function(instance) { + return "/realms/" + realm.realm + "/client-storage/providers/" + instance.providerId + "/" + instance.id; + } + + $scope.getInstanceName = function(instance) { + return instance.name; + } + $scope.getInstanceProvider = function(instance) { + return instance.providerId; + } + + $scope.isProviderEnabled = function(instance) { + return !instance.config['enabled'] || instance.config['enabled'][0] == 'true'; + } + + $scope.getInstancePriority = function(instance) { + if (!instance.config['priority']) { + return "0"; + } + return instance.config['priority'][0]; + } + + Components.query({realm: realm.realm, + parent: realm.id, + type: 'org.keycloak.storage.client.ClientStorageProvider' + }, function(data) { + $scope.instances = data; + $scope.instancesLoaded = true; + }); + + $scope.removeInstance = function(instance) { + Dialog.confirmDelete(instance.name, 'client storage provider', function() { + Components.remove({ + realm : realm.realm, + componentId : instance.id + }, function() { + $route.reload(); + Notifications.success("The provider has been deleted."); + }); + }); + }; +}); + +module.controller('GenericClientStorageCtrl', function($scope, $location, Notifications, $route, Dialog, realm, + serverInfo, instance, providerId, Components) { + console.log('GenericClientStorageCtrl'); + console.log('providerId: ' + providerId); + $scope.create = !instance.providerId; + console.log('create: ' + $scope.create); + var providers = serverInfo.componentTypes['org.keycloak.storage.client.ClientStorageProvider']; + console.log('providers length ' + providers.length); + var providerFactory = null; + for (var i = 0; i < providers.length; i++) { + var p = providers[i]; + console.log('provider: ' + p.id); + if (p.id == providerId) { + $scope.providerFactory = p; + providerFactory = p; + break; + } + + } + $scope.changed = false; + + console.log("providerFactory: " + providerFactory.id); + + function initClientStorageSettings() { + if ($scope.create) { + $scope.changed = true; + instance.name = providerFactory.id; + instance.providerId = providerFactory.id; + instance.providerType = 'org.keycloak.storage.client.ClientStorageProvider'; + instance.parentId = realm.id; + instance.config = { + + }; + instance.config['priority'] = ["0"]; + instance.config['enabled'] = ["true"]; + + $scope.fullSyncEnabled = false; + $scope.changedSyncEnabled = false; + instance.config['cachePolicy'] = ['DEFAULT']; + instance.config['evictionDay'] = ['']; + instance.config['evictionHour'] = ['']; + instance.config['evictionMinute'] = ['']; + instance.config['maxLifespan'] = ['']; + if (providerFactory.properties) { + + for (var i = 0; i < providerFactory.properties.length; i++) { + var configProperty = providerFactory.properties[i]; + if (configProperty.defaultValue) { + instance.config[configProperty.name] = [configProperty.defaultValue]; + } else { + instance.config[configProperty.name] = ['']; + } + + } + } + + } else { + $scope.changed = false; + if (!instance.config['enabled']) { + instance.config['enabled'] = ['true']; + } + if (!instance.config['cachePolicy']) { + instance.config['cachePolicy'] = ['DEFAULT']; + + } + if (!instance.config['evictionDay']) { + instance.config['evictionDay'] = ['']; + + } + if (!instance.config['evictionHour']) { + instance.config['evictionHour'] = ['']; + + } + if (!instance.config['evictionMinute']) { + instance.config['evictionMinute'] = ['']; + + } + if (!instance.config['maxLifespan']) { + instance.config['maxLifespan'] = ['']; + + } + if (!instance.config['priority']) { + instance.config['priority'] = ['0']; + } + + if (providerFactory.properties) { + for (var i = 0; i < providerFactory.properties.length; i++) { + var configProperty = providerFactory.properties[i]; + if (!instance.config[configProperty.name]) { + instance.config[configProperty.name] = ['']; + } + } + } + + } + } + + initClientStorageSettings(); + $scope.instance = angular.copy(instance); + $scope.realm = realm; + + $scope.$watch('instance', function() { + if (!angular.equals($scope.instance, instance)) { + $scope.changed = true; + } + + }, true); + + $scope.save = function() { + console.log('save provider'); + $scope.changed = false; + if ($scope.create) { + console.log('saving new provider'); + Components.save({realm: realm.realm}, $scope.instance, function (data, headers) { + var l = headers().location; + var id = l.substring(l.lastIndexOf("/") + 1); + + $location.url("/realms/" + realm.realm + "/client-storage/providers/" + $scope.instance.providerId + "/" + id); + Notifications.success("The provider has been created."); + }); + } else { + console.log('update existing provider'); + Components.update({realm: realm.realm, + componentId: instance.id + }, + $scope.instance, function () { + $route.reload(); + Notifications.success("The provider has been updated."); + }); + } + }; + + $scope.reset = function() { + $route.reload(); + }; + + $scope.cancel = function() { + console.log('cancel'); + if ($scope.create) { + $location.url("/realms/" + realm.realm + "/client-stores"); + } else { + $route.reload(); + } + }; + + + +}); + + |