You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3219 lines
114 KiB

  1. function getAccess(Auth, Current, role) {
  2. if (!Current.realm)return false;
  3. var realmAccess = Auth.user && Auth.user['realm_access'];
  4. if (realmAccess) {
  5. realmAccess = realmAccess[Current.realm.realm];
  6. if (realmAccess) {
  7. return realmAccess.indexOf(role) >= 0;
  8. }
  9. }
  10. return false;
  11. }
  12. function getAccessObject(Auth, Current) {
  13. return {
  14. get createRealm() {
  15. return Auth.user && Auth.user.createRealm;
  16. },
  17. get queryUsers() {
  18. return getAccess(Auth, Current, 'query-users') || this.viewUsers;
  19. },
  20. get queryGroups() {
  21. return getAccess(Auth, Current, 'query-groups') || this.viewUsers;
  22. },
  23. get queryClients() {
  24. return getAccess(Auth, Current, 'query-clients') || this.viewClients;
  25. },
  26. get viewRealm() {
  27. return getAccess(Auth, Current, 'view-realm') || getAccess(Auth, Current, 'manage-realm') || this.manageRealm;
  28. },
  29. get viewClients() {
  30. return getAccess(Auth, Current, 'view-clients') || getAccess(Auth, Current, 'manage-clients') || this.manageClients;
  31. },
  32. get viewUsers() {
  33. return getAccess(Auth, Current, 'view-users') || getAccess(Auth, Current, 'manage-users') || this.manageClients;
  34. },
  35. get viewEvents() {
  36. return getAccess(Auth, Current, 'view-events') || getAccess(Auth, Current, 'manage-events') || this.manageClients;
  37. },
  38. get viewIdentityProviders() {
  39. return getAccess(Auth, Current, 'view-identity-providers') || getAccess(Auth, Current, 'manage-identity-providers') || this.manageIdentityProviders;
  40. },
  41. get viewAuthorization() {
  42. return getAccess(Auth, Current, 'view-authorization') || this.manageAuthorization;
  43. },
  44. get manageRealm() {
  45. return getAccess(Auth, Current, 'manage-realm');
  46. },
  47. get manageClients() {
  48. return getAccess(Auth, Current, 'manage-clients');
  49. },
  50. get manageUsers() {
  51. return getAccess(Auth, Current, 'manage-users');
  52. },
  53. get manageEvents() {
  54. return getAccess(Auth, Current, 'manage-events');
  55. },
  56. get manageIdentityProviders() {
  57. return getAccess(Auth, Current, 'manage-identity-providers');
  58. },
  59. get manageAuthorization() {
  60. return getAccess(Auth, Current, 'manage-authorization');
  61. },
  62. get impersonation() {
  63. return getAccess(Auth, Current, 'impersonation');
  64. }
  65. };
  66. }
  67. module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location, Notifications, ServerInfo, RealmSpecificLocalizationTexts) {
  68. $scope.authUrl = authUrl;
  69. $scope.resourceUrl = resourceUrl;
  70. $scope.auth = Auth;
  71. $scope.serverInfo = ServerInfo.get();
  72. $scope.access = getAccessObject(Auth, Current);
  73. $scope.$watch(function() {
  74. return $location.path();
  75. }, function() {
  76. $scope.fragment = $location.path();
  77. $scope.path = $location.path().substring(1).split("/");
  78. });
  79. $scope.$watch(function() {
  80. return Current.realm;
  81. }, function() {
  82. if(Current.realm !== null && currentRealm !== Current.realm.id) {
  83. currentRealm = Current.realm.id;
  84. translateProvider.translations(locale, resourceBundle);
  85. RealmSpecificLocalizationTexts.get({id: currentRealm, locale: locale}, function (localizationTexts) {
  86. translateProvider.translations(locale, localizationTexts.toJSON());
  87. })
  88. }
  89. })
  90. });
  91. module.controller('HomeCtrl', function(Realm, Auth, Current, $location) {
  92. Realm.query(null, function(realms) {
  93. var realm;
  94. if (realms.length == 1) {
  95. realm = realms[0];
  96. } else if (realms.length == 2) {
  97. if (realms[0].realm == Auth.user.realm) {
  98. realm = realms[1];
  99. } else if (realms[1].realm == Auth.user.realm) {
  100. realm = realms[0];
  101. }
  102. }
  103. if (realm) {
  104. Current.realms = realms;
  105. Current.realm = realm;
  106. var access = getAccessObject(Auth, Current);
  107. if (access.viewRealm || access.manageRealm) {
  108. $location.url('/realms/' + realm.realm );
  109. } else if (access.queryClients) {
  110. $location.url('/realms/' + realm.realm + "/clients");
  111. } else if (access.viewIdentityProviders) {
  112. $location.url('/realms/' + realm.realm + "/identity-provider-settings");
  113. } else if (access.queryUsers) {
  114. $location.url('/realms/' + realm.realm + "/users");
  115. } else if (access.queryGroups) {
  116. $location.url('/realms/' + realm.realm + "/groups");
  117. } else if (access.viewEvents) {
  118. $location.url('/realms/' + realm.realm + "/events");
  119. }
  120. } else {
  121. $location.url('/realms');
  122. }
  123. });
  124. });
  125. module.controller('RealmTabCtrl', function(Dialog, $scope, Current, Realm, Notifications, $location) {
  126. $scope.removeRealm = function() {
  127. Dialog.confirmDelete(Current.realm.realm, 'realm', function() {
  128. Realm.remove({ id : Current.realm.realm }, function() {
  129. Current.realms = Realm.query();
  130. Notifications.success("The realm has been deleted.");
  131. $location.url("/");
  132. });
  133. });
  134. };
  135. });
  136. module.controller('ServerInfoCtrl', function($scope, ServerInfo) {
  137. ServerInfo.reload();
  138. $scope.serverInfo = ServerInfo.get();
  139. $scope.$watch($scope.serverInfo, function() {
  140. $scope.providers = [];
  141. for(var spi in $scope.serverInfo.providers) {
  142. var p = angular.copy($scope.serverInfo.providers[spi]);
  143. p.name = spi;
  144. $scope.providers.push(p)
  145. }
  146. });
  147. $scope.serverInfoReload = function() {
  148. ServerInfo.reload();
  149. }
  150. });
  151. module.controller('RealmListCtrl', function($scope, Realm, Current) {
  152. $scope.realms = Realm.query();
  153. Current.realms = $scope.realms;
  154. });
  155. module.controller('RealmDropdownCtrl', function($scope, Realm, Current, Auth, $location) {
  156. // Current.realms = Realm.get();
  157. $scope.current = Current;
  158. $scope.changeRealm = function(selectedRealm) {
  159. $location.url("/realms/" + selectedRealm);
  160. }
  161. });
  162. module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $http, $location, $route, Dialog, Notifications, Auth, $modal) {
  163. console.log('RealmCreateCtrl');
  164. Current.realm = null;
  165. $scope.realm = {
  166. enabled: true
  167. };
  168. $scope.changed = false;
  169. $scope.files = [];
  170. var oldCopy = angular.copy($scope.realm);
  171. $scope.importFile = function($fileContent){
  172. $scope.realm = angular.copy(JSON.parse($fileContent));
  173. $scope.importing = true;
  174. };
  175. $scope.viewImportDetails = function() {
  176. $modal.open({
  177. templateUrl: resourceUrl + '/partials/modal/view-object.html',
  178. controller: 'ObjectModalCtrl',
  179. resolve: {
  180. object: function () {
  181. return $scope.realm;
  182. }
  183. }
  184. })
  185. };
  186. $scope.$watch('realm', function() {
  187. if (!angular.equals($scope.realm, oldCopy)) {
  188. $scope.changed = true;
  189. }
  190. }, true);
  191. $scope.$watch('realm.realm', function() {
  192. $scope.realm.id = $scope.realm.realm;
  193. }, true);
  194. $scope.save = function() {
  195. var realmCopy = angular.copy($scope.realm);
  196. Realm.create(realmCopy, function() {
  197. Notifications.success("The realm has been created.");
  198. Auth.refreshPermissions(function() {
  199. $scope.$apply(function() {
  200. $location.url("/realms/" + realmCopy.realm);
  201. });
  202. });
  203. });
  204. };
  205. $scope.cancel = function() {
  206. $location.url("/");
  207. };
  208. $scope.reset = function() {
  209. $route.reload();
  210. }
  211. });
  212. module.controller('ObjectModalCtrl', function($scope, object) {
  213. $scope.object = object;
  214. });
  215. module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $location, $window, Dialog, Notifications, Auth) {
  216. $scope.createRealm = !realm.realm;
  217. $scope.serverInfo = serverInfo;
  218. $scope.realmName = realm.realm;
  219. $scope.disableRename = realm.realm == masterRealm;
  220. $scope.authServerUrl = authServerUrl;
  221. if (Current.realm == null || Current.realm.realm != realm.realm) {
  222. for (var i = 0; i < Current.realms.length; i++) {
  223. if (realm.realm == Current.realms[i].realm) {
  224. Current.realm = Current.realms[i];
  225. break;
  226. }
  227. }
  228. }
  229. for (var i = 0; i < Current.realms.length; i++) {
  230. if (Current.realms[i].realm == realm.realm) {
  231. Current.realm = Current.realms[i];
  232. }
  233. }
  234. $scope.realm = angular.copy(realm);
  235. var oldCopy = angular.copy($scope.realm);
  236. $scope.changed = $scope.create;
  237. $scope.$watch('realm', function() {
  238. if (!angular.equals($scope.realm, oldCopy)) {
  239. $scope.changed = true;
  240. }
  241. }, true);
  242. $scope.$watch('realmName', function() {
  243. if (!angular.equals($scope.realmName, oldCopy.realm)) {
  244. $scope.changed = true;
  245. }
  246. }, true);
  247. $scope.save = function() {
  248. var realmCopy = angular.copy($scope.realm);
  249. realmCopy.realm = $scope.realmName;
  250. $scope.changed = false;
  251. var nameChanged = !angular.equals($scope.realmName, oldCopy.realm);
  252. var oldName = oldCopy.realm;
  253. Realm.update({ id : oldCopy.realm}, realmCopy, function () {
  254. var data = Realm.query(function () {
  255. Current.realms = data;
  256. for (var i = 0; i < Current.realms.length; i++) {
  257. if (Current.realms[i].realm == realmCopy.realm) {
  258. Current.realm = Current.realms[i];
  259. oldCopy = angular.copy($scope.realm);
  260. }
  261. }
  262. });
  263. if (nameChanged) {
  264. console.debug(Auth);
  265. console.debug(Auth.authz.tokenParsed.iss);
  266. if (Auth.authz.tokenParsed.iss.endsWith(masterRealm)) {
  267. Auth.refreshPermissions(function () {
  268. Auth.refreshPermissions(function () {
  269. Notifications.success("Your changes have been saved to the realm.");
  270. $scope.$apply(function () {
  271. $location.url("/realms/" + realmCopy.realm);
  272. });
  273. });
  274. });
  275. } else {
  276. delete Auth.authz.token;
  277. delete Auth.authz.refreshToken;
  278. var newLocation = $window.location.href.replace('/' + oldName + '/', '/' + realmCopy.realm + '/')
  279. .replace('/realms/' + oldName, '/realms/' + realmCopy.realm);
  280. window.location.replace(newLocation);
  281. }
  282. } else {
  283. $location.url("/realms/" + realmCopy.realm);
  284. Notifications.success("Your changes have been saved to the realm.");
  285. }
  286. });
  287. };
  288. $scope.reset = function() {
  289. $scope.realm = angular.copy(oldCopy);
  290. $scope.changed = false;
  291. };
  292. $scope.cancel = function() {
  293. window.history.back();
  294. };
  295. });
  296. function genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, url) {
  297. $scope.realm = angular.copy(realm);
  298. $scope.serverInfo = serverInfo;
  299. $scope.registrationAllowed = $scope.realm.registrationAllowed;
  300. var oldCopy = angular.copy($scope.realm);
  301. $scope.changed = false;
  302. $scope.$watch('realm', function() {
  303. if (!angular.equals($scope.realm, oldCopy)) {
  304. $scope.changed = true;
  305. }
  306. }, true);
  307. $scope.save = function() {
  308. var realmCopy = angular.copy($scope.realm);
  309. console.log('updating realm...');
  310. $scope.changed = false;
  311. console.log('oldCopy.realm - ' + oldCopy.realm);
  312. Realm.update({ id : oldCopy.realm}, realmCopy, function () {
  313. $route.reload();
  314. Notifications.success("Your changes have been saved to the realm.");
  315. $scope.registrationAllowed = $scope.realm.registrationAllowed;
  316. });
  317. };
  318. $scope.reset = function() {
  319. $scope.realm = angular.copy(oldCopy);
  320. $scope.changed = false;
  321. };
  322. $scope.cancel = function() {
  323. $route.reload();
  324. };
  325. }
  326. module.controller('DefenseHeadersCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  327. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/defense/headers");
  328. });
  329. module.controller('RealmLoginSettingsCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  330. // KEYCLOAK-5474: Make sure duplicateEmailsAllowed is disabled if loginWithEmailAllowed
  331. $scope.$watch('realm.loginWithEmailAllowed', function() {
  332. if ($scope.realm.loginWithEmailAllowed) {
  333. $scope.realm.duplicateEmailsAllowed = false;
  334. }
  335. });
  336. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/login-settings");
  337. });
  338. module.controller('RealmOtpPolicyCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  339. $scope.optionsDigits = [ 6, 8 ];
  340. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/otp-policy");
  341. });
  342. module.controller('RealmWebAuthnPolicyCtrl', function ($scope, Current, Realm, realm, serverInfo, $http, $route, $location, Dialog, Notifications) {
  343. $scope.deleteAcceptableAaguid = function(index) {
  344. $scope.realm.webAuthnPolicyAcceptableAaguids.splice(index, 1);
  345. };
  346. $scope.addAcceptableAaguid = function() {
  347. $scope.realm.webAuthnPolicyAcceptableAaguids.push($scope.newAcceptableAaguid);
  348. $scope.newAcceptableAaguid = "";
  349. };
  350. // Just for case the user fill particular URL with disabled WebAuthn feature.
  351. $scope.redirectIfWebAuthnDisabled = function () {
  352. if (!serverInfo.featureEnabled('WEB_AUTHN')) {
  353. $location.url("/realms/" + $scope.realm.realm + "/authentication");
  354. }
  355. };
  356. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/webauthn-policy");
  357. });
  358. module.controller('RealmWebAuthnPasswordlessPolicyCtrl', function ($scope, Current, Realm, realm, serverInfo, $http, $route, $location, Dialog, Notifications) {
  359. $scope.deleteAcceptableAaguid = function(index) {
  360. $scope.realm.webAuthnPolicyPasswordlessAcceptableAaguids.splice(index, 1);
  361. };
  362. $scope.addAcceptableAaguid = function() {
  363. $scope.realm.webAuthnPolicyPasswordlessAcceptableAaguids.push($scope.newAcceptableAaguid);
  364. $scope.newAcceptableAaguid = "";
  365. };
  366. // Just for case the user fill particular URL with disabled WebAuthn feature.
  367. $scope.redirectIfWebAuthnDisabled = function () {
  368. if (!serverInfo.featureEnabled('WEB_AUTHN')) {
  369. $location.url("/realms/" + $scope.realm.realm + "/authentication");
  370. }
  371. };
  372. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/webauthn-policy-passwordless");
  373. });
  374. module.controller('RealmThemeCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  375. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/theme-settings");
  376. $scope.supportedLocalesOptions = {
  377. 'multiple' : true,
  378. 'simple_tags' : true,
  379. 'tags' : []
  380. };
  381. updateSupported();
  382. function localeForTheme(type, name) {
  383. name = name || 'base';
  384. for (var i = 0; i < serverInfo.themes[type].length; i++) {
  385. if (serverInfo.themes[type][i].name == name) {
  386. return serverInfo.themes[type][i].locales || [];
  387. }
  388. }
  389. return [];
  390. }
  391. function updateSupported() {
  392. if ($scope.realm.internationalizationEnabled) {
  393. var accountLocales = localeForTheme('account', $scope.realm.accountTheme);
  394. var loginLocales = localeForTheme('login', $scope.realm.loginTheme);
  395. var emailLocales = localeForTheme('email', $scope.realm.emailTheme);
  396. var supportedLocales = [];
  397. for (var i = 0; i < accountLocales.length; i++) {
  398. var l = accountLocales[i];
  399. if (loginLocales.indexOf(l) >= 0 && emailLocales.indexOf(l) >= 0) {
  400. supportedLocales.push(l);
  401. }
  402. }
  403. $scope.supportedLocalesOptions.tags = supportedLocales;
  404. if (!$scope.realm.supportedLocales) {
  405. $scope.realm.supportedLocales = supportedLocales;
  406. } else {
  407. for (var i = 0; i < $scope.realm.supportedLocales.length; i++) {
  408. if (supportedLocales.indexOf($scope.realm.supportedLocales[i]) == -1) {
  409. $scope.realm.supportedLocales = supportedLocales;
  410. }
  411. }
  412. }
  413. if (!$scope.realm.defaultLocale || supportedLocales.indexOf($scope.realm.defaultLocale) == -1) {
  414. $scope.realm.defaultLocale = 'en';
  415. }
  416. }
  417. }
  418. $scope.$watch('realm.loginTheme', updateSupported);
  419. $scope.$watch('realm.accountTheme', updateSupported);
  420. $scope.$watch('realm.emailTheme', updateSupported);
  421. $scope.$watch('realm.internationalizationEnabled', updateSupported);
  422. });
  423. module.controller('RealmLocalizationCtrl', function($scope, Current, $location, Realm, realm, serverInfo, Notifications, RealmSpecificLocales, realmSpecificLocales, RealmSpecificLocalizationTexts, RealmSpecificLocalizationText, Dialog, $translate){
  424. $scope.realm = realm;
  425. $scope.realmSpecificLocales = realmSpecificLocales;
  426. $scope.newLocale = null;
  427. $scope.selectedRealmSpecificLocales = null;
  428. $scope.localizationTexts = null;
  429. $scope.createLocale = function() {
  430. if(!$scope.newLocale) {
  431. Notifications.error($translate.instant('missing-locale'));
  432. return;
  433. }
  434. $scope.realmSpecificLocales.push($scope.newLocale)
  435. $scope.selectedRealmSpecificLocales = $scope.newLocale;
  436. $scope.newLocale = null;
  437. $location.url('/create/localization/' + realm.realm + '/' + $scope.selectedRealmSpecificLocales);
  438. }
  439. $scope.$watch(function() {
  440. return $scope.selectedRealmSpecificLocales;
  441. }, function() {
  442. if($scope.selectedRealmSpecificLocales != null) {
  443. $scope.updateRealmSpecificLocalizationTexts();
  444. }
  445. })
  446. $scope.updateRealmSpecificLocales = function() {
  447. RealmSpecificLocales.get({id: realm.realm}, function (updated) {
  448. $scope.realmSpecificLocales = updated;
  449. })
  450. }
  451. $scope.updateRealmSpecificLocalizationTexts = function() {
  452. RealmSpecificLocalizationTexts.get({id: realm.realm, locale: $scope.selectedRealmSpecificLocales }, function (updated) {
  453. $scope.localizationTexts = updated;
  454. })
  455. }
  456. $scope.removeLocalizationText = function(key) {
  457. Dialog.confirmDelete(key, 'localization text', function() {
  458. RealmSpecificLocalizationText.remove({
  459. realm: realm.realm,
  460. locale: $scope.selectedRealmSpecificLocales,
  461. key: key
  462. }, function () {
  463. $scope.updateRealmSpecificLocalizationTexts();
  464. Notifications.success($translate.instant('localization-text.remove.success'));
  465. });
  466. });
  467. }
  468. });
  469. module.controller('RealmLocalizationUploadCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, $upload, $translate){
  470. $scope.realm = realm;
  471. $scope.locale = null;
  472. $scope.files = [];
  473. $scope.onFileSelect = function($files) {
  474. $scope.files = $files;
  475. };
  476. $scope.reset = function() {
  477. $scope.locale = null;
  478. $scope.files = null;
  479. };
  480. $scope.save = function() {
  481. if(!$scope.files || $scope.files.length === 0) {
  482. Notifications.error($translate.instant('missing-file'));
  483. return;
  484. }
  485. //$files: an array of files selected, each file has name, size, and type.
  486. for (var i = 0; i < $scope.files.length; i++) {
  487. var $file = $scope.files[i];
  488. $scope.upload = $upload.upload({
  489. url: authUrl + '/admin/realms/' + realm.realm + '/localization/' + $scope.locale,
  490. file: $file
  491. }).then(function(response) {
  492. $scope.reset();
  493. Notifications.success($translate.instant('localization-file.upload.success'));
  494. }).catch(function() {
  495. Notifications.error($translate.instant('localization-file.upload.error'));
  496. });
  497. }
  498. };
  499. });
  500. module.controller('RealmLocalizationDetailCtrl', function($scope, Current, $location, Realm, realm, Notifications, locale, key, RealmSpecificLocalizationText, localizationText, $translate){
  501. $scope.realm = realm;
  502. $scope.locale = locale;
  503. $scope.key = key;
  504. $scope.value = ((localizationText)? localizationText.content : null);
  505. $scope.create = !key;
  506. $scope.save = function() {
  507. if ($scope.create) {
  508. RealmSpecificLocalizationText.save({
  509. realm: realm.realm,
  510. locale: $scope.locale,
  511. key: $scope.key
  512. }, $scope.value, function (data, headers) {
  513. $location.url("/realms/" + realm.realm + "/localization");
  514. Notifications.success($translate.instant('localization-text.create.success'));
  515. });
  516. } else {
  517. RealmSpecificLocalizationText.save({
  518. realm: realm.realm,
  519. locale: $scope.locale,
  520. key: $scope.key
  521. }, $scope.value, function (data, headers) {
  522. $location.url("/realms/" + realm.realm + "/localization");
  523. Notifications.success($translate.instant('localization-text.update.success'));
  524. });
  525. }
  526. };
  527. $scope.cancel = function () {
  528. $location.url("/realms/" + realm.realm + "/localization");
  529. };
  530. });
  531. module.controller('RealmCacheCtrl', function($scope, realm, RealmClearUserCache, RealmClearRealmCache, RealmClearKeysCache, Notifications) {
  532. $scope.realm = angular.copy(realm);
  533. $scope.clearUserCache = function() {
  534. RealmClearUserCache.save({ realm: realm.realm}, function () {
  535. Notifications.success("User cache cleared");
  536. });
  537. }
  538. $scope.clearRealmCache = function() {
  539. RealmClearRealmCache.save({ realm: realm.realm}, function () {
  540. Notifications.success("Realm cache cleared");
  541. });
  542. }
  543. $scope.clearKeysCache = function() {
  544. RealmClearKeysCache.save({ realm: realm.realm}, function () {
  545. Notifications.success("Public keys cache cleared");
  546. });
  547. }
  548. });
  549. module.controller('RealmPasswordPolicyCtrl', function($scope, Realm, realm, $http, $location, $route, Dialog, Notifications, serverInfo) {
  550. var parse = function(policyString) {
  551. var policies = [];
  552. if (!policyString || policyString.length == 0){
  553. return policies;
  554. }
  555. var policyArray = policyString.split(" and ");
  556. for (var i = 0; i < policyArray.length; i ++){
  557. var policyToken = policyArray[i];
  558. var id;
  559. var value;
  560. if (policyToken.indexOf('(') == -1) {
  561. id = policyToken.trim();
  562. value = null;
  563. } else {
  564. id = policyToken.substring(0, policyToken.indexOf('('));
  565. value = policyToken.substring(policyToken.indexOf('(') + 1, policyToken.lastIndexOf(')')).trim();
  566. }
  567. for (var j = 0; j < serverInfo.passwordPolicies.length; j++) {
  568. if (serverInfo.passwordPolicies[j].id == id) {
  569. // clone
  570. var p = JSON.parse(JSON.stringify(serverInfo.passwordPolicies[j]));
  571. p.value = value && value || p.defaultValue;
  572. policies.push(p);
  573. }
  574. }
  575. }
  576. return policies;
  577. };
  578. var toString = function(policies) {
  579. if (!policies || policies.length == 0) {
  580. return "";
  581. }
  582. var policyString = "";
  583. for (var i = 0; i < policies.length; i++) {
  584. policyString += policies[i].id + '(' + policies[i].value + ')';
  585. if (i != policies.length - 1) {
  586. policyString += ' and ';
  587. }
  588. }
  589. return policyString;
  590. }
  591. $scope.realm = realm;
  592. $scope.serverInfo = serverInfo;
  593. $scope.changed = false;
  594. console.log(JSON.stringify(parse(realm.passwordPolicy)));
  595. $scope.policy = parse(realm.passwordPolicy);
  596. var oldCopy = angular.copy($scope.policy);
  597. $scope.$watch('policy', function() {
  598. $scope.changed = ! angular.equals($scope.policy, oldCopy);
  599. }, true);
  600. $scope.addPolicy = function(policy){
  601. policy.value = policy.defaultValue;
  602. if (!$scope.policy) {
  603. $scope.policy = [];
  604. }
  605. $scope.policy.push(policy);
  606. }
  607. $scope.removePolicy = function(index){
  608. $scope.policy.splice(index, 1);
  609. }
  610. $scope.save = function() {
  611. $scope.realm.passwordPolicy = toString($scope.policy);
  612. console.log($scope.realm.passwordPolicy);
  613. Realm.update($scope.realm, function () {
  614. $route.reload();
  615. Notifications.success("Your changes have been saved to the realm.");
  616. });
  617. };
  618. $scope.reset = function() {
  619. $route.reload();
  620. };
  621. });
  622. module.controller('RealmDefaultRolesCtrl', function ($scope, $route, Realm, realm, roles, Notifications, ClientRole, Client) {
  623. console.log('RealmDefaultRolesCtrl');
  624. $scope.realm = realm;
  625. $scope.availableRealmRoles = [];
  626. $scope.selectedRealmRoles = [];
  627. $scope.selectedRealmDefRoles = [];
  628. $scope.availableClientRoles = [];
  629. $scope.selectedClientRoles = [];
  630. $scope.selectedClientDefRoles = [];
  631. if (!$scope.realm.hasOwnProperty('defaultRoles') || $scope.realm.defaultRoles === null) {
  632. $scope.realm.defaultRoles = [];
  633. }
  634. // Populate available roles. Available roles are neither already assigned
  635. for (var i = 0; i < roles.length; i++) {
  636. var item = roles[i].name;
  637. if ($scope.realm.defaultRoles.indexOf(item) < 0) {
  638. $scope.availableRealmRoles.push(item);
  639. }
  640. }
  641. $scope.addRealmDefaultRole = function () {
  642. // Remove selected roles from the Available roles and add them to realm default roles (move from left to right).
  643. for (var i = 0; i < $scope.selectedRealmRoles.length; i++) {
  644. var selectedRole = $scope.selectedRealmRoles[i];
  645. $scope.realm.defaultRoles.push(selectedRole);
  646. var index = $scope.availableRealmRoles.indexOf(selectedRole);
  647. if (index > -1) {
  648. $scope.availableRealmRoles.splice(index, 1);
  649. }
  650. }
  651. $scope.selectedRealmRoles = [];
  652. // Update/save the realm with new default roles.
  653. Realm.update($scope.realm, function () {
  654. Notifications.success("Realm default roles updated.");
  655. });
  656. };
  657. $scope.deleteRealmDefaultRole = function () {
  658. // Remove selected roles from the realm default roles and add them to available roles (move from right to left).
  659. for (var i = 0; i < $scope.selectedRealmDefRoles.length; i++) {
  660. $scope.availableRealmRoles.push($scope.selectedRealmDefRoles[i]);
  661. var index = $scope.realm.defaultRoles.indexOf($scope.selectedRealmDefRoles[i]);
  662. if (index > -1) {
  663. $scope.realm.defaultRoles.splice(index, 1);
  664. }
  665. }
  666. $scope.selectedRealmDefRoles = [];
  667. // Update/save the realm with new default roles.
  668. //var realmCopy = angular.copy($scope.realm);
  669. Realm.update($scope.realm, function () {
  670. Notifications.success("Realm default roles updated.");
  671. });
  672. };
  673. $scope.changeClient = function (client) {
  674. $scope.selectedClient = client;
  675. $scope.selectedClientRoles = [];
  676. $scope.selectedClientDefRoles = [];
  677. if (!client || !client.id) {
  678. $scope.selectedClient = null;
  679. return;
  680. }
  681. // Populate available roles for selected client
  682. if ($scope.selectedClient) {
  683. ClientRole.query({realm: $scope.realm.realm, client: $scope.selectedClient.id}, function (appDefaultRoles) {
  684. if (!$scope.selectedClient.hasOwnProperty('defaultRoles') || $scope.selectedClient.defaultRoles === null) {
  685. $scope.selectedClient.defaultRoles = [];
  686. }
  687. $scope.availableClientRoles = [];
  688. console.log('default roles', appDefaultRoles);
  689. for (var i = 0; i < appDefaultRoles.length; i++) {
  690. var roleName = appDefaultRoles[i].name;
  691. if ($scope.selectedClient.defaultRoles.indexOf(roleName) < 0) {
  692. $scope.availableClientRoles.push(roleName);
  693. }
  694. }
  695. });
  696. } else {
  697. $scope.availableClientRoles = null;
  698. }
  699. };
  700. $scope.addClientDefaultRole = function () {
  701. // Remove selected roles from the app available roles and add them to app default roles (move from left to right).
  702. for (var i = 0; i < $scope.selectedClientRoles.length; i++) {
  703. var role = $scope.selectedClientRoles[i];
  704. var idx = $scope.selectedClient.defaultRoles.indexOf(role);
  705. if (idx < 0) {
  706. $scope.selectedClient.defaultRoles.push(role);
  707. }
  708. idx = $scope.availableClientRoles.indexOf(role);
  709. if (idx != -1) {
  710. $scope.availableClientRoles.splice(idx, 1);
  711. }
  712. }
  713. $scope.selectedClientRoles = [];
  714. // Update/save the selected client with new default roles.
  715. delete $scope.selectedClient.text;
  716. Client.update({
  717. realm: $scope.realm.realm,
  718. client: $scope.selectedClient.id
  719. }, $scope.selectedClient, function () {
  720. Notifications.success("Your changes have been saved to the client.");
  721. Client.get({realm: realm.realm, client: $scope.selectedClient.id}, function(response) {
  722. response.text = response.clientId;
  723. $scope.changeClient(response);
  724. });
  725. });
  726. };
  727. $scope.rmClientDefaultRole = function () {
  728. // Remove selected roles from the app default roles and add them to app available roles (move from right to left).
  729. for (var i = 0; i < $scope.selectedClientDefRoles.length; i++) {
  730. var role = $scope.selectedClientDefRoles[i];
  731. var idx = $scope.selectedClient.defaultRoles.indexOf(role);
  732. if (idx != -1) {
  733. $scope.selectedClient.defaultRoles.splice(idx, 1);
  734. }
  735. idx = $scope.availableClientRoles.indexOf(role);
  736. if (idx < 0) {
  737. $scope.availableClientRoles.push(role);
  738. }
  739. }
  740. $scope.selectedClientDefRoles = [];
  741. // Update/save the selected client with new default roles.
  742. delete $scope.selectedClient.text;
  743. Client.update({
  744. realm: $scope.realm.realm,
  745. client: $scope.selectedClient.id
  746. }, $scope.selectedClient, function () {
  747. Notifications.success("Your changes have been saved to the client.");
  748. Client.get({realm: realm.realm, client: $scope.selectedClient.id}, function(response) {
  749. response.text = response.clientId;
  750. $scope.changeClient(response);
  751. });
  752. });
  753. };
  754. clientSelectControl($scope, $route.current.params.realm, Client);
  755. });
  756. module.controller('IdentityProviderTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
  757. $scope.removeIdentityProvider = function() {
  758. Dialog.confirmDelete($scope.identityProvider.alias, 'provider', function() {
  759. $scope.identityProvider.$remove({
  760. realm : Current.realm.realm,
  761. alias : $scope.identityProvider.alias
  762. }, function() {
  763. $location.url("/realms/" + Current.realm.realm + "/identity-provider-settings");
  764. Notifications.success("The identity provider has been deleted.");
  765. });
  766. });
  767. };
  768. });
  769. module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload, $http, $route, realm, instance, providerFactory, IdentityProvider, serverInfo, authFlows, $location, Notifications, Dialog) {
  770. $scope.realm = angular.copy(realm);
  771. $scope.initSamlProvider = function() {
  772. $scope.nameIdFormats = [
  773. /*
  774. {
  775. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
  776. name: "Transient"
  777. },
  778. */
  779. {
  780. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
  781. name: "Persistent"
  782. },
  783. {
  784. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
  785. name: "Email"
  786. },
  787. {
  788. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos",
  789. name: "Kerberos"
  790. },
  791. {
  792. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName",
  793. name: "X.509 Subject Name"
  794. },
  795. {
  796. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName",
  797. name: "Windows Domain Qualified Name"
  798. },
  799. {
  800. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
  801. name: "Unspecified"
  802. }
  803. ];
  804. $scope.signatureAlgorithms = [
  805. "RSA_SHA1",
  806. "RSA_SHA256",
  807. "RSA_SHA256_MGF1",
  808. "RSA_SHA512",
  809. "RSA_SHA512_MGF1",
  810. "DSA_SHA1"
  811. ];
  812. $scope.xmlKeyNameTranformers = [
  813. "NONE",
  814. "KEY_ID",
  815. "CERT_SUBJECT"
  816. ];
  817. $scope.principalTypes = [
  818. {
  819. type: "SUBJECT",
  820. name: "Subject NameID"
  821. },
  822. {
  823. type: "ATTRIBUTE",
  824. name: "Attribute [Name]"
  825. },
  826. {
  827. type: "FRIENDLY_ATTRIBUTE",
  828. name: "Attribute [Friendly Name]"
  829. }
  830. ];
  831. if (instance && instance.alias) {
  832. } else {
  833. $scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
  834. $scope.identityProvider.config.principalType = $scope.principalTypes[0].type;
  835. $scope.identityProvider.config.signatureAlgorithm = $scope.signatureAlgorithms[1];
  836. $scope.identityProvider.config.xmlSigKeyInfoKeyNameTransformer = $scope.xmlKeyNameTranformers[1];
  837. }
  838. $scope.identityProvider.config.entityId = $scope.identityProvider.config.entityId || (authUrl + '/realms/' + realm.realm);
  839. }
  840. $scope.hidePassword = true;
  841. $scope.fromUrl = {
  842. data: ''
  843. };
  844. if (instance && instance.alias) {
  845. $scope.identityProvider = angular.copy(instance);
  846. $scope.newIdentityProvider = false;
  847. for (var i in serverInfo.identityProviders) {
  848. var provider = serverInfo.identityProviders[i];
  849. if (provider.id == instance.providerId) {
  850. $scope.provider = provider;
  851. }
  852. }
  853. } else {
  854. $scope.identityProvider = {};
  855. $scope.identityProvider.config = {};
  856. $scope.identityProvider.alias = providerFactory.id;
  857. $scope.identityProvider.providerId = providerFactory.id;
  858. $scope.identityProvider.enabled = true;
  859. $scope.identityProvider.authenticateByDefault = false;
  860. $scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
  861. $scope.identityProvider.config.useJwksUrl = 'true';
  862. $scope.identityProvider.config.syncMode = 'IMPORT';
  863. $scope.newIdentityProvider = true;
  864. }
  865. $scope.changed = $scope.newIdentityProvider;
  866. $scope.$watch('identityProvider', function() {
  867. if (!angular.equals($scope.identityProvider, instance)) {
  868. $scope.changed = true;
  869. }
  870. }, true);
  871. $scope.serverInfo = serverInfo;
  872. $scope.allProviders = angular.copy(serverInfo.identityProviders);
  873. $scope.configuredProviders = angular.copy(realm.identityProviders);
  874. removeUsedSocial();
  875. $scope.authFlows = [];
  876. for (var i=0 ; i<authFlows.length ; i++) {
  877. if (authFlows[i].providerId == 'basic-flow') {
  878. $scope.authFlows.push(authFlows[i]);
  879. }
  880. }
  881. $scope.postBrokerAuthFlows = [];
  882. var emptyFlow = { alias: "" };
  883. $scope.postBrokerAuthFlows.push(emptyFlow);
  884. for (var i=0 ; i<$scope.authFlows.length ; i++) {
  885. $scope.postBrokerAuthFlows.push($scope.authFlows[i]);
  886. }
  887. if (!$scope.identityProvider.postBrokerLoginFlowAlias) {
  888. $scope.identityProvider.postBrokerLoginFlowAlias = $scope.postBrokerAuthFlows[0].alias;
  889. }
  890. $scope.$watch(function() {
  891. return $location.path();
  892. }, function() {
  893. $scope.path = $location.path().substring(1).split("/");
  894. });
  895. $scope.files = [];
  896. $scope.importFile = false;
  897. $scope.importUrl = false;
  898. $scope.onFileSelect = function($files) {
  899. $scope.importFile = true;
  900. $scope.files = $files;
  901. };
  902. $scope.clearFileSelect = function() {
  903. $scope.importUrl = false;
  904. $scope.importFile = false;
  905. $scope.files = null;
  906. };
  907. var setConfig = function(data) {
  908. if (data["enabledFromMetadata"] !== undefined ) {
  909. $scope.identityProvider.enabled = data["enabledFromMetadata"] == "true";
  910. delete data["enabledFromMetadata"];
  911. }
  912. for (var key in data) {
  913. $scope.identityProvider.config[key] = data[key];
  914. }
  915. }
  916. $scope.uploadFile = function() {
  917. if (!$scope.identityProvider.alias) {
  918. Notifications.error("You must specify an alias");
  919. return;
  920. }
  921. var input = {
  922. providerId: providerFactory.id
  923. }
  924. //$files: an array of files selected, each file has name, size, and type.
  925. for (var i = 0; i < $scope.files.length; i++) {
  926. var $file = $scope.files[i];
  927. $scope.upload = $upload.upload({
  928. url: authUrl + '/admin/realms/' + realm.realm + '/identity-provider/import-config',
  929. // method: POST or PUT,
  930. // headers: {'headerKey': 'headerValue'}, withCredential: true,
  931. data: input,
  932. file: $file
  933. /* set file formData name for 'Content-Desposition' header. Default: 'file' */
  934. //fileFormDataName: myFile,
  935. /* customize how data is added to formData. See #40#issuecomment-28612000 for example */
  936. //formDataAppender: function(formData, key, val){}
  937. }).progress(function(evt) {
  938. console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
  939. }).then(function(response) {
  940. setConfig(response.data);
  941. $scope.clearFileSelect();
  942. Notifications.success("The IDP metadata has been loaded from file.");
  943. }).catch(function() {
  944. Notifications.error("The file can not be uploaded. Please verify the file.");
  945. });
  946. }
  947. };
  948. $scope.importFrom = function() {
  949. if (!$scope.identityProvider.alias) {
  950. Notifications.error("You must specify an alias");
  951. return;
  952. }
  953. var input = {
  954. fromUrl: $scope.fromUrl.data,
  955. providerId: providerFactory.id
  956. }
  957. $http.post(authUrl + '/admin/realms/' + realm.realm + '/identity-provider/import-config', input)
  958. .then(function(response) {
  959. setConfig(response.data);
  960. $scope.fromUrl.data = '';
  961. $scope.importUrl = false;
  962. Notifications.success("Imported config information from url.");
  963. }).catch(function() {
  964. Notifications.error("Config can not be imported. Please verify the url.");
  965. });
  966. };
  967. $scope.$watch('fromUrl.data', function(newVal, oldVal){
  968. if ($scope.fromUrl.data && $scope.fromUrl.data.length > 0) {
  969. $scope.importUrl = true;
  970. } else{
  971. $scope.importUrl = false;
  972. }
  973. });
  974. $scope.$watch('configuredProviders', function(configuredProviders) {
  975. if (configuredProviders) {
  976. $scope.configuredProviders = angular.copy(configuredProviders);
  977. for (var j = 0; j < configuredProviders.length; j++) {
  978. var configProvidedId = configuredProviders[j].providerId;
  979. for (var i in $scope.allProviders) {
  980. var provider = $scope.allProviders[i];
  981. if (provider.id == configProvidedId) {
  982. configuredProviders[j].provider = provider;
  983. }
  984. }
  985. }
  986. $scope.configuredProviders = angular.copy(configuredProviders);
  987. }
  988. }, true);
  989. $scope.callbackUrl = authServerUrl + "/realms/" + realm.realm + "/broker/";
  990. $scope.addProvider = function(provider) {
  991. $location.url("/create/identity-provider/" + realm.realm + "/" + provider.id);
  992. };
  993. $scope.save = function() {
  994. if ($scope.newIdentityProvider) {
  995. if (!$scope.identityProvider.alias) {
  996. Notifications.error("You must specify an alias");
  997. return;
  998. }
  999. IdentityProvider.save({
  1000. realm: $scope.realm.realm, alias: ''
  1001. }, $scope.identityProvider, function () {
  1002. $location.url("/realms/" + realm.realm + "/identity-provider-settings/provider/" + $scope.identityProvider.providerId + "/" + $scope.identityProvider.alias);
  1003. Notifications.success("The " + $scope.identityProvider.alias + " provider has been created.");
  1004. });
  1005. } else {
  1006. IdentityProvider.update({
  1007. realm: $scope.realm.realm,
  1008. alias: $scope.identityProvider.alias
  1009. }, $scope.identityProvider, function () {
  1010. $route.reload();
  1011. Notifications.success("The " + $scope.identityProvider.alias + " provider has been updated.");
  1012. });
  1013. }
  1014. };
  1015. $scope.cancel = function() {
  1016. if ($scope.newIdentityProvider) {
  1017. $location.url("/realms/" + realm.realm + "/identity-provider-settings");
  1018. } else {
  1019. $route.reload();
  1020. }
  1021. };
  1022. $scope.reset = function() {
  1023. $scope.identityProvider = {};
  1024. $scope.configuredProviders = angular.copy($scope.realm.identityProviders);
  1025. };
  1026. $scope.showPassword = function(flag) {
  1027. $scope.hidePassword = flag;
  1028. };
  1029. $scope.removeIdentityProvider = function(identityProvider) {
  1030. Dialog.confirmDelete(identityProvider.alias, 'provider', function() {
  1031. IdentityProvider.remove({
  1032. realm : realm.realm,
  1033. alias : identityProvider.alias
  1034. }, function() {
  1035. $route.reload();
  1036. Notifications.success("The identity provider has been deleted.");
  1037. });
  1038. });
  1039. };
  1040. // KEYCLOAK-5932: remove social providers that have already been defined
  1041. function removeUsedSocial() {
  1042. var i = $scope.allProviders.length;
  1043. while (i--) {
  1044. if ($scope.allProviders[i].groupName !== 'Social') continue;
  1045. if ($scope.configuredProviders != null) {
  1046. for (var j = 0; j < $scope.configuredProviders.length; j++) {
  1047. if ($scope.configuredProviders[j].providerId === $scope.allProviders[i].id) {
  1048. $scope.allProviders.splice(i, 1);
  1049. break;
  1050. }
  1051. }
  1052. }
  1053. }
  1054. };
  1055. if (instance && instance.alias) {
  1056. try { $scope.authnContextClassRefs = JSON.parse($scope.identityProvider.config.authnContextClassRefs || '[]'); } catch (e) { $scope.authnContextClassRefs = []; }
  1057. try { $scope.authnContextDeclRefs = JSON.parse($scope.identityProvider.config.authnContextDeclRefs || '[]'); } catch (e) { $scope.authnContextDeclRefs = []; }
  1058. } else {
  1059. $scope.authnContextClassRefs = [];
  1060. $scope.authnContextDeclRefs = [];
  1061. }
  1062. $scope.deleteAuthnContextClassRef = function(index) {
  1063. $scope.authnContextClassRefs.splice(index, 1);
  1064. $scope.identityProvider.config.authnContextClassRefs = JSON.stringify($scope.authnContextClassRefs);
  1065. };
  1066. $scope.addAuthnContextClassRef = function() {
  1067. $scope.authnContextClassRefs.push($scope.newAuthnContextClassRef);
  1068. $scope.identityProvider.config.authnContextClassRefs = JSON.stringify($scope.authnContextClassRefs);
  1069. $scope.newAuthnContextClassRef = "";
  1070. };
  1071. $scope.deleteAuthnContextDeclRef = function(index) {
  1072. $scope.authnContextDeclRefs.splice(index, 1);
  1073. $scope.identityProvider.config.authnContextDeclRefs = JSON.stringify($scope.authnContextDeclRefs);
  1074. };
  1075. $scope.addAuthnContextDeclRef = function() {
  1076. $scope.authnContextDeclRefs.push($scope.newAuthnContextDeclRef);
  1077. $scope.identityProvider.config.authnContextDeclRefs = JSON.stringify($scope.authnContextDeclRefs);
  1078. $scope.newAuthnContextDeclRef = "";
  1079. };
  1080. });
  1081. module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, $route, Dialog, Notifications, TimeUnit, TimeUnit2, serverInfo) {
  1082. $scope.realm = realm;
  1083. $scope.serverInfo = serverInfo;
  1084. $scope.actionTokenProviders = $scope.serverInfo.providers.actionTokenHandler.providers;
  1085. $scope.realm.accessTokenLifespan = TimeUnit2.asUnit(realm.accessTokenLifespan);
  1086. $scope.realm.accessTokenLifespanForImplicitFlow = TimeUnit2.asUnit(realm.accessTokenLifespanForImplicitFlow);
  1087. $scope.realm.ssoSessionIdleTimeout = TimeUnit2.asUnit(realm.ssoSessionIdleTimeout);
  1088. $scope.realm.ssoSessionMaxLifespan = TimeUnit2.asUnit(realm.ssoSessionMaxLifespan);
  1089. $scope.realm.ssoSessionIdleTimeoutRememberMe = TimeUnit2.asUnit(realm.ssoSessionIdleTimeoutRememberMe);
  1090. $scope.realm.ssoSessionMaxLifespanRememberMe = TimeUnit2.asUnit(realm.ssoSessionMaxLifespanRememberMe);
  1091. $scope.realm.offlineSessionIdleTimeout = TimeUnit2.asUnit(realm.offlineSessionIdleTimeout);
  1092. // KEYCLOAK-7688 Offline Session Max for Offline Token
  1093. $scope.realm.offlineSessionMaxLifespan = TimeUnit2.asUnit(realm.offlineSessionMaxLifespan);
  1094. $scope.realm.clientSessionIdleTimeout = TimeUnit2.asUnit(realm.clientSessionIdleTimeout);
  1095. $scope.realm.clientSessionMaxLifespan = TimeUnit2.asUnit(realm.clientSessionMaxLifespan);
  1096. $scope.realm.clientOfflineSessionIdleTimeout = TimeUnit2.asUnit(realm.clientOfflineSessionIdleTimeout);
  1097. $scope.realm.clientOfflineSessionMaxLifespan = TimeUnit2.asUnit(realm.clientOfflineSessionMaxLifespan);
  1098. $scope.realm.accessCodeLifespan = TimeUnit2.asUnit(realm.accessCodeLifespan);
  1099. $scope.realm.accessCodeLifespanLogin = TimeUnit2.asUnit(realm.accessCodeLifespanLogin);
  1100. $scope.realm.accessCodeLifespanUserAction = TimeUnit2.asUnit(realm.accessCodeLifespanUserAction);
  1101. $scope.realm.actionTokenGeneratedByAdminLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByAdminLifespan);
  1102. $scope.realm.actionTokenGeneratedByUserLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByUserLifespan);
  1103. $scope.realm.attributes = realm.attributes
  1104. var oldCopy = angular.copy($scope.realm);
  1105. $scope.changed = false;
  1106. $scope.$watch('realm', function() {
  1107. if (!angular.equals($scope.realm, oldCopy)) {
  1108. $scope.changed = true;
  1109. }
  1110. }, true);
  1111. $scope.$watch('actionLifespanId', function () {
  1112. // changedActionLifespanId signals other watchers that we were merely
  1113. // changing the dropdown and we should not enable 'save' button
  1114. if ($scope.actionTokenAttribute && $scope.actionTokenAttribute.hasOwnProperty('time')) {
  1115. $scope.changedActionLifespanId = true;
  1116. }
  1117. $scope.actionTokenAttribute = TimeUnit2.asUnit($scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId]);
  1118. }, true);
  1119. $scope.$watch('actionTokenAttribute', function () {
  1120. if ($scope.actionLifespanId === null) return;
  1121. if ($scope.changedActionLifespanId) {
  1122. $scope.changedActionLifespanId = false;
  1123. return;
  1124. } else {
  1125. $scope.changed = true;
  1126. }
  1127. if ($scope.actionTokenAttribute !== null) {
  1128. $scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId] = $scope.actionTokenAttribute.toSeconds();
  1129. }
  1130. }, true);
  1131. $scope.changeRevokeRefreshToken = function() {
  1132. };
  1133. $scope.save = function() {
  1134. $scope.realm.accessTokenLifespan = $scope.realm.accessTokenLifespan.toSeconds();
  1135. $scope.realm.accessTokenLifespanForImplicitFlow = $scope.realm.accessTokenLifespanForImplicitFlow.toSeconds();
  1136. $scope.realm.ssoSessionIdleTimeout = $scope.realm.ssoSessionIdleTimeout.toSeconds();
  1137. $scope.realm.ssoSessionMaxLifespan = $scope.realm.ssoSessionMaxLifespan.toSeconds();
  1138. $scope.realm.ssoSessionIdleTimeoutRememberMe = $scope.realm.ssoSessionIdleTimeoutRememberMe.toSeconds();
  1139. $scope.realm.ssoSessionMaxLifespanRememberMe = $scope.realm.ssoSessionMaxLifespanRememberMe.toSeconds();
  1140. $scope.realm.offlineSessionIdleTimeout = $scope.realm.offlineSessionIdleTimeout.toSeconds();
  1141. // KEYCLOAK-7688 Offline Session Max for Offline Token
  1142. $scope.realm.offlineSessionMaxLifespan = $scope.realm.offlineSessionMaxLifespan.toSeconds();
  1143. $scope.realm.clientSessionIdleTimeout = $scope.realm.clientSessionIdleTimeout.toSeconds();
  1144. $scope.realm.clientSessionMaxLifespan = $scope.realm.clientSessionMaxLifespan.toSeconds();
  1145. $scope.realm.clientOfflineSessionIdleTimeout = $scope.realm.clientOfflineSessionIdleTimeout.toSeconds();
  1146. $scope.realm.clientOfflineSessionMaxLifespan = $scope.realm.clientOfflineSessionMaxLifespan.toSeconds();
  1147. $scope.realm.accessCodeLifespan = $scope.realm.accessCodeLifespan.toSeconds();
  1148. $scope.realm.accessCodeLifespanUserAction = $scope.realm.accessCodeLifespanUserAction.toSeconds();
  1149. $scope.realm.accessCodeLifespanLogin = $scope.realm.accessCodeLifespanLogin.toSeconds();
  1150. $scope.realm.actionTokenGeneratedByAdminLifespan = $scope.realm.actionTokenGeneratedByAdminLifespan.toSeconds();
  1151. $scope.realm.actionTokenGeneratedByUserLifespan = $scope.realm.actionTokenGeneratedByUserLifespan.toSeconds();
  1152. Realm.update($scope.realm, function () {
  1153. $route.reload();
  1154. Notifications.success("The changes have been saved to the realm.");
  1155. });
  1156. };
  1157. $scope.resetToDefaultToken = function (actionTokenId) {
  1158. $scope.actionTokenAttribute = {};
  1159. delete $scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId];
  1160. //Only for UI effects, resets to the original state
  1161. $scope.actionTokenAttribute.unit = 'Minutes';
  1162. }
  1163. $scope.reset = function() {
  1164. $route.reload();
  1165. };
  1166. });
  1167. module.controller('ViewKeyCtrl', function($scope, key) {
  1168. $scope.key = key;
  1169. });
  1170. module.controller('RealmKeysCtrl', function($scope, Realm, realm, $http, $route, $location, Dialog, Notifications, serverInfo, keys, Components, $modal) {
  1171. $scope.realm = angular.copy(realm);
  1172. $scope.keys = keys.keys;
  1173. $scope.active = {};
  1174. Components.query({realm: realm.realm,
  1175. parent: realm.id,
  1176. type: 'org.keycloak.keys.KeyProvider'
  1177. }, function(data) {
  1178. for (var i = 0; i < keys.keys.length; i++) {
  1179. for (var j = 0; j < data.length; j++) {
  1180. if (keys.keys[i].providerId == data[j].id) {
  1181. keys.keys[i].provider = data[j];
  1182. }
  1183. }
  1184. }
  1185. for (var t in keys.active) {
  1186. for (var i = 0; i < keys.keys.length; i++) {
  1187. if (keys.active[t] == keys.keys[i].kid) {
  1188. $scope.active[t] = keys.keys[i];
  1189. }
  1190. }
  1191. }
  1192. });
  1193. $scope.viewKey = function(key) {
  1194. $modal.open({
  1195. templateUrl: resourceUrl + '/partials/modal/view-key.html',
  1196. controller: 'ViewKeyCtrl',
  1197. resolve: {
  1198. key: function () {
  1199. return key;
  1200. }
  1201. }
  1202. })
  1203. }
  1204. });
  1205. module.controller('RealmKeysProvidersCtrl', function($scope, Realm, realm, $http, $route, $location, Dialog, Notifications, serverInfo, Components, $modal) {
  1206. $scope.realm = angular.copy(realm);
  1207. $scope.enableUpload = false;
  1208. $scope.providers = serverInfo.componentTypes['org.keycloak.keys.KeyProvider'];
  1209. Components.query({realm: realm.realm,
  1210. parent: realm.id,
  1211. type: 'org.keycloak.keys.KeyProvider'
  1212. }, function(data) {
  1213. $scope.instances = data;
  1214. for (var i = 0; i < $scope.instances.length; i++) {
  1215. for (var j = 0; j < $scope.providers.length; j++) {
  1216. if ($scope.providers[j].id === $scope.instances[i].providerId) {
  1217. $scope.instances[i].provider = $scope.providers[j];
  1218. }
  1219. }
  1220. }
  1221. });
  1222. $scope.addProvider = function(provider) {
  1223. $location.url("/create/keys/" + realm.realm + "/providers/" + provider.id);
  1224. };
  1225. $scope.removeInstance = function(instance) {
  1226. Dialog.confirmDelete(instance.name, 'key provider', function() {
  1227. Components.remove({
  1228. realm : realm.realm,
  1229. componentId : instance.id
  1230. }, function() {
  1231. $route.reload();
  1232. Notifications.success("The provider has been deleted.");
  1233. });
  1234. });
  1235. };
  1236. });
  1237. module.controller('GenericKeystoreCtrl', function($scope, $location, Notifications, $route, Dialog, realm, serverInfo, instance, providerId, Components) {
  1238. $scope.create = !instance.providerId;
  1239. $scope.realm = realm;
  1240. var providers = serverInfo.componentTypes['org.keycloak.keys.KeyProvider'];
  1241. var providerFactory = null;
  1242. for (var i = 0; i < providers.length; i++) {
  1243. var p = providers[i];
  1244. if (p.id == providerId) {
  1245. $scope.providerFactory = p;
  1246. providerFactory = p;
  1247. break;
  1248. }
  1249. }
  1250. if ($scope.create) {
  1251. $scope.instance = {
  1252. name: providerFactory.id,
  1253. providerId: providerFactory.id,
  1254. providerType: 'org.keycloak.keys.KeyProvider',
  1255. parentId: realm.id,
  1256. config: {
  1257. 'priority': ["0"]
  1258. }
  1259. }
  1260. } else {
  1261. $scope.instance = angular.copy(instance);
  1262. }
  1263. if (providerFactory.properties) {
  1264. for (var i = 0; i < providerFactory.properties.length; i++) {
  1265. var configProperty = providerFactory.properties[i];
  1266. if (!$scope.instance.config[configProperty.name]) {
  1267. if (configProperty.defaultValue) {
  1268. $scope.instance.config[configProperty.name] = [configProperty.defaultValue];
  1269. if (!$scope.create) {
  1270. instance.config[configProperty.name] = [configProperty.defaultValue];
  1271. }
  1272. } else {
  1273. $scope.instance.config[configProperty.name] = [''];
  1274. if (!$scope.create) {
  1275. instance.config[configProperty.name] = [configProperty.defaultValue];
  1276. }
  1277. }
  1278. }
  1279. }
  1280. }
  1281. $scope.$watch('instance', function() {
  1282. if (!angular.equals($scope.instance, instance)) {
  1283. $scope.changed = true;
  1284. }
  1285. }, true);
  1286. $scope.save = function() {
  1287. $scope.changed = false;
  1288. if ($scope.create) {
  1289. Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
  1290. var l = headers().location;
  1291. var id = l.substring(l.lastIndexOf("/") + 1);
  1292. $location.url("/realms/" + realm.realm + "/keys/providers/" + $scope.instance.providerId + "/" + id);
  1293. Notifications.success("The provider has been created.");
  1294. });
  1295. } else {
  1296. Components.update({realm: realm.realm,
  1297. componentId: instance.id
  1298. },
  1299. $scope.instance, function () {
  1300. $route.reload();
  1301. Notifications.success("The provider has been updated.");
  1302. });
  1303. }
  1304. };
  1305. $scope.reset = function() {
  1306. $route.reload();
  1307. };
  1308. $scope.cancel = function() {
  1309. if ($scope.create) {
  1310. $location.url("/realms/" + realm.realm + "/keys");
  1311. } else {
  1312. $route.reload();
  1313. }
  1314. };
  1315. });
  1316. module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmClientSessionStats, RealmLogoutAll, Notifications) {
  1317. $scope.realm = realm;
  1318. $scope.stats = stats;
  1319. $scope.logoutAll = function() {
  1320. RealmLogoutAll.save({realm : realm.realm}, function (globalReqResult) {
  1321. var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0;
  1322. var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0;
  1323. if (failedCount > 0) {
  1324. var msgStart = successCount>0 ? 'Successfully logout all users under: ' + globalReqResult.successRequests + ' . ' : '';
  1325. Notifications.error(msgStart + 'Failed to logout users under: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again');
  1326. } else {
  1327. window.location.reload();
  1328. }
  1329. });
  1330. };
  1331. });
  1332. module.controller('RealmRevocationCtrl', function($scope, Realm, RealmPushRevocation, realm, $http, $location, Dialog, Notifications) {
  1333. $scope.realm = angular.copy(realm);
  1334. var setNotBefore = function() {
  1335. if ($scope.realm.notBefore == 0) {
  1336. $scope.notBefore = "None";
  1337. } else {
  1338. $scope.notBefore = new Date($scope.realm.notBefore * 1000);
  1339. }
  1340. };
  1341. setNotBefore();
  1342. var reset = function() {
  1343. Realm.get({ id : realm.realm }, function(updated) {
  1344. $scope.realm = updated;
  1345. setNotBefore();
  1346. })
  1347. };
  1348. $scope.clear = function() {
  1349. Realm.update({ realm: realm.realm, notBefore : 0 }, function () {
  1350. $scope.notBefore = "None";
  1351. Notifications.success('Not Before cleared for realm.');
  1352. reset();
  1353. });
  1354. }
  1355. $scope.setNotBeforeNow = function() {
  1356. Realm.update({ realm: realm.realm, notBefore : new Date().getTime()/1000}, function () {
  1357. Notifications.success('Not Before set for realm.');
  1358. reset();
  1359. });
  1360. }
  1361. $scope.pushRevocation = function() {
  1362. RealmPushRevocation.save({ realm: realm.realm}, function (globalReqResult) {
  1363. var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0;
  1364. var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0;
  1365. if (successCount==0 && failedCount==0) {
  1366. Notifications.warn('No push sent. No admin URI configured or no registered cluster nodes available');
  1367. } else if (failedCount > 0) {
  1368. var msgStart = successCount>0 ? 'Successfully push notBefore to: ' + globalReqResult.successRequests + ' . ' : '';
  1369. Notifications.error(msgStart + 'Failed to push notBefore to: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again');
  1370. } else {
  1371. Notifications.success('Successfully push notBefore to all configured clients');
  1372. }
  1373. });
  1374. }
  1375. });
  1376. module.controller('RoleTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
  1377. $scope.removeRole = function() {
  1378. Dialog.confirmDelete($scope.role.name, 'role', function() {
  1379. RoleById.remove({
  1380. realm: realm.realm,
  1381. role: $scope.role.id
  1382. }, function () {
  1383. $route.reload();
  1384. Notifications.success("The role has been deleted.");
  1385. });
  1386. });
  1387. };
  1388. });
  1389. module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications, realm, RoleList, RoleById, filterFilter) {
  1390. $scope.realm = realm;
  1391. $scope.roles = [];
  1392. $scope.query = {
  1393. realm: realm.realm,
  1394. search : null,
  1395. max : 20,
  1396. first : 0
  1397. }
  1398. $scope.$watch('query.search', function (newVal, oldVal) {
  1399. if($scope.query.search && $scope.query.search.length >= 3) {
  1400. $scope.firstPage();
  1401. }
  1402. }, true);
  1403. $scope.firstPage = function() {
  1404. $scope.query.first = 0;
  1405. $scope.searchQuery();
  1406. }
  1407. $scope.previousPage = function() {
  1408. $scope.query.first -= parseInt($scope.query.max);
  1409. if ($scope.query.first < 0) {
  1410. $scope.query.first = 0;
  1411. }
  1412. $scope.searchQuery();
  1413. }
  1414. $scope.nextPage = function() {
  1415. $scope.query.first += parseInt($scope.query.max);
  1416. $scope.searchQuery();
  1417. }
  1418. $scope.searchQuery = function() {
  1419. $scope.searchLoaded = false;
  1420. $scope.roles = RoleList.query($scope.query, function() {
  1421. $scope.searchLoaded = true;
  1422. $scope.lastSearch = $scope.query.search;
  1423. });
  1424. };
  1425. $scope.searchQuery();
  1426. $scope.removeRole = function (role) {
  1427. Dialog.confirmDelete(role.name, 'role', function () {
  1428. RoleById.remove({
  1429. realm: realm.realm,
  1430. role: role.id
  1431. }, function () {
  1432. $route.reload();
  1433. Notifications.success("The role has been deleted.");
  1434. });
  1435. });
  1436. };
  1437. });
  1438. module.controller('RoleDetailCtrl', function($scope, realm, role, roles, Client, $route,
  1439. Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
  1440. $http, $location, Dialog, Notifications, RealmRoleRemover, ComponentUtils) {
  1441. $scope.realm = realm;
  1442. $scope.role = angular.copy(role);
  1443. $scope.create = !role.name;
  1444. $scope.changed = $scope.create;
  1445. $scope.save = function() {
  1446. convertAttributeValuesToLists();
  1447. console.log('save');
  1448. if ($scope.create) {
  1449. Role.save({
  1450. realm: realm.realm
  1451. }, $scope.role, function (data, headers) {
  1452. $scope.changed = false;
  1453. convertAttributeValuesToString($scope.role);
  1454. role = angular.copy($scope.role);
  1455. Role.get({ realm: realm.realm, role: role.name }, function(role) {
  1456. var id = role.id;
  1457. $location.url("/realms/" + realm.realm + "/roles/" + id);
  1458. Notifications.success("The role has been created.");
  1459. });
  1460. });
  1461. } else {
  1462. $scope.update();
  1463. }
  1464. };
  1465. $scope.remove = function() {
  1466. RealmRoleRemover.remove($scope.role, realm, Dialog, $location, Notifications);
  1467. };
  1468. $scope.cancel = function () {
  1469. $location.url("/realms/" + realm.realm + "/roles");
  1470. };
  1471. $scope.addAttribute = function() {
  1472. $scope.role.attributes[$scope.newAttribute.key] = $scope.newAttribute.value;
  1473. delete $scope.newAttribute;
  1474. }
  1475. $scope.removeAttribute = function(key) {
  1476. delete $scope.role.attributes[key];
  1477. }
  1478. function convertAttributeValuesToLists() {
  1479. var attrs = $scope.role.attributes;
  1480. for (var attribute in attrs) {
  1481. if (typeof attrs[attribute] === "string") {
  1482. var attrVals = attrs[attribute].split("##");
  1483. attrs[attribute] = attrVals;
  1484. }
  1485. }
  1486. }
  1487. function convertAttributeValuesToString(role) {
  1488. var attrs = role.attributes;
  1489. for (var attribute in attrs) {
  1490. if (typeof attrs[attribute] === "object") {
  1491. var attrVals = attrs[attribute].join("##");
  1492. attrs[attribute] = attrVals;
  1493. console.log("attribute" + attrVals)
  1494. }
  1495. }
  1496. }
  1497. roleControl($scope, $route, realm, role, roles, Client,
  1498. ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
  1499. $http, $location, Notifications, Dialog, ComponentUtils);
  1500. });
  1501. module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, realm, $http, $location, Dialog, Notifications, RealmSMTPConnectionTester) {
  1502. console.log('RealmSMTPSettingsCtrl');
  1503. var booleanSmtpAtts = ["auth","ssl","starttls"];
  1504. $scope.realm = realm;
  1505. if ($scope.realm.smtpServer) {
  1506. $scope.realm.smtpServer = typeObject($scope.realm.smtpServer);
  1507. };
  1508. var oldCopy = angular.copy($scope.realm);
  1509. $scope.changed = false;
  1510. $scope.$watch('realm', function() {
  1511. if (!angular.equals($scope.realm, oldCopy)) {
  1512. $scope.changed = true;
  1513. }
  1514. }, true);
  1515. $scope.save = function() {
  1516. var realmCopy = angular.copy($scope.realm);
  1517. realmCopy['smtpServer'] = detypeObject(realmCopy.smtpServer);
  1518. $scope.changed = false;
  1519. Realm.update(realmCopy, function () {
  1520. $location.url("/realms/" + realm.realm + "/smtp-settings");
  1521. Notifications.success("Your changes have been saved to the realm.");
  1522. });
  1523. };
  1524. $scope.reset = function() {
  1525. $scope.realm = angular.copy(oldCopy);
  1526. $scope.changed = false;
  1527. };
  1528. $scope.testConnection = function() {
  1529. RealmSMTPConnectionTester.save({realm: realm.realm}, realm.smtpServer, function() {
  1530. Notifications.success("SMTP connection successful. E-mail was sent!");
  1531. }, function(errorResponse) {
  1532. if (error.data.errorMessage) {
  1533. Notifications.error(error.data.errorMessage);
  1534. } else {
  1535. Notifications.error('Unexpected error during SMTP validation');
  1536. }
  1537. });
  1538. };
  1539. /* Convert string attributes containing a boolean to actual boolean type + convert an integer string (port) to integer. */
  1540. function typeObject(obj){
  1541. for (var att in obj){
  1542. if (booleanSmtpAtts.indexOf(att) < 0)
  1543. continue;
  1544. if (obj[att] === "true"){
  1545. obj[att] = true;
  1546. } else if (obj[att] === "false"){
  1547. obj[att] = false;
  1548. }
  1549. }
  1550. obj['port'] = parseInt(obj['port']);
  1551. return obj;
  1552. }
  1553. /* Convert all non-string values to strings to invert changes caused by the typeObject function. */
  1554. function detypeObject(obj){
  1555. for (var att in obj){
  1556. if (booleanSmtpAtts.indexOf(att) < 0)
  1557. continue;
  1558. if (obj[att] === true){
  1559. obj[att] = "true";
  1560. } else if (obj[att] === false){
  1561. obj[att] = "false"
  1562. }
  1563. }
  1564. obj['port'] = obj['port'] && obj['port'].toString();
  1565. return obj;
  1566. }
  1567. });
  1568. module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, RealmAdminEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
  1569. $scope.realm = realm;
  1570. $scope.eventsConfig = eventsConfig;
  1571. $scope.eventsConfig.expirationUnit = TimeUnit.autoUnit(eventsConfig.eventsExpiration);
  1572. $scope.eventsConfig.eventsExpiration = TimeUnit.toUnit(eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit);
  1573. $scope.eventListeners = Object.keys(serverInfo.providers.eventsListener.providers);
  1574. $scope.eventsConfigSelectOptions = {
  1575. 'multiple': true,
  1576. 'simple_tags': true,
  1577. 'tags': $scope.eventListeners
  1578. };
  1579. $scope.eventSelectOptions = {
  1580. 'multiple': true,
  1581. 'simple_tags': true,
  1582. 'tags': serverInfo.enums['eventType']
  1583. };
  1584. var oldCopy = angular.copy($scope.eventsConfig);
  1585. $scope.changed = false;
  1586. $scope.$watch('eventsConfig', function() {
  1587. if (!angular.equals($scope.eventsConfig, oldCopy)) {
  1588. $scope.changed = true;
  1589. }
  1590. }, true);
  1591. $scope.save = function() {
  1592. $scope.changed = false;
  1593. var copy = angular.copy($scope.eventsConfig)
  1594. delete copy['expirationUnit'];
  1595. copy.eventsExpiration = TimeUnit.toSeconds($scope.eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit);
  1596. RealmEventsConfig.update({
  1597. id : realm.realm
  1598. }, copy, function () {
  1599. $location.url("/realms/" + realm.realm + "/events-settings");
  1600. Notifications.success("Your changes have been saved to the realm.");
  1601. });
  1602. };
  1603. $scope.reset = function() {
  1604. $scope.eventsConfig = angular.copy(oldCopy);
  1605. $scope.changed = false;
  1606. };
  1607. $scope.clearEvents = function() {
  1608. Dialog.confirmDelete($scope.realm.realm, 'events', function() {
  1609. RealmEvents.remove({ id : $scope.realm.realm }, function() {
  1610. Notifications.success("The events has been cleared.");
  1611. });
  1612. });
  1613. };
  1614. $scope.clearAdminEvents = function() {
  1615. Dialog.confirmDelete($scope.realm.realm, 'admin-events', function() {
  1616. RealmAdminEvents.remove({ id : $scope.realm.realm }, function() {
  1617. Notifications.success("The admin events has been cleared.");
  1618. });
  1619. });
  1620. };
  1621. });
  1622. module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, serverInfo) {
  1623. $scope.realm = realm;
  1624. $scope.page = 0;
  1625. $scope.eventSelectOptions = {
  1626. 'multiple': true,
  1627. 'simple_tags': true,
  1628. 'tags': serverInfo.enums['eventType']
  1629. };
  1630. $scope.query = {
  1631. id : realm.realm,
  1632. max : 5,
  1633. first : 0
  1634. }
  1635. $scope.disablePaste = function(e) {
  1636. e.preventDefault();
  1637. return false;
  1638. }
  1639. $scope.update = function() {
  1640. $scope.query.first = 0;
  1641. for (var i in $scope.query) {
  1642. if ($scope.query[i] === '') {
  1643. delete $scope.query[i];
  1644. }
  1645. }
  1646. $scope.events = RealmEvents.query($scope.query);
  1647. }
  1648. $scope.reset = function() {
  1649. $scope.query.first = 0;
  1650. $scope.query.max = 5;
  1651. $scope.query.type = '';
  1652. $scope.query.client = '';
  1653. $scope.query.user = '';
  1654. $scope.query.dateFrom = '';
  1655. $scope.query.dateTo = '';
  1656. $scope.update();
  1657. }
  1658. $scope.queryUpdate = function() {
  1659. for (var i in $scope.query) {
  1660. if ($scope.query[i] === '') {
  1661. delete $scope.query[i];
  1662. }
  1663. }
  1664. $scope.events = RealmEvents.query($scope.query);
  1665. }
  1666. $scope.firstPage = function() {
  1667. $scope.query.first = 0;
  1668. $scope.queryUpdate();
  1669. }
  1670. $scope.previousPage = function() {
  1671. $scope.query.first -= parseInt($scope.query.max);
  1672. if ($scope.query.first < 0) {
  1673. $scope.query.first = 0;
  1674. }
  1675. $scope.queryUpdate();
  1676. }
  1677. $scope.nextPage = function() {
  1678. $scope.query.first += parseInt($scope.query.max);
  1679. $scope.queryUpdate();
  1680. }
  1681. $scope.update();
  1682. });
  1683. module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, realm, serverInfo, $modal, $filter) {
  1684. $scope.realm = realm;
  1685. $scope.page = 0;
  1686. $scope.query = {
  1687. id : realm.realm,
  1688. max : 5,
  1689. first : 0
  1690. };
  1691. $scope.adminEnabledEventOperationsOptions = {
  1692. 'multiple': true,
  1693. 'simple_tags': true,
  1694. 'tags': serverInfo.enums['operationType']
  1695. };
  1696. $scope.adminEnabledEventResourceTypesOptions = {
  1697. 'multiple': true,
  1698. 'simple_tags': true,
  1699. 'tags': serverInfo.enums['resourceType']
  1700. };
  1701. $scope.disablePaste = function(e) {
  1702. e.preventDefault();
  1703. return false;
  1704. }
  1705. $scope.update = function() {
  1706. $scope.query.first = 0;
  1707. for (var i in $scope.query) {
  1708. if ($scope.query[i] === '') {
  1709. delete $scope.query[i];
  1710. }
  1711. }
  1712. $scope.events = RealmAdminEvents.query($scope.query);
  1713. };
  1714. $scope.reset = function() {
  1715. $scope.query.first = 0;
  1716. $scope.query.max = 5;
  1717. $scope.query.operationTypes = '';
  1718. $scope.query.resourceTypes = '';
  1719. $scope.query.resourcePath = '';
  1720. $scope.query.authRealm = '';
  1721. $scope.query.authClient = '';
  1722. $scope.query.authUser = '';
  1723. $scope.query.authIpAddress = '';
  1724. $scope.query.dateFrom = '';
  1725. $scope.query.dateTo = '';
  1726. $scope.update();
  1727. };
  1728. $scope.queryUpdate = function() {
  1729. for (var i in $scope.query) {
  1730. if ($scope.query[i] === '') {
  1731. delete $scope.query[i];
  1732. }
  1733. }
  1734. $scope.events = RealmAdminEvents.query($scope.query);
  1735. }
  1736. $scope.firstPage = function() {
  1737. $scope.query.first = 0;
  1738. $scope.queryUpdate();
  1739. }
  1740. $scope.previousPage = function() {
  1741. $scope.query.first -= parseInt($scope.query.max);
  1742. if ($scope.query.first < 0) {
  1743. $scope.query.first = 0;
  1744. }
  1745. $scope.queryUpdate();
  1746. }
  1747. $scope.nextPage = function() {
  1748. $scope.query.first += parseInt($scope.query.max);
  1749. $scope.queryUpdate();
  1750. }
  1751. $scope.update();
  1752. $scope.viewRepresentation = function(event) {
  1753. $modal.open({
  1754. templateUrl: resourceUrl + '/partials/modal/realm-events-admin-representation.html',
  1755. controller: 'RealmAdminEventsModalCtrl',
  1756. resolve: {
  1757. event: function () {
  1758. return event;
  1759. }
  1760. }
  1761. })
  1762. }
  1763. $scope.viewAuth = function(event) {
  1764. $modal.open({
  1765. templateUrl: resourceUrl + '/partials/modal/realm-events-admin-auth.html',
  1766. controller: 'RealmAdminEventsModalCtrl',
  1767. resolve: {
  1768. event: function () {
  1769. return event;
  1770. }
  1771. }
  1772. })
  1773. }
  1774. });
  1775. module.controller('RealmAdminEventsModalCtrl', function($scope, $filter, event) {
  1776. $scope.event = event;
  1777. });
  1778. module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, TimeUnit, $route) {
  1779. console.log('RealmBruteForceCtrl');
  1780. $scope.realm = realm;
  1781. $scope.realm.waitIncrementUnit = TimeUnit.autoUnit(realm.waitIncrementSeconds);
  1782. $scope.realm.waitIncrement = TimeUnit.toUnit(realm.waitIncrementSeconds, $scope.realm.waitIncrementUnit);
  1783. $scope.realm.minimumQuickLoginWaitUnit = TimeUnit.autoUnit(realm.minimumQuickLoginWaitSeconds);
  1784. $scope.realm.minimumQuickLoginWait = TimeUnit.toUnit(realm.minimumQuickLoginWaitSeconds, $scope.realm.minimumQuickLoginWaitUnit);
  1785. $scope.realm.maxFailureWaitUnit = TimeUnit.autoUnit(realm.maxFailureWaitSeconds);
  1786. $scope.realm.maxFailureWait = TimeUnit.toUnit(realm.maxFailureWaitSeconds, $scope.realm.maxFailureWaitUnit);
  1787. $scope.realm.maxDeltaTimeUnit = TimeUnit.autoUnit(realm.maxDeltaTimeSeconds);
  1788. $scope.realm.maxDeltaTime = TimeUnit.toUnit(realm.maxDeltaTimeSeconds, $scope.realm.maxDeltaTimeUnit);
  1789. var oldCopy = angular.copy($scope.realm);
  1790. $scope.changed = false;
  1791. $scope.$watch('realm', function() {
  1792. if (!angular.equals($scope.realm, oldCopy)) {
  1793. $scope.changed = true;
  1794. }
  1795. }, true);
  1796. $scope.save = function() {
  1797. var realmCopy = angular.copy($scope.realm);
  1798. delete realmCopy["waitIncrementUnit"];
  1799. delete realmCopy["waitIncrement"];
  1800. delete realmCopy["minimumQuickLoginWaitUnit"];
  1801. delete realmCopy["minimumQuickLoginWait"];
  1802. delete realmCopy["maxFailureWaitUnit"];
  1803. delete realmCopy["maxFailureWait"];
  1804. delete realmCopy["maxDeltaTimeUnit"];
  1805. delete realmCopy["maxDeltaTime"];
  1806. realmCopy.waitIncrementSeconds = TimeUnit.toSeconds($scope.realm.waitIncrement, $scope.realm.waitIncrementUnit)
  1807. realmCopy.minimumQuickLoginWaitSeconds = TimeUnit.toSeconds($scope.realm.minimumQuickLoginWait, $scope.realm.minimumQuickLoginWaitUnit)
  1808. realmCopy.maxFailureWaitSeconds = TimeUnit.toSeconds($scope.realm.maxFailureWait, $scope.realm.maxFailureWaitUnit)
  1809. realmCopy.maxDeltaTimeSeconds = TimeUnit.toSeconds($scope.realm.maxDeltaTime, $scope.realm.maxDeltaTimeUnit)
  1810. $scope.changed = false;
  1811. Realm.update(realmCopy, function () {
  1812. oldCopy = angular.copy($scope.realm);
  1813. $location.url("/realms/" + realm.realm + "/defense/brute-force");
  1814. Notifications.success("Your changes have been saved to the realm.");
  1815. });
  1816. };
  1817. $scope.reset = function() {
  1818. $route.reload();
  1819. };
  1820. });
  1821. module.controller('IdentityProviderMapperListCtrl', function($scope, realm, identityProvider, mapperTypes, mappers) {
  1822. $scope.realm = realm;
  1823. $scope.identityProvider = identityProvider;
  1824. $scope.mapperTypes = mapperTypes;
  1825. $scope.mappers = mappers;
  1826. });
  1827. module.controller('IdentityProviderMapperCtrl', function($scope, realm, identityProvider, mapperTypes, mapper, IdentityProviderMapper, Notifications, Dialog, $location) {
  1828. $scope.realm = realm;
  1829. $scope.identityProvider = identityProvider;
  1830. $scope.create = false;
  1831. $scope.mapper = angular.copy(mapper);
  1832. $scope.changed = false;
  1833. $scope.mapperType = mapperTypes[mapper.identityProviderMapper];
  1834. $scope.$watch(function() {
  1835. return $location.path();
  1836. }, function() {
  1837. $scope.path = $location.path().substring(1).split("/");
  1838. });
  1839. $scope.$watch('mapper', function() {
  1840. if (!angular.equals($scope.mapper, mapper)) {
  1841. $scope.changed = true;
  1842. }
  1843. }, true);
  1844. $scope.save = function() {
  1845. IdentityProviderMapper.update({
  1846. realm : realm.realm,
  1847. alias: identityProvider.alias,
  1848. mapperId : mapper.id
  1849. }, $scope.mapper, function() {
  1850. $scope.changed = false;
  1851. mapper = angular.copy($scope.mapper);
  1852. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers/" + mapper.id);
  1853. Notifications.success("Your changes have been saved.");
  1854. });
  1855. };
  1856. $scope.reset = function() {
  1857. $scope.mapper = angular.copy(mapper);
  1858. $scope.changed = false;
  1859. };
  1860. $scope.cancel = function() {
  1861. //$location.url("/realms");
  1862. window.history.back();
  1863. };
  1864. $scope.remove = function() {
  1865. Dialog.confirmDelete($scope.mapper.name, 'mapper', function() {
  1866. IdentityProviderMapper.remove({ realm: realm.realm, alias: mapper.identityProviderAlias, mapperId : $scope.mapper.id }, function() {
  1867. Notifications.success("The mapper has been deleted.");
  1868. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers");
  1869. });
  1870. });
  1871. };
  1872. });
  1873. module.controller('IdentityProviderMapperCreateCtrl', function($scope, realm, identityProvider, mapperTypes, IdentityProviderMapper, Notifications, Dialog, $location) {
  1874. $scope.realm = realm;
  1875. $scope.identityProvider = identityProvider;
  1876. $scope.create = true;
  1877. $scope.mapper = { identityProviderAlias: identityProvider.alias, config: {}};
  1878. $scope.mapperTypes = mapperTypes;
  1879. // make first type the default
  1880. $scope.mapperType = mapperTypes[Object.keys(mapperTypes)[0]];
  1881. $scope.mapper.config.syncMode = 'INHERIT';
  1882. $scope.$watch(function() {
  1883. return $location.path();
  1884. }, function() {
  1885. $scope.path = $location.path().substring(1).split("/");
  1886. });
  1887. $scope.save = function() {
  1888. $scope.mapper.identityProviderMapper = $scope.mapperType.id;
  1889. IdentityProviderMapper.save({
  1890. realm : realm.realm, alias: identityProvider.alias
  1891. }, $scope.mapper, function(data, headers) {
  1892. var l = headers().location;
  1893. var id = l.substring(l.lastIndexOf("/") + 1);
  1894. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers/" + id);
  1895. Notifications.success("Mapper has been created.");
  1896. });
  1897. };
  1898. $scope.cancel = function() {
  1899. //$location.url("/realms");
  1900. window.history.back();
  1901. };
  1902. });
  1903. module.controller('RealmFlowBindingCtrl', function($scope, flows, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  1904. $scope.flows = [];
  1905. $scope.clientFlows = [];
  1906. for (var i=0 ; i<flows.length ; i++) {
  1907. if (flows[i].providerId == 'client-flow') {
  1908. $scope.clientFlows.push(flows[i]);
  1909. } else {
  1910. $scope.flows.push(flows[i]);
  1911. }
  1912. }
  1913. $scope.profileInfo = serverInfo.profileInfo;
  1914. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/flow-bindings");
  1915. });
  1916. module.controller('CreateFlowCtrl', function($scope, realm,
  1917. AuthenticationFlows,
  1918. Notifications, $location) {
  1919. console.debug('CreateFlowCtrl');
  1920. $scope.realm = realm;
  1921. $scope.flow = {
  1922. alias: "",
  1923. providerId: "basic-flow",
  1924. description: "",
  1925. topLevel: true,
  1926. builtIn: false
  1927. }
  1928. $scope.save = function() {
  1929. AuthenticationFlows.save({realm: realm.realm, flow: ""}, $scope.flow, function() {
  1930. $location.url("/realms/" + realm.realm + "/authentication/flows/" + $scope.flow.alias);
  1931. Notifications.success("Flow Created.");
  1932. })
  1933. }
  1934. $scope.cancel = function() {
  1935. $location.url("/realms/" + realm.realm + "/authentication/flows");
  1936. };
  1937. });
  1938. module.controller('CreateExecutionFlowCtrl', function($scope, realm, parentFlow, formProviders,
  1939. CreateExecutionFlow,
  1940. Notifications, $location) {
  1941. $scope.realm = realm;
  1942. $scope.formProviders = formProviders;
  1943. var defaultFlowType = parentFlow.providerId == 'client-flow' ? 'client-flow' : 'basic-flow';
  1944. $scope.flow = {
  1945. alias: "",
  1946. type: defaultFlowType,
  1947. description: ""
  1948. }
  1949. $scope.provider = {};
  1950. if (formProviders.length > 0) {
  1951. $scope.provider = formProviders[0];
  1952. }
  1953. $scope.save = function() {
  1954. $scope.flow.provider = $scope.provider.id;
  1955. CreateExecutionFlow.save({realm: realm.realm, alias: parentFlow.alias}, $scope.flow, function() {
  1956. $location.url("/realms/" + realm.realm + "/authentication/flows");
  1957. Notifications.success("Flow Created.");
  1958. })
  1959. }
  1960. $scope.cancel = function() {
  1961. $location.url("/realms/" + realm.realm + "/authentication/flows");
  1962. };
  1963. });
  1964. module.controller('CreateExecutionCtrl', function($scope, realm, parentFlow, formActionProviders, authenticatorProviders, clientAuthenticatorProviders,
  1965. CreateExecution,
  1966. Notifications, $location) {
  1967. $scope.realm = realm;
  1968. $scope.parentFlow = parentFlow;
  1969. if (parentFlow.providerId == 'form-flow') {
  1970. $scope.providers = formActionProviders;
  1971. } else if (parentFlow.providerId == 'client-flow') {
  1972. $scope.providers = clientAuthenticatorProviders;
  1973. } else {
  1974. $scope.providers = authenticatorProviders;
  1975. }
  1976. $scope.provider = {};
  1977. if ($scope.providers.length > 0) {
  1978. $scope.provider = $scope.providers[0];
  1979. }
  1980. $scope.save = function() {
  1981. var execution = {
  1982. provider: $scope.provider.id
  1983. }
  1984. CreateExecution.save({realm: realm.realm, alias: parentFlow.alias}, execution, function() {
  1985. $location.url("/realms/" + realm.realm + "/authentication/flows");
  1986. Notifications.success("Execution Created.");
  1987. })
  1988. }
  1989. $scope.cancel = function() {
  1990. $location.url("/realms/" + realm.realm + "/authentication/flows");
  1991. };
  1992. });
  1993. module.controller('AuthenticationFlowsCtrl', function($scope, $route, realm, flows, selectedFlow, LastFlowSelected, Dialog,
  1994. AuthenticationFlows, AuthenticationFlowsCopy, AuthenticationFlowsUpdate, AuthenticationFlowExecutions,
  1995. AuthenticationExecution, AuthenticationExecutionRaisePriority, AuthenticationExecutionLowerPriority,
  1996. $modal, Notifications, CopyDialog, UpdateDialog, $location) {
  1997. $scope.realm = realm;
  1998. $scope.flows = flows;
  1999. if (selectedFlow !== null) {
  2000. LastFlowSelected.alias = selectedFlow;
  2001. }
  2002. if (selectedFlow === null && LastFlowSelected.alias !== null) {
  2003. selectedFlow = LastFlowSelected.alias;
  2004. }
  2005. if (flows.length > 0) {
  2006. $scope.flow = flows[0];
  2007. if (selectedFlow) {
  2008. for (var i = 0; i < flows.length; i++) {
  2009. if (flows[i].alias == selectedFlow) {
  2010. $scope.flow = flows[i];
  2011. break;
  2012. }
  2013. }
  2014. }
  2015. }
  2016. $scope.selectFlow = function(flow) {
  2017. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.alias);
  2018. };
  2019. var setupForm = function() {
  2020. AuthenticationFlowExecutions.query({realm: realm.realm, alias: $scope.flow.alias}, function(data) {
  2021. $scope.executions = data;
  2022. $scope.choicesmax = 0;
  2023. $scope.levelmax = 0;
  2024. for (var i = 0; i < $scope.executions.length; i++ ) {
  2025. var execution = $scope.executions[i];
  2026. if (execution.requirementChoices.length > $scope.choicesmax) {
  2027. $scope.choicesmax = execution.requirementChoices.length;
  2028. }
  2029. if (execution.level > $scope.levelmax) {
  2030. $scope.levelmax = execution.level;
  2031. }
  2032. }
  2033. $scope.levelmaxempties = [];
  2034. for (j = 0; j < $scope.levelmax; j++) {
  2035. $scope.levelmaxempties.push(j);
  2036. }
  2037. for (var i = 0; i < $scope.executions.length; i++ ) {
  2038. var execution = $scope.executions[i];
  2039. execution.empties = [];
  2040. for (j = 0; j < $scope.choicesmax - execution.requirementChoices.length; j++) {
  2041. execution.empties.push(j);
  2042. }
  2043. execution.preLevels = [];
  2044. for (j = 0; j < execution.level; j++) {
  2045. execution.preLevels.push(j);
  2046. }
  2047. execution.postLevels = [];
  2048. for (j = execution.level; j < $scope.levelmax; j++) {
  2049. execution.postLevels.push(j);
  2050. }
  2051. }
  2052. })
  2053. };
  2054. $scope.copyFlow = function() {
  2055. CopyDialog.open('Copy Authentication Flow', $scope.flow.alias, function(name) {
  2056. AuthenticationFlowsCopy.save({realm: realm.realm, alias: $scope.flow.alias}, {
  2057. newName: name
  2058. }, function() {
  2059. $location.url("/realms/" + realm.realm + '/authentication/flows/' + name);
  2060. Notifications.success("Flow copied.");
  2061. })
  2062. })
  2063. };
  2064. $scope.deleteFlow = function() {
  2065. Dialog.confirmDelete($scope.flow.alias, 'flow', function() {
  2066. $scope.removeFlow();
  2067. });
  2068. };
  2069. $scope.removeFlow = function() {
  2070. console.log('Remove flow:' + $scope.flow.alias);
  2071. if (realm.browserFlow == $scope.flow.alias) {
  2072. Notifications.error("Cannot remove flow, it is currently being used as the browser flow.");
  2073. } else if (realm.registrationFlow == $scope.flow.alias) {
  2074. Notifications.error("Cannot remove flow, it is currently being used as the registration flow.");
  2075. } else if (realm.directGrantFlow == $scope.flow.alias) {
  2076. Notifications.error("Cannot remove flow, it is currently being used as the direct grant flow.");
  2077. } else if (realm.resetCredentialsFlow == $scope.flow.alias) {
  2078. Notifications.error("Cannot remove flow, it is currently being used as the reset credentials flow.");
  2079. } else if (realm.clientAuthenticationFlow == $scope.flow.alias) {
  2080. Notifications.error("Cannot remove flow, it is currently being used as the client authentication flow.");
  2081. } else if (realm.dockerAuthenticationFlow == $scope.flow.alias) {
  2082. Notifications.error("Cannot remove flow, it is currently being used as the docker authentication flow.");
  2083. } else {
  2084. AuthenticationFlows.remove({realm: realm.realm, flow: $scope.flow.id}, function () {
  2085. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flows[0].alias);
  2086. Notifications.success("Flow removed");
  2087. })
  2088. }
  2089. };
  2090. $scope.editFlow = function(flow) {
  2091. var copy = angular.copy(flow);
  2092. UpdateDialog.open('Update Authentication Flow', copy.alias, copy.description, function(name, desc) {
  2093. copy.alias = name;
  2094. copy.description = desc;
  2095. AuthenticationFlowsUpdate.update({realm: realm.realm, flow: flow.id}, copy, function() {
  2096. $location.url("/realms/" + realm.realm + '/authentication/flows/' + name);
  2097. Notifications.success("Flow updated");
  2098. });
  2099. })
  2100. };
  2101. $scope.addFlow = function() {
  2102. $location.url("/realms/" + realm.realm + '/authentication/flows/' + $scope.flow.id + '/create/flow/execution/' + $scope.flow.id);
  2103. }
  2104. $scope.addSubFlow = function(execution) {
  2105. $location.url("/realms/" + realm.realm + '/authentication/flows/' + execution.flowId + '/create/flow/execution/' + $scope.flow.alias);
  2106. }
  2107. $scope.addSubFlowExecution = function(execution) {
  2108. $location.url("/realms/" + realm.realm + '/authentication/flows/' + execution.flowId + '/create/execution/' + $scope.flow.alias);
  2109. }
  2110. $scope.addExecution = function() {
  2111. $location.url("/realms/" + realm.realm + '/authentication/flows/' + $scope.flow.id + '/create/execution/' + $scope.flow.id);
  2112. }
  2113. $scope.createFlow = function() {
  2114. $location.url("/realms/" + realm.realm + '/authentication/create/flow');
  2115. }
  2116. $scope.updateExecution = function(execution) {
  2117. var copy = angular.copy(execution);
  2118. delete copy.empties;
  2119. delete copy.levels;
  2120. delete copy.preLevels;
  2121. delete copy.postLevels;
  2122. AuthenticationFlowExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() {
  2123. Notifications.success("Auth requirement updated");
  2124. setupForm();
  2125. });
  2126. };
  2127. $scope.editExecutionFlow = function(execution) {
  2128. var copy = angular.copy(execution);
  2129. delete copy.empties;
  2130. delete copy.levels;
  2131. delete copy.preLevels;
  2132. delete copy.postLevels;
  2133. UpdateDialog.open('Update Execution Flow', copy.displayName, copy.description, function(name, desc) {
  2134. copy.displayName = name;
  2135. copy.description = desc;
  2136. AuthenticationFlowExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() {
  2137. Notifications.success("Execution Flow updated");
  2138. setupForm();
  2139. });
  2140. })
  2141. };
  2142. $scope.removeExecution = function(execution) {
  2143. console.log('removeExecution: ' + execution.id);
  2144. var exeOrFlow = execution.authenticationFlow ? 'flow' : 'execution';
  2145. Dialog.confirmDelete(execution.displayName, exeOrFlow, function() {
  2146. AuthenticationExecution.remove({realm: realm.realm, execution: execution.id}, function() {
  2147. Notifications.success("The " + exeOrFlow + " was removed.");
  2148. setupForm();
  2149. });
  2150. });
  2151. }
  2152. $scope.raisePriority = function(execution) {
  2153. AuthenticationExecutionRaisePriority.save({realm: realm.realm, execution: execution.id}, function() {
  2154. Notifications.success("Priority raised");
  2155. setupForm();
  2156. })
  2157. }
  2158. $scope.lowerPriority = function(execution) {
  2159. AuthenticationExecutionLowerPriority.save({realm: realm.realm, execution: execution.id}, function() {
  2160. Notifications.success("Priority lowered");
  2161. setupForm();
  2162. })
  2163. }
  2164. $scope.setupForm = setupForm;
  2165. if (selectedFlow == null) {
  2166. $scope.selectFlow(flows[0]);
  2167. } else {
  2168. setupForm();
  2169. }
  2170. });
  2171. module.controller('RequiredActionsCtrl', function($scope, realm, unregisteredRequiredActions,
  2172. $modal, $route,
  2173. RegisterRequiredAction, RequiredActions, RequiredActionRaisePriority, RequiredActionLowerPriority, Notifications) {
  2174. console.log('RequiredActionsCtrl');
  2175. $scope.realm = realm;
  2176. $scope.unregisteredRequiredActions = unregisteredRequiredActions;
  2177. $scope.requiredActions = [];
  2178. var setupRequiredActionsForm = function() {
  2179. console.log('setupRequiredActionsForm');
  2180. RequiredActions.query({realm: realm.realm}, function(data) {
  2181. $scope.requiredActions = [];
  2182. for (var i = 0; i < data.length; i++) {
  2183. $scope.requiredActions.push(data[i]);
  2184. }
  2185. });
  2186. };
  2187. $scope.updateRequiredAction = function(action) {
  2188. RequiredActions.update({realm: realm.realm, alias: action.alias}, action, function() {
  2189. Notifications.success("Required action updated");
  2190. setupRequiredActionsForm();
  2191. });
  2192. }
  2193. $scope.raisePriority = function(action) {
  2194. RequiredActionRaisePriority.save({realm: realm.realm, alias: action.alias}, function() {
  2195. Notifications.success("Required action's priority raised");
  2196. setupRequiredActionsForm();
  2197. })
  2198. }
  2199. $scope.lowerPriority = function(action) {
  2200. RequiredActionLowerPriority.save({realm: realm.realm, alias: action.alias}, function() {
  2201. Notifications.success("Required action's priority lowered");
  2202. setupRequiredActionsForm();
  2203. })
  2204. }
  2205. $scope.register = function() {
  2206. var controller = function($scope, $modalInstance) {
  2207. $scope.unregisteredRequiredActions = unregisteredRequiredActions;
  2208. $scope.selected = {
  2209. selected: $scope.unregisteredRequiredActions[0]
  2210. }
  2211. $scope.ok = function () {
  2212. $modalInstance.close();
  2213. RegisterRequiredAction.save({realm: realm.realm}, $scope.selected.selected, function() {
  2214. $route.reload();
  2215. });
  2216. };
  2217. $scope.cancel = function () {
  2218. $modalInstance.dismiss('cancel');
  2219. };
  2220. }
  2221. $modal.open({
  2222. templateUrl: resourceUrl + '/partials/modal/unregistered-required-action-selector.html',
  2223. controller: controller,
  2224. resolve: {
  2225. }
  2226. });
  2227. }
  2228. setupRequiredActionsForm();
  2229. });
  2230. module.controller('AuthenticationConfigCtrl', function($scope, realm, flow, configType, config, AuthenticationConfig, Notifications,
  2231. Dialog, $location, ComponentUtils) {
  2232. $scope.realm = realm;
  2233. $scope.flow = flow;
  2234. $scope.configType = configType;
  2235. $scope.create = false;
  2236. $scope.config = angular.copy(config);
  2237. $scope.changed = false;
  2238. $scope.$watch(function() {
  2239. return $location.path();
  2240. }, function() {
  2241. $scope.path = $location.path().substring(1).split("/");
  2242. });
  2243. $scope.$watch('config', function() {
  2244. if (!angular.equals($scope.config, config)) {
  2245. $scope.changed = true;
  2246. }
  2247. }, true);
  2248. $scope.save = function() {
  2249. var configCopy = angular.copy($scope.config);
  2250. ComponentUtils.convertAllListValuesToMultivaluedString(configType.properties, configCopy.config);
  2251. AuthenticationConfig.update({
  2252. realm : realm.realm,
  2253. config : config.id
  2254. }, configCopy, function() {
  2255. $scope.changed = false;
  2256. config = angular.copy($scope.config);
  2257. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + config.id);
  2258. Notifications.success("Your changes have been saved.");
  2259. });
  2260. };
  2261. $scope.reset = function() {
  2262. $scope.config = angular.copy(config);
  2263. $scope.changed = false;
  2264. };
  2265. $scope.cancel = function() {
  2266. //$location.url("/realms");
  2267. window.history.back();
  2268. };
  2269. $scope.remove = function() {
  2270. Dialog.confirmDelete($scope.config.alias, 'config', function() {
  2271. AuthenticationConfig.remove({ realm: realm.realm, config : $scope.config.id }, function() {
  2272. Notifications.success("The config has been deleted.");
  2273. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id);
  2274. });
  2275. });
  2276. };
  2277. });
  2278. module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, flow, configType, execution, AuthenticationExecutionConfig,
  2279. Notifications, Dialog, $location, ComponentUtils) {
  2280. $scope.realm = realm;
  2281. $scope.flow = flow;
  2282. $scope.create = true;
  2283. $scope.configType = configType;
  2284. var defaultConfig = {};
  2285. if (configType && Array.isArray(configType.properties)) {
  2286. for(var i = 0; i < configType.properties.length; i++) {
  2287. var property = configType.properties[i];
  2288. if (property && property.name) {
  2289. defaultConfig[property.name] = property.defaultValue;
  2290. }
  2291. }
  2292. }
  2293. $scope.config = { config: defaultConfig};
  2294. $scope.$watch(function() {
  2295. return $location.path();
  2296. }, function() {
  2297. $scope.path = $location.path().substring(1).split("/");
  2298. });
  2299. $scope.save = function() {
  2300. var configCopy = angular.copy($scope.config);
  2301. ComponentUtils.convertAllListValuesToMultivaluedString(configType.properties, configCopy.config);
  2302. AuthenticationExecutionConfig.save({
  2303. realm : realm.realm,
  2304. execution: execution
  2305. }, configCopy, function(data, headers) {
  2306. var l = headers().location;
  2307. var id = l.substring(l.lastIndexOf("/") + 1);
  2308. var url = "/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + id;
  2309. console.log('redirect url: ' + url);
  2310. $location.url(url);
  2311. Notifications.success("Config has been created.");
  2312. });
  2313. };
  2314. $scope.cancel = function() {
  2315. //$location.url("/realms");
  2316. window.history.back();
  2317. };
  2318. });
  2319. module.controller('ClientInitialAccessCtrl', function($scope, realm, clientInitialAccess, ClientInitialAccess, Dialog, Notifications, $route, $location) {
  2320. $scope.realm = realm;
  2321. $scope.clientInitialAccess = clientInitialAccess;
  2322. $scope.remove = function(id) {
  2323. Dialog.confirmDelete(id, 'initial access token', function() {
  2324. ClientInitialAccess.remove({ realm: realm.realm, id: id }, function() {
  2325. Notifications.success("The initial access token was deleted.");
  2326. $route.reload();
  2327. });
  2328. });
  2329. }
  2330. });
  2331. module.controller('ClientInitialAccessCreateCtrl', function($scope, realm, ClientInitialAccess, TimeUnit, Dialog, $location, $translate) {
  2332. $scope.expirationUnit = 'Days';
  2333. $scope.expiration = TimeUnit.toUnit(0, $scope.expirationUnit);
  2334. $scope.count = 1;
  2335. $scope.realm = realm;
  2336. $scope.save = function() {
  2337. var expiration = TimeUnit.toSeconds($scope.expiration, $scope.expirationUnit);
  2338. ClientInitialAccess.save({
  2339. realm: realm.realm
  2340. }, { expiration: expiration, count: $scope.count}, function (data) {
  2341. console.debug(data);
  2342. $scope.id = data.id;
  2343. $scope.token = data.token;
  2344. });
  2345. };
  2346. $scope.cancel = function() {
  2347. $location.url('/realms/' + realm.realm + '/client-registration/client-initial-access');
  2348. };
  2349. $scope.done = function() {
  2350. var btns = {
  2351. ok: {
  2352. label: $translate.instant('continue'),
  2353. cssClass: 'btn btn-primary'
  2354. },
  2355. cancel: {
  2356. label: $translate.instant('cancel'),
  2357. cssClass: 'btn btn-default'
  2358. }
  2359. }
  2360. var title = $translate.instant('initial-access-token.confirm.title');
  2361. var message = $translate.instant('initial-access-token.confirm.text');
  2362. Dialog.open(title, message, btns, function() {
  2363. $location.url('/realms/' + realm.realm + '/client-registration/client-initial-access');
  2364. });
  2365. };
  2366. });
  2367. module.controller('ClientRegPoliciesCtrl', function($scope, realm, clientRegistrationPolicyProviders, policies, Dialog, Notifications, Components, $route, $location) {
  2368. $scope.realm = realm;
  2369. $scope.providers = clientRegistrationPolicyProviders;
  2370. $scope.anonPolicies = [];
  2371. $scope.authPolicies = [];
  2372. for (var i=0 ; i<policies.length ; i++) {
  2373. var policy = policies[i];
  2374. if (policy.subType === 'anonymous') {
  2375. $scope.anonPolicies.push(policy);
  2376. } else if (policy.subType === 'authenticated') {
  2377. $scope.authPolicies.push(policy);
  2378. } else {
  2379. throw 'subType is required for clientRegistration policy component!';
  2380. }
  2381. }
  2382. $scope.addProvider = function(authType, provider) {
  2383. console.log('Add provider: authType ' + authType + ', providerId: ' + provider.id);
  2384. $location.url("/realms/" + realm.realm + "/client-registration/client-reg-policies/create/" + authType + '/' + provider.id);
  2385. };
  2386. $scope.getInstanceLink = function(instance) {
  2387. return "/realms/" + realm.realm + "/client-registration/client-reg-policies/" + instance.providerId + "/" + instance.id;
  2388. }
  2389. $scope.removeInstance = function(instance) {
  2390. Dialog.confirmDelete(instance.name, 'client registration policy', function() {
  2391. Components.remove({
  2392. realm : realm.realm,
  2393. componentId : instance.id
  2394. }, function() {
  2395. $route.reload();
  2396. Notifications.success("The policy has been deleted.");
  2397. });
  2398. });
  2399. };
  2400. });
  2401. module.controller('ClientRegPolicyDetailCtrl', function ($scope, realm, clientRegistrationPolicyProviders, instance, Dialog, Notifications, Components, ComponentUtils, $route, $location, $translate) {
  2402. $scope.realm = realm;
  2403. $scope.instance = instance;
  2404. $scope.providerTypes = clientRegistrationPolicyProviders;
  2405. for (let i = 0; i < $scope.providerTypes.length; i++) {
  2406. let providerType = $scope.providerTypes[i];
  2407. if (providerType.id === instance.providerId) {
  2408. $scope.providerType = providerType;
  2409. break;
  2410. }
  2411. }
  2412. $scope.create = !$scope.instance.name;
  2413. function toDefaultValue(configProperty) {
  2414. if (configProperty.type === 'MultivaluedString' || configProperty.type === 'MultivaluedList') {
  2415. if (configProperty.defaultValue) {
  2416. return configProperty.defaultValue;
  2417. } else {
  2418. return [];
  2419. }
  2420. }
  2421. if (configProperty.defaultValue) {
  2422. return [ configProperty.defaultValue ];
  2423. } else {
  2424. return [ '' ];
  2425. }
  2426. }
  2427. $translate($scope.instance.providerId + ".label")
  2428. .then((translatedValue) => {
  2429. $scope.headerTitle = translatedValue;
  2430. }).catch(() => {
  2431. $scope.headerTitle = $scope.instance.providerId;
  2432. });
  2433. if ($scope.create) {
  2434. $scope.instance.name = "";
  2435. $scope.instance.parentId = realm.id;
  2436. $scope.instance.config = {};
  2437. if ($scope.providerType.properties) {
  2438. for (let i = 0; i < $scope.providerType.properties.length; i++) {
  2439. let configProperty = $scope.providerType.properties[i];
  2440. $scope.instance.config[configProperty.name] = toDefaultValue(configProperty);
  2441. }
  2442. }
  2443. }
  2444. if ($scope.providerType.properties) {
  2445. ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.providerType.properties, $scope.instance.config);
  2446. ComponentUtils.addMvOptionsToMultivaluedLists($scope.providerType.properties);
  2447. }
  2448. let oldCopy = angular.copy($scope.instance);
  2449. $scope.changed = false;
  2450. $scope.$watch('instance', function() {
  2451. if (!angular.equals($scope.instance, oldCopy)) {
  2452. $scope.changed = true;
  2453. }
  2454. }, true);
  2455. $scope.reset = function() {
  2456. $scope.create ? window.history.back() : $route.reload();
  2457. };
  2458. $scope.hasValidValues = () => $scope.changed && $scope.instance.name;
  2459. $scope.save = function() {
  2460. $scope.changed = false;
  2461. if ($scope.create) {
  2462. Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
  2463. var l = headers().location;
  2464. var id = l.substring(l.lastIndexOf("/") + 1);
  2465. $location.url("/realms/" + realm.realm + "/client-registration/client-reg-policies/" + $scope.instance.providerId + "/" + id);
  2466. Notifications.success("The policy has been created.");
  2467. });
  2468. } else {
  2469. Components.update({realm: realm.realm,
  2470. componentId: instance.id
  2471. },
  2472. $scope.instance, function () {
  2473. $route.reload();
  2474. Notifications.success("The policy has been updated.");
  2475. });
  2476. }
  2477. };
  2478. });
  2479. module.controller('RealmImportCtrl', function($scope, realm, $route,
  2480. Notifications, $modal, $resource) {
  2481. $scope.rawContent = {};
  2482. $scope.fileContent = {
  2483. enabled: true
  2484. };
  2485. $scope.changed = false;
  2486. $scope.files = [];
  2487. $scope.realm = realm;
  2488. $scope.overwrite = false;
  2489. $scope.skip = false;
  2490. $scope.importUsers = false;
  2491. $scope.importGroups = false;
  2492. $scope.importClients = false;
  2493. $scope.importIdentityProviders = false;
  2494. $scope.importRealmRoles = false;
  2495. $scope.importClientRoles = false;
  2496. $scope.ifResourceExists='FAIL';
  2497. $scope.isMultiRealm = false;
  2498. $scope.results = {};
  2499. $scope.currentPage = 0;
  2500. var pageSize = 15;
  2501. var oldCopy = angular.copy($scope.fileContent);
  2502. $scope.importFile = function($fileContent){
  2503. var parsed;
  2504. try {
  2505. parsed = JSON.parse($fileContent);
  2506. } catch (e) {
  2507. Notifications.error('Unable to parse JSON file.');
  2508. return;
  2509. }
  2510. $scope.rawContent = angular.copy(parsed);
  2511. if (($scope.rawContent instanceof Array) && ($scope.rawContent.length > 0)) {
  2512. if ($scope.rawContent.length > 1) $scope.isMultiRealm = true;
  2513. $scope.fileContent = $scope.rawContent[0];
  2514. } else {
  2515. $scope.fileContent = $scope.rawContent;
  2516. }
  2517. $scope.importing = true;
  2518. setOnOffSwitchDefaults();
  2519. $scope.results = {};
  2520. if (!$scope.hasResources()) {
  2521. $scope.nothingToImport();
  2522. }
  2523. };
  2524. $scope.hasResults = function() {
  2525. return (Object.keys($scope.results).length > 0) &&
  2526. ($scope.results.results !== undefined) &&
  2527. ($scope.results.results.length > 0);
  2528. }
  2529. $scope.resultsPage = function() {
  2530. if (!$scope.hasResults()) return {};
  2531. return $scope.results.results.slice(startIndex(), endIndex());
  2532. }
  2533. function startIndex() {
  2534. return pageSize * $scope.currentPage;
  2535. }
  2536. function endIndex() {
  2537. var length = $scope.results.results.length;
  2538. var endIndex = startIndex() + pageSize;
  2539. if (endIndex > length) endIndex = length;
  2540. return endIndex;
  2541. }
  2542. function setOnOffSwitchDefaults() {
  2543. $scope.importUsers = $scope.hasArray('users');
  2544. $scope.importGroups = $scope.hasArray('groups');
  2545. $scope.importClients = $scope.hasArray('clients');
  2546. $scope.importIdentityProviders = $scope.hasArray('identityProviders');
  2547. $scope.importRealmRoles = $scope.hasRealmRoles();
  2548. $scope.importClientRoles = $scope.hasClientRoles();
  2549. }
  2550. $scope.setFirstPage = function() {
  2551. $scope.currentPage = 0;
  2552. }
  2553. $scope.setNextPage = function() {
  2554. $scope.currentPage++;
  2555. }
  2556. $scope.setPreviousPage = function() {
  2557. $scope.currentPage--;
  2558. }
  2559. $scope.hasNext = function() {
  2560. if (!$scope.hasResults()) return false;
  2561. var length = $scope.results.results.length;
  2562. //console.log('length=' + length);
  2563. var endIndex = startIndex() + pageSize;
  2564. //console.log('endIndex=' + endIndex);
  2565. return length > endIndex;
  2566. }
  2567. $scope.hasPrevious = function() {
  2568. if (!$scope.hasResults()) return false;
  2569. return $scope.currentPage > 0;
  2570. }
  2571. $scope.viewImportDetails = function() {
  2572. $modal.open({
  2573. templateUrl: resourceUrl + '/partials/modal/view-object.html',
  2574. controller: 'ObjectModalCtrl',
  2575. resolve: {
  2576. object: function () {
  2577. return $scope.fileContent;
  2578. }
  2579. }
  2580. })
  2581. };
  2582. $scope.hasArray = function(section) {
  2583. return ($scope.fileContent !== 'undefined') &&
  2584. ($scope.fileContent.hasOwnProperty(section)) &&
  2585. ($scope.fileContent[section] instanceof Array) &&
  2586. ($scope.fileContent[section].length > 0);
  2587. }
  2588. $scope.hasRealmRoles = function() {
  2589. return $scope.hasRoles() &&
  2590. ($scope.fileContent.roles.hasOwnProperty('realm')) &&
  2591. ($scope.fileContent.roles.realm instanceof Array) &&
  2592. ($scope.fileContent.roles.realm.length > 0);
  2593. }
  2594. $scope.hasRoles = function() {
  2595. return ($scope.fileContent !== 'undefined') &&
  2596. ($scope.fileContent.hasOwnProperty('roles')) &&
  2597. ($scope.fileContent.roles !== 'undefined');
  2598. }
  2599. $scope.hasClientRoles = function() {
  2600. return $scope.hasRoles() &&
  2601. ($scope.fileContent.roles.hasOwnProperty('client')) &&
  2602. (Object.keys($scope.fileContent.roles.client).length > 0);
  2603. }
  2604. $scope.itemCount = function(section) {
  2605. if (!$scope.importing) return 0;
  2606. if ($scope.hasRealmRoles() && (section === 'roles.realm')) return $scope.fileContent.roles.realm.length;
  2607. if ($scope.hasClientRoles() && (section === 'roles.client')) return clientRolesCount($scope.fileContent.roles.client);
  2608. if (!$scope.fileContent.hasOwnProperty(section)) return 0;
  2609. return $scope.fileContent[section].length;
  2610. }
  2611. clientRolesCount = function(clientRoles) {
  2612. var total = 0;
  2613. for (var clientName in clientRoles) {
  2614. total += clientRoles[clientName].length;
  2615. }
  2616. return total;
  2617. }
  2618. $scope.hasResources = function() {
  2619. return ($scope.importUsers && $scope.hasArray('users')) ||
  2620. ($scope.importGroups && $scope.hasArray('groups')) ||
  2621. ($scope.importClients && $scope.hasArray('clients')) ||
  2622. ($scope.importIdentityProviders && $scope.hasArray('identityProviders')) ||
  2623. ($scope.importRealmRoles && $scope.hasRealmRoles()) ||
  2624. ($scope.importClientRoles && $scope.hasClientRoles());
  2625. }
  2626. $scope.nothingToImport = function() {
  2627. Notifications.error('No resources specified to import.');
  2628. }
  2629. $scope.$watch('fileContent', function() {
  2630. if (!angular.equals($scope.fileContent, oldCopy)) {
  2631. $scope.changed = true;
  2632. }
  2633. setOnOffSwitchDefaults();
  2634. }, true);
  2635. $scope.successMessage = function() {
  2636. var message = $scope.results.added + ' records added. ';
  2637. if ($scope.ifResourceExists === 'SKIP') {
  2638. message += $scope.results.skipped + ' records skipped.'
  2639. }
  2640. if ($scope.ifResourceExists === 'OVERWRITE') {
  2641. message += $scope.results.overwritten + ' records overwritten.';
  2642. }
  2643. return message;
  2644. }
  2645. $scope.save = function() {
  2646. var json = angular.copy($scope.fileContent);
  2647. json.ifResourceExists = $scope.ifResourceExists;
  2648. if (!$scope.importUsers) delete json.users;
  2649. if (!$scope.importGroups) delete json.groups;
  2650. if (!$scope.importIdentityProviders) delete json.identityProviders;
  2651. if (!$scope.importClients) delete json.clients;
  2652. if (json.hasOwnProperty('roles')) {
  2653. if (!$scope.importRealmRoles) delete json.roles.realm;
  2654. if (!$scope.importClientRoles) delete json.roles.client;
  2655. }
  2656. var importFile = $resource(authUrl + '/admin/realms/' + realm.realm + '/partialImport');
  2657. $scope.results = importFile.save(json, function() {
  2658. Notifications.success($scope.successMessage());
  2659. }, function(error) {
  2660. if (error.data.errorMessage) {
  2661. Notifications.error(error.data.errorMessage);
  2662. } else {
  2663. Notifications.error('Unexpected error during import');
  2664. }
  2665. });
  2666. };
  2667. $scope.reset = function() {
  2668. $route.reload();
  2669. }
  2670. });
  2671. module.controller('RealmExportCtrl', function($scope, realm, $http,
  2672. $httpParamSerializer, Notifications, Dialog) {
  2673. $scope.realm = realm;
  2674. $scope.exportGroupsAndRoles = false;
  2675. $scope.exportClients = false;
  2676. $scope.export = function() {
  2677. if ($scope.exportGroupsAndRoles || $scope.exportClients) {
  2678. Dialog.confirm('Export', 'This operation may make server unresponsive for a while.\n\nAre you sure you want to proceed?', download);
  2679. } else {
  2680. download();
  2681. }
  2682. }
  2683. function download() {
  2684. var exportUrl = authUrl + '/admin/realms/' + realm.realm + '/partial-export';
  2685. var params = {};
  2686. if ($scope.exportGroupsAndRoles) {
  2687. params['exportGroupsAndRoles'] = true;
  2688. }
  2689. if ($scope.exportClients) {
  2690. params['exportClients'] = true;
  2691. }
  2692. if (Object.keys(params).length > 0) {
  2693. exportUrl += '?' + $httpParamSerializer(params);
  2694. }
  2695. $http.post(exportUrl)
  2696. .then(function(response) {
  2697. var download = angular.fromJson(response.data);
  2698. download = angular.toJson(download, true);
  2699. saveAs(new Blob([download], { type: 'application/json' }), 'realm-export.json');
  2700. }).catch(function() {
  2701. Notifications.error("Sorry, something went wrong.");
  2702. });
  2703. }
  2704. });