1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 21:29:42 +02:00

Remove group permissions on delete event

This commit is contained in:
Harvey Kandola 2018-03-09 09:51:44 +00:00
parent 1c4a4424e5
commit 359e0e29eb
7 changed files with 236 additions and 142 deletions

10
.editorconfig Normal file
View file

@ -0,0 +1,10 @@
sample EditorConfig file
# indicate this is the root of the project
root = true
[*]
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
indent_size = 4

View file

@ -202,6 +202,7 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
return return
} }
// Delete group and associated membership data
_, err = h.Store.Group.Delete(ctx, g.RefID) _, err = h.Store.Group.Delete(ctx, g.RefID)
if err != nil { if err != nil {
ctx.Transaction.Rollback() ctx.Transaction.Rollback()
@ -210,6 +211,15 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
return return
} }
// Delete permissions associated with group
_, err = h.Store.Permission.DeleteGroupPermissions(ctx, groupID)
if err != nil {
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
ctx.Transaction.Commit() ctx.Transaction.Commit()
h.Store.Audit.Record(ctx, audit.EventTypeGroupDelete) h.Store.Audit.Record(ctx, audit.EventTypeGroupDelete)

View file

@ -289,3 +289,13 @@ func (s Scope) DeleteSpaceCategoryPermissions(ctx domain.RequestContext, spaceID
return b.DeleteWhere(ctx.Transaction, sql) return b.DeleteWhere(ctx.Transaction, sql)
} }
// DeleteGroupPermissions removes all roles for the specified group
func (s Scope) DeleteGroupPermissions(ctx domain.RequestContext, groupID string) (rows int64, err error) {
b := mysql.BaseQuery{}
sql := fmt.Sprintf("DELETE FROM permission WHERE orgid='%s' AND who='role' AND whoid='%s'",
ctx.OrgID, groupID)
return b.DeleteWhere(ctx.Transaction, sql)
}

View file

@ -88,17 +88,18 @@ type PermissionStorer interface {
AddPermissions(ctx RequestContext, r permission.Permission, actions ...permission.Action) (err error) AddPermissions(ctx RequestContext, r permission.Permission, actions ...permission.Action) (err error)
GetUserSpacePermissions(ctx RequestContext, spaceID string) (r []permission.Permission, err error) GetUserSpacePermissions(ctx RequestContext, spaceID string) (r []permission.Permission, err error)
GetSpacePermissions(ctx RequestContext, spaceID string) (r []permission.Permission, err error) GetSpacePermissions(ctx RequestContext, spaceID string) (r []permission.Permission, err error)
DeleteSpacePermissions(ctx RequestContext, spaceID string) (rows int64, err error)
DeleteUserSpacePermissions(ctx RequestContext, spaceID, userID string) (rows int64, err error)
DeleteUserPermissions(ctx RequestContext, userID string) (rows int64, err error)
DeleteCategoryPermissions(ctx RequestContext, categoryID string) (rows int64, err error)
DeleteSpaceCategoryPermissions(ctx RequestContext, spaceID string) (rows int64, err error)
GetCategoryPermissions(ctx RequestContext, catID string) (r []permission.Permission, err error) GetCategoryPermissions(ctx RequestContext, catID string) (r []permission.Permission, err error)
GetCategoryUsers(ctx RequestContext, catID string) (u []user.User, err error) GetCategoryUsers(ctx RequestContext, catID string) (u []user.User, err error)
GetUserCategoryPermissions(ctx RequestContext, userID string) (r []permission.Permission, err error) GetUserCategoryPermissions(ctx RequestContext, userID string) (r []permission.Permission, err error)
GetUserDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error) GetUserDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error)
GetDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error) GetDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error)
DeleteDocumentPermissions(ctx RequestContext, documentID string) (rows int64, err error) DeleteDocumentPermissions(ctx RequestContext, documentID string) (rows int64, err error)
DeleteSpacePermissions(ctx RequestContext, spaceID string) (rows int64, err error)
DeleteUserSpacePermissions(ctx RequestContext, spaceID, userID string) (rows int64, err error)
DeleteUserPermissions(ctx RequestContext, userID string) (rows int64, err error)
DeleteCategoryPermissions(ctx RequestContext, categoryID string) (rows int64, err error)
DeleteSpaceCategoryPermissions(ctx RequestContext, spaceID string) (rows int64, err error)
DeleteGroupPermissions(ctx RequestContext, groupID string) (rows int64, err error)
} }
// UserStorer defines required methods for user management // UserStorer defines required methods for user management

View file

@ -33,7 +33,9 @@ export default Component.extend(AuthProvider, ModalMixin, {
}, },
loadGroups() { loadGroups() {
this.get('groupSvc').getAll().then((groups) => { this.get('groupSvc')
.getAll()
.then(groups => {
this.set('groups', groups); this.set('groups', groups);
}); });
}, },
@ -46,14 +48,18 @@ export default Component.extend(AuthProvider, ModalMixin, {
let groupId = this.get('membersGroup.id'); let groupId = this.get('membersGroup.id');
let searchText = this.get('searchText'); let searchText = this.get('searchText');
this.get('groupSvc').getGroupMembers(groupId).then((members) => { this.get('groupSvc')
.getGroupMembers(groupId)
.then(members => {
this.set('members', members); this.set('members', members);
this.get('userSvc').matchUsers(searchText).then((users) => { this.get('userSvc')
users.forEach((user) => { .matchUsers(searchText)
.then(users => {
users.forEach(user => {
let m = members.findBy('userId', user.get('id')); let m = members.findBy('userId', user.get('id'));
user.set('isMember', is.not.undefined(m)); user.set('isMember', is.not.undefined(m));
}) });
if (this.get('showMembers') && members.length === 0) { if (this.get('showMembers') && members.length === 0) {
this.set('showMembers', false); this.set('showMembers', false);
@ -67,7 +73,11 @@ export default Component.extend(AuthProvider, ModalMixin, {
actions: { actions: {
onOpenGroupModal() { onOpenGroupModal() {
this.modalOpen("#add-group-modal", {"show": true}, '#new-group-name'); this.modalOpen(
'#add-group-modal',
{ show: true },
'#new-group-name'
);
}, },
onAddGroup(e) { onAddGroup(e) {
@ -76,21 +86,29 @@ export default Component.extend(AuthProvider, ModalMixin, {
let newGroup = this.get('newGroup'); let newGroup = this.get('newGroup');
if (is.empty(newGroup.name)) { if (is.empty(newGroup.name)) {
$("#new-group-name").addClass("is-invalid").focus(); $('#new-group-name')
.addClass('is-invalid')
.focus();
return; return;
} }
this.get('groupSvc').add(newGroup).then(() => { this.get('groupSvc')
.add(newGroup)
.then(() => {
this.loadGroups(); this.loadGroups();
}); });
this.modalClose("#add-group-modal"); this.modalClose('#add-group-modal');
this.setDefaults(); this.setDefaults();
}, },
onShowDeleteModal(groupId) { onShowDeleteModal(groupId) {
this.set('deleteGroup', { name: '', id: groupId }); this.set('deleteGroup', { name: '', id: groupId });
this.modalOpen("#delete-group-modal", {"show": true}, '#delete-group-name'); this.modalOpen(
'#delete-group-modal',
{ show: true },
'#delete-group-name'
);
}, },
onDeleteGroup(e) { onDeleteGroup(e) {
@ -99,22 +117,33 @@ export default Component.extend(AuthProvider, ModalMixin, {
let deleteGroup = this.get('deleteGroup'); let deleteGroup = this.get('deleteGroup');
let group = this.get('groups').findBy('id', deleteGroup.id); let group = this.get('groups').findBy('id', deleteGroup.id);
if (is.empty(deleteGroup.name) || group.get('name') !== deleteGroup.name) { if (
$("#delete-group-name").addClass("is-invalid").focus(); is.empty(deleteGroup.name) ||
group.get('name') !== deleteGroup.name
) {
$('#delete-group-name')
.addClass('is-invalid')
.focus();
return; return;
} }
this.get('groupSvc').delete(deleteGroup.id).then(() => { this.get('groupSvc')
.delete(deleteGroup.id)
.then(() => {
this.loadGroups(); this.loadGroups();
}); });
this.modalClose("#delete-group-modal"); this.modalClose('#delete-group-modal');
this.set('deleteGroup', { name: '', id: '' }); this.set('deleteGroup', { name: '', id: '' });
}, },
onShowEditModal(groupId) { onShowEditModal(groupId) {
this.set('editGroup', this.get('groups').findBy('id', groupId)); this.set('editGroup', this.get('groups').findBy('id', groupId));
this.modalOpen("#edit-group-modal", {"show": true}, '#edit-group-name'); this.modalOpen(
'#edit-group-modal',
{ show: true },
'#edit-group-name'
);
}, },
onEditGroup(e) { onEditGroup(e) {
@ -123,21 +152,29 @@ export default Component.extend(AuthProvider, ModalMixin, {
let group = this.get('editGroup'); let group = this.get('editGroup');
if (is.empty(group.get('name'))) { if (is.empty(group.get('name'))) {
$("#edit-group-name").addClass("is-invalid").focus(); $('#edit-group-name')
.addClass('is-invalid')
.focus();
return; return;
} }
this.get('groupSvc').update(group).then(() => { this.get('groupSvc')
.update(group)
.then(() => {
this.load(); this.load();
}); });
this.modalClose("#edit-group-modal"); this.modalClose('#edit-group-modal');
this.set('editGroup', null); this.set('editGroup', null);
}, },
onShowMembersModal(groupId) { onShowMembersModal(groupId) {
this.set('membersGroup', this.get('groups').findBy('id', groupId)); this.set('membersGroup', this.get('groups').findBy('id', groupId));
this.modalOpen("#group-members-modal", {"show": true}, '#group-members-search'); this.modalOpen(
'#group-members-modal',
{ show: true },
'#group-members-search'
);
this.set('members', null); this.set('members', null);
this.set('users', null); this.set('users', null);
this.set('showMembers', true); this.set('showMembers', true);
@ -146,7 +183,9 @@ export default Component.extend(AuthProvider, ModalMixin, {
}, },
onSearch() { onSearch() {
debounce(this, function() { debounce(
this,
function() {
let searchText = this.get('searchText'); let searchText = this.get('searchText');
this.loadGroupInfo(); this.loadGroupInfo();
@ -157,13 +196,17 @@ export default Component.extend(AuthProvider, ModalMixin, {
this.set('showMembers', true); this.set('showMembers', true);
this.set('showUsers', false); this.set('showUsers', false);
} }
}, 250); },
250
);
}, },
onLeaveGroup(userId) { onLeaveGroup(userId) {
let groupId = this.get('membersGroup.id'); let groupId = this.get('membersGroup.id');
this.get('groupSvc').leave(groupId, userId).then(() => { this.get('groupSvc')
.leave(groupId, userId)
.then(() => {
this.loadGroupInfo(); this.loadGroupInfo();
this.loadGroups(); this.loadGroups();
}); });
@ -172,7 +215,9 @@ export default Component.extend(AuthProvider, ModalMixin, {
onJoinGroup(userId) { onJoinGroup(userId) {
let groupId = this.get('membersGroup.id'); let groupId = this.get('membersGroup.id');
this.get('groupSvc').join(groupId, userId).then(() => { this.get('groupSvc')
.join(groupId, userId)
.then(() => {
this.loadGroupInfo(); this.loadGroupInfo();
this.loadGroups(); this.loadGroups();
}); });

View file

@ -16,7 +16,7 @@ var Router = EmberRouter.extend({
location: config.locationType location: config.locationType
}); });
export default Router.map(function () { export default Router.map(function() {
this.route('folders', { this.route('folders', {
path: '/' path: '/'
}); });
@ -25,28 +25,39 @@ export default Router.map(function () {
path: 'dashboard' path: 'dashboard'
}); });
this.route('folder', { this.route(
'folder',
{
path: 's/:folder_id/:folder_slug' path: 's/:folder_id/:folder_slug'
}, function() { },
function() {
this.route('category', { this.route('category', {
path: 'category' path: 'category'
})
}); });
}
);
this.route('document', { this.route(
'document',
{
path: 's/:folder_id/:folder_slug/d/:document_id/:document_slug' path: 's/:folder_id/:folder_slug/d/:document_id/:document_slug'
}, function () { },
function() {
this.route('section', { this.route('section', {
path: 'section/:page_id' path: 'section/:page_id'
}); });
this.route('block', { this.route('block', {
path: 'block/:block_id' path: 'block/:block_id'
}); });
}); }
);
this.route('customize', { this.route(
'customize',
{
path: 'settings' path: 'settings'
}, function () { },
function() {
this.route('general', { this.route('general', {
path: 'general' path: 'general'
}); });
@ -71,7 +82,8 @@ export default Router.map(function () {
this.route('audit', { this.route('audit', {
path: 'audit' path: 'audit'
}); });
}); }
);
this.route('setup', { this.route('setup', {
path: 'setup' path: 'setup'
@ -81,9 +93,12 @@ export default Router.map(function () {
path: 'secure/:token' path: 'secure/:token'
}); });
this.route('auth', { this.route(
'auth',
{
path: 'auth' path: 'auth'
}, function () { },
function() {
this.route('sso', { this.route('sso', {
path: 'sso/:token' path: 'sso/:token'
}); });
@ -105,7 +120,8 @@ export default Router.map(function () {
this.route('share', { this.route('share', {
path: 'share/:id/:slug/:serial' path: 'share/:id/:slug/:serial'
}); });
}); }
);
this.route('profile', { this.route('profile', {
path: 'profile' path: 'profile'

View file

@ -11,7 +11,7 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header">Add Group</div> <div class="modal-header">Add Group</div>
<div class="modal-body"> <div class="modal-body">
<form onsubmit={{action 'onAddGroup'}}> <form onsubmit= {{action 'onAddGroup'}}>
<div class="form-group"> <div class="form-group">
<label for="new-group-name">Name</label> <label for="new-group-name">Name</label>
{{focus-input id="new-group-name" type="text" class="form-control mousetrap" placeholder="Enter group name" value=newGroup.name}} {{focus-input id="new-group-name" type="text" class="form-control mousetrap" placeholder="Enter group name" value=newGroup.name}}
@ -25,7 +25,7 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" onclick={{action 'onAddGroup'}}>Add</button> <button type="button" class="btn btn-success" onclick= {{action 'onAddGroup'}}>Add</button>
</div> </div>
</div> </div>
</div> </div>
@ -56,7 +56,9 @@
</div> </div>
</div> </div>
{{else}} {{else}}
<div class="margin-top-30"><i>No groups</i></div> <div class="margin-top-30">
<i>No groups</i>
</div>
{{/each}} {{/each}}
</div> </div>
@ -65,7 +67,7 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header">Delete Group</div> <div class="modal-header">Delete Group</div>
<div class="modal-body"> <div class="modal-body">
<form onsubmit={{action 'onDeleteGroup'}}> <form onsubmit= {{action 'onDeleteGroup'}}>
<p>Are you sure you want to delete this group?</p> <p>Are you sure you want to delete this group?</p>
<div class="form-group"> <div class="form-group">
<label for="delete-group-name">Please type group name to confirm</label> <label for="delete-group-name">Please type group name to confirm</label>
@ -76,7 +78,7 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-danger" onclick={{action 'onDeleteGroup'}}>Delete</button> <button type="button" class="btn btn-danger" onclick= {{action 'onDeleteGroup'}}>Delete</button>
</div> </div>
</div> </div>
</div> </div>
@ -87,7 +89,7 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header">Edit Group</div> <div class="modal-header">Edit Group</div>
<div class="modal-body"> <div class="modal-body">
<form onsubmit={{action 'onEditGroup'}}> <form onsubmit= {{action 'onEditGroup'}}>
<div class="form-group"> <div class="form-group">
<label for="edit-group-name">Name</label> <label for="edit-group-name">Name</label>
{{input id="edit-group-name" type="text" class="form-control mousetrap" placeholder="Enter group name" value=editGroup.name}} {{input id="edit-group-name" type="text" class="form-control mousetrap" placeholder="Enter group name" value=editGroup.name}}
@ -101,7 +103,7 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" onclick={{action 'onEditGroup'}}>Save</button> <button type="button" class="btn btn-success" onclick= {{action 'onEditGroup'}}>Save</button>
</div> </div>
</div> </div>
</div> </div>