realm.js 163 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475
  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: Current.realm.realm, 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. if ($scope.realm.attributes != null) {
  236. $scope.realm.attributes['userProfileEnabled'] = $scope.realm.attributes['userProfileEnabled'] == 'true';
  237. }
  238. var oldCopy = angular.copy($scope.realm);
  239. $scope.realmCopy = oldCopy;
  240. $scope.changed = $scope.create;
  241. $scope.$watch('realm', function() {
  242. if (!angular.equals($scope.realm, oldCopy)) {
  243. $scope.changed = true;
  244. }
  245. }, true);
  246. $scope.$watch('realmName', function() {
  247. if (!angular.equals($scope.realmName, oldCopy.realm)) {
  248. $scope.changed = true;
  249. }
  250. }, true);
  251. $scope.save = function() {
  252. var realmCopy = angular.copy($scope.realm);
  253. realmCopy.realm = $scope.realmName;
  254. $scope.changed = false;
  255. var nameChanged = !angular.equals($scope.realmName, oldCopy.realm);
  256. var oldName = oldCopy.realm;
  257. Realm.update({ id : oldCopy.realm}, realmCopy, function () {
  258. var data = Realm.query(function () {
  259. Current.realms = data;
  260. for (var i = 0; i < Current.realms.length; i++) {
  261. if (Current.realms[i].realm == realmCopy.realm) {
  262. Current.realm = Current.realms[i];
  263. oldCopy = angular.copy($scope.realm);
  264. $scope.realmCopy = oldCopy;
  265. }
  266. }
  267. });
  268. if (nameChanged) {
  269. console.debug(Auth);
  270. console.debug(Auth.authz.tokenParsed.iss);
  271. if (Auth.authz.tokenParsed.iss.endsWith(masterRealm)) {
  272. Auth.refreshPermissions(function () {
  273. Auth.refreshPermissions(function () {
  274. Notifications.success("Your changes have been saved to the realm.");
  275. $scope.$apply(function () {
  276. $location.url("/realms/" + realmCopy.realm);
  277. });
  278. });
  279. });
  280. } else {
  281. delete Auth.authz.token;
  282. delete Auth.authz.refreshToken;
  283. var newLocation = $window.location.href.replace('/' + oldName + '/', '/' + realmCopy.realm + '/')
  284. .replace('/realms/' + oldName, '/realms/' + realmCopy.realm);
  285. window.location.replace(newLocation);
  286. }
  287. } else {
  288. $location.url("/realms/" + realmCopy.realm);
  289. Notifications.success("Your changes have been saved to the realm.");
  290. }
  291. });
  292. };
  293. $scope.reset = function() {
  294. $scope.realm = angular.copy(oldCopy);
  295. $scope.changed = false;
  296. };
  297. $scope.cancel = function() {
  298. window.history.back();
  299. };
  300. });
  301. function genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, url) {
  302. $scope.realm = angular.copy(realm);
  303. $scope.serverInfo = serverInfo;
  304. $scope.registrationAllowed = $scope.realm.registrationAllowed;
  305. var oldCopy = angular.copy($scope.realm);
  306. $scope.changed = false;
  307. $scope.$watch('realm', function() {
  308. if (!angular.equals($scope.realm, oldCopy)) {
  309. $scope.changed = true;
  310. }
  311. }, true);
  312. $scope.save = function() {
  313. var realmCopy = angular.copy($scope.realm);
  314. console.log('updating realm...');
  315. $scope.changed = false;
  316. console.log('oldCopy.realm - ' + oldCopy.realm);
  317. Realm.update({ id : oldCopy.realm}, realmCopy, function () {
  318. $route.reload();
  319. Notifications.success("Your changes have been saved to the realm.");
  320. $scope.registrationAllowed = $scope.realm.registrationAllowed;
  321. });
  322. };
  323. $scope.reset = function() {
  324. $scope.realm = angular.copy(oldCopy);
  325. $scope.changed = false;
  326. };
  327. $scope.cancel = function() {
  328. $route.reload();
  329. };
  330. }
  331. module.controller('DefenseHeadersCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  332. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/defense/headers");
  333. });
  334. module.controller('RealmLoginSettingsCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  335. // KEYCLOAK-5474: Make sure duplicateEmailsAllowed is disabled if loginWithEmailAllowed
  336. $scope.$watch('realm.loginWithEmailAllowed', function() {
  337. if ($scope.realm.loginWithEmailAllowed) {
  338. $scope.realm.duplicateEmailsAllowed = false;
  339. }
  340. });
  341. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/login-settings");
  342. });
  343. module.controller('RealmOtpPolicyCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  344. $scope.optionsDigits = [ 6, 8 ];
  345. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/otp-policy");
  346. });
  347. module.controller('RealmWebAuthnPolicyCtrl', function ($scope, Current, Realm, realm, serverInfo, $http, $route, $location, Dialog, Notifications) {
  348. $scope.deleteAcceptableAaguid = function(index) {
  349. $scope.realm.webAuthnPolicyAcceptableAaguids.splice(index, 1);
  350. };
  351. $scope.addAcceptableAaguid = function() {
  352. $scope.realm.webAuthnPolicyAcceptableAaguids.push($scope.newAcceptableAaguid);
  353. $scope.newAcceptableAaguid = "";
  354. };
  355. // Just for case the user fill particular URL with disabled WebAuthn feature.
  356. $scope.redirectIfWebAuthnDisabled = function () {
  357. if (!serverInfo.featureEnabled('WEB_AUTHN')) {
  358. $location.url("/realms/" + $scope.realm.realm + "/authentication");
  359. }
  360. };
  361. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/webauthn-policy");
  362. });
  363. module.controller('RealmWebAuthnPasswordlessPolicyCtrl', function ($scope, Current, Realm, realm, serverInfo, $http, $route, $location, Dialog, Notifications) {
  364. $scope.deleteAcceptableAaguid = function(index) {
  365. $scope.realm.webAuthnPolicyPasswordlessAcceptableAaguids.splice(index, 1);
  366. };
  367. $scope.addAcceptableAaguid = function() {
  368. $scope.realm.webAuthnPolicyPasswordlessAcceptableAaguids.push($scope.newAcceptableAaguid);
  369. $scope.newAcceptableAaguid = "";
  370. };
  371. // Just for case the user fill particular URL with disabled WebAuthn feature.
  372. $scope.redirectIfWebAuthnDisabled = function () {
  373. if (!serverInfo.featureEnabled('WEB_AUTHN')) {
  374. $location.url("/realms/" + $scope.realm.realm + "/authentication");
  375. }
  376. };
  377. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/webauthn-policy-passwordless");
  378. });
  379. module.controller('RealmCibaPolicyCtrl', function ($scope, Current, Realm, realm, serverInfo, $http, $route, $location, Dialog, Notifications) {
  380. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/ciba-policy");
  381. });
  382. module.controller('RealmThemeCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  383. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/theme-settings");
  384. $scope.supportedLocalesOptions = {
  385. 'multiple' : true,
  386. 'simple_tags' : true,
  387. 'tags' : []
  388. };
  389. updateSupported();
  390. function localeForTheme(type, name) {
  391. name = name || 'base';
  392. for (var i = 0; i < serverInfo.themes[type].length; i++) {
  393. if (serverInfo.themes[type][i].name == name) {
  394. return serverInfo.themes[type][i].locales || [];
  395. }
  396. }
  397. return [];
  398. }
  399. function updateSupported() {
  400. if ($scope.realm.internationalizationEnabled) {
  401. var accountLocales = localeForTheme('account', $scope.realm.accountTheme);
  402. var loginLocales = localeForTheme('login', $scope.realm.loginTheme);
  403. var emailLocales = localeForTheme('email', $scope.realm.emailTheme);
  404. var supportedLocales = [];
  405. for (var i = 0; i < accountLocales.length; i++) {
  406. var l = accountLocales[i];
  407. if (loginLocales.indexOf(l) >= 0 && emailLocales.indexOf(l) >= 0) {
  408. supportedLocales.push(l);
  409. }
  410. }
  411. $scope.supportedLocalesOptions.tags = supportedLocales;
  412. if (!$scope.realm.supportedLocales) {
  413. $scope.realm.supportedLocales = supportedLocales;
  414. } else {
  415. for (var i = 0; i < $scope.realm.supportedLocales.length; i++) {
  416. if (supportedLocales.indexOf($scope.realm.supportedLocales[i]) == -1) {
  417. $scope.realm.supportedLocales = supportedLocales;
  418. }
  419. }
  420. }
  421. if (!$scope.realm.defaultLocale || supportedLocales.indexOf($scope.realm.defaultLocale) == -1) {
  422. $scope.realm.defaultLocale = 'en';
  423. }
  424. }
  425. }
  426. $scope.$watch('realm.loginTheme', updateSupported);
  427. $scope.$watch('realm.accountTheme', updateSupported);
  428. $scope.$watch('realm.emailTheme', updateSupported);
  429. $scope.$watch('realm.internationalizationEnabled', updateSupported);
  430. });
  431. module.controller('RealmLocalizationCtrl', function($scope, Current, $location, Realm, realm, serverInfo, Notifications, RealmSpecificLocales, realmSpecificLocales, RealmSpecificLocalizationTexts, RealmSpecificLocalizationText, Dialog, $translate){
  432. $scope.realm = realm;
  433. $scope.realmSpecificLocales = realmSpecificLocales;
  434. $scope.newLocale = null;
  435. $scope.selectedRealmSpecificLocales = null;
  436. $scope.localizationTexts = null;
  437. $scope.createLocale = function() {
  438. if(!$scope.newLocale) {
  439. Notifications.error($translate.instant('missing-locale'));
  440. return;
  441. }
  442. $scope.realmSpecificLocales.push($scope.newLocale)
  443. $scope.selectedRealmSpecificLocales = $scope.newLocale;
  444. $scope.newLocale = null;
  445. $location.url('/create/localization/' + realm.realm + '/' + $scope.selectedRealmSpecificLocales);
  446. }
  447. $scope.$watch(function() {
  448. return $scope.selectedRealmSpecificLocales;
  449. }, function() {
  450. if($scope.selectedRealmSpecificLocales != null) {
  451. $scope.updateRealmSpecificLocalizationTexts();
  452. }
  453. })
  454. $scope.updateRealmSpecificLocales = function() {
  455. RealmSpecificLocales.get({id: realm.realm}, function (updated) {
  456. $scope.realmSpecificLocales = updated;
  457. })
  458. }
  459. $scope.updateRealmSpecificLocalizationTexts = function() {
  460. RealmSpecificLocalizationTexts.get({id: realm.realm, locale: $scope.selectedRealmSpecificLocales }, function (updated) {
  461. $scope.localizationTexts = updated;
  462. })
  463. }
  464. $scope.removeLocalizationText = function(key) {
  465. Dialog.confirmDelete(key, 'localization text', function() {
  466. RealmSpecificLocalizationText.remove({
  467. realm: realm.realm,
  468. locale: $scope.selectedRealmSpecificLocales,
  469. key: key
  470. }, function () {
  471. $scope.updateRealmSpecificLocalizationTexts();
  472. Notifications.success($translate.instant('localization-text.remove.success'));
  473. });
  474. });
  475. }
  476. });
  477. module.controller('RealmLocalizationUploadCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, $upload, $translate){
  478. $scope.realm = realm;
  479. $scope.locale = null;
  480. $scope.files = [];
  481. $scope.onFileSelect = function($files) {
  482. $scope.files = $files;
  483. };
  484. $scope.reset = function() {
  485. $scope.locale = null;
  486. $scope.files = null;
  487. };
  488. $scope.save = function() {
  489. if(!$scope.files || $scope.files.length === 0) {
  490. Notifications.error($translate.instant('missing-file'));
  491. return;
  492. }
  493. //$files: an array of files selected, each file has name, size, and type.
  494. for (var i = 0; i < $scope.files.length; i++) {
  495. var $file = $scope.files[i];
  496. $scope.upload = $upload.upload({
  497. url: authUrl + '/admin/realms/' + realm.realm + '/localization/' + $scope.locale,
  498. file: $file
  499. }).then(function(response) {
  500. $scope.reset();
  501. Notifications.success($translate.instant('localization-file.upload.success'));
  502. }).catch(function() {
  503. Notifications.error($translate.instant('localization-file.upload.error'));
  504. });
  505. }
  506. };
  507. });
  508. module.controller('RealmLocalizationDetailCtrl', function($scope, Current, $location, Realm, realm, Notifications, locale, key, RealmSpecificLocalizationText, localizationText, $translate){
  509. $scope.realm = realm;
  510. $scope.locale = locale;
  511. $scope.key = key;
  512. $scope.value = ((localizationText)? localizationText.content : null);
  513. $scope.create = !key;
  514. $scope.save = function() {
  515. if ($scope.create) {
  516. RealmSpecificLocalizationText.save({
  517. realm: realm.realm,
  518. locale: $scope.locale,
  519. key: $scope.key
  520. }, $scope.value, function (data, headers) {
  521. $location.url("/realms/" + realm.realm + "/localization");
  522. Notifications.success($translate.instant('localization-text.create.success'));
  523. });
  524. } else {
  525. RealmSpecificLocalizationText.save({
  526. realm: realm.realm,
  527. locale: $scope.locale,
  528. key: $scope.key
  529. }, $scope.value, function (data, headers) {
  530. $location.url("/realms/" + realm.realm + "/localization");
  531. Notifications.success($translate.instant('localization-text.update.success'));
  532. });
  533. }
  534. };
  535. $scope.cancel = function () {
  536. $location.url("/realms/" + realm.realm + "/localization");
  537. };
  538. });
  539. module.controller('RealmCacheCtrl', function($scope, realm, RealmClearUserCache, RealmClearRealmCache, RealmClearKeysCache, Notifications) {
  540. $scope.realm = angular.copy(realm);
  541. $scope.clearUserCache = function() {
  542. RealmClearUserCache.save({ realm: realm.realm}, function () {
  543. Notifications.success("User cache cleared");
  544. });
  545. }
  546. $scope.clearRealmCache = function() {
  547. RealmClearRealmCache.save({ realm: realm.realm}, function () {
  548. Notifications.success("Realm cache cleared");
  549. });
  550. }
  551. $scope.clearKeysCache = function() {
  552. RealmClearKeysCache.save({ realm: realm.realm}, function () {
  553. Notifications.success("Public keys cache cleared");
  554. });
  555. }
  556. });
  557. module.controller('RealmPasswordPolicyCtrl', function($scope, Realm, realm, $http, $location, $route, Dialog, Notifications, serverInfo) {
  558. var parse = function(policyString) {
  559. var policies = [];
  560. if (!policyString || policyString.length == 0){
  561. return policies;
  562. }
  563. var policyArray = policyString.split(" and ");
  564. for (var i = 0; i < policyArray.length; i ++){
  565. var policyToken = policyArray[i];
  566. var id;
  567. var value;
  568. if (policyToken.indexOf('(') == -1) {
  569. id = policyToken.trim();
  570. value = null;
  571. } else {
  572. id = policyToken.substring(0, policyToken.indexOf('('));
  573. value = policyToken.substring(policyToken.indexOf('(') + 1, policyToken.lastIndexOf(')')).trim();
  574. }
  575. for (var j = 0; j < serverInfo.passwordPolicies.length; j++) {
  576. if (serverInfo.passwordPolicies[j].id == id) {
  577. // clone
  578. var p = JSON.parse(JSON.stringify(serverInfo.passwordPolicies[j]));
  579. p.value = value && value || p.defaultValue;
  580. policies.push(p);
  581. }
  582. }
  583. }
  584. return policies;
  585. };
  586. var toString = function(policies) {
  587. if (!policies || policies.length == 0) {
  588. return "";
  589. }
  590. var policyString = "";
  591. for (var i = 0; i < policies.length; i++) {
  592. policyString += policies[i].id + '(' + policies[i].value + ')';
  593. if (i != policies.length - 1) {
  594. policyString += ' and ';
  595. }
  596. }
  597. return policyString;
  598. }
  599. $scope.realm = realm;
  600. $scope.serverInfo = serverInfo;
  601. $scope.changed = false;
  602. console.log(JSON.stringify(parse(realm.passwordPolicy)));
  603. $scope.policy = parse(realm.passwordPolicy);
  604. var oldCopy = angular.copy($scope.policy);
  605. $scope.$watch('policy', function() {
  606. $scope.changed = ! angular.equals($scope.policy, oldCopy);
  607. }, true);
  608. $scope.addPolicy = function(policy){
  609. policy.value = policy.defaultValue;
  610. if (!$scope.policy) {
  611. $scope.policy = [];
  612. }
  613. $scope.policy.push(policy);
  614. }
  615. $scope.removePolicy = function(index){
  616. $scope.policy.splice(index, 1);
  617. }
  618. $scope.save = function() {
  619. $scope.realm.passwordPolicy = toString($scope.policy);
  620. console.log($scope.realm.passwordPolicy);
  621. Realm.update($scope.realm, function () {
  622. $route.reload();
  623. Notifications.success("Your changes have been saved to the realm.");
  624. });
  625. };
  626. $scope.reset = function() {
  627. $route.reload();
  628. };
  629. });
  630. module.controller('RealmDefaultRolesCtrl', function ($scope, $route, realm, roles, Notifications, ClientRole, Client, RoleRealmComposites, RoleClientComposites, ComponentUtils, $http) {
  631. console.log('RealmDefaultRolesCtrl');
  632. $scope.realm = realm;
  633. $scope.availableRealmRoles = angular.copy(roles);
  634. $scope.selectedRealmRoles = [];
  635. $scope.selectedRealmDefRoles = [];
  636. $scope.availableClientRoles = [];
  637. $scope.selectedClientRoles = [];
  638. $scope.selectedClientDefRoles = [];
  639. for (var j = 0; j < $scope.availableRealmRoles.length; j++) {
  640. if ($scope.availableRealmRoles[j].id === realm.defaultRole.id) {
  641. var realmRole = $scope.availableRealmRoles[j];
  642. var idx = $scope.availableRealmRoles.indexOf(realmRole);
  643. $scope.availableRealmRoles.splice(idx, 1);
  644. break;
  645. }
  646. }
  647. $scope.realmMappings = RoleRealmComposites.query({realm : realm.realm, role : realm.defaultRole.id}, function(){
  648. for (var i = 0; i < $scope.realmMappings.length; i++) {
  649. var role = $scope.realmMappings[i];
  650. for (var j = 0; j < $scope.availableRealmRoles.length; j++) {
  651. var realmRole = $scope.availableRealmRoles[j];
  652. if (realmRole.id === role.id) {
  653. var idx = $scope.availableRealmRoles.indexOf(realmRole);
  654. if (idx !== -1) {
  655. $scope.availableRealmRoles.splice(idx, 1);
  656. break;
  657. }
  658. }
  659. }
  660. }
  661. });
  662. $scope.addRealmDefaultRole = function () {
  663. $scope.selectedRealmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']');
  664. $http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
  665. $scope.selectedRealmRolesToAdd).then(function() {
  666. // Remove selected roles from the Available roles and add them to realm default roles (move from left to right).
  667. for (var i = 0; i < $scope.selectedRealmRolesToAdd.length; i++) {
  668. var selectedRole = $scope.selectedRealmRolesToAdd[i];
  669. var index = ComponentUtils.findIndexById($scope.availableRealmRoles, selectedRole.id);
  670. if (index > -1) {
  671. $scope.availableRealmRoles.splice(index, 1);
  672. $scope.realmMappings.push(selectedRole);
  673. }
  674. }
  675. $scope.selectedRealmRoles = [];
  676. $scope.selectedRealmRolesToAdd = [];
  677. Notifications.success("Default roles updated.");
  678. });
  679. };
  680. $scope.deleteRealmDefaultRole = function () {
  681. $scope.selectedClientRolesToRemove = JSON.parse('[' + $scope.selectedRealmDefRoles + ']');
  682. $http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
  683. {data : $scope.selectedClientRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
  684. // Remove selected roles from the realm default roles and add them to available roles (move from right to left).
  685. for (var i = 0; i < $scope.selectedClientRolesToRemove.length; i++) {
  686. var selectedRole = $scope.selectedClientRolesToRemove[i];
  687. var index = ComponentUtils.findIndexById($scope.realmMappings, selectedRole.id);
  688. if (index > -1) {
  689. $scope.realmMappings.splice(index, 1);
  690. $scope.availableRealmRoles.push(selectedRole);
  691. }
  692. }
  693. $scope.selectedRealmDefRoles = [];
  694. $scope.selectedClientRolesToRemove = [];
  695. Notifications.success("Default roles updated.");
  696. });
  697. };
  698. $scope.changeClient = function (client) {
  699. if (!client || !client.id) {
  700. $scope.selectedClient = null;
  701. return;
  702. }
  703. $scope.selectedClient = client;
  704. $scope.selectedClientRoles = [];
  705. $scope.selectedClientDefRoles = [];
  706. // Populate available roles for selected client
  707. if ($scope.selectedClient) {
  708. $scope.availableClientRoles = ClientRole.query({realm: realm.realm, client: client.id}, function () {
  709. $scope.clientMappings = RoleClientComposites.query({realm : realm.realm, role : realm.defaultRole.id, client : client.id}, function(){
  710. for (var i = 0; i < $scope.clientMappings.length; i++) {
  711. var role = $scope.clientMappings[i];
  712. for (var j = 0; j < $scope.availableClientRoles.length; j++) {
  713. var clientRole = $scope.availableClientRoles[j];
  714. if (clientRole.id === role.id) {
  715. var idx = $scope.availableClientRoles.indexOf(clientRole);
  716. if (idx !== -1) {
  717. $scope.availableClientRoles.splice(idx, 1);
  718. break;
  719. }
  720. }
  721. }
  722. }
  723. });
  724. for (var j = 0; j < $scope.availableClientRoles.length; j++) {
  725. if ($scope.availableClientRoles[j] === realm.defaultRole.id) {
  726. var clientRole = $scope.availableClientRoles[j];
  727. var idx = $scope.availableClientRoles.indexof(clientRole);
  728. $scope.availableClientRoles.splice(idx, 1);
  729. break;
  730. }
  731. }
  732. });
  733. } else {
  734. $scope.availableClientRoles = null;
  735. }
  736. };
  737. $scope.addClientDefaultRole = function () {
  738. $scope.selectedClientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']');
  739. $http.post(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
  740. $scope.selectedClientRolesToAdd).then(function() {
  741. // Remove selected roles from the app available roles and add them to app default roles (move from left to right).
  742. for (var i = 0; i < $scope.selectedClientRolesToAdd.length; i++) {
  743. var selectedRole = $scope.selectedClientRolesToAdd[i];
  744. var index = ComponentUtils.findIndexById($scope.availableClientRoles, selectedRole.id);
  745. if (index > -1) {
  746. $scope.availableClientRoles.splice(index, 1);
  747. $scope.clientMappings.push(selectedRole);
  748. }
  749. }
  750. $scope.selectedClientRoles = [];
  751. $scope.selectedClientRolesToAdd = [];
  752. Notifications.success("Default roles updated.");
  753. });
  754. };
  755. $scope.rmClientDefaultRole = function () {
  756. $scope.selectedClientRolesToRemove = JSON.parse('[' + $scope.selectedClientDefRoles + ']');
  757. $http.delete(authUrl + '/admin/realms/' + realm.realm + '/roles-by-id/' + realm.defaultRole.id + '/composites',
  758. {data : $scope.selectedClientRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
  759. // Remove selected roles from the realm default roles and add them to available roles (move from right to left).
  760. for (var i = 0; i < $scope.selectedClientRolesToRemove.length; i++) {
  761. var selectedRole = $scope.selectedClientRolesToRemove[i];
  762. var index = ComponentUtils.findIndexById($scope.clientMappings, selectedRole.id);
  763. if (index > -1) {
  764. $scope.clientMappings.splice(index, 1);
  765. $scope.availableClientRoles.push(selectedRole);
  766. }
  767. }
  768. $scope.selectedClientDefRoles = [];
  769. $scope.selectedClientRolesToRemove = [];
  770. Notifications.success("Default roles updated.");
  771. });
  772. };
  773. clientSelectControl($scope, $route.current.params.realm, Client);
  774. });
  775. module.controller('IdentityProviderTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
  776. $scope.removeIdentityProvider = function() {
  777. Dialog.confirmDelete($scope.identityProvider.alias, 'provider', function() {
  778. $scope.identityProvider.$remove({
  779. realm : Current.realm.realm,
  780. alias : $scope.identityProvider.alias
  781. }, function() {
  782. $location.url("/realms/" + Current.realm.realm + "/identity-provider-settings");
  783. Notifications.success("The identity provider has been deleted.");
  784. });
  785. });
  786. };
  787. });
  788. module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload, $http, $route, realm, instance, providerFactory, IdentityProvider, serverInfo, authFlows, $location, Notifications, Dialog) {
  789. $scope.realm = angular.copy(realm);
  790. $scope.initSamlProvider = function() {
  791. $scope.nameIdFormats = [
  792. {
  793. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
  794. name: "Persistent"
  795. },
  796. {
  797. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
  798. name: "Transient"
  799. },
  800. {
  801. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
  802. name: "Email"
  803. },
  804. {
  805. format: "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos",
  806. name: "Kerberos"
  807. },
  808. {
  809. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName",
  810. name: "X.509 Subject Name"
  811. },
  812. {
  813. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName",
  814. name: "Windows Domain Qualified Name"
  815. },
  816. {
  817. format: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
  818. name: "Unspecified"
  819. }
  820. ];
  821. $scope.signatureAlgorithms = [
  822. "RSA_SHA1",
  823. "RSA_SHA256",
  824. "RSA_SHA256_MGF1",
  825. "RSA_SHA512",
  826. "RSA_SHA512_MGF1",
  827. "DSA_SHA1"
  828. ];
  829. $scope.xmlKeyNameTranformers = [
  830. "NONE",
  831. "KEY_ID",
  832. "CERT_SUBJECT"
  833. ];
  834. $scope.principalTypes = [
  835. {
  836. type: "SUBJECT",
  837. name: "Subject NameID"
  838. },
  839. {
  840. type: "ATTRIBUTE",
  841. name: "Attribute [Name]"
  842. },
  843. {
  844. type: "FRIENDLY_ATTRIBUTE",
  845. name: "Attribute [Friendly Name]"
  846. }
  847. ];
  848. if (instance && instance.alias) {
  849. } else {
  850. $scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
  851. $scope.identityProvider.config.principalType = $scope.principalTypes[0].type;
  852. $scope.identityProvider.config.signatureAlgorithm = $scope.signatureAlgorithms[1];
  853. $scope.identityProvider.config.xmlSigKeyInfoKeyNameTransformer = $scope.xmlKeyNameTranformers[1];
  854. $scope.identityProvider.config.allowCreate = 'true';
  855. }
  856. $scope.identityProvider.config.entityId = $scope.identityProvider.config.entityId || (authUrl + '/realms/' + realm.realm);
  857. }
  858. $scope.hidePassword = true;
  859. $scope.fromUrl = {
  860. data: ''
  861. };
  862. if (instance && instance.alias) {
  863. $scope.identityProvider = angular.copy(instance);
  864. $scope.newIdentityProvider = false;
  865. for (var i in serverInfo.identityProviders) {
  866. var provider = serverInfo.identityProviders[i];
  867. if (provider.id == instance.providerId) {
  868. $scope.provider = provider;
  869. }
  870. }
  871. } else {
  872. $scope.identityProvider = {};
  873. $scope.identityProvider.config = {};
  874. $scope.identityProvider.alias = providerFactory.id;
  875. $scope.identityProvider.providerId = providerFactory.id;
  876. $scope.identityProvider.enabled = true;
  877. $scope.identityProvider.authenticateByDefault = false;
  878. $scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
  879. $scope.identityProvider.config.useJwksUrl = 'true';
  880. $scope.identityProvider.config.syncMode = 'IMPORT';
  881. $scope.newIdentityProvider = true;
  882. }
  883. $scope.changed = $scope.newIdentityProvider;
  884. $scope.$watch('identityProvider', function() {
  885. if (!angular.equals($scope.identityProvider, instance)) {
  886. $scope.changed = true;
  887. }
  888. }, true);
  889. $scope.serverInfo = serverInfo;
  890. $scope.allProviders = angular.copy(serverInfo.identityProviders);
  891. $scope.configuredProviders = angular.copy(realm.identityProviders);
  892. removeUsedSocial();
  893. $scope.authFlows = [];
  894. for (var i=0 ; i<authFlows.length ; i++) {
  895. if (authFlows[i].providerId == 'basic-flow') {
  896. $scope.authFlows.push(authFlows[i]);
  897. }
  898. }
  899. $scope.postBrokerAuthFlows = [];
  900. var emptyFlow = { alias: "" };
  901. $scope.postBrokerAuthFlows.push(emptyFlow);
  902. for (var i=0 ; i<$scope.authFlows.length ; i++) {
  903. $scope.postBrokerAuthFlows.push($scope.authFlows[i]);
  904. }
  905. if (!$scope.identityProvider.postBrokerLoginFlowAlias) {
  906. $scope.identityProvider.postBrokerLoginFlowAlias = $scope.postBrokerAuthFlows[0].alias;
  907. }
  908. $scope.$watch(function() {
  909. return $location.path();
  910. }, function() {
  911. $scope.path = $location.path().substring(1).split("/");
  912. });
  913. $scope.files = [];
  914. $scope.importFile = false;
  915. $scope.importUrl = false;
  916. $scope.onFileSelect = function($files) {
  917. $scope.importFile = true;
  918. $scope.files = $files;
  919. };
  920. $scope.clearFileSelect = function() {
  921. $scope.importUrl = false;
  922. $scope.importFile = false;
  923. $scope.files = null;
  924. };
  925. var setConfig = function(data) {
  926. if (data["enabledFromMetadata"] !== undefined ) {
  927. $scope.identityProvider.enabled = data["enabledFromMetadata"] == "true";
  928. delete data["enabledFromMetadata"];
  929. }
  930. for (var key in data) {
  931. $scope.identityProvider.config[key] = data[key];
  932. }
  933. }
  934. $scope.uploadFile = function() {
  935. if (!$scope.identityProvider.alias) {
  936. Notifications.error("You must specify an alias");
  937. return;
  938. }
  939. var input = {
  940. providerId: providerFactory.id
  941. }
  942. //$files: an array of files selected, each file has name, size, and type.
  943. for (var i = 0; i < $scope.files.length; i++) {
  944. var $file = $scope.files[i];
  945. $scope.upload = $upload.upload({
  946. url: authUrl + '/admin/realms/' + realm.realm + '/identity-provider/import-config',
  947. // method: POST or PUT,
  948. // headers: {'headerKey': 'headerValue'}, withCredential: true,
  949. data: input,
  950. file: $file
  951. /* set file formData name for 'Content-Desposition' header. Default: 'file' */
  952. //fileFormDataName: myFile,
  953. /* customize how data is added to formData. See #40#issuecomment-28612000 for example */
  954. //formDataAppender: function(formData, key, val){}
  955. }).progress(function(evt) {
  956. console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
  957. }).then(function(response) {
  958. setConfig(response.data);
  959. $scope.clearFileSelect();
  960. Notifications.success("The IDP metadata has been loaded from file.");
  961. }).catch(function() {
  962. Notifications.error("The file can not be uploaded. Please verify the file.");
  963. });
  964. }
  965. };
  966. $scope.importFrom = function() {
  967. if (!$scope.identityProvider.alias) {
  968. Notifications.error("You must specify an alias");
  969. return;
  970. }
  971. var input = {
  972. fromUrl: $scope.fromUrl.data,
  973. providerId: providerFactory.id
  974. }
  975. $http.post(authUrl + '/admin/realms/' + realm.realm + '/identity-provider/import-config', input)
  976. .then(function(response) {
  977. setConfig(response.data);
  978. $scope.fromUrl.data = '';
  979. $scope.importUrl = false;
  980. Notifications.success("Imported config information from url.");
  981. }).catch(function() {
  982. Notifications.error("Config can not be imported. Please verify the url.");
  983. });
  984. };
  985. $scope.$watch('fromUrl.data', function(newVal, oldVal){
  986. if ($scope.fromUrl.data && $scope.fromUrl.data.length > 0) {
  987. $scope.importUrl = true;
  988. } else{
  989. $scope.importUrl = false;
  990. }
  991. });
  992. $scope.$watch('configuredProviders', function(configuredProviders) {
  993. if (configuredProviders) {
  994. $scope.configuredProviders = angular.copy(configuredProviders);
  995. for (var j = 0; j < configuredProviders.length; j++) {
  996. var configProvidedId = configuredProviders[j].providerId;
  997. for (var i in $scope.allProviders) {
  998. var provider = $scope.allProviders[i];
  999. if (provider.id == configProvidedId) {
  1000. configuredProviders[j].provider = provider;
  1001. }
  1002. }
  1003. }
  1004. $scope.configuredProviders = angular.copy(configuredProviders);
  1005. }
  1006. }, true);
  1007. $scope.callbackUrl = authServerUrl + "/realms/" + realm.realm + "/broker/";
  1008. $scope.addProvider = function(provider) {
  1009. $location.url("/create/identity-provider/" + realm.realm + "/" + provider.id);
  1010. };
  1011. $scope.save = function() {
  1012. if ($scope.newIdentityProvider) {
  1013. if (!$scope.identityProvider.alias) {
  1014. Notifications.error("You must specify an alias");
  1015. return;
  1016. }
  1017. IdentityProvider.save({
  1018. realm: $scope.realm.realm, alias: ''
  1019. }, $scope.identityProvider, function () {
  1020. $location.url("/realms/" + realm.realm + "/identity-provider-settings/provider/" + $scope.identityProvider.providerId + "/" + $scope.identityProvider.alias);
  1021. Notifications.success("The " + $scope.identityProvider.alias + " provider has been created.");
  1022. });
  1023. } else {
  1024. IdentityProvider.update({
  1025. realm: $scope.realm.realm,
  1026. alias: $scope.identityProvider.alias
  1027. }, $scope.identityProvider, function () {
  1028. $route.reload();
  1029. Notifications.success("The " + $scope.identityProvider.alias + " provider has been updated.");
  1030. });
  1031. }
  1032. };
  1033. $scope.cancel = function() {
  1034. if ($scope.newIdentityProvider) {
  1035. $location.url("/realms/" + realm.realm + "/identity-provider-settings");
  1036. } else {
  1037. $route.reload();
  1038. }
  1039. };
  1040. $scope.reset = function() {
  1041. $scope.identityProvider = {};
  1042. $scope.configuredProviders = angular.copy($scope.realm.identityProviders);
  1043. };
  1044. $scope.showPassword = function(flag) {
  1045. $scope.hidePassword = flag;
  1046. };
  1047. $scope.removeIdentityProvider = function(identityProvider) {
  1048. Dialog.confirmDelete(identityProvider.alias, 'provider', function() {
  1049. IdentityProvider.remove({
  1050. realm : realm.realm,
  1051. alias : identityProvider.alias
  1052. }, function() {
  1053. $route.reload();
  1054. Notifications.success("The identity provider has been deleted.");
  1055. });
  1056. });
  1057. };
  1058. // KEYCLOAK-5932: remove social providers that have already been defined
  1059. function removeUsedSocial() {
  1060. var i = $scope.allProviders.length;
  1061. while (i--) {
  1062. if ($scope.allProviders[i].groupName !== 'Social') continue;
  1063. if ($scope.configuredProviders != null) {
  1064. for (var j = 0; j < $scope.configuredProviders.length; j++) {
  1065. if ($scope.configuredProviders[j].providerId === $scope.allProviders[i].id) {
  1066. $scope.allProviders.splice(i, 1);
  1067. break;
  1068. }
  1069. }
  1070. }
  1071. }
  1072. };
  1073. if (instance && instance.alias) {
  1074. try { $scope.authnContextClassRefs = JSON.parse($scope.identityProvider.config.authnContextClassRefs || '[]'); } catch (e) { $scope.authnContextClassRefs = []; }
  1075. try { $scope.authnContextDeclRefs = JSON.parse($scope.identityProvider.config.authnContextDeclRefs || '[]'); } catch (e) { $scope.authnContextDeclRefs = []; }
  1076. } else {
  1077. $scope.authnContextClassRefs = [];
  1078. $scope.authnContextDeclRefs = [];
  1079. }
  1080. $scope.deleteAuthnContextClassRef = function(index) {
  1081. $scope.authnContextClassRefs.splice(index, 1);
  1082. $scope.identityProvider.config.authnContextClassRefs = JSON.stringify($scope.authnContextClassRefs);
  1083. };
  1084. $scope.addAuthnContextClassRef = function() {
  1085. $scope.authnContextClassRefs.push($scope.newAuthnContextClassRef);
  1086. $scope.identityProvider.config.authnContextClassRefs = JSON.stringify($scope.authnContextClassRefs);
  1087. $scope.newAuthnContextClassRef = "";
  1088. };
  1089. $scope.deleteAuthnContextDeclRef = function(index) {
  1090. $scope.authnContextDeclRefs.splice(index, 1);
  1091. $scope.identityProvider.config.authnContextDeclRefs = JSON.stringify($scope.authnContextDeclRefs);
  1092. };
  1093. $scope.addAuthnContextDeclRef = function() {
  1094. $scope.authnContextDeclRefs.push($scope.newAuthnContextDeclRef);
  1095. $scope.identityProvider.config.authnContextDeclRefs = JSON.stringify($scope.authnContextDeclRefs);
  1096. $scope.newAuthnContextDeclRef = "";
  1097. };
  1098. });
  1099. module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http, $location, $route, Dialog, Notifications, TimeUnit, TimeUnit2, serverInfo) {
  1100. $scope.realm = realm;
  1101. $scope.serverInfo = serverInfo;
  1102. $scope.actionTokenProviders = $scope.serverInfo.providers.actionTokenHandler.providers;
  1103. $scope.realm.accessTokenLifespan = TimeUnit2.asUnit(realm.accessTokenLifespan);
  1104. $scope.realm.accessTokenLifespanForImplicitFlow = TimeUnit2.asUnit(realm.accessTokenLifespanForImplicitFlow);
  1105. $scope.realm.ssoSessionIdleTimeout = TimeUnit2.asUnit(realm.ssoSessionIdleTimeout);
  1106. $scope.realm.ssoSessionMaxLifespan = TimeUnit2.asUnit(realm.ssoSessionMaxLifespan);
  1107. $scope.realm.ssoSessionIdleTimeoutRememberMe = TimeUnit2.asUnit(realm.ssoSessionIdleTimeoutRememberMe);
  1108. $scope.realm.ssoSessionMaxLifespanRememberMe = TimeUnit2.asUnit(realm.ssoSessionMaxLifespanRememberMe);
  1109. $scope.realm.offlineSessionIdleTimeout = TimeUnit2.asUnit(realm.offlineSessionIdleTimeout);
  1110. // KEYCLOAK-7688 Offline Session Max for Offline Token
  1111. $scope.realm.offlineSessionMaxLifespan = TimeUnit2.asUnit(realm.offlineSessionMaxLifespan);
  1112. $scope.realm.clientSessionIdleTimeout = TimeUnit2.asUnit(realm.clientSessionIdleTimeout);
  1113. $scope.realm.clientSessionMaxLifespan = TimeUnit2.asUnit(realm.clientSessionMaxLifespan);
  1114. $scope.realm.clientOfflineSessionIdleTimeout = TimeUnit2.asUnit(realm.clientOfflineSessionIdleTimeout);
  1115. $scope.realm.clientOfflineSessionMaxLifespan = TimeUnit2.asUnit(realm.clientOfflineSessionMaxLifespan);
  1116. $scope.realm.accessCodeLifespan = TimeUnit2.asUnit(realm.accessCodeLifespan);
  1117. $scope.realm.accessCodeLifespanLogin = TimeUnit2.asUnit(realm.accessCodeLifespanLogin);
  1118. $scope.realm.accessCodeLifespanUserAction = TimeUnit2.asUnit(realm.accessCodeLifespanUserAction);
  1119. $scope.realm.actionTokenGeneratedByAdminLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByAdminLifespan);
  1120. $scope.realm.actionTokenGeneratedByUserLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByUserLifespan);
  1121. $scope.realm.oauth2DeviceCodeLifespan = TimeUnit2.asUnit(realm.oauth2DeviceCodeLifespan);
  1122. $scope.realm.attributes.parRequestUriLifespan = TimeUnit2.asUnit(realm.attributes.parRequestUriLifespan);
  1123. $scope.realm.attributes = realm.attributes;
  1124. var oldCopy = angular.copy($scope.realm);
  1125. $scope.changed = false;
  1126. $scope.$watch('realm', function() {
  1127. if (!angular.equals($scope.realm, oldCopy)) {
  1128. $scope.changed = true;
  1129. }
  1130. }, true);
  1131. $scope.$watch('actionLifespanId', function () {
  1132. // changedActionLifespanId signals other watchers that we were merely
  1133. // changing the dropdown and we should not enable 'save' button
  1134. if ($scope.actionTokenAttribute && $scope.actionTokenAttribute.hasOwnProperty('time')) {
  1135. $scope.changedActionLifespanId = true;
  1136. }
  1137. $scope.actionTokenAttribute = TimeUnit2.asUnit($scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId]);
  1138. }, true);
  1139. $scope.$watch('actionTokenAttribute', function () {
  1140. if ($scope.actionLifespanId === null) return;
  1141. if ($scope.changedActionLifespanId) {
  1142. $scope.changedActionLifespanId = false;
  1143. return;
  1144. } else {
  1145. $scope.changed = true;
  1146. }
  1147. if ($scope.actionTokenAttribute !== null) {
  1148. $scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId] = $scope.actionTokenAttribute.toSeconds();
  1149. }
  1150. }, true);
  1151. $scope.changeRevokeRefreshToken = function() {
  1152. };
  1153. $scope.save = function() {
  1154. $scope.realm.accessTokenLifespan = $scope.realm.accessTokenLifespan.toSeconds();
  1155. $scope.realm.accessTokenLifespanForImplicitFlow = $scope.realm.accessTokenLifespanForImplicitFlow.toSeconds();
  1156. $scope.realm.ssoSessionIdleTimeout = $scope.realm.ssoSessionIdleTimeout.toSeconds();
  1157. $scope.realm.ssoSessionMaxLifespan = $scope.realm.ssoSessionMaxLifespan.toSeconds();
  1158. $scope.realm.ssoSessionIdleTimeoutRememberMe = $scope.realm.ssoSessionIdleTimeoutRememberMe.toSeconds();
  1159. $scope.realm.ssoSessionMaxLifespanRememberMe = $scope.realm.ssoSessionMaxLifespanRememberMe.toSeconds();
  1160. $scope.realm.offlineSessionIdleTimeout = $scope.realm.offlineSessionIdleTimeout.toSeconds();
  1161. // KEYCLOAK-7688 Offline Session Max for Offline Token
  1162. $scope.realm.offlineSessionMaxLifespan = $scope.realm.offlineSessionMaxLifespan.toSeconds();
  1163. $scope.realm.clientSessionIdleTimeout = $scope.realm.clientSessionIdleTimeout.toSeconds();
  1164. $scope.realm.clientSessionMaxLifespan = $scope.realm.clientSessionMaxLifespan.toSeconds();
  1165. $scope.realm.clientOfflineSessionIdleTimeout = $scope.realm.clientOfflineSessionIdleTimeout.toSeconds();
  1166. $scope.realm.clientOfflineSessionMaxLifespan = $scope.realm.clientOfflineSessionMaxLifespan.toSeconds();
  1167. $scope.realm.accessCodeLifespan = $scope.realm.accessCodeLifespan.toSeconds();
  1168. $scope.realm.accessCodeLifespanUserAction = $scope.realm.accessCodeLifespanUserAction.toSeconds();
  1169. $scope.realm.accessCodeLifespanLogin = $scope.realm.accessCodeLifespanLogin.toSeconds();
  1170. $scope.realm.actionTokenGeneratedByAdminLifespan = $scope.realm.actionTokenGeneratedByAdminLifespan.toSeconds();
  1171. $scope.realm.actionTokenGeneratedByUserLifespan = $scope.realm.actionTokenGeneratedByUserLifespan.toSeconds();
  1172. $scope.realm.oauth2DeviceCodeLifespan = $scope.realm.oauth2DeviceCodeLifespan.toSeconds();
  1173. $scope.realm.attributes.parRequestUriLifespan = $scope.realm.attributes.parRequestUriLifespan.toSeconds();
  1174. Realm.update($scope.realm, function () {
  1175. $route.reload();
  1176. Notifications.success("The changes have been saved to the realm.");
  1177. });
  1178. };
  1179. $scope.resetToDefaultToken = function (actionTokenId) {
  1180. $scope.actionTokenAttribute = {};
  1181. delete $scope.realm.attributes['actionTokenGeneratedByUserLifespan.' + $scope.actionLifespanId];
  1182. //Only for UI effects, resets to the original state
  1183. $scope.actionTokenAttribute.unit = 'Minutes';
  1184. }
  1185. $scope.reset = function() {
  1186. $route.reload();
  1187. };
  1188. });
  1189. module.controller('RealmUserProfileCtrl', function($scope, Realm, realm, clientScopes, $http, $location, $route, UserProfile, Dialog, Notifications, serverInfo) {
  1190. $scope.realm = realm;
  1191. $scope.validatorProviders = serverInfo.componentTypes['org.keycloak.validate.Validator'];
  1192. $scope.isShowAttributes = true;
  1193. $scope.isShowAttributeGroups = false;
  1194. $scope.isShowJsonEditor = false;
  1195. UserProfile.get({realm: realm.realm}, function(config) {
  1196. $scope.config = config;
  1197. $scope.rawConfig = angular.toJson(config, true);
  1198. });
  1199. $scope.isShowAttributes = true;
  1200. $scope.isShowAttributeGroups = false;
  1201. $scope.isShowJsonEditor = false;
  1202. $scope.showAttributes = function() {
  1203. $route.reload();
  1204. delete $scope.currentAttributeGroup;
  1205. }
  1206. $scope.showAttributeGroups = function() {
  1207. $scope.isShowAttributes = false;
  1208. $scope.isShowAttributeGroups = true;
  1209. $scope.isShowJsonEditor = false;
  1210. delete $scope.currentAttribute;
  1211. }
  1212. $scope.showJsonEditor = function() {
  1213. $scope.isShowAttributes = false;
  1214. $scope.isShowAttributeGroups = false;
  1215. $scope.isShowJsonEditor = true;
  1216. delete $scope.currentAttribute;
  1217. delete $scope.currentAttributeGroup;
  1218. }
  1219. $scope.isRequiredRoles = {
  1220. minimumInputLength: 0,
  1221. delay: 500,
  1222. allowClear: true,
  1223. id: function(e) { return e; },
  1224. query: function (query) {
  1225. var expectedRoles = ['user', 'admin'];
  1226. var roles = [];
  1227. if ('' == query.term.trim()) {
  1228. roles = expectedRoles;
  1229. } else {
  1230. for (var i = 0; i < expectedRoles.length; i++) {
  1231. if (expectedRoles[i].indexOf(query.term.trim()) != -1) {
  1232. roles.push(expectedRoles[i]);
  1233. }
  1234. }
  1235. }
  1236. query.callback({results: roles});
  1237. },
  1238. formatResult: function(object, container, query) {
  1239. return object;
  1240. },
  1241. formatSelection: function(object, container, query) {
  1242. return object;
  1243. }
  1244. };
  1245. $scope.isRequiredScopes = {
  1246. minimumInputLength: 1,
  1247. delay: 500,
  1248. allowClear: true,
  1249. query: function (query) {
  1250. var scopes = [];
  1251. if ('' == query.term.trim()) {
  1252. scopes = clientScopes;
  1253. } else {
  1254. for (var i = 0; i < clientScopes.length; i++) {
  1255. if (clientScopes[i].name.indexOf(query.term.trim()) != -1) {
  1256. scopes.push(clientScopes[i]);
  1257. }
  1258. }
  1259. }
  1260. query.callback({results: scopes});
  1261. },
  1262. formatResult: function(object, container, query) {
  1263. return object.name;
  1264. },
  1265. formatSelection: function(object, container, query) {
  1266. return object.name;
  1267. }
  1268. };
  1269. $scope.selectorByScopeSelect = {
  1270. minimumInputLength: 1,
  1271. delay: 500,
  1272. allowClear: true,
  1273. query: function (query) {
  1274. var scopes = [];
  1275. if ('' == query.term.trim()) {
  1276. scopes = clientScopes;
  1277. } else {
  1278. for (var i = 0; i < clientScopes.length; i++) {
  1279. if (clientScopes[i].name.indexOf(query.term.trim()) != -1) {
  1280. scopes.push(clientScopes[i]);
  1281. }
  1282. }
  1283. }
  1284. query.callback({results: scopes});
  1285. },
  1286. formatResult: function(object, container, query) {
  1287. return object.name;
  1288. },
  1289. formatSelection: function(object, container, query) {
  1290. return object.name;
  1291. }
  1292. };
  1293. $scope.attributeSelected = false;
  1294. $scope.showAttributeListing = function() {
  1295. return !$scope.attributeSelected && $scope.currentAttribute == null && $scope.isShowAttributes;
  1296. }
  1297. $scope.showAttributeGroupListing = function() {
  1298. return !$scope.attributeGroupSelected && $scope.currentAttributeGroup == null && $scope.isShowAttributeGroups;
  1299. }
  1300. $scope.createAttribute = function() {
  1301. $scope.isCreateAttribute = true;
  1302. $scope.currentAttribute = {
  1303. selector: {
  1304. scopes: []
  1305. },
  1306. required: {
  1307. roles: [],
  1308. scopes: []
  1309. },
  1310. permissions: {
  1311. view: [],
  1312. edit: []
  1313. }
  1314. };
  1315. };
  1316. $scope.createAttributeGroup = function() {
  1317. $scope.isCreateAttributeGroup = true;
  1318. $scope.currentAttributeGroup = {};
  1319. };
  1320. $scope.isNotUsernameOrEmail = function(attributeName) {
  1321. return attributeName != "username" && attributeName != "email";
  1322. };
  1323. $scope.guiOrderUp = function(index) {
  1324. $scope.moveAttribute(index, index - 1);
  1325. };
  1326. $scope.guiOrderDown = function(index) {
  1327. $scope.moveAttribute(index, index + 1);
  1328. };
  1329. $scope.moveAttribute = function(old_index, new_index){
  1330. $scope.config.attributes.splice(new_index, 0, $scope.config.attributes.splice(old_index, 1)[0]);
  1331. $scope.save();
  1332. }
  1333. $scope.groupOrderUp = function(index) {
  1334. $scope.moveAttributeGroup(index, index - 1);
  1335. };
  1336. $scope.groupOrderDown = function(index) {
  1337. $scope.moveAttributeGroup(index, index + 1);
  1338. };
  1339. $scope.moveAttributeGroup = function(old_index, new_index){
  1340. $scope.config.groups.splice(new_index, 0, $scope.config.groups.splice(old_index, 1)[0]);
  1341. $scope.save(false);
  1342. }
  1343. $scope.removeAttribute = function(attribute) {
  1344. Dialog.confirmDelete(attribute.name, 'attribute', function() {
  1345. let newAttributes = [];
  1346. for (var v of $scope.config.attributes) {
  1347. if (v != attribute) {
  1348. newAttributes.push(v);
  1349. }
  1350. }
  1351. $scope.config.attributes = newAttributes;
  1352. $scope.save();
  1353. });
  1354. };
  1355. $scope.removeAttributeGroup = function(attributeGroup) {
  1356. Dialog.confirmDelete(attributeGroup.name, 'group', function() {
  1357. let newGroups = [];
  1358. for (var v of $scope.config.groups) {
  1359. if (v != attributeGroup) {
  1360. newGroups.push(v);
  1361. }
  1362. }
  1363. $scope.config.groups = newGroups;
  1364. $scope.save();
  1365. });
  1366. };
  1367. $scope.addAttributeAnnotation = function() {
  1368. if (!$scope.currentAttribute.annotations) {
  1369. $scope.currentAttribute.annotations = {};
  1370. }
  1371. $scope.currentAttribute.annotations[$scope.newAnnotation.key] = $scope.newAnnotation.value;
  1372. delete $scope.newAnnotation;
  1373. }
  1374. $scope.removeAttributeAnnotation = function(key) {
  1375. delete $scope.currentAttribute.annotations[key];
  1376. }
  1377. $scope.addAttributeGroupAnnotation = function() {
  1378. if (!$scope.currentAttributeGroup.annotations) {
  1379. $scope.currentAttributeGroup.annotations = {};
  1380. }
  1381. $scope.currentAttributeGroup.annotations[$scope.newAttributeGroupAnnotation.key] = $scope.newAttributeGroupAnnotation.value;
  1382. delete $scope.newGroupAnnotation;
  1383. }
  1384. $scope.removeAttributeGroupAnnotation = function(key) {
  1385. delete $scope.currentAttributeGroup.annotations[key];
  1386. }
  1387. $scope.editAttribute = function(attribute) {
  1388. if (attribute.permissions == null) {
  1389. attribute.permissions = {
  1390. view: [],
  1391. edit: []
  1392. };
  1393. }
  1394. if (attribute.selector == null) {
  1395. attribute.selector = {
  1396. scopes: []
  1397. };
  1398. }
  1399. if (attribute.required) {
  1400. if (attribute.required.roles) {
  1401. $scope.requiredRoles = attribute.required.roles;
  1402. }
  1403. if (attribute.required.scopes) {
  1404. for (var i = 0; i < attribute.required.scopes.length; i++) {
  1405. $scope.requiredScopes.push({
  1406. id: attribute.required.scopes[i],
  1407. name: attribute.required.scopes[i]
  1408. });
  1409. }
  1410. }
  1411. }
  1412. if (attribute.selector && attribute.selector.scopes) {
  1413. for (var i = 0; i < attribute.selector.scopes.length; i++) {
  1414. $scope.selectorByScope.push({
  1415. id: attribute.selector.scopes[i],
  1416. name: attribute.selector.scopes[i]
  1417. });
  1418. }
  1419. }
  1420. $scope.isRequired = attribute.required != null;
  1421. $scope.canUserView = attribute.permissions.view.includes('user');
  1422. $scope.canAdminView = attribute.permissions.view.includes('admin');
  1423. $scope.canUserEdit = attribute.permissions.edit.includes('user');
  1424. $scope.canAdminEdit = attribute.permissions.edit.includes('admin');
  1425. $scope.currentAttribute = attribute;
  1426. $scope.attributeSelected = true;
  1427. };
  1428. $scope.editAttributeGroup = function(attributeGroup) {
  1429. $scope.currentAttributeGroup = attributeGroup;
  1430. $scope.attributeGroupSelected = true;
  1431. };
  1432. $scope.groupIsReferencedInAnyAttribute = function(group) {
  1433. for (var currentAttribute of $scope.config.attributes) {
  1434. if (currentAttribute.group === group.name) {
  1435. return true
  1436. }
  1437. }
  1438. return false;
  1439. }
  1440. $scope.$watch('isRequired', function() {
  1441. if ($scope.isRequired) {
  1442. $scope.currentAttribute.required = {
  1443. roles: [],
  1444. scopes: []
  1445. };
  1446. } else if ($scope.currentAttribute) {
  1447. delete $scope.currentAttribute.required;
  1448. }
  1449. }, true);
  1450. handlePermission = function(permission, role, allowed) {
  1451. let attribute = $scope.currentAttribute;
  1452. if (attribute && attribute.permissions) {
  1453. let roles = [];
  1454. for (let r of attribute.permissions[permission]) {
  1455. if (r != role) {
  1456. roles.push(r);
  1457. }
  1458. }
  1459. if (allowed) {
  1460. roles.push(role);
  1461. }
  1462. attribute.permissions[permission] = roles;
  1463. }
  1464. }
  1465. $scope.$watch('canUserView', function() {
  1466. handlePermission('view', 'user', $scope.canUserView);
  1467. }, true);
  1468. $scope.$watch('canAdminView', function() {
  1469. handlePermission('view', 'admin', $scope.canAdminView);
  1470. }, true);
  1471. $scope.$watch('canUserEdit', function() {
  1472. handlePermission('edit', 'user', $scope.canUserEdit);
  1473. }, true);
  1474. $scope.$watch('canAdminEdit', function() {
  1475. handlePermission('edit', 'admin', $scope.canAdminEdit);
  1476. }, true);
  1477. $scope.addValidator = function(validator) {
  1478. if ($scope.currentAttribute.validations == null) {
  1479. $scope.currentAttribute.validations = {};
  1480. }
  1481. let config = {};
  1482. for (let key in validator.config) {
  1483. let values = validator.config[key];
  1484. if (Array.isArray(values)) {
  1485. config[key] = values;
  1486. } else {
  1487. for (let k in values) {
  1488. config[key] = values[k];
  1489. }
  1490. }
  1491. }
  1492. $scope.currentAttribute.validations[validator.id] = config;
  1493. delete $scope.newValidator;
  1494. };
  1495. $scope.selectValidator = function(validator) {
  1496. validator.config = {};
  1497. };
  1498. $scope.cancelAddValidator = function() {
  1499. delete $scope.newValidator;
  1500. };
  1501. $scope.removeValidator = function(id) {
  1502. let newValidators = {};
  1503. for (let v in $scope.currentAttribute.validations) {
  1504. if (v != id) {
  1505. newValidators[v] = $scope.currentAttribute.validations[v];
  1506. }
  1507. }
  1508. if (newValidators.length == 0) {
  1509. delete $scope.currentAttribute.validations;
  1510. return;
  1511. }
  1512. $scope.currentAttribute.validations = newValidators;
  1513. };
  1514. $scope.reloadConfigurationFromUserProfile = function () {
  1515. UserProfile.get({realm: realm.realm}, function(config) {
  1516. $scope.config = config;
  1517. $scope.rawConfig = angular.toJson(config, true);
  1518. });
  1519. }
  1520. $scope.save = function() {
  1521. $scope.save(true)
  1522. }
  1523. $scope.save = function(reload) {
  1524. if ($scope.isShowJsonEditor) {
  1525. $scope.config = JSON.parse($scope.rawConfig);
  1526. }
  1527. if ($scope.currentAttribute) {
  1528. if ($scope.isRequired) {
  1529. $scope.currentAttribute.required.roles = $scope.requiredRoles;
  1530. for (var i = 0; i < $scope.requiredScopes.length; i++) {
  1531. $scope.currentAttribute.required.scopes.push($scope.requiredScopes[i].name);
  1532. }
  1533. }
  1534. $scope.currentAttribute.selector = {scopes: []};
  1535. for (var i = 0; i < $scope.selectorByScope.length; i++) {
  1536. $scope.currentAttribute.selector.scopes.push($scope.selectorByScope[i].name);
  1537. }
  1538. if ($scope.isCreateAttribute) {
  1539. $scope.config['attributes'].push($scope.currentAttribute);
  1540. }
  1541. }
  1542. if ($scope.currentAttributeGroup) {
  1543. if ($scope.config['groups'] == null) {
  1544. $scope.config['groups'] = []
  1545. }
  1546. if ($scope.isCreateAttributeGroup) {
  1547. $scope.config['groups'].push($scope.currentAttributeGroup);
  1548. }
  1549. }
  1550. UserProfile.update({realm: realm.realm},
  1551. $scope.config, function () {
  1552. $scope.attributeSelected = false;
  1553. delete $scope.currentAttribute;
  1554. delete $scope.isCreateAttribute
  1555. delete $scope.attributeSelected;
  1556. delete $scope.currentAttributeGroup;
  1557. delete $scope.isCreateAttributeGroup;
  1558. delete $scope.attributeGroupSelected;
  1559. delete $scope.isRequired;
  1560. delete $scope.canUserView;
  1561. delete $scope.canAdminView;
  1562. delete $scope.canUserEdit;
  1563. delete $scope.canAdminEdit;
  1564. if (reload) {
  1565. $route.reload();
  1566. } else {
  1567. $scope.reloadConfigurationFromUserProfile();
  1568. }
  1569. Notifications.success("User Profile configuration has been saved.");
  1570. });
  1571. };
  1572. $scope.cancelEditAttributeGroup = function() {
  1573. delete $scope.currentAttributeGroup;
  1574. delete $scope.isCreateAttributeGroup;
  1575. delete $scope.attributeGroupSelected;
  1576. $scope.reloadConfigurationFromUserProfile();
  1577. }
  1578. $scope.reset = function() {
  1579. $route.reload();
  1580. };
  1581. });
  1582. module.controller('ViewKeyCtrl', function($scope, key) {
  1583. $scope.key = key;
  1584. });
  1585. module.controller('RealmKeysCtrl', function($scope, Realm, realm, $http, $route, $location, Dialog, Notifications, serverInfo, keys, Components, $modal) {
  1586. $scope.realm = angular.copy(realm);
  1587. $scope.keys = keys.keys;
  1588. $scope.active = {};
  1589. Components.query({realm: realm.realm,
  1590. parent: realm.id,
  1591. type: 'org.keycloak.keys.KeyProvider'
  1592. }, function(data) {
  1593. for (var i = 0; i < keys.keys.length; i++) {
  1594. for (var j = 0; j < data.length; j++) {
  1595. if (keys.keys[i].providerId == data[j].id) {
  1596. keys.keys[i].provider = data[j];
  1597. }
  1598. }
  1599. }
  1600. for (var t in keys.active) {
  1601. for (var i = 0; i < keys.keys.length; i++) {
  1602. if (keys.active[t] == keys.keys[i].kid) {
  1603. $scope.active[t] = keys.keys[i];
  1604. }
  1605. }
  1606. }
  1607. });
  1608. $scope.viewKey = function(key) {
  1609. $modal.open({
  1610. templateUrl: resourceUrl + '/partials/modal/view-key.html',
  1611. controller: 'ViewKeyCtrl',
  1612. resolve: {
  1613. key: function () {
  1614. return key;
  1615. }
  1616. }
  1617. })
  1618. }
  1619. });
  1620. module.controller('RealmKeysProvidersCtrl', function($scope, Realm, realm, $http, $route, $location, Dialog, Notifications, serverInfo, Components, $modal) {
  1621. $scope.realm = angular.copy(realm);
  1622. $scope.enableUpload = false;
  1623. $scope.providers = serverInfo.componentTypes['org.keycloak.keys.KeyProvider'];
  1624. Components.query({realm: realm.realm,
  1625. parent: realm.id,
  1626. type: 'org.keycloak.keys.KeyProvider'
  1627. }, function(data) {
  1628. $scope.instances = data;
  1629. for (var i = 0; i < $scope.instances.length; i++) {
  1630. for (var j = 0; j < $scope.providers.length; j++) {
  1631. if ($scope.providers[j].id === $scope.instances[i].providerId) {
  1632. $scope.instances[i].provider = $scope.providers[j];
  1633. }
  1634. }
  1635. }
  1636. });
  1637. $scope.addProvider = function(provider) {
  1638. $location.url("/create/keys/" + realm.realm + "/providers/" + provider.id);
  1639. };
  1640. $scope.removeInstance = function(instance) {
  1641. Dialog.confirmDelete(instance.name, 'key provider', function() {
  1642. Components.remove({
  1643. realm : realm.realm,
  1644. componentId : instance.id
  1645. }, function() {
  1646. $route.reload();
  1647. Notifications.success("The provider has been deleted.");
  1648. });
  1649. });
  1650. };
  1651. });
  1652. module.controller('GenericKeystoreCtrl', function($scope, $location, Notifications, $route, Dialog, realm, serverInfo, instance, providerId, Components) {
  1653. $scope.create = !instance.providerId;
  1654. $scope.realm = realm;
  1655. var providers = serverInfo.componentTypes['org.keycloak.keys.KeyProvider'];
  1656. var providerFactory = null;
  1657. for (var i = 0; i < providers.length; i++) {
  1658. var p = providers[i];
  1659. if (p.id == providerId) {
  1660. $scope.providerFactory = p;
  1661. providerFactory = p;
  1662. break;
  1663. }
  1664. }
  1665. if ($scope.create) {
  1666. $scope.instance = {
  1667. name: providerFactory.id,
  1668. providerId: providerFactory.id,
  1669. providerType: 'org.keycloak.keys.KeyProvider',
  1670. parentId: realm.id,
  1671. config: {
  1672. 'priority': ["0"]
  1673. }
  1674. }
  1675. } else {
  1676. $scope.instance = angular.copy(instance);
  1677. }
  1678. if (providerFactory.properties) {
  1679. for (var i = 0; i < providerFactory.properties.length; i++) {
  1680. var configProperty = providerFactory.properties[i];
  1681. if (!$scope.instance.config[configProperty.name]) {
  1682. if (configProperty.defaultValue) {
  1683. $scope.instance.config[configProperty.name] = [configProperty.defaultValue];
  1684. if (!$scope.create) {
  1685. instance.config[configProperty.name] = [configProperty.defaultValue];
  1686. }
  1687. } else {
  1688. $scope.instance.config[configProperty.name] = [''];
  1689. if (!$scope.create) {
  1690. instance.config[configProperty.name] = [configProperty.defaultValue];
  1691. }
  1692. }
  1693. }
  1694. }
  1695. }
  1696. $scope.$watch('instance', function() {
  1697. if (!angular.equals($scope.instance, instance)) {
  1698. $scope.changed = true;
  1699. }
  1700. }, true);
  1701. $scope.save = function() {
  1702. $scope.changed = false;
  1703. if ($scope.create) {
  1704. Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
  1705. var l = headers().location;
  1706. var id = l.substring(l.lastIndexOf("/") + 1);
  1707. $location.url("/realms/" + realm.realm + "/keys/providers/" + $scope.instance.providerId + "/" + id);
  1708. Notifications.success("The provider has been created.");
  1709. });
  1710. } else {
  1711. Components.update({realm: realm.realm,
  1712. componentId: instance.id
  1713. },
  1714. $scope.instance, function () {
  1715. $route.reload();
  1716. Notifications.success("The provider has been updated.");
  1717. });
  1718. }
  1719. };
  1720. $scope.reset = function() {
  1721. $route.reload();
  1722. };
  1723. $scope.cancel = function() {
  1724. if ($scope.create) {
  1725. $location.url("/realms/" + realm.realm + "/keys");
  1726. } else {
  1727. $route.reload();
  1728. }
  1729. };
  1730. });
  1731. module.controller('RealmSessionStatsCtrl', function($scope, realm, stats, RealmClientSessionStats, RealmLogoutAll, Notifications) {
  1732. $scope.realm = realm;
  1733. $scope.stats = stats;
  1734. $scope.logoutAll = function() {
  1735. RealmLogoutAll.save({realm : realm.realm}, function (globalReqResult) {
  1736. var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0;
  1737. var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0;
  1738. if (failedCount > 0) {
  1739. var msgStart = successCount>0 ? 'Successfully logout all users under: ' + globalReqResult.successRequests + ' . ' : '';
  1740. Notifications.error(msgStart + 'Failed to logout users under: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again');
  1741. } else {
  1742. window.location.reload();
  1743. }
  1744. });
  1745. };
  1746. });
  1747. module.controller('RealmRevocationCtrl', function($scope, Realm, RealmPushRevocation, realm, $http, $location, Dialog, Notifications) {
  1748. $scope.realm = angular.copy(realm);
  1749. var setNotBefore = function() {
  1750. if ($scope.realm.notBefore == 0) {
  1751. $scope.notBefore = "None";
  1752. } else {
  1753. $scope.notBefore = new Date($scope.realm.notBefore * 1000);
  1754. }
  1755. };
  1756. setNotBefore();
  1757. var reset = function() {
  1758. Realm.get({ id : realm.realm }, function(updated) {
  1759. $scope.realm = updated;
  1760. setNotBefore();
  1761. })
  1762. };
  1763. $scope.clear = function() {
  1764. Realm.update({ realm: realm.realm, notBefore : 0 }, function () {
  1765. $scope.notBefore = "None";
  1766. Notifications.success('Not Before cleared for realm.');
  1767. reset();
  1768. });
  1769. }
  1770. $scope.setNotBeforeNow = function() {
  1771. Realm.update({ realm: realm.realm, notBefore : new Date().getTime()/1000}, function () {
  1772. Notifications.success('Not Before set for realm.');
  1773. reset();
  1774. });
  1775. }
  1776. $scope.pushRevocation = function() {
  1777. RealmPushRevocation.save({ realm: realm.realm}, function (globalReqResult) {
  1778. var successCount = globalReqResult.successRequests ? globalReqResult.successRequests.length : 0;
  1779. var failedCount = globalReqResult.failedRequests ? globalReqResult.failedRequests.length : 0;
  1780. if (successCount==0 && failedCount==0) {
  1781. Notifications.warn('No push sent. No admin URI configured or no registered cluster nodes available');
  1782. } else if (failedCount > 0) {
  1783. var msgStart = successCount>0 ? 'Successfully push notBefore to: ' + globalReqResult.successRequests + ' . ' : '';
  1784. Notifications.error(msgStart + 'Failed to push notBefore to: ' + globalReqResult.failedRequests + '. Verify availability of failed hosts and try again');
  1785. } else {
  1786. Notifications.success('Successfully push notBefore to all configured clients');
  1787. }
  1788. });
  1789. }
  1790. });
  1791. module.controller('RoleTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
  1792. $scope.removeRole = function() {
  1793. Dialog.confirmDelete($scope.role.name, 'role', function() {
  1794. RoleById.remove({
  1795. realm: realm.realm,
  1796. role: $scope.role.id
  1797. }, function () {
  1798. $route.reload();
  1799. Notifications.success("The role has been deleted.");
  1800. });
  1801. });
  1802. };
  1803. });
  1804. module.controller('RoleListCtrl', function($scope, $route, Dialog, Notifications, realm, RoleList, RoleById, filterFilter) {
  1805. $scope.realm = realm;
  1806. $scope.roles = [];
  1807. $scope.defaultRoleName = realm.defaultRole.name;
  1808. $scope.query = {
  1809. realm: realm.realm,
  1810. search : null,
  1811. max : 20,
  1812. first : 0
  1813. }
  1814. $scope.$watch('query.search', function (newVal, oldVal) {
  1815. if($scope.query.search && $scope.query.search.length >= 3) {
  1816. $scope.firstPage();
  1817. }
  1818. }, true);
  1819. $scope.firstPage = function() {
  1820. $scope.query.first = 0;
  1821. $scope.searchQuery();
  1822. }
  1823. $scope.previousPage = function() {
  1824. $scope.query.first -= parseInt($scope.query.max);
  1825. if ($scope.query.first < 0) {
  1826. $scope.query.first = 0;
  1827. }
  1828. $scope.searchQuery();
  1829. }
  1830. $scope.nextPage = function() {
  1831. $scope.query.first += parseInt($scope.query.max);
  1832. $scope.searchQuery();
  1833. }
  1834. $scope.searchQuery = function() {
  1835. $scope.searchLoaded = false;
  1836. $scope.roles = RoleList.query($scope.query, function() {
  1837. $scope.searchLoaded = true;
  1838. $scope.lastSearch = $scope.query.search;
  1839. });
  1840. };
  1841. $scope.searchQuery();
  1842. $scope.determineEditLink = function(role) {
  1843. return role.name === $scope.defaultRoleName ? "/realms/" + $scope.realm.realm + "/default-roles" : "/realms/" + $scope.realm.realm + "/roles/" + role.id;
  1844. }
  1845. $scope.removeRole = function (role) {
  1846. if (role.name === $scope.defaultRoleName) return;
  1847. Dialog.confirmDelete(role.name, 'role', function () {
  1848. RoleById.remove({
  1849. realm: realm.realm,
  1850. role: role.id
  1851. }, function () {
  1852. $route.reload();
  1853. Notifications.success("The role has been deleted.");
  1854. });
  1855. });
  1856. };
  1857. });
  1858. module.controller('RoleDetailCtrl', function($scope, realm, role, roles, Client, $route,
  1859. Role, ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
  1860. $http, $location, Dialog, Notifications, RealmRoleRemover, ComponentUtils) {
  1861. $scope.realm = realm;
  1862. $scope.role = angular.copy(role);
  1863. $scope.create = !role.name;
  1864. $scope.changed = $scope.create;
  1865. $scope.save = function() {
  1866. convertAttributeValuesToLists();
  1867. console.log('save');
  1868. if ($scope.create) {
  1869. Role.save({
  1870. realm: realm.realm
  1871. }, $scope.role, function (data, headers) {
  1872. $scope.changed = false;
  1873. convertAttributeValuesToString($scope.role);
  1874. role = angular.copy($scope.role);
  1875. Role.get({ realm: realm.realm, role: role.name }, function(role) {
  1876. var id = role.id;
  1877. $location.url("/realms/" + realm.realm + "/roles/" + id);
  1878. Notifications.success("The role has been created.");
  1879. });
  1880. });
  1881. } else {
  1882. $scope.update();
  1883. }
  1884. };
  1885. $scope.remove = function() {
  1886. RealmRoleRemover.remove($scope.role, realm, Dialog, $location, Notifications);
  1887. };
  1888. $scope.cancel = function () {
  1889. $location.url("/realms/" + realm.realm + "/roles");
  1890. };
  1891. $scope.addAttribute = function() {
  1892. $scope.role.attributes[$scope.newAttribute.key] = $scope.newAttribute.value;
  1893. delete $scope.newAttribute;
  1894. }
  1895. $scope.removeAttribute = function(key) {
  1896. delete $scope.role.attributes[key];
  1897. }
  1898. function convertAttributeValuesToLists() {
  1899. var attrs = $scope.role.attributes;
  1900. for (var attribute in attrs) {
  1901. if (typeof attrs[attribute] === "string") {
  1902. var attrVals = attrs[attribute].split("##");
  1903. attrs[attribute] = attrVals;
  1904. }
  1905. }
  1906. }
  1907. function convertAttributeValuesToString(role) {
  1908. var attrs = role.attributes;
  1909. for (var attribute in attrs) {
  1910. if (typeof attrs[attribute] === "object") {
  1911. var attrVals = attrs[attribute].join("##");
  1912. attrs[attribute] = attrVals;
  1913. console.log("attribute" + attrVals)
  1914. }
  1915. }
  1916. }
  1917. roleControl($scope, $route, realm, role, roles, Client,
  1918. ClientRole, RoleById, RoleRealmComposites, RoleClientComposites,
  1919. $http, $location, Notifications, Dialog, ComponentUtils);
  1920. });
  1921. module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, realm, $http, $location, Dialog, Notifications, RealmSMTPConnectionTester) {
  1922. console.log('RealmSMTPSettingsCtrl');
  1923. var booleanSmtpAtts = ["auth","ssl","starttls"];
  1924. $scope.realm = realm;
  1925. if ($scope.realm.smtpServer) {
  1926. $scope.realm.smtpServer = typeObject($scope.realm.smtpServer);
  1927. };
  1928. var oldCopy = angular.copy($scope.realm);
  1929. $scope.changed = false;
  1930. $scope.$watch('realm', function() {
  1931. if (!angular.equals($scope.realm, oldCopy)) {
  1932. $scope.changed = true;
  1933. }
  1934. }, true);
  1935. $scope.save = function() {
  1936. var realmCopy = angular.copy($scope.realm);
  1937. realmCopy['smtpServer'] = detypeObject(realmCopy.smtpServer);
  1938. $scope.changed = false;
  1939. Realm.update(realmCopy, function () {
  1940. $location.url("/realms/" + realm.realm + "/smtp-settings");
  1941. Notifications.success("Your changes have been saved to the realm.");
  1942. });
  1943. };
  1944. $scope.reset = function() {
  1945. $scope.realm = angular.copy(oldCopy);
  1946. $scope.changed = false;
  1947. };
  1948. $scope.testConnection = function() {
  1949. RealmSMTPConnectionTester.save({realm: realm.realm}, realm.smtpServer, function() {
  1950. Notifications.success("SMTP connection successful. E-mail was sent!");
  1951. }, function(errorResponse) {
  1952. if (error.data.errorMessage) {
  1953. Notifications.error(error.data.errorMessage);
  1954. } else {
  1955. Notifications.error('Unexpected error during SMTP validation');
  1956. }
  1957. });
  1958. };
  1959. /* Convert string attributes containing a boolean to actual boolean type + convert an integer string (port) to integer. */
  1960. function typeObject(obj){
  1961. for (var att in obj){
  1962. if (booleanSmtpAtts.indexOf(att) < 0)
  1963. continue;
  1964. if (obj[att] === "true"){
  1965. obj[att] = true;
  1966. } else if (obj[att] === "false"){
  1967. obj[att] = false;
  1968. }
  1969. }
  1970. obj['port'] = parseInt(obj['port']);
  1971. return obj;
  1972. }
  1973. /* Convert all non-string values to strings to invert changes caused by the typeObject function. */
  1974. function detypeObject(obj){
  1975. for (var att in obj){
  1976. if (booleanSmtpAtts.indexOf(att) < 0)
  1977. continue;
  1978. if (obj[att] === true){
  1979. obj[att] = "true";
  1980. } else if (obj[att] === false){
  1981. obj[att] = "false"
  1982. }
  1983. }
  1984. obj['port'] = obj['port'] && obj['port'].toString();
  1985. return obj;
  1986. }
  1987. });
  1988. module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, RealmAdminEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) {
  1989. $scope.realm = realm;
  1990. $scope.eventsConfig = eventsConfig;
  1991. $scope.eventsConfig.expirationUnit = TimeUnit.autoUnit(eventsConfig.eventsExpiration);
  1992. $scope.eventsConfig.eventsExpiration = TimeUnit.toUnit(eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit);
  1993. $scope.eventListeners = Object.keys(serverInfo.providers.eventsListener.providers);
  1994. $scope.eventsConfigSelectOptions = {
  1995. 'multiple': true,
  1996. 'simple_tags': true,
  1997. 'tags': $scope.eventListeners
  1998. };
  1999. $scope.eventSelectOptions = {
  2000. 'multiple': true,
  2001. 'simple_tags': true,
  2002. 'tags': serverInfo.enums['eventType']
  2003. };
  2004. var oldCopy = angular.copy($scope.eventsConfig);
  2005. $scope.changed = false;
  2006. $scope.$watch('eventsConfig', function() {
  2007. if (!angular.equals($scope.eventsConfig, oldCopy)) {
  2008. $scope.changed = true;
  2009. }
  2010. }, true);
  2011. $scope.save = function() {
  2012. $scope.changed = false;
  2013. var copy = angular.copy($scope.eventsConfig)
  2014. delete copy['expirationUnit'];
  2015. copy.eventsExpiration = TimeUnit.toSeconds($scope.eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit);
  2016. RealmEventsConfig.update({
  2017. id : realm.realm
  2018. }, copy, function () {
  2019. $location.url("/realms/" + realm.realm + "/events-settings");
  2020. Notifications.success("Your changes have been saved to the realm.");
  2021. });
  2022. };
  2023. $scope.reset = function() {
  2024. $scope.eventsConfig = angular.copy(oldCopy);
  2025. $scope.changed = false;
  2026. };
  2027. $scope.clearEvents = function() {
  2028. Dialog.confirmDelete($scope.realm.realm, 'events', function() {
  2029. RealmEvents.remove({ id : $scope.realm.realm }, function() {
  2030. Notifications.success("The events has been cleared.");
  2031. });
  2032. });
  2033. };
  2034. $scope.clearAdminEvents = function() {
  2035. Dialog.confirmDelete($scope.realm.realm, 'admin-events', function() {
  2036. RealmAdminEvents.remove({ id : $scope.realm.realm }, function() {
  2037. Notifications.success("The admin events has been cleared.");
  2038. });
  2039. });
  2040. };
  2041. });
  2042. module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm, serverInfo) {
  2043. $scope.realm = realm;
  2044. $scope.page = 0;
  2045. $scope.eventSelectOptions = {
  2046. 'multiple': true,
  2047. 'simple_tags': true,
  2048. 'tags': serverInfo.enums['eventType']
  2049. };
  2050. $scope.query = {
  2051. id : realm.realm,
  2052. max : 5,
  2053. first : 0
  2054. }
  2055. $scope.disablePaste = function(e) {
  2056. e.preventDefault();
  2057. return false;
  2058. }
  2059. $scope.update = function() {
  2060. $scope.query.first = 0;
  2061. for (var i in $scope.query) {
  2062. if ($scope.query[i] === '') {
  2063. delete $scope.query[i];
  2064. }
  2065. }
  2066. $scope.events = RealmEvents.query($scope.query);
  2067. }
  2068. $scope.reset = function() {
  2069. $scope.query.first = 0;
  2070. $scope.query.max = 5;
  2071. $scope.query.type = '';
  2072. $scope.query.client = '';
  2073. $scope.query.user = '';
  2074. $scope.query.dateFrom = '';
  2075. $scope.query.dateTo = '';
  2076. $scope.update();
  2077. }
  2078. $scope.queryUpdate = function() {
  2079. for (var i in $scope.query) {
  2080. if ($scope.query[i] === '') {
  2081. delete $scope.query[i];
  2082. }
  2083. }
  2084. $scope.events = RealmEvents.query($scope.query);
  2085. }
  2086. $scope.firstPage = function() {
  2087. $scope.query.first = 0;
  2088. $scope.queryUpdate();
  2089. }
  2090. $scope.previousPage = function() {
  2091. $scope.query.first -= parseInt($scope.query.max);
  2092. if ($scope.query.first < 0) {
  2093. $scope.query.first = 0;
  2094. }
  2095. $scope.queryUpdate();
  2096. }
  2097. $scope.nextPage = function() {
  2098. $scope.query.first += parseInt($scope.query.max);
  2099. $scope.queryUpdate();
  2100. }
  2101. $scope.update();
  2102. });
  2103. module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, realm, serverInfo, $modal, $filter) {
  2104. $scope.realm = realm;
  2105. $scope.page = 0;
  2106. $scope.query = {
  2107. id : realm.realm,
  2108. max : 5,
  2109. first : 0
  2110. };
  2111. $scope.adminEnabledEventOperationsOptions = {
  2112. 'multiple': true,
  2113. 'simple_tags': true,
  2114. 'tags': serverInfo.enums['operationType']
  2115. };
  2116. $scope.adminEnabledEventResourceTypesOptions = {
  2117. 'multiple': true,
  2118. 'simple_tags': true,
  2119. 'tags': serverInfo.enums['resourceType']
  2120. };
  2121. $scope.disablePaste = function(e) {
  2122. e.preventDefault();
  2123. return false;
  2124. }
  2125. $scope.update = function() {
  2126. $scope.query.first = 0;
  2127. for (var i in $scope.query) {
  2128. if ($scope.query[i] === '') {
  2129. delete $scope.query[i];
  2130. }
  2131. }
  2132. $scope.events = RealmAdminEvents.query($scope.query);
  2133. };
  2134. $scope.reset = function() {
  2135. $scope.query.first = 0;
  2136. $scope.query.max = 5;
  2137. $scope.query.operationTypes = '';
  2138. $scope.query.resourceTypes = '';
  2139. $scope.query.resourcePath = '';
  2140. $scope.query.authRealm = '';
  2141. $scope.query.authClient = '';
  2142. $scope.query.authUser = '';
  2143. $scope.query.authIpAddress = '';
  2144. $scope.query.dateFrom = '';
  2145. $scope.query.dateTo = '';
  2146. $scope.update();
  2147. };
  2148. $scope.queryUpdate = function() {
  2149. for (var i in $scope.query) {
  2150. if ($scope.query[i] === '') {
  2151. delete $scope.query[i];
  2152. }
  2153. }
  2154. $scope.events = RealmAdminEvents.query($scope.query);
  2155. }
  2156. $scope.firstPage = function() {
  2157. $scope.query.first = 0;
  2158. $scope.queryUpdate();
  2159. }
  2160. $scope.previousPage = function() {
  2161. $scope.query.first -= parseInt($scope.query.max);
  2162. if ($scope.query.first < 0) {
  2163. $scope.query.first = 0;
  2164. }
  2165. $scope.queryUpdate();
  2166. }
  2167. $scope.nextPage = function() {
  2168. $scope.query.first += parseInt($scope.query.max);
  2169. $scope.queryUpdate();
  2170. }
  2171. $scope.update();
  2172. $scope.viewRepresentation = function(event) {
  2173. $modal.open({
  2174. templateUrl: resourceUrl + '/partials/modal/realm-events-admin-representation.html',
  2175. controller: 'RealmAdminEventsModalCtrl',
  2176. resolve: {
  2177. event: function () {
  2178. return event;
  2179. }
  2180. }
  2181. })
  2182. }
  2183. $scope.viewAuth = function(event) {
  2184. $modal.open({
  2185. templateUrl: resourceUrl + '/partials/modal/realm-events-admin-auth.html',
  2186. controller: 'RealmAdminEventsModalCtrl',
  2187. resolve: {
  2188. event: function () {
  2189. return event;
  2190. }
  2191. }
  2192. })
  2193. }
  2194. });
  2195. module.controller('RealmAdminEventsModalCtrl', function($scope, $filter, event) {
  2196. $scope.event = event;
  2197. });
  2198. module.controller('RealmBruteForceCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, TimeUnit, $route) {
  2199. console.log('RealmBruteForceCtrl');
  2200. $scope.realm = realm;
  2201. $scope.realm.waitIncrementUnit = TimeUnit.autoUnit(realm.waitIncrementSeconds);
  2202. $scope.realm.waitIncrement = TimeUnit.toUnit(realm.waitIncrementSeconds, $scope.realm.waitIncrementUnit);
  2203. $scope.realm.minimumQuickLoginWaitUnit = TimeUnit.autoUnit(realm.minimumQuickLoginWaitSeconds);
  2204. $scope.realm.minimumQuickLoginWait = TimeUnit.toUnit(realm.minimumQuickLoginWaitSeconds, $scope.realm.minimumQuickLoginWaitUnit);
  2205. $scope.realm.maxFailureWaitUnit = TimeUnit.autoUnit(realm.maxFailureWaitSeconds);
  2206. $scope.realm.maxFailureWait = TimeUnit.toUnit(realm.maxFailureWaitSeconds, $scope.realm.maxFailureWaitUnit);
  2207. $scope.realm.maxDeltaTimeUnit = TimeUnit.autoUnit(realm.maxDeltaTimeSeconds);
  2208. $scope.realm.maxDeltaTime = TimeUnit.toUnit(realm.maxDeltaTimeSeconds, $scope.realm.maxDeltaTimeUnit);
  2209. var oldCopy = angular.copy($scope.realm);
  2210. $scope.changed = false;
  2211. $scope.$watch('realm', function() {
  2212. if (!angular.equals($scope.realm, oldCopy)) {
  2213. $scope.changed = true;
  2214. }
  2215. }, true);
  2216. $scope.save = function() {
  2217. var realmCopy = angular.copy($scope.realm);
  2218. delete realmCopy["waitIncrementUnit"];
  2219. delete realmCopy["waitIncrement"];
  2220. delete realmCopy["minimumQuickLoginWaitUnit"];
  2221. delete realmCopy["minimumQuickLoginWait"];
  2222. delete realmCopy["maxFailureWaitUnit"];
  2223. delete realmCopy["maxFailureWait"];
  2224. delete realmCopy["maxDeltaTimeUnit"];
  2225. delete realmCopy["maxDeltaTime"];
  2226. realmCopy.waitIncrementSeconds = TimeUnit.toSeconds($scope.realm.waitIncrement, $scope.realm.waitIncrementUnit)
  2227. realmCopy.minimumQuickLoginWaitSeconds = TimeUnit.toSeconds($scope.realm.minimumQuickLoginWait, $scope.realm.minimumQuickLoginWaitUnit)
  2228. realmCopy.maxFailureWaitSeconds = TimeUnit.toSeconds($scope.realm.maxFailureWait, $scope.realm.maxFailureWaitUnit)
  2229. realmCopy.maxDeltaTimeSeconds = TimeUnit.toSeconds($scope.realm.maxDeltaTime, $scope.realm.maxDeltaTimeUnit)
  2230. $scope.changed = false;
  2231. Realm.update(realmCopy, function () {
  2232. oldCopy = angular.copy($scope.realm);
  2233. $location.url("/realms/" + realm.realm + "/defense/brute-force");
  2234. Notifications.success("Your changes have been saved to the realm.");
  2235. });
  2236. };
  2237. $scope.reset = function() {
  2238. $route.reload();
  2239. };
  2240. });
  2241. module.controller('IdentityProviderMapperListCtrl', function($scope, realm, identityProvider, mapperTypes, mappers) {
  2242. $scope.realm = realm;
  2243. $scope.identityProvider = identityProvider;
  2244. $scope.mapperTypes = mapperTypes;
  2245. $scope.mappers = mappers;
  2246. });
  2247. module.controller('IdentityProviderMapperCtrl', function ($scope, realm, identityProvider, mapperTypes, mapper, IdentityProviderMapper, Notifications, Dialog, ComponentUtils, $location) {
  2248. $scope.realm = realm;
  2249. $scope.identityProvider = identityProvider;
  2250. $scope.create = false;
  2251. $scope.changed = false;
  2252. $scope.mapperType = mapperTypes[mapper.identityProviderMapper];
  2253. ComponentUtils.convertAllMultivaluedStringValuesToList($scope.mapperType.properties, mapper.config);
  2254. ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.mapperType.properties, mapper.config);
  2255. $scope.mapper = angular.copy(mapper);
  2256. $scope.$watch(function () {
  2257. return $location.path();
  2258. }, function() {
  2259. $scope.path = $location.path().substring(1).split("/");
  2260. });
  2261. $scope.$watch('mapper', function() {
  2262. if (!angular.equals($scope.mapper, mapper)) {
  2263. $scope.changed = true;
  2264. }
  2265. }, true);
  2266. $scope.save = function() {
  2267. let mapperCopy = angular.copy($scope.mapper);
  2268. ComponentUtils.convertAllListValuesToMultivaluedString($scope.mapperType.properties, mapperCopy.config);
  2269. IdentityProviderMapper.update({
  2270. realm : realm.realm,
  2271. alias : identityProvider.alias,
  2272. mapperId : mapper.id
  2273. }, mapperCopy, function () {
  2274. $scope.changed = false;
  2275. ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.mapperType.properties, $scope.mapper.config);
  2276. mapper = angular.copy($scope.mapper);
  2277. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers/" + mapper.id);
  2278. Notifications.success("Your changes have been saved.");
  2279. });
  2280. };
  2281. $scope.reset = function() {
  2282. $scope.mapper = angular.copy(mapper);
  2283. $scope.changed = false;
  2284. };
  2285. $scope.cancel = function() {
  2286. //$location.url("/realms");
  2287. window.history.back();
  2288. };
  2289. $scope.remove = function() {
  2290. Dialog.confirmDelete($scope.mapper.name, 'mapper', function() {
  2291. IdentityProviderMapper.remove({ realm: realm.realm, alias: mapper.identityProviderAlias, mapperId : $scope.mapper.id }, function() {
  2292. Notifications.success("The mapper has been deleted.");
  2293. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers");
  2294. });
  2295. });
  2296. };
  2297. });
  2298. module.controller('IdentityProviderMapperCreateCtrl', function ($scope, realm, identityProvider, mapperTypes, IdentityProviderMapper, Notifications, Dialog, ComponentUtils, $location) {
  2299. $scope.realm = realm;
  2300. $scope.identityProvider = identityProvider;
  2301. $scope.create = true;
  2302. $scope.mapper = { identityProviderAlias: identityProvider.alias, config: {}};
  2303. $scope.mapperTypes = mapperTypes;
  2304. // make first type the default
  2305. $scope.mapperType = mapperTypes[Object.keys(mapperTypes)[0]];
  2306. $scope.mapper.config.syncMode = 'INHERIT';
  2307. $scope.$watch(function() {
  2308. return $location.path();
  2309. }, function() {
  2310. $scope.path = $location.path().substring(1).split("/");
  2311. });
  2312. $scope.save = function () {
  2313. $scope.mapper.identityProviderMapper = $scope.mapperType.id;
  2314. let copyMapper = angular.copy($scope.mapper);
  2315. ComponentUtils.convertAllListValuesToMultivaluedString($scope.mapperType.properties, copyMapper.config);
  2316. IdentityProviderMapper.save({
  2317. realm : realm.realm,
  2318. alias : identityProvider.alias
  2319. }, copyMapper, function (data, headers) {
  2320. var l = headers().location;
  2321. var id = l.substring(l.lastIndexOf("/") + 1);
  2322. $location.url("/realms/" + realm.realm + '/identity-provider-mappers/' + identityProvider.alias + "/mappers/" + id);
  2323. Notifications.success("Mapper has been created.");
  2324. });
  2325. };
  2326. $scope.cancel = function() {
  2327. //$location.url("/realms");
  2328. window.history.back();
  2329. };
  2330. });
  2331. module.controller('RealmFlowBindingCtrl', function($scope, flows, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications) {
  2332. $scope.flows = [];
  2333. $scope.clientFlows = [];
  2334. for (var i=0 ; i<flows.length ; i++) {
  2335. if (flows[i].providerId == 'client-flow') {
  2336. $scope.clientFlows.push(flows[i]);
  2337. } else {
  2338. $scope.flows.push(flows[i]);
  2339. }
  2340. }
  2341. $scope.profileInfo = serverInfo.profileInfo;
  2342. genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $route, Dialog, Notifications, "/realms/" + realm.realm + "/authentication/flow-bindings");
  2343. });
  2344. module.controller('CreateFlowCtrl', function($scope, realm,
  2345. AuthenticationFlows,
  2346. Notifications, $location) {
  2347. console.debug('CreateFlowCtrl');
  2348. $scope.realm = realm;
  2349. $scope.flow = {
  2350. alias: "",
  2351. providerId: "basic-flow",
  2352. description: "",
  2353. topLevel: true,
  2354. builtIn: false
  2355. }
  2356. $scope.save = function() {
  2357. AuthenticationFlows.save({realm: realm.realm, flow: ""}, $scope.flow, function() {
  2358. $location.url("/realms/" + realm.realm + "/authentication/flows/" + $scope.flow.alias);
  2359. Notifications.success("Flow Created.");
  2360. })
  2361. }
  2362. $scope.cancel = function() {
  2363. $location.url("/realms/" + realm.realm + "/authentication/flows");
  2364. };
  2365. });
  2366. module.controller('CreateExecutionFlowCtrl', function($scope, realm, parentFlow, formProviders,
  2367. CreateExecutionFlow,
  2368. Notifications, $location) {
  2369. $scope.realm = realm;
  2370. $scope.formProviders = formProviders;
  2371. var defaultFlowType = parentFlow.providerId == 'client-flow' ? 'client-flow' : 'basic-flow';
  2372. $scope.flow = {
  2373. alias: "",
  2374. type: defaultFlowType,
  2375. description: ""
  2376. }
  2377. $scope.provider = {};
  2378. if (formProviders.length > 0) {
  2379. $scope.provider = formProviders[0];
  2380. }
  2381. $scope.save = function() {
  2382. $scope.flow.provider = $scope.provider.id;
  2383. CreateExecutionFlow.save({realm: realm.realm, alias: parentFlow.alias}, $scope.flow, function() {
  2384. $location.url("/realms/" + realm.realm + "/authentication/flows");
  2385. Notifications.success("Flow Created.");
  2386. })
  2387. }
  2388. $scope.cancel = function() {
  2389. $location.url("/realms/" + realm.realm + "/authentication/flows");
  2390. };
  2391. });
  2392. module.controller('CreateExecutionCtrl', function($scope, realm, parentFlow, formActionProviders, authenticatorProviders, clientAuthenticatorProviders,
  2393. CreateExecution,
  2394. Notifications, $location) {
  2395. $scope.realm = realm;
  2396. $scope.parentFlow = parentFlow;
  2397. if (parentFlow.providerId == 'form-flow') {
  2398. $scope.providers = formActionProviders;
  2399. } else if (parentFlow.providerId == 'client-flow') {
  2400. $scope.providers = clientAuthenticatorProviders;
  2401. } else {
  2402. $scope.providers = authenticatorProviders;
  2403. }
  2404. $scope.provider = {};
  2405. if ($scope.providers.length > 0) {
  2406. $scope.provider = $scope.providers[0];
  2407. }
  2408. $scope.save = function() {
  2409. var execution = {
  2410. provider: $scope.provider.id
  2411. }
  2412. CreateExecution.save({realm: realm.realm, alias: parentFlow.alias}, execution, function() {
  2413. $location.url("/realms/" + realm.realm + "/authentication/flows");
  2414. Notifications.success("Execution Created.");
  2415. })
  2416. }
  2417. $scope.cancel = function() {
  2418. $location.url("/realms/" + realm.realm + "/authentication/flows");
  2419. };
  2420. });
  2421. module.controller('AuthenticationFlowsCtrl', function($scope, $route, realm, flows, selectedFlow, LastFlowSelected, Dialog,
  2422. AuthenticationFlows, AuthenticationFlowsCopy, AuthenticationFlowsUpdate, AuthenticationFlowExecutions,
  2423. AuthenticationExecution, AuthenticationExecutionRaisePriority, AuthenticationExecutionLowerPriority,
  2424. $modal, Notifications, CopyDialog, UpdateDialog, $location) {
  2425. $scope.realm = realm;
  2426. $scope.flows = flows;
  2427. if (selectedFlow !== null) {
  2428. LastFlowSelected.alias = selectedFlow;
  2429. }
  2430. if (selectedFlow === null && LastFlowSelected.alias !== null) {
  2431. selectedFlow = LastFlowSelected.alias;
  2432. }
  2433. if (flows.length > 0) {
  2434. $scope.flow = flows[0];
  2435. if (selectedFlow) {
  2436. for (var i = 0; i < flows.length; i++) {
  2437. if (flows[i].alias == selectedFlow) {
  2438. $scope.flow = flows[i];
  2439. break;
  2440. }
  2441. }
  2442. }
  2443. }
  2444. $scope.selectFlow = function(flow) {
  2445. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.alias);
  2446. };
  2447. var setupForm = function() {
  2448. AuthenticationFlowExecutions.query({realm: realm.realm, alias: $scope.flow.alias}, function(data) {
  2449. $scope.executions = data;
  2450. $scope.choicesmax = 0;
  2451. $scope.levelmax = 0;
  2452. for (var i = 0; i < $scope.executions.length; i++ ) {
  2453. var execution = $scope.executions[i];
  2454. if (execution.requirementChoices.length > $scope.choicesmax) {
  2455. $scope.choicesmax = execution.requirementChoices.length;
  2456. }
  2457. if (execution.level > $scope.levelmax) {
  2458. $scope.levelmax = execution.level;
  2459. }
  2460. }
  2461. $scope.levelmaxempties = [];
  2462. for (j = 0; j < $scope.levelmax; j++) {
  2463. $scope.levelmaxempties.push(j);
  2464. }
  2465. for (var i = 0; i < $scope.executions.length; i++ ) {
  2466. var execution = $scope.executions[i];
  2467. execution.empties = [];
  2468. for (j = 0; j < $scope.choicesmax - execution.requirementChoices.length; j++) {
  2469. execution.empties.push(j);
  2470. }
  2471. execution.preLevels = [];
  2472. for (j = 0; j < execution.level; j++) {
  2473. execution.preLevels.push(j);
  2474. }
  2475. execution.postLevels = [];
  2476. for (j = execution.level; j < $scope.levelmax; j++) {
  2477. execution.postLevels.push(j);
  2478. }
  2479. }
  2480. })
  2481. };
  2482. $scope.copyFlow = function() {
  2483. CopyDialog.open('Copy Authentication Flow', $scope.flow.alias, function(name) {
  2484. AuthenticationFlowsCopy.save({realm: realm.realm, alias: $scope.flow.alias}, {
  2485. newName: name
  2486. }, function() {
  2487. $location.url("/realms/" + realm.realm + '/authentication/flows/' + name);
  2488. Notifications.success("Flow copied.");
  2489. })
  2490. })
  2491. };
  2492. $scope.deleteFlow = function() {
  2493. Dialog.confirmDelete($scope.flow.alias, 'flow', function() {
  2494. $scope.removeFlow();
  2495. });
  2496. };
  2497. $scope.removeFlow = function() {
  2498. console.log('Remove flow:' + $scope.flow.alias);
  2499. if (realm.browserFlow == $scope.flow.alias) {
  2500. Notifications.error("Cannot remove flow, it is currently being used as the browser flow.");
  2501. } else if (realm.registrationFlow == $scope.flow.alias) {
  2502. Notifications.error("Cannot remove flow, it is currently being used as the registration flow.");
  2503. } else if (realm.directGrantFlow == $scope.flow.alias) {
  2504. Notifications.error("Cannot remove flow, it is currently being used as the direct grant flow.");
  2505. } else if (realm.resetCredentialsFlow == $scope.flow.alias) {
  2506. Notifications.error("Cannot remove flow, it is currently being used as the reset credentials flow.");
  2507. } else if (realm.clientAuthenticationFlow == $scope.flow.alias) {
  2508. Notifications.error("Cannot remove flow, it is currently being used as the client authentication flow.");
  2509. } else if (realm.dockerAuthenticationFlow == $scope.flow.alias) {
  2510. Notifications.error("Cannot remove flow, it is currently being used as the docker authentication flow.");
  2511. } else {
  2512. AuthenticationFlows.remove({realm: realm.realm, flow: $scope.flow.id}, function () {
  2513. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flows[0].alias);
  2514. Notifications.success("Flow removed");
  2515. })
  2516. }
  2517. };
  2518. $scope.editFlow = function(flow) {
  2519. var copy = angular.copy(flow);
  2520. UpdateDialog.open('Update Authentication Flow', copy.alias, copy.description, function(name, desc) {
  2521. copy.alias = name;
  2522. copy.description = desc;
  2523. AuthenticationFlowsUpdate.update({realm: realm.realm, flow: flow.id}, copy, function() {
  2524. $location.url("/realms/" + realm.realm + '/authentication/flows/' + name);
  2525. Notifications.success("Flow updated");
  2526. });
  2527. })
  2528. };
  2529. $scope.addFlow = function() {
  2530. $location.url("/realms/" + realm.realm + '/authentication/flows/' + $scope.flow.id + '/create/flow/execution/' + $scope.flow.id);
  2531. }
  2532. $scope.addSubFlow = function(execution) {
  2533. $location.url("/realms/" + realm.realm + '/authentication/flows/' + execution.flowId + '/create/flow/execution/' + $scope.flow.alias);
  2534. }
  2535. $scope.addSubFlowExecution = function(execution) {
  2536. $location.url("/realms/" + realm.realm + '/authentication/flows/' + execution.flowId + '/create/execution/' + $scope.flow.alias);
  2537. }
  2538. $scope.addExecution = function() {
  2539. $location.url("/realms/" + realm.realm + '/authentication/flows/' + $scope.flow.id + '/create/execution/' + $scope.flow.id);
  2540. }
  2541. $scope.createFlow = function() {
  2542. $location.url("/realms/" + realm.realm + '/authentication/create/flow');
  2543. }
  2544. $scope.updateExecution = function(execution) {
  2545. var copy = angular.copy(execution);
  2546. delete copy.empties;
  2547. delete copy.levels;
  2548. delete copy.preLevels;
  2549. delete copy.postLevels;
  2550. AuthenticationFlowExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() {
  2551. Notifications.success("Auth requirement updated");
  2552. setupForm();
  2553. });
  2554. };
  2555. $scope.editExecutionFlow = function(execution) {
  2556. var copy = angular.copy(execution);
  2557. delete copy.empties;
  2558. delete copy.levels;
  2559. delete copy.preLevels;
  2560. delete copy.postLevels;
  2561. UpdateDialog.open('Update Execution Flow', copy.displayName, copy.description, function(name, desc) {
  2562. copy.displayName = name;
  2563. copy.description = desc;
  2564. AuthenticationFlowExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() {
  2565. Notifications.success("Execution Flow updated");
  2566. setupForm();
  2567. });
  2568. })
  2569. };
  2570. $scope.removeExecution = function(execution) {
  2571. console.log('removeExecution: ' + execution.id);
  2572. var exeOrFlow = execution.authenticationFlow ? 'flow' : 'execution';
  2573. Dialog.confirmDelete(execution.displayName, exeOrFlow, function() {
  2574. AuthenticationExecution.remove({realm: realm.realm, execution: execution.id}, function() {
  2575. Notifications.success("The " + exeOrFlow + " was removed.");
  2576. setupForm();
  2577. });
  2578. });
  2579. }
  2580. $scope.raisePriority = function(execution) {
  2581. AuthenticationExecutionRaisePriority.save({realm: realm.realm, execution: execution.id}, function() {
  2582. Notifications.success("Priority raised");
  2583. setupForm();
  2584. })
  2585. }
  2586. $scope.lowerPriority = function(execution) {
  2587. AuthenticationExecutionLowerPriority.save({realm: realm.realm, execution: execution.id}, function() {
  2588. Notifications.success("Priority lowered");
  2589. setupForm();
  2590. })
  2591. }
  2592. $scope.setupForm = setupForm;
  2593. if (selectedFlow == null) {
  2594. $scope.selectFlow(flows[0]);
  2595. } else {
  2596. setupForm();
  2597. }
  2598. });
  2599. module.controller('RequiredActionsCtrl', function($scope, realm, unregisteredRequiredActions,
  2600. $modal, $route,
  2601. RegisterRequiredAction, RequiredActions, RequiredActionRaisePriority, RequiredActionLowerPriority, Notifications) {
  2602. console.log('RequiredActionsCtrl');
  2603. $scope.realm = realm;
  2604. $scope.unregisteredRequiredActions = unregisteredRequiredActions;
  2605. $scope.requiredActions = [];
  2606. var setupRequiredActionsForm = function() {
  2607. console.log('setupRequiredActionsForm');
  2608. RequiredActions.query({realm: realm.realm}, function(data) {
  2609. $scope.requiredActions = [];
  2610. for (var i = 0; i < data.length; i++) {
  2611. $scope.requiredActions.push(data[i]);
  2612. }
  2613. });
  2614. };
  2615. $scope.updateRequiredAction = function(action) {
  2616. RequiredActions.update({realm: realm.realm, alias: action.alias}, action, function() {
  2617. Notifications.success("Required action updated");
  2618. setupRequiredActionsForm();
  2619. });
  2620. }
  2621. $scope.raisePriority = function(action) {
  2622. RequiredActionRaisePriority.save({realm: realm.realm, alias: action.alias}, function() {
  2623. Notifications.success("Required action's priority raised");
  2624. setupRequiredActionsForm();
  2625. })
  2626. }
  2627. $scope.lowerPriority = function(action) {
  2628. RequiredActionLowerPriority.save({realm: realm.realm, alias: action.alias}, function() {
  2629. Notifications.success("Required action's priority lowered");
  2630. setupRequiredActionsForm();
  2631. })
  2632. }
  2633. $scope.register = function() {
  2634. var controller = function($scope, $modalInstance) {
  2635. $scope.unregisteredRequiredActions = unregisteredRequiredActions;
  2636. $scope.selected = {
  2637. selected: $scope.unregisteredRequiredActions[0]
  2638. }
  2639. $scope.ok = function () {
  2640. $modalInstance.close();
  2641. RegisterRequiredAction.save({realm: realm.realm}, $scope.selected.selected, function() {
  2642. $route.reload();
  2643. });
  2644. };
  2645. $scope.cancel = function () {
  2646. $modalInstance.dismiss('cancel');
  2647. };
  2648. }
  2649. $modal.open({
  2650. templateUrl: resourceUrl + '/partials/modal/unregistered-required-action-selector.html',
  2651. controller: controller,
  2652. resolve: {
  2653. }
  2654. });
  2655. }
  2656. setupRequiredActionsForm();
  2657. });
  2658. module.controller('AuthenticationConfigCtrl', function($scope, realm, flow, configType, config, AuthenticationConfig, Notifications,
  2659. Dialog, $location, ComponentUtils) {
  2660. $scope.realm = realm;
  2661. $scope.flow = flow;
  2662. $scope.configType = configType;
  2663. $scope.create = false;
  2664. $scope.config = angular.copy(config);
  2665. $scope.changed = false;
  2666. $scope.$watch(function() {
  2667. return $location.path();
  2668. }, function() {
  2669. $scope.path = $location.path().substring(1).split("/");
  2670. });
  2671. $scope.$watch('config', function() {
  2672. if (!angular.equals($scope.config, config)) {
  2673. $scope.changed = true;
  2674. }
  2675. }, true);
  2676. $scope.save = function() {
  2677. var configCopy = angular.copy($scope.config);
  2678. ComponentUtils.convertAllListValuesToMultivaluedString(configType.properties, configCopy.config);
  2679. AuthenticationConfig.update({
  2680. realm : realm.realm,
  2681. config : config.id
  2682. }, configCopy, function() {
  2683. $scope.changed = false;
  2684. config = angular.copy($scope.config);
  2685. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + config.id);
  2686. Notifications.success("Your changes have been saved.");
  2687. });
  2688. };
  2689. $scope.reset = function() {
  2690. $scope.config = angular.copy(config);
  2691. $scope.changed = false;
  2692. };
  2693. $scope.cancel = function() {
  2694. //$location.url("/realms");
  2695. window.history.back();
  2696. };
  2697. $scope.remove = function() {
  2698. Dialog.confirmDelete($scope.config.alias, 'config', function() {
  2699. AuthenticationConfig.remove({ realm: realm.realm, config : $scope.config.id }, function() {
  2700. Notifications.success("The config has been deleted.");
  2701. $location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id);
  2702. });
  2703. });
  2704. };
  2705. });
  2706. module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, flow, configType, execution, AuthenticationExecutionConfig,
  2707. Notifications, Dialog, $location, ComponentUtils) {
  2708. $scope.realm = realm;
  2709. $scope.flow = flow;
  2710. $scope.create = true;
  2711. $scope.configType = configType;
  2712. var defaultConfig = {};
  2713. if (configType && Array.isArray(configType.properties)) {
  2714. for(var i = 0; i < configType.properties.length; i++) {
  2715. var property = configType.properties[i];
  2716. if (property && property.name) {
  2717. defaultConfig[property.name] = property.defaultValue;
  2718. }
  2719. }
  2720. }
  2721. $scope.config = { config: defaultConfig};
  2722. $scope.$watch(function() {
  2723. return $location.path();
  2724. }, function() {
  2725. $scope.path = $location.path().substring(1).split("/");
  2726. });
  2727. $scope.save = function() {
  2728. var configCopy = angular.copy($scope.config);
  2729. ComponentUtils.convertAllListValuesToMultivaluedString(configType.properties, configCopy.config);
  2730. AuthenticationExecutionConfig.save({
  2731. realm : realm.realm,
  2732. execution: execution
  2733. }, configCopy, function(data, headers) {
  2734. var l = headers().location;
  2735. var id = l.substring(l.lastIndexOf("/") + 1);
  2736. var url = "/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + id;
  2737. console.log('redirect url: ' + url);
  2738. $location.url(url);
  2739. Notifications.success("Config has been created.");
  2740. });
  2741. };
  2742. $scope.cancel = function() {
  2743. //$location.url("/realms");
  2744. window.history.back();
  2745. };
  2746. });
  2747. module.controller('ClientInitialAccessCtrl', function($scope, realm, clientInitialAccess, ClientInitialAccess, Dialog, Notifications, $route, $location) {
  2748. $scope.realm = realm;
  2749. $scope.clientInitialAccess = clientInitialAccess;
  2750. $scope.remove = function(id) {
  2751. Dialog.confirmDelete(id, 'initial access token', function() {
  2752. ClientInitialAccess.remove({ realm: realm.realm, id: id }, function() {
  2753. Notifications.success("The initial access token was deleted.");
  2754. $route.reload();
  2755. });
  2756. });
  2757. }
  2758. });
  2759. module.controller('ClientInitialAccessCreateCtrl', function($scope, realm, ClientInitialAccess, TimeUnit, Dialog, $location, $translate) {
  2760. $scope.expirationUnit = 'Days';
  2761. $scope.expiration = TimeUnit.toUnit(0, $scope.expirationUnit);
  2762. $scope.count = 1;
  2763. $scope.realm = realm;
  2764. $scope.save = function() {
  2765. var expiration = TimeUnit.toSeconds($scope.expiration, $scope.expirationUnit);
  2766. ClientInitialAccess.save({
  2767. realm: realm.realm
  2768. }, { expiration: expiration, count: $scope.count}, function (data) {
  2769. console.debug(data);
  2770. $scope.id = data.id;
  2771. $scope.token = data.token;
  2772. });
  2773. };
  2774. $scope.cancel = function() {
  2775. $location.url('/realms/' + realm.realm + '/client-registration/client-initial-access');
  2776. };
  2777. $scope.done = function() {
  2778. var btns = {
  2779. ok: {
  2780. label: $translate.instant('continue'),
  2781. cssClass: 'btn btn-primary'
  2782. },
  2783. cancel: {
  2784. label: $translate.instant('cancel'),
  2785. cssClass: 'btn btn-default'
  2786. }
  2787. }
  2788. var title = $translate.instant('initial-access-token.confirm.title');
  2789. var message = $translate.instant('initial-access-token.confirm.text');
  2790. Dialog.open(title, message, btns, function() {
  2791. $location.url('/realms/' + realm.realm + '/client-registration/client-initial-access');
  2792. });
  2793. };
  2794. });
  2795. module.controller('ClientRegPoliciesCtrl', function($scope, realm, clientRegistrationPolicyProviders, policies, Dialog, Notifications, Components, $route, $location) {
  2796. $scope.realm = realm;
  2797. $scope.providers = clientRegistrationPolicyProviders;
  2798. $scope.anonPolicies = [];
  2799. $scope.authPolicies = [];
  2800. for (var i=0 ; i<policies.length ; i++) {
  2801. var policy = policies[i];
  2802. if (policy.subType === 'anonymous') {
  2803. $scope.anonPolicies.push(policy);
  2804. } else if (policy.subType === 'authenticated') {
  2805. $scope.authPolicies.push(policy);
  2806. } else {
  2807. throw 'subType is required for clientRegistration policy component!';
  2808. }
  2809. }
  2810. $scope.addProvider = function(authType, provider) {
  2811. console.log('Add provider: authType ' + authType + ', providerId: ' + provider.id);
  2812. $location.url("/realms/" + realm.realm + "/client-registration/client-reg-policies/create/" + authType + '/' + provider.id);
  2813. };
  2814. $scope.getInstanceLink = function(instance) {
  2815. return "/realms/" + realm.realm + "/client-registration/client-reg-policies/" + instance.providerId + "/" + instance.id;
  2816. }
  2817. $scope.removeInstance = function(instance) {
  2818. Dialog.confirmDelete(instance.name, 'client registration policy', function() {
  2819. Components.remove({
  2820. realm : realm.realm,
  2821. componentId : instance.id
  2822. }, function() {
  2823. $route.reload();
  2824. Notifications.success("The policy has been deleted.");
  2825. });
  2826. });
  2827. };
  2828. });
  2829. module.controller('ClientRegPolicyDetailCtrl', function ($scope, realm, clientRegistrationPolicyProviders, instance, Dialog, Notifications, Components, ComponentUtils, $route, $location, $translate) {
  2830. $scope.realm = realm;
  2831. $scope.instance = instance;
  2832. $scope.providerTypes = clientRegistrationPolicyProviders;
  2833. for (let i = 0; i < $scope.providerTypes.length; i++) {
  2834. let providerType = $scope.providerTypes[i];
  2835. if (providerType.id === instance.providerId) {
  2836. $scope.providerType = providerType;
  2837. break;
  2838. }
  2839. }
  2840. $scope.create = !$scope.instance.name;
  2841. function toDefaultValue(configProperty) {
  2842. if (configProperty.type === 'MultivaluedString' || configProperty.type === 'MultivaluedList') {
  2843. if (configProperty.defaultValue) {
  2844. return configProperty.defaultValue;
  2845. } else {
  2846. return [];
  2847. }
  2848. }
  2849. if (configProperty.defaultValue) {
  2850. return [ configProperty.defaultValue ];
  2851. } else {
  2852. return [ '' ];
  2853. }
  2854. }
  2855. $translate($scope.instance.providerId + ".label")
  2856. .then((translatedValue) => {
  2857. $scope.headerTitle = translatedValue;
  2858. }).catch(() => {
  2859. $scope.headerTitle = $scope.instance.providerId;
  2860. });
  2861. if ($scope.create) {
  2862. $scope.instance.name = "";
  2863. $scope.instance.parentId = realm.id;
  2864. $scope.instance.config = {};
  2865. if ($scope.providerType.properties) {
  2866. for (let i = 0; i < $scope.providerType.properties.length; i++) {
  2867. let configProperty = $scope.providerType.properties[i];
  2868. $scope.instance.config[configProperty.name] = toDefaultValue(configProperty);
  2869. }
  2870. }
  2871. }
  2872. if ($scope.providerType.properties) {
  2873. ComponentUtils.addLastEmptyValueToMultivaluedLists($scope.providerType.properties, $scope.instance.config);
  2874. ComponentUtils.addMvOptionsToMultivaluedLists($scope.providerType.properties);
  2875. }
  2876. let oldCopy = angular.copy($scope.instance);
  2877. $scope.changed = false;
  2878. $scope.$watch('instance', function() {
  2879. if (!angular.equals($scope.instance, oldCopy)) {
  2880. $scope.changed = true;
  2881. }
  2882. }, true);
  2883. $scope.reset = function() {
  2884. $scope.create ? window.history.back() : $route.reload();
  2885. };
  2886. $scope.hasValidValues = () => $scope.changed && $scope.instance.name;
  2887. $scope.save = function() {
  2888. $scope.changed = false;
  2889. if ($scope.create) {
  2890. Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
  2891. var l = headers().location;
  2892. var id = l.substring(l.lastIndexOf("/") + 1);
  2893. $location.url("/realms/" + realm.realm + "/client-registration/client-reg-policies/" + $scope.instance.providerId + "/" + id);
  2894. Notifications.success("The policy has been created.");
  2895. });
  2896. } else {
  2897. Components.update({realm: realm.realm,
  2898. componentId: instance.id
  2899. },
  2900. $scope.instance, function () {
  2901. $route.reload();
  2902. Notifications.success("The policy has been updated.");
  2903. });
  2904. }
  2905. };
  2906. });
  2907. module.controller('ClientPoliciesProfilesListCtrl', function($scope, realm, clientProfiles, ClientPoliciesProfiles, Dialog, Notifications, $route, $location) {
  2908. console.log('ClientPoliciesProfilesListCtrl');
  2909. $scope.realm = realm;
  2910. $scope.clientProfiles = clientProfiles;
  2911. $scope.removeClientProfile = function(clientProfile) {
  2912. Dialog.confirmDelete(clientProfile.name, 'client profile', function() {
  2913. console.log("Deleting client profile from the JSON: " + clientProfile.name);
  2914. for (var i = 0; i < $scope.clientProfiles.profiles.length; i++) {
  2915. var currentProfile = $scope.clientProfiles.profiles[i];
  2916. if (currentProfile.name === clientProfile.name) {
  2917. $scope.clientProfiles.profiles.splice(i, 1);
  2918. break;
  2919. }
  2920. }
  2921. ClientPoliciesProfiles.update({
  2922. realm: realm.realm,
  2923. }, $scope.clientProfiles, function () {
  2924. $route.reload();
  2925. Notifications.success("The client profile was deleted.");
  2926. }, function (errorResponse) {
  2927. $route.reload();
  2928. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  2929. Notifications.error('Failed to delete client profile: ' + errDetails);
  2930. });
  2931. });
  2932. };
  2933. });
  2934. module.controller('ClientPoliciesProfilesJsonCtrl', function($scope, realm, clientProfiles, ClientPoliciesProfiles, Dialog, Notifications, $route, $location) {
  2935. console.log('ClientPoliciesProfilesJsonCtrl');
  2936. $scope.realm = realm;
  2937. $scope.clientProfilesString = angular.toJson(clientProfiles, true);
  2938. $scope.save = function() {
  2939. var clientProfilesObj = null;
  2940. try {
  2941. clientProfilesObj = angular.fromJson($scope.clientProfilesString);
  2942. } catch (e) {
  2943. Notifications.error("Provided JSON is incorrect: " + e.message);
  2944. console.log(e);
  2945. return;
  2946. }
  2947. var clientProfilesCompressed = angular.toJson(clientProfilesObj, false);
  2948. ClientPoliciesProfiles.update({
  2949. realm: realm.realm,
  2950. }, clientProfilesCompressed, function () {
  2951. $route.reload();
  2952. Notifications.success("The client profiles configuration was updated.");
  2953. }, function(errorResponse) {
  2954. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  2955. Notifications.error("Failed to update client profiles: " + errDetails);
  2956. console.log("Error response when updating client profiles JSON: Status: " + errorResponse.status +
  2957. ", statusText: " + errorResponse.statusText + ", data: " + JSON.stringify(errorResponse.data));
  2958. });
  2959. };
  2960. $scope.reset = function() {
  2961. $route.reload();
  2962. };
  2963. });
  2964. module.controller('ClientPoliciesProfilesEditCtrl', function($scope, realm, clientProfiles, ClientPoliciesProfiles, Dialog, Notifications, $route, $location) {
  2965. var targetProfileName = $route.current.params.profileName;
  2966. $scope.createNew = targetProfileName == null;
  2967. if ($scope.createNew) {
  2968. console.log('ClientPoliciesProfilesEditCtrl: creating new profile');
  2969. } else {
  2970. console.log('ClientPoliciesProfilesEditCtrl: updating profile ' + targetProfileName);
  2971. }
  2972. $scope.realm = realm;
  2973. $scope.editedProfile = null;
  2974. function getProfileByName(profilesArray) {
  2975. if (!profilesArray) return null;
  2976. for (var i=0 ; i < profilesArray.length ; i++) {
  2977. var currentProfile = profilesArray[i];
  2978. if (targetProfileName === currentProfile.name) {
  2979. return currentProfile;
  2980. }
  2981. }
  2982. }
  2983. if ($scope.createNew) {
  2984. $scope.editedProfile = {
  2985. name: "",
  2986. executors: []
  2987. };
  2988. } else {
  2989. var globalProfile = false;
  2990. $scope.editedProfile = getProfileByName(clientProfiles.profiles);
  2991. if (!$scope.editedProfile) {
  2992. $scope.editedProfile = getProfileByName(clientProfiles.globalProfiles);
  2993. globalProfile = true;
  2994. }
  2995. if ($scope.editedProfile == null) {
  2996. console.log("Profile of name " + targetProfileName + " not found");
  2997. throw 'Profile not found';
  2998. }
  2999. }
  3000. // needs to be a function because when this controller runs, the permissions might not be loaded yet
  3001. $scope.isReadOnly = function() {
  3002. return !$scope.access.manageRealm || globalProfile;
  3003. }
  3004. $scope.removeExecutor = function(executorIndex) {
  3005. Dialog.confirmDelete($scope.editedProfile.executors[executorIndex].executor, 'executor', function() {
  3006. console.log("remove executor of index " + executorIndex);
  3007. // Delete executor
  3008. $scope.editedProfile.executors.splice(executorIndex, 1);
  3009. ClientPoliciesProfiles.update({
  3010. realm: realm.realm,
  3011. }, clientProfiles, function () {
  3012. Notifications.success("The executor was deleted.");
  3013. }, function (errorResponse) {
  3014. $route.reload();
  3015. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3016. Notifications.error('Failed to delete executor: ' + errDetails);
  3017. });
  3018. });
  3019. }
  3020. $scope.save = function() {
  3021. if (!$scope.editedProfile.name || $scope.editedProfile.name === '') {
  3022. Notifications.error('Name must be provided');
  3023. return;
  3024. }
  3025. if ($scope.createNew) {
  3026. clientProfiles.profiles.push($scope.editedProfile);
  3027. }
  3028. ClientPoliciesProfiles.update({
  3029. realm: realm.realm,
  3030. }, clientProfiles, function () {
  3031. if ($scope.createNew) {
  3032. Notifications.success("The client profile was created.");
  3033. $location.url('/realms/' + realm.realm + '/client-policies/profiles-update/' + $scope.editedProfile.name);
  3034. } else {
  3035. Notifications.success("The client profile was updated.");
  3036. $location.url('/realms/' + realm.realm + '/client-policies/profiles');
  3037. }
  3038. }, function(errorResponse) {
  3039. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3040. if ($scope.createNew) {
  3041. Notifications.error('Failed to create client profile: ' + errDetails);
  3042. } else {
  3043. Notifications.error('Failed to update client profile: ' + errDetails);
  3044. }
  3045. });
  3046. };
  3047. $scope.back = function() {
  3048. $location.url('/realms/' + realm.realm + '/client-policies/profiles');
  3049. };
  3050. });
  3051. module.controller('ClientPoliciesProfilesEditExecutorCtrl', function($scope, realm, serverInfo, clientProfiles, ClientPoliciesProfiles, ComponentUtils, Dialog, Notifications, $route, $location) {
  3052. var updatedExecutorIndex = $route.current.params.executorIndex;
  3053. var targetProfileName = $route.current.params.profileName;
  3054. $scope.createNew = updatedExecutorIndex == null;
  3055. if ($scope.createNew) {
  3056. console.log('ClientPoliciesProfilesEditExecutorCtrl: adding executor to profile ' + targetProfileName);
  3057. } else {
  3058. console.log('ClientPoliciesProfilesEditExecutorCtrl: updating executor with index ' + updatedExecutorIndex + ' of profile ' + targetProfileName);
  3059. }
  3060. $scope.realm = realm;
  3061. function getProfileByName(profilesArray) {
  3062. if (!profilesArray) return null;
  3063. for (var i=0 ; i < profilesArray.length ; i++) {
  3064. var currentProfile = profilesArray[i];
  3065. if (targetProfileName === currentProfile.name) {
  3066. return currentProfile;
  3067. }
  3068. }
  3069. }
  3070. var globalProfile = false;
  3071. $scope.editedProfile = getProfileByName(clientProfiles.profiles);
  3072. if (!$scope.editedProfile) {
  3073. $scope.editedProfile = getProfileByName(clientProfiles.globalProfiles);
  3074. globalProfile = true;
  3075. }
  3076. if ($scope.editedProfile == null) {
  3077. throw 'Client profile of specified name not found';
  3078. }
  3079. // needs to be a function because when this controller runs, the permissions might not be loaded yet
  3080. $scope.isReadOnly = function() {
  3081. return !$scope.access.manageRealm || globalProfile;
  3082. }
  3083. $scope.executorTypes = serverInfo.componentTypes['org.keycloak.services.clientpolicy.executor.ClientPolicyExecutorProvider'];
  3084. for (var j=0 ; j < $scope.executorTypes.length ; j++) {
  3085. var currExecutorType = $scope.executorTypes[j];
  3086. if (currExecutorType.properties) {
  3087. console.log("Adjusting executorType: " + currExecutorType.id);
  3088. ComponentUtils.addMvOptionsToMultivaluedLists(currExecutorType.properties);
  3089. }
  3090. }
  3091. function getExecutorByIndex(clientProfile, executorIndex) {
  3092. if (clientProfile.executors.length <= executorIndex) {
  3093. console.error('Client profile does not have executor of specified index');
  3094. $location.path('/notfound');
  3095. return null;
  3096. } else {
  3097. return clientProfile.executors[executorIndex];
  3098. }
  3099. }
  3100. if ($scope.createNew) {
  3101. // make first type the default
  3102. $scope.executorType = $scope.executorTypes[0];
  3103. var oldExecutorType = $scope.executorType;
  3104. initConfig();
  3105. $scope.$watch('executorType', function() {
  3106. if (!angular.equals($scope.executorType, oldExecutorType)) {
  3107. oldExecutorType = $scope.executorType;
  3108. initConfig();
  3109. }
  3110. }, true);
  3111. } else {
  3112. var exec = getExecutorByIndex($scope.editedProfile, updatedExecutorIndex);
  3113. if (exec) {
  3114. // a failsafe in case the configuration was deleted entirely (or set to null) in the JSON view
  3115. if (!exec.configuration) {
  3116. exec.configuration = {}
  3117. }
  3118. $scope.executor = {
  3119. config: exec.configuration
  3120. };
  3121. $scope.executorType = null;
  3122. for (var j=0 ; j < $scope.executorTypes.length ; j++) {
  3123. var currentExType = $scope.executorTypes[j];
  3124. if (exec.executor === currentExType.id) {
  3125. $scope.executorType = currentExType;
  3126. break;
  3127. }
  3128. }
  3129. for (var j=0 ; j < $scope.executorType.properties.length ; j++) {
  3130. // Convert boolean properties from the configuration to strings as expected by the kc-provider-config directive
  3131. var currentProperty = $scope.executorType.properties[j];
  3132. if (currentProperty.type === 'boolean') {
  3133. $scope.executor.config[currentProperty.name] = ($scope.executor.config[currentProperty.name]) ? "true" : "false";
  3134. }
  3135. // a workaround for select2 to prevent displaying empty boxes
  3136. var configProperty = $scope.executor.config[$scope.executorType.properties[j].name];
  3137. if (Array.isArray(configProperty) && configProperty.length === 0) {
  3138. $scope.executor.config[$scope.executorType.properties[j].name] = null
  3139. }
  3140. }
  3141. }
  3142. }
  3143. function toDefaultValue(configProperty) {
  3144. if (configProperty.type === 'boolean') {
  3145. return (configProperty.defaultValue) ? "true" : "false";
  3146. }
  3147. if (configProperty.defaultValue !== undefined) {
  3148. if ((configProperty.type === 'MultivaluedString' || configProperty.type === 'MultivaluedList') && !Array.isArray(configProperty.defaultValue)) {
  3149. return [configProperty.defaultValue]
  3150. }
  3151. return configProperty.defaultValue;
  3152. } else {
  3153. return null;
  3154. }
  3155. }
  3156. function initConfig() {
  3157. console.log("Initialized config now. ConfigType is: " + $scope.executorType.id);
  3158. $scope.executor = {
  3159. config: {}
  3160. };
  3161. for (let i = 0; i < $scope.executorType.properties.length; i++) {
  3162. let configProperty = $scope.executorType.properties[i];
  3163. $scope.executor.config[configProperty.name] = toDefaultValue(configProperty);
  3164. }
  3165. }
  3166. $scope.save = function() {
  3167. console.log("save: " + $scope.executorType.id);
  3168. var executorName = $scope.executorType.id;
  3169. if (!$scope.editedProfile.executors) {
  3170. $scope.editedProfile.executors = [];
  3171. }
  3172. ComponentUtils.removeLastEmptyValue($scope.executor.config);
  3173. // Convert String properties required by the kc-provider-config directive back to booleans
  3174. for (var j=0 ; j < $scope.executorType.properties.length ; j++) {
  3175. var currentProperty = $scope.executorType.properties[j];
  3176. if (currentProperty.type === 'boolean') {
  3177. $scope.executor.config[currentProperty.name] = ($scope.executor.config[currentProperty.name] === "true") ? true : false;
  3178. }
  3179. }
  3180. if ($scope.createNew) {
  3181. var selectedExecutor = {
  3182. executor: $scope.executorType.id,
  3183. configuration: $scope.executor.config
  3184. };
  3185. $scope.editedProfile.executors.push(selectedExecutor);
  3186. } else {
  3187. var currentExecutor = getExecutorByIndex($scope.editedProfile, updatedExecutorIndex);
  3188. if (currentExecutor) {
  3189. currentExecutor.configuration = $scope.executor.config;
  3190. }
  3191. }
  3192. ClientPoliciesProfiles.update({
  3193. realm: realm.realm,
  3194. }, clientProfiles, function () {
  3195. if ($scope.createNew) {
  3196. Notifications.success("Executor created successfully");
  3197. } else {
  3198. Notifications.success("Executor updated successfully");
  3199. }
  3200. $location.url('/realms/' + realm.realm + '/client-policies/profiles-update/' + $scope.editedProfile.name);
  3201. }, function(errorResponse) {
  3202. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3203. if ($scope.createNew) {
  3204. Notifications.error('Failed to create executor: ' + errDetails);
  3205. } else {
  3206. Notifications.error('Failed to update executor: ' + errDetails);
  3207. }
  3208. });
  3209. };
  3210. $scope.cancel = function() {
  3211. $location.url('/realms/' + realm.realm + '/client-policies/profiles-update/' + $scope.editedProfile.name);
  3212. };
  3213. });
  3214. module.controller('ClientPoliciesListCtrl', function($scope, realm, clientPolicies, ClientPolicies, Dialog, Notifications, $route, $location) {
  3215. console.log('ClientPoliciesListCtrl');
  3216. $scope.realm = realm;
  3217. $scope.clientPolicies = clientPolicies;
  3218. $scope.removeClientPolicy = function(clientPolicy) {
  3219. Dialog.confirmDelete(clientPolicy.name, 'client policy', function() {
  3220. console.log("Deleting client policy from the JSON: " + clientPolicy.name);
  3221. for (var i = 0; i < $scope.clientPolicies.policies.length; i++) {
  3222. var currentPolicy = $scope.clientPolicies.policies[i];
  3223. if (currentPolicy.name === clientPolicy.name) {
  3224. $scope.clientPolicies.policies.splice(i, 1);
  3225. break;
  3226. }
  3227. }
  3228. ClientPolicies.update({
  3229. realm: realm.realm,
  3230. }, $scope.clientPolicies, function () {
  3231. $route.reload();
  3232. Notifications.success("The client policy was deleted.");
  3233. }, function (errorResponse) {
  3234. $route.reload();
  3235. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3236. Notifications.error('Failed to delete client policy: ' + errDetails);
  3237. });
  3238. });
  3239. };
  3240. });
  3241. module.controller('ClientPoliciesJsonCtrl', function($scope, realm, clientPolicies, Dialog, Notifications, ClientPolicies, $route, $location) {
  3242. console.log('ClientPoliciesJsonCtrl');
  3243. $scope.realm = realm;
  3244. $scope.clientPoliciesString = angular.toJson(clientPolicies, true);
  3245. $scope.save = function() {
  3246. var clientPoliciesObj = null;
  3247. try {
  3248. var clientPoliciesObj = angular.fromJson($scope.clientPoliciesString);
  3249. } catch (e) {
  3250. Notifications.error("Provided JSON is incorrect: " + e.message);
  3251. console.log(e);
  3252. return;
  3253. }
  3254. var clientPoliciesCompressed = angular.toJson(clientPoliciesObj, false);
  3255. ClientPolicies.update({
  3256. realm: realm.realm,
  3257. }, clientPoliciesCompressed, function () {
  3258. $route.reload();
  3259. Notifications.success("The client policies configuration was updated.");
  3260. }, function(errorResponse) {
  3261. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3262. Notifications.error("Failed to update client policies: " + errDetails);
  3263. console.log("Error response when updating client policies JSON: Status: " + errorResponse.status +
  3264. ", statusText: " + errorResponse.statusText + ", data: " + JSON.stringify(errorResponse.data));
  3265. });
  3266. };
  3267. $scope.reset = function() {
  3268. $route.reload();
  3269. };
  3270. });
  3271. module.controller('ClientPoliciesEditCtrl', function($scope, realm, clientProfiles, clientPolicies, ClientPolicies, Dialog, Notifications, $route, $location) {
  3272. var targetPolicyName = $route.current.params.policyName;
  3273. $scope.createNew = targetPolicyName == null;
  3274. if ($scope.createNew) {
  3275. console.log('ClientPoliciesEditCtrl: creating new policy');
  3276. } else {
  3277. console.log('ClientPoliciesEditCtrl: updating policy ' + targetPolicyName);
  3278. }
  3279. $scope.realm = realm;
  3280. $scope.clientPolicies = clientPolicies;
  3281. $scope.clientProfiles = clientProfiles;
  3282. $scope.editedPolicy = null;
  3283. if ($scope.createNew) {
  3284. $scope.editedPolicy = {
  3285. name: "",
  3286. enabled: true,
  3287. profiles: [],
  3288. conditions: []
  3289. };
  3290. } else {
  3291. for (var i=0 ; i < $scope.clientPolicies.policies.length ; i++) {
  3292. var currentPolicy = $scope.clientPolicies.policies[i];
  3293. if (targetPolicyName === currentPolicy.name) {
  3294. $scope.editedPolicy = currentPolicy;
  3295. break;
  3296. }
  3297. }
  3298. if ($scope.editedPolicy == null) {
  3299. console.log("Policy of name " + targetPolicyName + " not found");
  3300. throw 'Policy not found';
  3301. }
  3302. }
  3303. // needs to be a function because when this controller runs, the permissions might not be loaded yet
  3304. $scope.isReadOnly = function() {
  3305. return !$scope.access.manageRealm;
  3306. }
  3307. $scope.availableProfiles = [];
  3308. var allClientProfiles = clientProfiles.profiles;
  3309. if (clientProfiles.globalProfiles) {
  3310. allClientProfiles = allClientProfiles.concat(clientProfiles.globalProfiles);
  3311. }
  3312. for (var k=0 ; k<allClientProfiles.length ; k++) {
  3313. var profileName = allClientProfiles[k].name;
  3314. if (!$scope.editedPolicy.profiles || !$scope.editedPolicy.profiles.includes(profileName)) {
  3315. $scope.availableProfiles.push(profileName);
  3316. }
  3317. }
  3318. $scope.removeCondition = function(conditionIndex) {
  3319. Dialog.confirmDelete($scope.editedPolicy.conditions[conditionIndex].condition, 'condition', function() {
  3320. console.log("remove condition of index " + conditionIndex);
  3321. // Delete condition
  3322. $scope.editedPolicy.conditions.splice(conditionIndex, 1);
  3323. ClientPolicies.update({
  3324. realm: realm.realm,
  3325. }, $scope.clientPolicies, function () {
  3326. Notifications.success("The condition was deleted.");
  3327. }, function (errorResponse) {
  3328. $route.reload();
  3329. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3330. Notifications.error('Failed to delete condition: ' + errDetails);
  3331. });
  3332. });
  3333. }
  3334. $scope.save = function() {
  3335. if (!$scope.editedPolicy.name || $scope.editedPolicy.name === '') {
  3336. Notifications.error('Name must be provided');
  3337. return;
  3338. }
  3339. if ($scope.createNew) {
  3340. $scope.clientPolicies.policies.push($scope.editedPolicy);
  3341. }
  3342. ClientPolicies.update({
  3343. realm: realm.realm,
  3344. }, $scope.clientPolicies, function () {
  3345. if ($scope.createNew) {
  3346. Notifications.success("The client policy was created.");
  3347. $location.url('/realms/' + realm.realm + '/client-policies/policies-update/' + $scope.editedPolicy.name);
  3348. } else {
  3349. Notifications.success("The client policy was updated.");
  3350. $location.url('/realms/' + realm.realm + '/client-policies/policies');
  3351. }
  3352. }, function(errorResponse) {
  3353. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3354. if ($scope.createNew) {
  3355. Notifications.error('Failed to create client policy: ' + errDetails);
  3356. } else {
  3357. Notifications.error('Failed to update client policy: ' + errDetails);
  3358. }
  3359. });
  3360. };
  3361. $scope.back = function() {
  3362. $location.url('/realms/' + realm.realm + '/client-policies/policies');
  3363. };
  3364. function moveProfileAndUpdatePolicy(arrayFrom, arrayTo, profileName, notificationsMessage) {
  3365. for (var i=0 ; i<arrayFrom.length ; i++) {
  3366. if (arrayFrom[i] === profileName) {
  3367. arrayFrom.splice(i, 1);
  3368. arrayTo.push(profileName);
  3369. break;
  3370. }
  3371. }
  3372. ClientPolicies.update({
  3373. realm: realm.realm,
  3374. }, $scope.clientPolicies, function () {
  3375. Notifications.success(notificationsMessage);
  3376. }, function(errorResponse) {
  3377. $route.reload();
  3378. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3379. Notifications.error('Failed to update profiles of the policy: ' + errDetails);
  3380. });
  3381. }
  3382. $scope.addProfile = function(profileName) {
  3383. console.log("addProfile: " + profileName);
  3384. moveProfileAndUpdatePolicy($scope.availableProfiles, $scope.editedPolicy.profiles, profileName, "Profile added to the policy");
  3385. };
  3386. $scope.removeProfile = function(profileName) {
  3387. console.log("removeProfile: " + profileName);
  3388. moveProfileAndUpdatePolicy( $scope.editedPolicy.profiles, $scope.availableProfiles, profileName, "Profile removed from the policy");
  3389. }
  3390. });
  3391. module.controller('ClientPoliciesEditConditionCtrl', function($scope, realm, serverInfo, clientPolicies, ClientPolicies, Components, ComponentUtils, Dialog, Notifications, $route, $location) {
  3392. var updatedConditionIndex = $route.current.params.conditionIndex;
  3393. var targetPolicyName = $route.current.params.policyName;
  3394. $scope.createNew = updatedConditionIndex == null;
  3395. if ($scope.createNew) {
  3396. console.log('ClientPoliciesEditConditionCtrl: adding condition to policy ' + targetPolicyName);
  3397. } else {
  3398. console.log('ClientPoliciesEditConditionCtrl: updating condition with index ' + updatedConditionIndex + ' of policy ' + targetPolicyName);
  3399. }
  3400. $scope.realm = realm;
  3401. $scope.editedPolicy = null;
  3402. for (var i=0 ; i < clientPolicies.policies.length ; i++) {
  3403. var currentPolicy = clientPolicies.policies[i];
  3404. if (targetPolicyName === currentPolicy.name) {
  3405. $scope.editedPolicy = currentPolicy;
  3406. break;
  3407. }
  3408. }
  3409. if ($scope.editedPolicy == null) {
  3410. throw 'Client policy of specified name not found';
  3411. }
  3412. // needs to be a function because when this controller runs, the permissions might not be loaded yet
  3413. $scope.isReadOnly = function() {
  3414. return !$scope.access.manageRealm;
  3415. }
  3416. $scope.conditionTypes = serverInfo.componentTypes['org.keycloak.services.clientpolicy.condition.ClientPolicyConditionProvider'];
  3417. for (var j=0 ; j < $scope.conditionTypes.length ; j++) {
  3418. var currConditionType = $scope.conditionTypes[j];
  3419. if (currConditionType.properties) {
  3420. console.log("Adjusting conditionType: " + currConditionType.id);
  3421. ComponentUtils.addMvOptionsToMultivaluedLists(currConditionType.properties);
  3422. }
  3423. }
  3424. function getConditionByIndex(clientPolicy, conditionIndex) {
  3425. if (clientPolicy.conditions.length <= conditionIndex) {
  3426. console.error('Client policy does not have condition of specified index');
  3427. $location.path('/notfound');
  3428. return null;
  3429. } else {
  3430. return clientPolicy.conditions[conditionIndex];
  3431. }
  3432. }
  3433. if ($scope.createNew) {
  3434. // make first type the default
  3435. $scope.conditionType = $scope.conditionTypes[0];
  3436. var oldConditionType = $scope.conditionType;
  3437. initConfig();
  3438. $scope.$watch('conditionType', function() {
  3439. if (!angular.equals($scope.conditionType, oldConditionType)) {
  3440. oldConditionType = $scope.conditionType;
  3441. initConfig();
  3442. }
  3443. }, true);
  3444. } else {
  3445. var cond = getConditionByIndex($scope.editedPolicy, updatedConditionIndex);
  3446. if (cond) {
  3447. // a failsafe in case the configuration was deleted entirely (or set to null) in the JSON view
  3448. if (!cond.configuration) {
  3449. cond.configuration = {}
  3450. }
  3451. $scope.condition = {
  3452. config: cond.configuration
  3453. };
  3454. $scope.conditionType = null;
  3455. for (var j=0 ; j < $scope.conditionTypes.length ; j++) {
  3456. var currentCndType = $scope.conditionTypes[j];
  3457. if (cond.condition === currentCndType.id) {
  3458. $scope.conditionType = currentCndType;
  3459. break;
  3460. }
  3461. }
  3462. for (var j=0 ; j < $scope.conditionType.properties.length ; j++) {
  3463. // Convert boolean properties from the configuration to strings as expected by the kc-provider-config directive
  3464. var currentProperty = $scope.conditionType.properties[j];
  3465. if (currentProperty.type === 'boolean') {
  3466. $scope.condition.config[currentProperty.name] = ($scope.condition.config[currentProperty.name]) ? "true" : "false";
  3467. }
  3468. // a workaround for select2 to prevent displaying empty boxes
  3469. var configProperty = $scope.condition.config[$scope.conditionType.properties[j].name];
  3470. if (Array.isArray(configProperty) && configProperty.length === 0) {
  3471. $scope.condition.config[$scope.conditionType.properties[j].name] = null
  3472. }
  3473. }
  3474. }
  3475. }
  3476. function toDefaultValue(configProperty) {
  3477. if (configProperty.type === 'boolean') {
  3478. return (configProperty.defaultValue) ? "true" : "false";
  3479. }
  3480. if (configProperty.defaultValue !== undefined) {
  3481. if ((configProperty.type === 'MultivaluedString' || configProperty.type === 'MultivaluedList') && !Array.isArray(configProperty.defaultValue)) {
  3482. return [configProperty.defaultValue]
  3483. }
  3484. return configProperty.defaultValue;
  3485. } else {
  3486. return null;
  3487. }
  3488. }
  3489. function initConfig() {
  3490. console.log("Initialized config now. ConfigType is: " + $scope.conditionType.id);
  3491. $scope.condition = {
  3492. config: {}
  3493. };
  3494. for (let i = 0; i < $scope.conditionType.properties.length; i++) {
  3495. let configProperty = $scope.conditionType.properties[i];
  3496. $scope.condition.config[configProperty.name] = toDefaultValue(configProperty);
  3497. }
  3498. }
  3499. $scope.save = function() {
  3500. console.log("save: " + $scope.conditionType.id);
  3501. var conditionName = $scope.conditionType.id;
  3502. if (!$scope.editedPolicy.conditions) {
  3503. $scope.editedPolicy.conditions = [];
  3504. }
  3505. ComponentUtils.removeLastEmptyValue($scope.condition.config);
  3506. // Convert String properties required by the kc-provider-config directive back to booleans
  3507. for (var j=0 ; j < $scope.conditionType.properties.length ; j++) {
  3508. var currentProperty = $scope.conditionType.properties[j];
  3509. if (currentProperty.type === 'boolean') {
  3510. $scope.condition.config[currentProperty.name] = ($scope.condition.config[currentProperty.name] === "true") ? true : false;
  3511. }
  3512. }
  3513. var selectedCondition;
  3514. if ($scope.createNew) {
  3515. var selectedCondition = {
  3516. condition: $scope.conditionType.id,
  3517. configuration: $scope.condition.config
  3518. };
  3519. $scope.editedPolicy.conditions.push(selectedCondition);
  3520. } else {
  3521. var currentCondition = getConditionByIndex($scope.editedPolicy, updatedConditionIndex);
  3522. if (currentCondition) {
  3523. currentCondition.configuration = $scope.condition.config;
  3524. }
  3525. }
  3526. ClientPolicies.update({
  3527. realm: realm.realm,
  3528. }, clientPolicies, function () {
  3529. if ($scope.createNew) {
  3530. Notifications.success("Condition created successfully");
  3531. } else {
  3532. Notifications.success("Condition updated successfully");
  3533. }
  3534. $location.url('/realms/' + realm.realm + '/client-policies/policies-update/' + $scope.editedPolicy.name);
  3535. }, function(errorResponse) {
  3536. var errDetails = (!errorResponse.data.errorMessage) ? "unknown error, please see the server log" : errorResponse.data.errorMessage
  3537. if ($scope.createNew) {
  3538. Notifications.error('Failed to create condition: ' + errDetails);
  3539. } else {
  3540. Notifications.error('Failed to update condition: ' + errDetails);
  3541. }
  3542. });
  3543. };
  3544. $scope.cancel = function() {
  3545. $location.url('/realms/' + realm.realm + '/client-policies/policies-update/' + $scope.editedPolicy.name);
  3546. };
  3547. });
  3548. module.controller('RealmImportCtrl', function($scope, realm, $route,
  3549. Notifications, $modal, $resource) {
  3550. $scope.rawContent = {};
  3551. $scope.fileContent = {
  3552. enabled: true
  3553. };
  3554. $scope.changed = false;
  3555. $scope.files = [];
  3556. $scope.realm = realm;
  3557. $scope.overwrite = false;
  3558. $scope.skip = false;
  3559. $scope.importUsers = false;
  3560. $scope.importGroups = false;
  3561. $scope.importClients = false;
  3562. $scope.importIdentityProviders = false;
  3563. $scope.importRealmRoles = false;
  3564. $scope.importClientRoles = false;
  3565. $scope.ifResourceExists='FAIL';
  3566. $scope.isMultiRealm = false;
  3567. $scope.results = {};
  3568. $scope.currentPage = 0;
  3569. var pageSize = 15;
  3570. var oldCopy = angular.copy($scope.fileContent);
  3571. $scope.importFile = function($fileContent){
  3572. var parsed;
  3573. try {
  3574. parsed = JSON.parse($fileContent);
  3575. } catch (e) {
  3576. Notifications.error('Unable to parse JSON file.');
  3577. return;
  3578. }
  3579. $scope.rawContent = angular.copy(parsed);
  3580. if (($scope.rawContent instanceof Array) && ($scope.rawContent.length > 0)) {
  3581. if ($scope.rawContent.length > 1) $scope.isMultiRealm = true;
  3582. $scope.fileContent = $scope.rawContent[0];
  3583. } else {
  3584. $scope.fileContent = $scope.rawContent;
  3585. }
  3586. $scope.importing = true;
  3587. setOnOffSwitchDefaults();
  3588. $scope.results = {};
  3589. if (!$scope.hasResources()) {
  3590. $scope.nothingToImport();
  3591. }
  3592. };
  3593. $scope.hasResults = function() {
  3594. return (Object.keys($scope.results).length > 0) &&
  3595. ($scope.results.results !== undefined) &&
  3596. ($scope.results.results.length > 0);
  3597. }
  3598. $scope.resultsPage = function() {
  3599. if (!$scope.hasResults()) return {};
  3600. return $scope.results.results.slice(startIndex(), endIndex());
  3601. }
  3602. function startIndex() {
  3603. return pageSize * $scope.currentPage;
  3604. }
  3605. function endIndex() {
  3606. var length = $scope.results.results.length;
  3607. var endIndex = startIndex() + pageSize;
  3608. if (endIndex > length) endIndex = length;
  3609. return endIndex;
  3610. }
  3611. function setOnOffSwitchDefaults() {
  3612. $scope.importUsers = $scope.hasArray('users');
  3613. $scope.importGroups = $scope.hasArray('groups');
  3614. $scope.importClients = $scope.hasArray('clients');
  3615. $scope.importIdentityProviders = $scope.hasArray('identityProviders');
  3616. $scope.importRealmRoles = $scope.hasRealmRoles();
  3617. $scope.importClientRoles = $scope.hasClientRoles();
  3618. }
  3619. $scope.setFirstPage = function() {
  3620. $scope.currentPage = 0;
  3621. }
  3622. $scope.setNextPage = function() {
  3623. $scope.currentPage++;
  3624. }
  3625. $scope.setPreviousPage = function() {
  3626. $scope.currentPage--;
  3627. }
  3628. $scope.hasNext = function() {
  3629. if (!$scope.hasResults()) return false;
  3630. var length = $scope.results.results.length;
  3631. //console.log('length=' + length);
  3632. var endIndex = startIndex() + pageSize;
  3633. //console.log('endIndex=' + endIndex);
  3634. return length > endIndex;
  3635. }
  3636. $scope.hasPrevious = function() {
  3637. if (!$scope.hasResults()) return false;
  3638. return $scope.currentPage > 0;
  3639. }
  3640. $scope.viewImportDetails = function() {
  3641. $modal.open({
  3642. templateUrl: resourceUrl + '/partials/modal/view-object.html',
  3643. controller: 'ObjectModalCtrl',
  3644. resolve: {
  3645. object: function () {
  3646. return $scope.fileContent;
  3647. }
  3648. }
  3649. })
  3650. };
  3651. $scope.hasArray = function(section) {
  3652. return ($scope.fileContent !== 'undefined') &&
  3653. ($scope.fileContent.hasOwnProperty(section)) &&
  3654. ($scope.fileContent[section] instanceof Array) &&
  3655. ($scope.fileContent[section].length > 0);
  3656. }
  3657. $scope.hasRealmRoles = function() {
  3658. return $scope.hasRoles() &&
  3659. ($scope.fileContent.roles.hasOwnProperty('realm')) &&
  3660. ($scope.fileContent.roles.realm instanceof Array) &&
  3661. ($scope.fileContent.roles.realm.length > 0);
  3662. }
  3663. $scope.hasRoles = function() {
  3664. return ($scope.fileContent !== 'undefined') &&
  3665. ($scope.fileContent.hasOwnProperty('roles')) &&
  3666. ($scope.fileContent.roles !== 'undefined');
  3667. }
  3668. $scope.hasClientRoles = function() {
  3669. return $scope.hasRoles() &&
  3670. ($scope.fileContent.roles.hasOwnProperty('client')) &&
  3671. (Object.keys($scope.fileContent.roles.client).length > 0);
  3672. }
  3673. $scope.itemCount = function(section) {
  3674. if (!$scope.importing) return 0;
  3675. if ($scope.hasRealmRoles() && (section === 'roles.realm')) return $scope.fileContent.roles.realm.length;
  3676. if ($scope.hasClientRoles() && (section === 'roles.client')) return clientRolesCount($scope.fileContent.roles.client);
  3677. if (!$scope.fileContent.hasOwnProperty(section)) return 0;
  3678. return $scope.fileContent[section].length;
  3679. }
  3680. clientRolesCount = function(clientRoles) {
  3681. var total = 0;
  3682. for (var clientName in clientRoles) {
  3683. total += clientRoles[clientName].length;
  3684. }
  3685. return total;
  3686. }
  3687. $scope.hasResources = function() {
  3688. return ($scope.importUsers && $scope.hasArray('users')) ||
  3689. ($scope.importGroups && $scope.hasArray('groups')) ||
  3690. ($scope.importClients && $scope.hasArray('clients')) ||
  3691. ($scope.importIdentityProviders && $scope.hasArray('identityProviders')) ||
  3692. ($scope.importRealmRoles && $scope.hasRealmRoles()) ||
  3693. ($scope.importClientRoles && $scope.hasClientRoles());
  3694. }
  3695. $scope.nothingToImport = function() {
  3696. Notifications.error('No resources specified to import.');
  3697. }
  3698. $scope.$watch('fileContent', function() {
  3699. if (!angular.equals($scope.fileContent, oldCopy)) {
  3700. $scope.changed = true;
  3701. }
  3702. setOnOffSwitchDefaults();
  3703. }, true);
  3704. $scope.successMessage = function() {
  3705. var message = $scope.results.added + ' records added. ';
  3706. if ($scope.ifResourceExists === 'SKIP') {
  3707. message += $scope.results.skipped + ' records skipped.'
  3708. }
  3709. if ($scope.ifResourceExists === 'OVERWRITE') {
  3710. message += $scope.results.overwritten + ' records overwritten.';
  3711. }
  3712. return message;
  3713. }
  3714. $scope.save = function() {
  3715. var json = angular.copy($scope.fileContent);
  3716. json.ifResourceExists = $scope.ifResourceExists;
  3717. if (!$scope.importUsers) delete json.users;
  3718. if (!$scope.importGroups) delete json.groups;
  3719. if (!$scope.importIdentityProviders) delete json.identityProviders;
  3720. if (!$scope.importClients) delete json.clients;
  3721. if (json.hasOwnProperty('roles')) {
  3722. if (!$scope.importRealmRoles) delete json.roles.realm;
  3723. if (!$scope.importClientRoles) delete json.roles.client;
  3724. }
  3725. var importFile = $resource(authUrl + '/admin/realms/' + realm.realm + '/partialImport');
  3726. $scope.results = importFile.save(json, function() {
  3727. Notifications.success($scope.successMessage());
  3728. }, function(error) {
  3729. if (error.data.errorMessage) {
  3730. Notifications.error(error.data.errorMessage);
  3731. } else {
  3732. Notifications.error('Unexpected error during import');
  3733. }
  3734. });
  3735. };
  3736. $scope.reset = function() {
  3737. $route.reload();
  3738. }
  3739. });
  3740. module.controller('RealmExportCtrl', function($scope, realm, $http,
  3741. $httpParamSerializer, Notifications, Dialog) {
  3742. $scope.realm = realm;
  3743. $scope.exportGroupsAndRoles = false;
  3744. $scope.exportClients = false;
  3745. $scope.export = function() {
  3746. if ($scope.exportGroupsAndRoles || $scope.exportClients) {
  3747. Dialog.confirm('Export', 'This operation may make server unresponsive for a while.\n\nAre you sure you want to proceed?', download);
  3748. } else {
  3749. download();
  3750. }
  3751. }
  3752. function download() {
  3753. var exportUrl = authUrl + '/admin/realms/' + realm.realm + '/partial-export';
  3754. var params = {};
  3755. if ($scope.exportGroupsAndRoles) {
  3756. params['exportGroupsAndRoles'] = true;
  3757. }
  3758. if ($scope.exportClients) {
  3759. params['exportClients'] = true;
  3760. }
  3761. if (Object.keys(params).length > 0) {
  3762. exportUrl += '?' + $httpParamSerializer(params);
  3763. }
  3764. $http.post(exportUrl)
  3765. .then(function(response) {
  3766. var download = angular.fromJson(response.data);
  3767. download = angular.toJson(download, true);
  3768. saveAs(new Blob([download], { type: 'application/json' }), 'realm-export.json');
  3769. }).catch(function() {
  3770. Notifications.error("Sorry, something went wrong.");
  3771. });
  3772. }
  3773. });