PageRenderTime 41ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/uma-server-webapp/src/main/webapp/resources/js/policy.js

http://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server
JavaScript | 786 lines | 567 code | 176 blank | 43 comment | 48 complexity | 31897df1dad506674fb240a251b4f624 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright 2018 The MIT Internet Trust Consortium
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *******************************************************************************/
  16. var ResourceSetModel = Backbone.Model.extend({
  17. urlRoot: 'api/resourceset'
  18. });
  19. var ResourceSetCollection = Backbone.Collection.extend({
  20. model: ResourceSetModel,
  21. url: 'api/resourceset'
  22. });
  23. var PolicyModel = Backbone.Model.extend({
  24. urlRoot: function() {
  25. return 'api/resourceset/' + this.options.rsid + '/policy/';
  26. },
  27. initialize: function(model, options) {
  28. this.options = options;
  29. }
  30. });
  31. var PolicyCollection = Backbone.Collection.extend({
  32. model: PolicyModel,
  33. url: function() {
  34. return 'api/resourceset/' + this.options.rsid + '/policy/';
  35. },
  36. initialize: function(models, options) {
  37. this.options = options;
  38. }
  39. });
  40. var ResourceSetListView = Backbone.View.extend({
  41. tagName: 'span',
  42. initialize:function (options) {
  43. this.options = options;
  44. },
  45. load:function(callback) {
  46. if (this.model.isFetched &&
  47. this.options.clientList.isFetched &&
  48. this.options.systemScopeList.isFetched) {
  49. callback();
  50. return;
  51. }
  52. $('#loadingbox').sheet('show');
  53. $('#loading').html(
  54. '<span class="label" id="loading-resourcesets">' + $.t('policy.resource-sets') + '</span> ' +
  55. '<span class="label" id="loading-clients">' + $.t('common.clients') + '</span> ' +
  56. '<span class="label" id="loading-scopes">' + $.t('common.scopes') + '</span> '
  57. );
  58. $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-resourcesets').addClass('label-success');}}),
  59. this.options.clientList.fetchIfNeeded({success:function(e) {$('#loading-clients').addClass('label-success');}}),
  60. this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  61. .done(function() {
  62. $('#loadingbox').sheet('hide');
  63. callback();
  64. });
  65. },
  66. events: {
  67. "click .refresh-table":"refreshTable"
  68. },
  69. render:function (eventName) {
  70. $(this.el).html($('#tmpl-resource-set-table').html());
  71. var _self = this;
  72. _.each(this.model.models, function (resourceSet) {
  73. // look up client
  74. var client = this.options.clientList.getByClientId(resourceSet.get('clientId'));
  75. // if there's no client ID, this is an error!
  76. if (client != null) {
  77. var view = new ResourceSetView({model: resourceSet, client: client, systemScopeList: _self.options.systemScopeList});
  78. view.parentView = _self;
  79. $('#resource-set-table', this.el).append(view.render().el);
  80. }
  81. }, this);
  82. this.togglePlaceholder();
  83. $(this.el).i18n();
  84. return this;
  85. },
  86. togglePlaceholder:function() {
  87. if (this.model.length > 0) {
  88. $('#resource-set-table', this.el).show();
  89. $('#resource-set-table-empty', this.el).hide();
  90. } else {
  91. $('#resource-set-table', this.el).hide();
  92. $('#resource-set-table-empty', this.el).show();
  93. }
  94. },
  95. refreshTable:function(e) {
  96. e.preventDefault();
  97. var _self = this;
  98. $('#loadingbox').sheet('show');
  99. $('#loading').html(
  100. '<span class="label" id="loading-resourcesets">' + $.t('policy.resource-sets') + '</span> ' +
  101. '<span class="label" id="loading-clients">' + $.t('common.clients') + '</span> ' +
  102. '<span class="label" id="loading-scopes">' + $.t('common.scopes') + '</span> '
  103. );
  104. $.when(this.model.fetch({success:function(e) {$('#loading-resourcesets').addClass('label-success');}}),
  105. this.options.clientList.fetch({success:function(e) {$('#loading-clients').addClass('label-success');}}),
  106. this.options.systemScopeList.fetch({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  107. .done(function() {
  108. $('#loadingbox').sheet('hide');
  109. _self.render();
  110. });
  111. }
  112. });
  113. var ResourceSetView = Backbone.View.extend({
  114. tagName: 'tr',
  115. initialize:function(options) {
  116. this.options = options;
  117. if (!this.template) {
  118. this.template = _.template($('#tmpl-resource-set').html());
  119. }
  120. if (!this.scopeTemplate) {
  121. this.scopeTemplate = _.template($('#tmpl-scope-list').html());
  122. }
  123. if (!this.moreInfoTemplate) {
  124. this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html());
  125. }
  126. this.model.bind('change', this.render, this);
  127. },
  128. render:function(eventName) {
  129. var json = {rs: this.model.toJSON(), client: this.options.client.toJSON()};
  130. this.$el.html(this.template(json));
  131. $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList}));
  132. $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()}));
  133. $(this.el).i18n();
  134. return this;
  135. },
  136. events:{
  137. 'click .btn-edit': 'editPolicies',
  138. 'click .btn-delete': 'deleteResourceSet',
  139. 'click .toggleMoreInformation': 'toggleMoreInformation'
  140. },
  141. editPolicies:function(e) {
  142. e.preventDefault();
  143. app.navigate('user/policy/' + this.model.get('id'), {trigger: true});
  144. },
  145. deleteResourceSet:function(e) {
  146. e.preventDefault();
  147. if (confirm($.t('policy.rs-table.confirm'))) {
  148. var _self = this;
  149. this.model.destroy({
  150. dataType: false, processData: false,
  151. success:function () {
  152. _self.$el.fadeTo("fast", 0.00, function () { //fade
  153. $(this).slideUp("fast", function () { //slide up
  154. $(this).remove(); //then remove from the DOM
  155. _self.parentView.togglePlaceholder();
  156. });
  157. });
  158. },
  159. error:function (error, response) {
  160. console.log("An error occurred when deleting a resource set");
  161. //Pull out the response text.
  162. var responseJson = JSON.parse(response.responseText);
  163. //Display an alert with an error message
  164. $('#modalAlert div.modal-header').html(responseJson.error);
  165. $('#modalAlert div.modal-body').html(responseJson.error_description);
  166. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  167. "backdrop" : "static",
  168. "keyboard" : true,
  169. "show" : true // ensure the modal is shown immediately
  170. });
  171. }
  172. });
  173. _self.parentView.delegateEvents();
  174. }
  175. return false;
  176. },
  177. toggleMoreInformation:function(e) {
  178. e.preventDefault();
  179. if ($('.moreInformation', this.el).is(':visible')) {
  180. // hide it
  181. $('.moreInformation', this.el).hide('fast');
  182. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right');
  183. $('.moreInformationContainer', this.el).removeClass('alert').removeClass('alert-info').addClass('muted');
  184. } else {
  185. // show it
  186. $('.moreInformation', this.el).show('fast');
  187. $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down');
  188. $('.moreInformationContainer', this.el).addClass('alert').addClass('alert-info').removeClass('muted');
  189. }
  190. },
  191. });
  192. var PolicyListView = Backbone.View.extend({
  193. tagName: 'span',
  194. initialize:function(options) {
  195. this.options = options;
  196. },
  197. load:function(callback) {
  198. if (this.model.isFetched &&
  199. this.options.rs.isFetched &&
  200. this.options.systemScopeList.isFetched) {
  201. callback();
  202. return;
  203. }
  204. $('#loadingbox').sheet('show');
  205. $('#loading').html(
  206. '<span class="label" id="loading-policies">' + $.t('policy.loading-policies') + '</span> ' +
  207. '<span class="label" id="loading-rs">' + $.t('policy.loading-rs') + '</span> ' +
  208. '<span class="label" id="loading-scopes">' + $.t("common.scopes") + '</span> '
  209. );
  210. $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-policies').addClass('label-success');}}),
  211. this.options.rs.fetchIfNeeded({success:function(e) {$('#loading-rs').addClass('label-success');}}),
  212. this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  213. .done(function() {
  214. $('#loadingbox').sheet('hide');
  215. callback();
  216. });
  217. },
  218. events:{
  219. 'click .btn-add':'addPolicy',
  220. 'click .btn-cancel':'cancel'
  221. },
  222. cancel:function(e) {
  223. e.preventDefault();
  224. app.navigate('user/policy', {trigger: true});
  225. },
  226. togglePlaceholder:function() {
  227. if (this.model.length > 0) {
  228. $('#policy-info', this.el).show();
  229. $('#policy-table', this.el).show();
  230. $('#policy-table-empty', this.el).hide();
  231. } else {
  232. $('#policy-info', this.el).hide();
  233. $('#policy-table', this.el).hide();
  234. $('#policy-table-empty', this.el).show();
  235. }
  236. },
  237. addPolicy:function(e) {
  238. e.preventDefault();
  239. app.navigate('user/policy/' + this.options.rs.get('id') +'/new', {trigger: true});
  240. },
  241. render:function (eventName) {
  242. $(this.el).html($('#tmpl-policy-table').html());
  243. var _self = this;
  244. _.each(this.model.models, function (policy) {
  245. var view = new PolicyView({model: policy, systemScopeList: _self.options.systemScopeList, rs: _self.options.rs});
  246. view.parentView = _self;
  247. $('#policy-table', this.el).append(view.render().el);
  248. }, this);
  249. this.togglePlaceholder();
  250. $(this.el).i18n();
  251. return this;
  252. }
  253. });
  254. var PolicyView = Backbone.View.extend({
  255. tagName: 'tr',
  256. initialize:function(options) {
  257. this.options = options;
  258. if (!this.template) {
  259. this.template = _.template($('#tmpl-policy').html());
  260. }
  261. if (!this.scopeTemplate) {
  262. this.scopeTemplate = _.template($('#tmpl-scope-list').html());
  263. }
  264. },
  265. events:{
  266. 'click .btn-edit':'editPolicy',
  267. 'click .btn-remove':'removePolicy'
  268. },
  269. editPolicy:function(e) {
  270. e.preventDefault();
  271. app.navigate('user/policy/' + this.options.rs.get("id") + '/' + this.model.get('id'), {trigger: true});
  272. },
  273. removePolicy:function(e) {
  274. e.preventDefault();
  275. if (confirm($.t('policy.policy-table.confirm'))) {
  276. var _self = this;
  277. this.model.destroy({
  278. dataType: false, processData: false,
  279. success:function () {
  280. _self.$el.fadeTo("fast", 0.00, function () { //fade
  281. $(this).slideUp("fast", function () { //slide up
  282. $(this).remove(); //then remove from the DOM
  283. _self.parentView.togglePlaceholder();
  284. });
  285. });
  286. },
  287. error:function (error, response) {
  288. console.log("An error occurred when deleting a client");
  289. //Pull out the response text.
  290. var responseJson = JSON.parse(response.responseText);
  291. //Display an alert with an error message
  292. $('#modalAlert div.modal-header').html(responseJson.error);
  293. $('#modalAlert div.modal-body').html(responseJson.error_description);
  294. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  295. "backdrop" : "static",
  296. "keyboard" : true,
  297. "show" : true // ensure the modal is shown immediately
  298. });
  299. }
  300. });
  301. _self.parentView.delegateEvents();
  302. }
  303. },
  304. render:function (eventName) {
  305. var json = this.model.toJSON();
  306. this.$el.html(this.template(json));
  307. $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList}));
  308. $(this.el).i18n();
  309. return this;
  310. }
  311. });
  312. var PolicyFormView = Backbone.View.extend({
  313. tagName: 'div',
  314. initialize:function(options) {
  315. this.options = options;
  316. if (!this.template) {
  317. this.template = _.template($('#tmpl-policy-form').html());
  318. }
  319. this.issuerCollection = new Backbone.Collection();
  320. },
  321. events:{
  322. 'click .btn-share': 'addWebfingerClaim',
  323. 'click .btn-share-advanced': 'addAdvancedClaim',
  324. 'click .btn-clear': 'clearAllClaims',
  325. 'click .btn-save': 'savePolicy',
  326. 'click .btn-cancel': 'cancel'
  327. },
  328. load:function(callback) {
  329. if (this.model.isFetched &&
  330. this.options.rs.isFetched &&
  331. this.options.systemScopeList.isFetched) {
  332. callback();
  333. return;
  334. }
  335. $('#loadingbox').sheet('show');
  336. $('#loading').html(
  337. '<span class="label" id="loading-policies">' + $.t('policy.loading-policy') + '</span> ' +
  338. '<span class="label" id="loading-rs">' + $.t('policy.loading-rs') + '</span> ' +
  339. '<span class="label" id="loading-scopes">' + $.t("common.scopes") + '</span> '
  340. );
  341. $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-policies').addClass('label-success');}}),
  342. this.options.rs.fetchIfNeeded({success:function(e) {$('#loading-rs').addClass('label-success');}}),
  343. this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}}))
  344. .done(function() {
  345. $('#loadingbox').sheet('hide');
  346. callback();
  347. });
  348. },
  349. addWebfingerClaim:function(e) {
  350. e.preventDefault();
  351. // post to the webfinger helper and get the response back
  352. var _self = this;
  353. var email = $('#email', this.el).val();
  354. $('#loadingbox').sheet('show');
  355. $('#loading').html(
  356. 'Looking up identity provider...'
  357. );
  358. var base = $('base').attr('href');
  359. $.getJSON(base + '/api/emailsearch?' + $.param({'identifier': email}), function(data) {
  360. // grab the current state of the scopes checkboxes just in case
  361. var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get();
  362. _self.model.set({
  363. scopes: scopes,
  364. claimsRequired: data
  365. }, {trigger: false});
  366. _self.render();
  367. $('#loadingbox').sheet('hide');
  368. }).error(function(jqXHR, textStatus, errorThrown) {
  369. console.log("An error occurred when doing a webfinger lookup", errorThrown);
  370. $('#loadingbox').sheet('hide');
  371. //Display an alert with an error message
  372. $('#modalAlert div.modal-header').html($.t('policy.webfinger-error'));
  373. $('#modalAlert div.modal-body').html($.t('policy.webfinger-error-description', {email: email}));
  374. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  375. "backdrop" : "static",
  376. "keyboard" : true,
  377. "show" : true // ensure the modal is shown immediately
  378. });
  379. });
  380. },
  381. addAdvancedClaim:function(e) {
  382. e.preventDefault();
  383. var name = $('#name', this.el).val();
  384. var friendly = $('#friendly-name', this.el).val();
  385. var rawValue = $('#value', this.el).val();
  386. var valueType = $('#value-type', this.el).val();
  387. var value = null;
  388. if (valueType == 'number') {
  389. value = Number(rawValue);
  390. } else if (valueType == 'boolean') {
  391. value = (rawValue.toLowerCase() == 'true');
  392. } else if (valueType == 'json') {
  393. value = JSON.parse(rawValue);
  394. } else {
  395. // treat it as a string, the default
  396. value = rawValue;
  397. }
  398. var issuers = this.issuerCollection.pluck('item');
  399. console.log(name, friendly, rawValue, valueType, value, issuers);
  400. if (!_.isEmpty(issuers)
  401. && name
  402. && value) {
  403. // we've got a valid claim, add it to our set
  404. // grab the current state of the scopes checkboxes just in case
  405. var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get();
  406. var claimsRequired = this.model.get('claimsRequired');
  407. if (!claimsRequired) {
  408. claimsRequired = [];
  409. }
  410. claimsRequired.push({
  411. name: name,
  412. friendlyName: friendly,
  413. value: value,
  414. issuer: issuers
  415. });
  416. this.model.set({
  417. scopes: scopes,
  418. claimsRequired: claimsRequired
  419. }, {trigger: false});
  420. $('#name', this.el).val('');
  421. $('#friendly-name', this.el).val('');
  422. $('#value', this.el).val('');
  423. $('#value-type', this.el).val('text');
  424. this.render();
  425. // re-select the advanced tab
  426. $('a[data-target="#policy-advanced-tab"]', this.el).tab('show')
  427. } else {
  428. // something is missing
  429. $('#loadingbox').sheet('hide');
  430. //Display an alert with an error message
  431. $('#modalAlert div.modal-header').html($.t('policy.advanced-error'));
  432. $('#modalAlert div.modal-body').html($.t('policy.advanced-error-description'));
  433. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  434. "backdrop" : "static",
  435. "keyboard" : true,
  436. "show" : true // ensure the modal is shown immediately
  437. });
  438. }
  439. },
  440. clearAllClaims:function(e) {
  441. e.preventDefault();
  442. if (confirm($.t('policy.policy-form.clear-all-confirm'))) {
  443. var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get();
  444. var claimsRequired = [];
  445. this.model.set({
  446. scopes: scopes,
  447. claimsRequired: claimsRequired
  448. }, {trigger: false});
  449. this.render();
  450. }
  451. },
  452. savePolicy:function(e) {
  453. e.preventDefault();
  454. // get all the scopes that are checked
  455. var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get();
  456. var valid = this.model.set({
  457. scopes: scopes
  458. });
  459. if (valid) {
  460. var _self = this;
  461. this.model.save({}, {
  462. success:function() {
  463. app.systemScopeList.add(_self.model);
  464. // refresh the associated RS
  465. _self.options.rs.fetch({success: function() {
  466. app.navigate('user/policy/' + _self.options.rs.get('id'), {trigger: true});
  467. }});
  468. },
  469. error:function(error, response) {
  470. //Pull out the response text.
  471. var responseJson = JSON.parse(response.responseText);
  472. //Display an alert with an error message
  473. $('#modalAlert div.modal-header').html(responseJson.error);
  474. $('#modalAlert div.modal-body').html(responseJson.error_description);
  475. $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog
  476. "backdrop" : "static",
  477. "keyboard" : true,
  478. "show" : true // ensure the modal is shown immediately
  479. });
  480. }
  481. });
  482. }
  483. return false;
  484. },
  485. cancel:function(e) {
  486. e.preventDefault();
  487. app.navigate('user/policy/' + this.options.rs.get('id'), {trigger: true});
  488. },
  489. render:function (eventName) {
  490. var json = this.model.toJSON();
  491. var rs = this.options.rs.toJSON();
  492. this.$el.html(this.template({policy: json, rs: rs}));
  493. // build and bind issuer view
  494. var issuerView = new ListWidgetView({
  495. placeholder: $.t('policy.policy-form.issuer-placeholder'),
  496. helpBlockText: $.t('policy.policy-form.issuer-help'),
  497. collection: this.issuerCollection});
  498. $("#issuers .controls",this.el).html(issuerView.render().el);
  499. $(this.el).i18n();
  500. return this;
  501. }
  502. });
  503. ui.routes.push({path: "user/policy", name: "policy", callback:
  504. function() {
  505. this.breadCrumbView.collection.reset();
  506. this.breadCrumbView.collection.add([
  507. {text:$.t('admin.home'), href:""},
  508. {text:$.t('policy.resource-sets'), href:"manage/#user/policy"}
  509. ]);
  510. this.updateSidebar('user/policy');
  511. var view = new ResourceSetListView({model: this.resourceSetList, clientList: this.clientList, systemScopeList: this.systemScopeList});
  512. view.load(function() {
  513. $('#content').html(view.render().el);
  514. setPageTitle($.t('policy.resource-sets'));
  515. });
  516. }
  517. });
  518. ui.routes.push({path: "user/policy/:rsid", name: "editPolicies", callback:
  519. function(rsid) {
  520. this.breadCrumbView.collection.reset();
  521. this.breadCrumbView.collection.add([
  522. {text:$.t('admin.home'), href:""},
  523. {text:$.t('policy.resource-sets'), href:"manage/#user/policy"},
  524. {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid}
  525. ]);
  526. this.updateSidebar('user/policy');
  527. var rs = this.resourceSetList.get(rsid);
  528. var policies = null;
  529. if (rs == null) {
  530. // need to load it directly
  531. policies = new PolicyCollection([], {rsid: rsid});
  532. rs = new ResourceSetModel({id: rsid});
  533. this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future
  534. } else {
  535. // the resource set is loaded, preload the claims
  536. policies = new PolicyCollection(rs.get('policies'), {rsid: rsid});
  537. policies.isFetched = true;
  538. }
  539. var view = new PolicyListView({model: policies, rs: rs, systemScopeList: this.systemScopeList});
  540. view.load(function() {
  541. $('#content').html(view.render().el);
  542. setPageTitle($.t('policy.edit-policy'));
  543. });
  544. }
  545. });
  546. ui.routes.push({path: "user/policy/:rsid/new", name: "newPolicy", callback:
  547. function(rsid) {
  548. this.breadCrumbView.collection.reset();
  549. this.breadCrumbView.collection.add([
  550. {text:$.t('admin.home'), href:""},
  551. {text:$.t('policy.resource-sets'), href:"manage/#user/policy"},
  552. {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid},
  553. {text:$.t('policy.new-policy'), href:"manage/#user/policy/" + rsid + "/new"}
  554. ]);
  555. this.updateSidebar('user/policy');
  556. var policy = policy = new PolicyModel({}, {rsid: rsid});
  557. var rs = this.resourceSetList.get(rsid);
  558. if (rs == null) {
  559. // need to load it directly
  560. rs = new ResourceSetModel({id: rsid});
  561. this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future
  562. }
  563. var view = new PolicyFormView({model: policy, rs: rs, systemScopeList: this.systemScopeList});
  564. view.load(function() {
  565. $('#content').html(view.render().el);
  566. setPageTitle($.t('policy.edit-policy'));
  567. });
  568. }
  569. });
  570. ui.routes.push({path: "user/policy/:rsid/:pid", name: "editPolicy", callback:
  571. function(rsid, pid) {
  572. this.breadCrumbView.collection.reset();
  573. this.breadCrumbView.collection.add([
  574. {text:$.t('admin.home'), href:""},
  575. {text:$.t('policy.resource-sets'), href:"manage/#user/policy"},
  576. {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid},
  577. {text:$.t('policy.edit-policy'), href:"manage/#user/policy/" + rsid + "/" + pid}
  578. ]);
  579. this.updateSidebar('user/policy');
  580. var rs = this.resourceSetList.get(rsid);
  581. var policy = null;
  582. if (rs == null) {
  583. // need to load it directly
  584. policy = new PolicyModel({id: pid}, {rsid: rsid});
  585. rs = new ResourceSetModel({id: rsid});
  586. this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future
  587. } else {
  588. // the resource set is loaded, preload the claims
  589. _.each(rs.get('policies'), function(p) {
  590. if (p.id == pid) {
  591. policy = new PolicyModel(p, {rsid: rsid});
  592. policy.isFetched = true;
  593. }
  594. });
  595. if (policy == null) {
  596. // need to load it directly
  597. policy = new PolicyModel({id: pid}, {rsid: rsid});
  598. }
  599. }
  600. var view = new PolicyFormView({model: policy, rs: rs, systemScopeList: this.systemScopeList});
  601. view.load(function() {
  602. $('#content').html(view.render().el);
  603. setPageTitle($.t('policy.edit-policy'));
  604. });
  605. }
  606. });
  607. ui.templates.push('resources/template/policy.html');
  608. ui.init.push(function(app) {
  609. app.resourceSetList = new ResourceSetCollection();
  610. });