mirror of
https://github.com/ziirish/burp-ui.git
synced 2026-05-21 06:45:24 -06:00
add: support for role and group inheritance
This commit is contained in:
parent
ec4a1bff2b
commit
b32c185725
12 changed files with 270 additions and 64 deletions
|
|
@ -63,6 +63,7 @@
|
|||
<tr>
|
||||
<th>{{ _('Group name') }}</th>
|
||||
<th>{{ _('Authorization Backend') }}</th>
|
||||
<th>{{ _('Role') }}</th>
|
||||
<th>{{ _('Members') }}</th>
|
||||
<th>{{ _('Grants') }}</th>
|
||||
<th>{{ _('Controls') }}</th>
|
||||
|
|
@ -139,7 +140,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ _('Cancel') }}</button>
|
||||
<button type="button" class="btn btn-info" data-dismiss="modal" id="perform-group-delete">{{ _('Confirm') }}</button>
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal" id="perform-group-delete">{{ _('Confirm') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -214,23 +215,21 @@
|
|||
</ui-select>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="mode == 'grant'">
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="$parent.isAdmin"> {{ _("Is Admin") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="$parent.isAdmin"> {{ _("Is Admin") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="$parent.isModerator"> {{ _("Is Moderator") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="$parent.isModerator"> {{ _("Is Moderator") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% include "notifications.html" %}
|
||||
<div class="col-sm-12 col-md-12 main">
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
{% include "small_topbar.html" %}
|
||||
<ul class="breadcrumb" style="margin-bottom: 5px;">
|
||||
<li><a href="{{ url_for('view.home') }}">{{ _('Home') }}</a></li>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% include "notifications.html" %}
|
||||
<div class="col-sm-12 col-md-12 main">
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
{% include "small_topbar.html" %}
|
||||
<ul class="breadcrumb" style="margin-bottom: 5px;">
|
||||
<li><a href="{{ url_for('view.home') }}">{{ _('Home') }}</a></li>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% include "notifications.html" %}
|
||||
<div class="col-sm-12 col-md-12 main">
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
{% include "small_topbar.html" %}
|
||||
<ul class="breadcrumb" style="margin-bottom: 5px;">
|
||||
<li><a href="{{ url_for('view.home') }}">{{ _('Home') }}</a></li>
|
||||
|
|
@ -32,6 +32,24 @@
|
|||
</ui-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="isAdmin" ng-disabled="!isAdminEnabled"> {{ _("Is Admin") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-3 col-lg-offset-2">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="isModerator" ng-disabled="!isModeratorEnabled"> {{ _("Is Moderator") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-lg-10 col-lg-offset-2">
|
||||
<button type="submit" class="btn btn-primary" ng-disabled="!updateGroup.$valid || !validGrantInput"><i class="fa fa-fw fa-floppy-o" aria-hidden="true"></i>{{ _('Save') }}</button>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% include "notifications.html" %}
|
||||
<div class="col-sm-12 col-md-12 main">
|
||||
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
|
||||
{% include "small_topbar.html" %}
|
||||
<ul class="breadcrumb" style="margin-bottom: 5px;">
|
||||
<li><a href="{{ url_for('view.home') }}">{{ _('Home') }}</a></li>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ var _users = {};
|
|||
var _groups = {};
|
||||
var _acl_backends = {};
|
||||
var _users_array = [];
|
||||
var __promises = [];
|
||||
var __globals_promises = [];
|
||||
|
||||
var app = angular.module('MainApp', ['ngSanitize', 'ui.select', 'mgcrea.ngStrap', 'datatables']);
|
||||
|
|
@ -87,6 +86,38 @@ app.controller('AdminCtrl', ['$scope', '$http', '$q', '$scrollspy', 'DTOptionsBu
|
|||
});
|
||||
locals.push(l);
|
||||
}
|
||||
if ($scope.isAdmin) {
|
||||
var l = $http({
|
||||
url: '{{ url_for("api.acl_admins") }}',
|
||||
method: 'PUT',
|
||||
params: {
|
||||
memberName: '@'+$scope.name,
|
||||
backendName: $scope.acl_backend,
|
||||
},
|
||||
headers: { 'X-From-UI': true },
|
||||
})
|
||||
.catch(buiFail)
|
||||
.then(function(resp2) {
|
||||
notifAll(resp2.data);
|
||||
});
|
||||
locals.push(l);
|
||||
}
|
||||
if ($scope.isModerator) {
|
||||
var l = $http({
|
||||
url: '{{ url_for("api.acl_moderators") }}',
|
||||
method: 'PUT',
|
||||
params: {
|
||||
memberName: '@'+$scope.name,
|
||||
backendName: $scope.acl_backend,
|
||||
},
|
||||
headers: { 'X-From-UI': true },
|
||||
})
|
||||
.catch(buiFail)
|
||||
.then(function(resp2) {
|
||||
notifAll(resp2.data);
|
||||
});
|
||||
locals.push(l);
|
||||
}
|
||||
$q.all(locals).finally(function() {
|
||||
_authorization_groups();
|
||||
});
|
||||
|
|
@ -287,6 +318,27 @@ var _groups_table = $('#table-groups').DataTable( {
|
|||
return ret;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: null,
|
||||
render: function ( data, type, row ) {
|
||||
if (type === 'filter' || type === 'sort') {
|
||||
return data.roles;
|
||||
}
|
||||
var ret = '';
|
||||
$.each(data.roles, function(i, role) {
|
||||
inh = _groups[data.id][role+'_by'];
|
||||
if (inh) {
|
||||
ret += '<span data-toggle="tooltip" data-placement="auto top" title=\'{{ _("Inherited by: ") }}'+inh+'\' data-html="true">';
|
||||
}
|
||||
ret += '<span class="label label-warning">'+(inh ? '<em>' : '')+role+(inh ? '</em>' : '')+'</span>';
|
||||
if (inh) {
|
||||
ret += '</span>';
|
||||
}
|
||||
ret += ' ';
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
{
|
||||
data: 'members',
|
||||
render: function ( data, type, row ) {
|
||||
|
|
@ -374,14 +426,22 @@ var _users_table = $('#table-users').DataTable( {
|
|||
}
|
||||
},
|
||||
{
|
||||
data: 'roles',
|
||||
data: null,
|
||||
render: function ( data, type, row ) {
|
||||
if (type === 'filter' || type === 'sort') {
|
||||
return data;
|
||||
return data.roles;
|
||||
}
|
||||
var ret = '';
|
||||
$.each(data, function(i, role) {
|
||||
ret += '<span class="label label-warning">'+role+'</span> ';
|
||||
$.each(data.roles, function(i, role) {
|
||||
inh = _users[data.id][role+'_by'];
|
||||
if (inh) {
|
||||
ret += '<span data-toggle="tooltip" data-placement="auto top" title=\'{{ _("Inherited by: ") }}'+inh+'\' data-html="true">';
|
||||
}
|
||||
ret += '<span class="label label-warning">'+(inh ? '<em>' : '')+role+(inh ? '</em>' : '')+'</span>';
|
||||
if (inh) {
|
||||
ret += '</span>';
|
||||
}
|
||||
ret += ' ';
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -390,11 +450,23 @@ var _users_table = $('#table-users').DataTable( {
|
|||
data: 'groups',
|
||||
render: function ( data, type, row ) {
|
||||
if (type === 'filter' || type === 'sort') {
|
||||
return data;
|
||||
var ret = [];
|
||||
$.each(data, function(i, group) {
|
||||
ret.push(group.name);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
var ret = '';
|
||||
$.each(data, function(i, group) {
|
||||
ret += '<span class="label label-primary">'+group+'</span> ';
|
||||
var inh = group.inherit;
|
||||
if (inh) {
|
||||
ret += '<span data-toggle="tooltip" data-placement="auto top" title=\'{{ _("Inherited by: ") }}'+inh+'\' data-html="true">';
|
||||
}
|
||||
ret += '<span class="label label-primary">'+(inh ? '<em>' : '')+group.name+(inh ? '</em>' : '')+'</span>';
|
||||
if (inh) {
|
||||
ret += '</span>';
|
||||
}
|
||||
ret += ' ';
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -452,8 +524,8 @@ var _authorization_users = function() {
|
|||
$('#table-users-container').hide();
|
||||
var __usernames = [];
|
||||
var __top_promises = [];
|
||||
var __promises = [];
|
||||
var t = $.getJSON('{{ url_for("api.acl_grants") }}').done(function (grants) {
|
||||
__promises = [];
|
||||
$.each(grants, function(i, user) {
|
||||
__usernames.push(user.id);
|
||||
if (_users[user.id]) {
|
||||
|
|
@ -472,6 +544,8 @@ var _authorization_users = function() {
|
|||
backends: [user.backend],
|
||||
roles: [],
|
||||
groups: [],
|
||||
admin_by: null,
|
||||
moderator_by: null,
|
||||
grants: [user.grant],
|
||||
raw: [user],
|
||||
};
|
||||
|
|
@ -482,12 +556,14 @@ var _authorization_users = function() {
|
|||
p = $.getJSON('{{ url_for("api.acl_is_admin", member="") }}'+user.id).done(function (data) {
|
||||
if (data.admin) {
|
||||
_users[user.id]['roles'].push('admin');
|
||||
_users[user.id]['admin_by'] = data.inherit;
|
||||
}
|
||||
});
|
||||
__promises.push(p);
|
||||
p = $.getJSON('{{ url_for("api.acl_is_moderator", member="") }}'+user.id).done(function (data) {
|
||||
if (data.moderator) {
|
||||
_users[user.id]['roles'].push('moderator');
|
||||
_users[user.id]['moderator_by'] = data.inherit;
|
||||
}
|
||||
});
|
||||
__promises.push(p);
|
||||
|
|
@ -506,15 +582,17 @@ var _authorization_users = function() {
|
|||
});
|
||||
if (redraw) {
|
||||
$.when.apply( $, __globals_promises ).always(function() {
|
||||
_users_table.clear();
|
||||
_users_table.rows.add(_users_array).draw();
|
||||
_users_table.fixedHeader.adjust();
|
||||
$('#waiting-user-container').hide();
|
||||
$('#table-users-container').show();
|
||||
$.when.apply( $, __promises ).always(function() {
|
||||
_users_table.clear();
|
||||
_users_table.rows.add(_users_array).draw();
|
||||
_users_table.fixedHeader.adjust();
|
||||
$('#waiting-user-container').hide();
|
||||
$('#table-users-container').show();
|
||||
});
|
||||
});
|
||||
}
|
||||
$.when.apply( $, __top_promises ).done(function() {
|
||||
$.when.apply( $, __promises ).done(function() {
|
||||
$.when.apply( $, __promises ).always(function() {
|
||||
_users_array = [];
|
||||
$.each(_users, function(key, value) {
|
||||
_users_array.push(value);
|
||||
|
|
@ -536,6 +614,7 @@ var _authorization_groups = function() {
|
|||
$('#table-groups-container').hide();
|
||||
var __groupnames = [];
|
||||
var __top_promises = [];
|
||||
var __promises = [];
|
||||
var t = $.getJSON('{{ url_for("api.acl_groups") }}').done(function (groups) {
|
||||
$.each(groups, function(i, group) {
|
||||
__groupnames.push(group.id);
|
||||
|
|
@ -554,10 +633,27 @@ var _authorization_groups = function() {
|
|||
_groups[group.id] = {
|
||||
id: group.id,
|
||||
backends: [group.backend],
|
||||
roles: [],
|
||||
admin_by: null,
|
||||
moderator_by: null,
|
||||
members: group.members,
|
||||
grants: [group.grant],
|
||||
raw: [group],
|
||||
};
|
||||
var p = $.getJSON('{{ url_for("api.acl_is_admin", member="") }}@'+group.id).done(function (data) {
|
||||
if (data.admin) {
|
||||
_groups[group.id]['roles'].push('admin');
|
||||
_groups[group.id]['admin_by'] = data.inherit;
|
||||
}
|
||||
});
|
||||
__promises.push(p);
|
||||
p = $.getJSON('{{ url_for("api.acl_is_moderator", member="") }}@'+group.id).done(function (data) {
|
||||
if (data.moderator) {
|
||||
_groups[group.id]['roles'].push('moderator');
|
||||
_groups[group.id]['moderator_by'] = data.inherit;
|
||||
}
|
||||
});
|
||||
__promises.push(p);
|
||||
}
|
||||
});
|
||||
__top_promises.push(t);
|
||||
|
|
@ -573,24 +669,28 @@ var _authorization_groups = function() {
|
|||
});
|
||||
if (redraw) {
|
||||
$.when.apply( $, __globals_promises ).always(function() {
|
||||
_groups_table.clear();
|
||||
_groups_table.rows.add(_groups_array).draw();
|
||||
_groups_table.fixedHeader.adjust();
|
||||
$('#waiting-group-container').hide();
|
||||
$('#table-groups-container').show();
|
||||
$.when.apply( $, __promises ).always(function() {
|
||||
_groups_table.clear();
|
||||
_groups_table.rows.add(_groups_array).draw();
|
||||
_groups_table.fixedHeader.adjust();
|
||||
$('#waiting-group-container').hide();
|
||||
$('#table-groups-container').show();
|
||||
});
|
||||
});
|
||||
}
|
||||
$.when.apply( $, __top_promises ).done(function() {
|
||||
_groups_array = [];
|
||||
$.each(_groups, function(key, value) {
|
||||
_groups_array.push(value);
|
||||
});
|
||||
$.when.apply( $, __globals_promises ).always(function() {
|
||||
_groups_table.clear();
|
||||
_groups_table.rows.add(_groups_array).draw();
|
||||
_groups_table.fixedHeader.adjust();
|
||||
$('#waiting-group-container').hide();
|
||||
$('#table-groups-container').show();
|
||||
$.when.apply( $, __promises ).always(function() {
|
||||
_groups_array = [];
|
||||
$.each(_groups, function(key, value) {
|
||||
_groups_array.push(value);
|
||||
});
|
||||
$.when.apply( $, __globals_promises ).always(function() {
|
||||
_groups_table.clear();
|
||||
_groups_table.rows.add(_groups_array).draw();
|
||||
_groups_table.fixedHeader.adjust();
|
||||
$('#waiting-group-container').hide();
|
||||
$('#table-groups-container').show();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{% import 'macros.html' as macros %}
|
||||
{% set gpname = "@"+group %}
|
||||
|
||||
var _admin = function() {
|
||||
// do nothing
|
||||
|
|
@ -20,6 +21,10 @@ app.controller('AdminCtrl', ['$scope', '$http', '$q', '$scrollspy', 'DTOptionsBu
|
|||
$scope.grantValue = '{{ _("Loading, please wait...") }}';
|
||||
$scope.isLoading = true;
|
||||
$scope.orig = {};
|
||||
$scope.isAdmin = false;
|
||||
$scope.isAdminEnabled = false;
|
||||
$scope.isModerator = false;
|
||||
$scope.isModeratorEnabled = false;
|
||||
vm.updateGroup = {};
|
||||
vm.updateGroup.backendUsers = [];
|
||||
|
||||
|
|
@ -61,6 +66,19 @@ app.controller('AdminCtrl', ['$scope', '$http', '$q', '$scrollspy', 'DTOptionsBu
|
|||
});
|
||||
_g_promises.push(g);
|
||||
|
||||
$http.get('{{ url_for("api.acl_is_admin", backend=backend, member=gpname) }}', { headers: { 'X-From-UI': true } })
|
||||
.then(function (response) {
|
||||
$scope.isAdmin = response.data.admin;
|
||||
$scope.orig['admin'] = response.data.admin;
|
||||
$scope.isAdminEnabled = true;
|
||||
});
|
||||
$http.get('{{ url_for("api.acl_is_moderator", backend=backend, member=gpname) }}', { headers: { 'X-From-UI': true } })
|
||||
.then(function (response) {
|
||||
$scope.isModerator = response.data.moderator;
|
||||
$scope.orig['moderator'] = response.data.moderator;
|
||||
$scope.isModeratorEnabled = true;
|
||||
});
|
||||
|
||||
$q.all(_g_promises).finally(function () {
|
||||
var _all = _.map(vm.updateGroup.backendUsers, 'id');
|
||||
var missing = _.difference(vm.updateGroup.groupMembers, _all);
|
||||
|
|
@ -87,6 +105,44 @@ app.controller('AdminCtrl', ['$scope', '$http', '$q', '$scrollspy', 'DTOptionsBu
|
|||
submit.html(sav);
|
||||
submit.attr('disabled', false);
|
||||
};
|
||||
if ($scope.isAdmin !== $scope.orig.admin) {
|
||||
disableSubmit();
|
||||
var url = '{{ url_for("api.acl_admins", backend=backend, member=gpname) }}';
|
||||
var method = 'PUT';
|
||||
if (!$scope.isAdmin) {
|
||||
method = 'DELETE';
|
||||
}
|
||||
var p = $http({
|
||||
url: url,
|
||||
method: method,
|
||||
headers: { 'X-From-UI': true },
|
||||
})
|
||||
.catch(buiFail)
|
||||
.then(function(response) {
|
||||
$scope.orig.admin = $scope.isAdmin;
|
||||
notifAll(response.data);
|
||||
});
|
||||
promises.push(p);
|
||||
}
|
||||
if ($scope.isModerator !== $scope.orig.moderator) {
|
||||
disableSubmit();
|
||||
var url = '{{ url_for("api.acl_moderators", backend=backend, member=gpname) }}';
|
||||
var method = 'PUT';
|
||||
if (!$scope.isModerator) {
|
||||
method = 'DELETE';
|
||||
}
|
||||
var p = $http({
|
||||
url: url,
|
||||
method: method,
|
||||
headers: { 'X-From-UI': true },
|
||||
})
|
||||
.catch(buiFail)
|
||||
.then(function(response) {
|
||||
$scope.orig.moderator = $scope.isModerator;
|
||||
notifAll(response.data);
|
||||
});
|
||||
promises.push(p);
|
||||
}
|
||||
if ($scope.grantValue != $scope.orig.grantValue) {
|
||||
disableSubmit();
|
||||
var p = $http({
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
<div class="container-fluid">
|
||||
<div class="row" {% if ng_controller %}ng-controller="{{ ng_controller }} as pctrl"{% endif %}>
|
||||
{% if not live and not login and not about and not authentication and not authorization and not sessions -%}
|
||||
{% if not live and not login and not about -%}
|
||||
{% include "sidebar.html" %}
|
||||
{% else -%}
|
||||
{% set no_sidebar = True %}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div id="navbar-config">
|
||||
<h4>{{ _('Administration navigation') }}</h4>
|
||||
<ul class="nav nav-sidebar">
|
||||
<li {% if authentications %}class="active"{% endif %}><a href="{{ url_for('view.admin_authentications') }}"><i class="fa fa-fw fa-id-card-o" aria-hidden="true"></i> {{ _('Authentication') }}</a></li>
|
||||
<li {% if authorizations %}class="active"{% endif %}><a href="{{ url_for('view.admin_authorizations') }}"><i class="fa fa-fw fa-lock" aria-hidden="true"></i> {{ _('Authorization') }}</a></li>
|
||||
<li {% if authentications or sessions or authentication %}class="active"{% endif %}><a href="{{ url_for('view.admin_authentications') }}"><i class="fa fa-fw fa-id-card-o" aria-hidden="true"></i> {{ _('Authentication') }}</a></li>
|
||||
<li {% if authorizations or authorization %}class="active"{% endif %}><a href="{{ url_for('view.admin_authorizations') }}"><i class="fa fa-fw fa-lock" aria-hidden="true"></i> {{ _('Authorization') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue