mirror of
https://github.com/documize/community.git
synced 2025-07-19 21:29:42 +02:00
new permission endpoint
WIP
This commit is contained in:
parent
ae05cacf3f
commit
5f7c6d211f
32 changed files with 334 additions and 249 deletions
|
@ -714,7 +714,7 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
|
||||||
response.WriteEmpty(w)
|
response.WriteEmpty(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPermissions returns permissions for the requested space, for all users.
|
// GetPermissions returns permissions for alll users for given space.
|
||||||
func (h *Handler) GetPermissions(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) GetPermissions(w http.ResponseWriter, r *http.Request) {
|
||||||
method := "space.GetPermissions"
|
method := "space.GetPermissions"
|
||||||
ctx := domain.GetRequestContext(r)
|
ctx := domain.GetRequestContext(r)
|
||||||
|
@ -730,12 +730,21 @@ func (h *Handler) GetPermissions(w http.ResponseWriter, r *http.Request) {
|
||||||
response.WriteServerError(w, method, err)
|
response.WriteServerError(w, method, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(perms) == 0 {
|
if len(perms) == 0 {
|
||||||
perms = []space.Permission{}
|
perms = []space.Permission{}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.WriteJSON(w, perms)
|
userPerms := make(map[string][]space.Permission)
|
||||||
|
for _, p := range perms {
|
||||||
|
userPerms[p.WhoID] = append(userPerms[p.WhoID], p)
|
||||||
|
}
|
||||||
|
|
||||||
|
records := []space.PermissionRecord{}
|
||||||
|
for _, up := range userPerms {
|
||||||
|
records = append(records, space.DecodeUserPermissions(up))
|
||||||
|
}
|
||||||
|
|
||||||
|
response.WriteJSON(w, records)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserPermissions returns permissions for the requested space, for current user.
|
// GetUserPermissions returns permissions for the requested space, for current user.
|
||||||
|
@ -754,12 +763,12 @@ func (h *Handler) GetUserPermissions(w http.ResponseWriter, r *http.Request) {
|
||||||
response.WriteServerError(w, method, err)
|
response.WriteServerError(w, method, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(perms) == 0 {
|
if len(perms) == 0 {
|
||||||
perms = []space.Permission{}
|
perms = []space.Permission{}
|
||||||
}
|
}
|
||||||
|
|
||||||
response.WriteJSON(w, perms)
|
record := space.DecodeUserPermissions(perms)
|
||||||
|
response.WriteJSON(w, record)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptInvitation records the fact that a user has completed space onboard process.
|
// AcceptInvitation records the fact that a user has completed space onboard process.
|
||||||
|
|
|
@ -208,7 +208,7 @@ func (s Scope) AddPermission(ctx domain.RequestContext, r space.Permission) (err
|
||||||
// AddPermissions inserts records into permission database table, one per action.
|
// AddPermissions inserts records into permission database table, one per action.
|
||||||
func (s Scope) AddPermissions(ctx domain.RequestContext, r space.Permission, actions ...space.PermissionAction) (err error) {
|
func (s Scope) AddPermissions(ctx domain.RequestContext, r space.Permission, actions ...space.PermissionAction) (err error) {
|
||||||
for _, a := range actions {
|
for _, a := range actions {
|
||||||
r.Action = string(a)
|
r.Action = a
|
||||||
s.AddPermission(ctx, r)
|
s.AddPermission(ctx, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,12 +242,12 @@ func (s Scope) GetUserPermissions(ctx domain.RequestContext, spaceID string) (r
|
||||||
func (s Scope) GetPermissions(ctx domain.RequestContext, spaceID string) (r []space.Permission, err error) {
|
func (s Scope) GetPermissions(ctx domain.RequestContext, spaceID string) (r []space.Permission, err error) {
|
||||||
err = s.Runtime.Db.Select(&r, `
|
err = s.Runtime.Db.Select(&r, `
|
||||||
SELECT id, orgid, who, whoid, action, scope, location, refid
|
SELECT id, orgid, who, whoid, action, scope, location, refid
|
||||||
FROM permission WHERE orgid=? AND location='space' AND refid=? AND who='user' AND (whoid=? OR whoid='')
|
FROM permission WHERE orgid=? AND location='space' AND refid=? AND who='user'
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT p.id, p.orgid, p.who, p.whoid, p.action, p.scope, p.location, p.refid
|
SELECT p.id, p.orgid, p.who, p.whoid, p.action, p.scope, p.location, p.refid
|
||||||
FROM permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.location='space' AND p.refid=?
|
FROM permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.location='space' AND p.refid=?
|
||||||
AND p.who='role' AND (r.userid=? OR r.userid='')`,
|
AND p.who='role'`,
|
||||||
ctx.OrgID, spaceID, ctx.UserID, ctx.OrgID, spaceID, ctx.OrgID)
|
ctx.OrgID, spaceID, ctx.OrgID, spaceID)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
err = nil
|
err = nil
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
if (!this.get('isEditor')) {
|
if (!this.get('permissions.documentEdit')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ export default Ember.Component.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('tagz', tagz);
|
this.set('tagz', tagz);
|
||||||
this.set('canAdd', this.get('isEditor') && this.get('tagz').get('length') < 3);
|
this.set('canAdd', this.get('permissions.documentEdit') && this.get('tagz').get('length') < 3);
|
||||||
},
|
},
|
||||||
|
|
||||||
didUpdateAttrs() {
|
didUpdateAttrs() {
|
||||||
this.set('canAdd', this.get('isEditor') && this.get('tagz').get('length') < 3);
|
this.set('canAdd', this.get('permissions.documentEdit') && this.get('tagz').get('length') < 3);
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default Ember.Component.extend({
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.set('canCreate', this.get('folderService').get('canEditCurrentFolder'));
|
this.set('canCreate', this.get('permissions.documentAdd'));
|
||||||
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
|
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
folderName: '',
|
folderName: '',
|
||||||
hasNameError: computed.empty('folderName'),
|
hasNameError: computed.empty('folderName'),
|
||||||
editMode: false,
|
editMode: false,
|
||||||
isEditor: false,
|
|
||||||
|
|
||||||
keyUp(e) {
|
keyUp(e) {
|
||||||
if (e.keyCode === 27) { // escape key
|
if (e.keyCode === 27) { // escape key
|
||||||
|
|
|
@ -14,10 +14,6 @@ import NotifierMixin from '../../mixins/notifier';
|
||||||
import TooltipMixin from '../../mixins/tooltip';
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
import AuthMixin from '../../mixins/auth';
|
import AuthMixin from '../../mixins/auth';
|
||||||
|
|
||||||
const {
|
|
||||||
computed
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
||||||
folderService: Ember.inject.service('folder'),
|
folderService: Ember.inject.service('folder'),
|
||||||
session: Ember.inject.service(),
|
session: Ember.inject.service(),
|
||||||
|
@ -25,16 +21,11 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
||||||
showToolbar: false,
|
showToolbar: false,
|
||||||
folder: {},
|
folder: {},
|
||||||
busy: false,
|
busy: false,
|
||||||
isFolderOwner: computed.equal('folder.userId', 'session.user.id'),
|
|
||||||
moveFolderId: "",
|
moveFolderId: "",
|
||||||
drop: null,
|
drop: null,
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id"));
|
console.log(this.get('permissions'));
|
||||||
|
|
||||||
let show = this.get('session.authenticated') || this.get('isFolderOwner') || this.get('hasSelectedDocuments') || this.get('folderService').get('canEditCurrentFolder');
|
|
||||||
this.set('showToolbar', show);
|
|
||||||
|
|
||||||
let targets = _.reject(this.get('folders'), {
|
let targets = _.reject(this.get('folders'), {
|
||||||
id: this.get('folder').get('id')
|
id: this.get('folder').get('id')
|
||||||
});
|
});
|
||||||
|
@ -44,11 +35,17 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
if (this.get('hasSelectedDocuments')) {
|
if (this.get('hasSelectedDocuments')) {
|
||||||
|
if (this.get('permissions.documentMove')) {
|
||||||
this.addTooltip(document.getElementById("move-documents-button"));
|
this.addTooltip(document.getElementById("move-documents-button"));
|
||||||
|
}
|
||||||
|
if (this.get('permissions.documentDelete')) {
|
||||||
this.addTooltip(document.getElementById("delete-documents-button"));
|
this.addTooltip(document.getElementById("delete-documents-button"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.get('isFolderOwner')) {
|
if (this.get('permissions.spaceOwner')) {
|
||||||
this.addTooltip(document.getElementById("space-delete-button"));
|
this.addTooltip(document.getElementById("space-delete-button"));
|
||||||
|
}
|
||||||
|
if (this.get('permissions.spaceManage')) {
|
||||||
this.addTooltip(document.getElementById("space-settings-button"));
|
this.addTooltip(document.getElementById("space-settings-button"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,75 +26,62 @@ export default Ember.Component.extend(NotifierMixin, {
|
||||||
this.get('userService').getAll().then((users) => {
|
this.get('userService').getAll().then((users) => {
|
||||||
this.set('users', users);
|
this.set('users', users);
|
||||||
|
|
||||||
var folderPermissions = [];
|
// set up users
|
||||||
|
let folderPermissions = [];
|
||||||
|
|
||||||
users.forEach((user) => {
|
users.forEach((user) => {
|
||||||
let isActive = user.get('active');
|
let isActive = user.get('active');
|
||||||
|
|
||||||
let u = {
|
let u = {
|
||||||
fullname: user.get('fullname'),
|
|
||||||
orgId: this.get('folder.orgId'),
|
orgId: this.get('folder.orgId'),
|
||||||
who: 'user',
|
folderId: this.get('folder.id'),
|
||||||
whoId: user.get('id'),
|
userId: user.get('id'),
|
||||||
location: 'space',
|
fullname: user.get('fullname'),
|
||||||
scope: 'object',
|
|
||||||
refId: this.get('folder.id'),
|
|
||||||
spaceView: false,
|
spaceView: false,
|
||||||
spaceManage: false,
|
spaceManage: false,
|
||||||
spaceOwner: false,
|
spaceOwner: false,
|
||||||
docAdd: false,
|
documentAdd: false,
|
||||||
docEdit: false,
|
documentEdit: false,
|
||||||
docDelete: false,
|
documentDelete: false,
|
||||||
docMove: false,
|
documentMove: false,
|
||||||
docCopy: false,
|
documentCopy: false,
|
||||||
docTemplate: false,
|
documentTemplate: false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
folderPermissions.pushObject(u);
|
let data = this.get('store').normalize('space-permission', u)
|
||||||
|
folderPermissions.pushObject(this.get('store').push(data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var u = {
|
// set up Everyone user
|
||||||
fullname: " Everyone",
|
let u = {
|
||||||
orgId: this.get('folder.orgId'),
|
orgId: this.get('folder.orgId'),
|
||||||
who: 'user',
|
folderId: this.get('folder.id'),
|
||||||
whoId: '',
|
userId: '',
|
||||||
location: 'space',
|
fullname: ' Everyone',
|
||||||
scope: 'object',
|
|
||||||
refId: this.get('folder.id'),
|
|
||||||
spaceView: false,
|
spaceView: false,
|
||||||
spaceManage: false,
|
spaceManage: false,
|
||||||
spaceOwner: false,
|
spaceOwner: false,
|
||||||
docAdd: false,
|
documentAdd: false,
|
||||||
docEdit: false,
|
documentEdit: false,
|
||||||
docDelete: false,
|
documentDelete: false,
|
||||||
docMove: false,
|
documentMove: false,
|
||||||
docCopy: false,
|
documentCopy: false,
|
||||||
docTemplate: false,
|
documentTemplate: false
|
||||||
};
|
};
|
||||||
|
|
||||||
folderPermissions.pushObject(u);
|
let data = this.get('store').normalize('space-permission', u)
|
||||||
|
folderPermissions.pushObject(this.get('store').push(data));
|
||||||
|
|
||||||
this.get('folderService').getPermissions(this.get('folder.id')).then((permissions) => {
|
this.get('folderService').getPermissions(this.get('folder.id')).then((permissions) => {
|
||||||
permissions.forEach((permission, index) => { // eslint-disable-line no-unused-vars
|
permissions.forEach((permission, index) => { // eslint-disable-line no-unused-vars
|
||||||
var folderPermission = folderPermissions.findBy('userId', permission.get('userId'));
|
let user = folderPermissions.findBy('userId', permission.get('userId'));
|
||||||
if (is.not.undefined(folderPermission)) {
|
if (is.not.undefined(user)) {
|
||||||
Ember.setProperties(folderPermission, {
|
Ember.setProperties(user, permission);
|
||||||
orgId: permission.get('orgId'),
|
|
||||||
folderId: permission.get('folderId'),
|
|
||||||
canEdit: permission.get('canEdit'),
|
|
||||||
canView: permission.get('canView'),
|
|
||||||
canViewPrevious: permission.get('canView')
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
folderPermissions.map((permission) => {
|
|
||||||
let data = this.get('store').normalize('folder-permission', permission);
|
|
||||||
return this.get('store').push(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('permissions', folderPermissions.sortBy('fullname'));
|
this.set('permissions', folderPermissions.sortBy('fullname'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -107,48 +94,44 @@ export default Ember.Component.extend(NotifierMixin, {
|
||||||
actions: {
|
actions: {
|
||||||
setPermissions() {
|
setPermissions() {
|
||||||
let message = this.getDefaultInvitationMessage();
|
let message = this.getDefaultInvitationMessage();
|
||||||
let folder = this.get('folder');
|
// let folder = this.get('folder');
|
||||||
let permissions = this.get('permissions');
|
let permissions = this.get('permissions');
|
||||||
|
|
||||||
this.get('permissions').forEach((permission, index) => { // eslint-disable-line no-unused-vars
|
permissions.forEach((permission, index) => { // eslint-disable-line no-unused-vars
|
||||||
Ember.set(permission, 'canView', $("#canView-" + permission.userId).prop('checked'));
|
Ember.set(permission, 'spaceView', $("#space-role-view-" + permission.get('userId')).prop('checked'));
|
||||||
Ember.set(permission, 'canEdit', $("#canEdit-" + permission.userId).prop('checked'));
|
Ember.set(permission, 'spaceManage', $("#space-role-manage-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'spaceOwner', $("#space-role-owner-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentAdd', $("#doc-role-add-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentEdit', $("#doc-role-edit-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentDelete', $("#doc-role-delete-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentMove', $("#doc-role-move-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentCopy', $("#doc-role-copy-" + permission.get('userId')).prop('checked'));
|
||||||
|
Ember.set(permission, 'documentTemplate', $("#doc-role-template-" + permission.get('userId')).prop('checked'));
|
||||||
});
|
});
|
||||||
|
|
||||||
var data = permissions.map((obj) => {
|
let payload = { Message: message, Permissions: permissions };
|
||||||
let permission = {
|
console.log(payload);
|
||||||
'orgId': obj.orgId,
|
|
||||||
'folderId': obj.folderId,
|
|
||||||
'userId': obj.userId,
|
|
||||||
'canEdit': obj.canEdit,
|
|
||||||
'canView': obj.canView
|
|
||||||
};
|
|
||||||
|
|
||||||
return permission;
|
// this.get('folderService').savePermissions(folder.get('id'), payload).then(() => {
|
||||||
});
|
// this.showNotification('Saved permissions');
|
||||||
|
// });
|
||||||
|
|
||||||
var payload = { Message: message, Roles: data };
|
// var hasEveryone = _.find(data, function (permission) {
|
||||||
|
// return permission.userId === "" && (permission.canView || permission.canEdit);
|
||||||
|
// });
|
||||||
|
|
||||||
this.get('folderService').savePermissions(folder.get('id'), payload).then(() => {
|
// if (is.not.undefined(hasEveryone)) {
|
||||||
this.showNotification('Saved permissions');
|
// folder.markAsPublic();
|
||||||
});
|
// } else {
|
||||||
|
// if (data.length > 1) {
|
||||||
|
// folder.markAsRestricted();
|
||||||
|
// } else {
|
||||||
|
// folder.markAsPrivate();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
var hasEveryone = _.find(data, function (permission) {
|
// this.get('folderService').save(folder).then(function () {
|
||||||
return permission.userId === "" && (permission.canView || permission.canEdit);
|
// });
|
||||||
});
|
|
||||||
|
|
||||||
if (is.not.undefined(hasEveryone)) {
|
|
||||||
folder.markAsPublic();
|
|
||||||
} else {
|
|
||||||
if (data.length > 1) {
|
|
||||||
folder.markAsRestricted();
|
|
||||||
} else {
|
|
||||||
folder.markAsPrivate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.get('folderService').save(folder).then(function () {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,13 +11,12 @@
|
||||||
|
|
||||||
import Model from 'ember-data/model';
|
import Model from 'ember-data/model';
|
||||||
import attr from 'ember-data/attr';
|
import attr from 'ember-data/attr';
|
||||||
// import { belongsTo, hasMany } from 'ember-data/relationships';
|
import { belongsTo } from 'ember-data/relationships';
|
||||||
|
|
||||||
export default Model.extend({
|
export default Model.extend({
|
||||||
orgId: attr('string'),
|
orgId: attr('string'),
|
||||||
folderId: attr('string'),
|
folderId: attr('string'),
|
||||||
userId: attr('string'),
|
userId: attr('string'),
|
||||||
fullname: attr('string'),
|
fullname: attr('string'),
|
||||||
canView: attr('boolean', { defaultValue: false }),
|
permissions: belongsTo('space-permission')
|
||||||
canEdit: attr('boolean', { defaultValue: false })
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,10 +15,17 @@ import attr from 'ember-data/attr';
|
||||||
|
|
||||||
export default Model.extend({
|
export default Model.extend({
|
||||||
orgId: attr('string'),
|
orgId: attr('string'),
|
||||||
who: attr('string'),
|
folderId: attr('string'),
|
||||||
whoId: attr('string'),
|
userId: attr('string'),
|
||||||
action: attr('string'),
|
fullname: attr('string'), // client-side usage only, not from API
|
||||||
scope: attr('string'),
|
|
||||||
location: attr('string'),
|
spaceView: attr('boolean'),
|
||||||
refId: attr('string')
|
spaceManage: attr('boolean'),
|
||||||
|
spaceOwner: attr('boolean'),
|
||||||
|
documentAdd: attr('boolean'),
|
||||||
|
documentEdit: attr('boolean'),
|
||||||
|
documentDelete: attr('boolean'),
|
||||||
|
documentMove: attr('boolean'),
|
||||||
|
documentCopy: attr('boolean'),
|
||||||
|
documentTemplate: attr('boolean')
|
||||||
});
|
});
|
|
@ -30,7 +30,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
pages: this.get('documentService').getPages(this.modelFor('document').document.get('id')),
|
pages: this.get('documentService').getPages(this.modelFor('document').document.get('id')),
|
||||||
links: this.modelFor('document').links,
|
links: this.modelFor('document').links,
|
||||||
sections: this.modelFor('document').sections,
|
sections: this.modelFor('document').sections,
|
||||||
isEditor: this.get('folderService').get('canEditCurrentFolder')
|
permissions: this.get('folderService').get('permissions')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
{{document/sidebar-zone folders=model.folders folder=model.folder document=model.document
|
{{document/sidebar-zone folders=model.folders folder=model.folder document=model.document
|
||||||
pages=model.pages sections=model.section links=model.links isEditor=model.isEditor tab=tab
|
pages=model.pages sections=model.section links=model.links permissions=model.permissions tab=tab
|
||||||
onDocumentDelete=(action 'onDocumentDelete') onSaveTemplate=(action 'onSaveTemplate')
|
onDocumentDelete=(action 'onDocumentDelete') onSaveTemplate=(action 'onSaveTemplate')
|
||||||
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange') onGotoPage=(action 'onGotoPage')}}
|
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange')
|
||||||
|
onGotoPage=(action 'onGotoPage')}}
|
||||||
{{/layout/zone-sidebar}}
|
{{/layout/zone-sidebar}}
|
||||||
{{#layout/zone-content}}
|
{{#layout/zone-content}}
|
||||||
<div id="zone-document-content" class="zone-document-content">
|
<div id="zone-document-content" class="zone-document-content">
|
||||||
|
@ -15,9 +16,9 @@
|
||||||
</div>
|
</div>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{document/document-heading document=model.document isEditor=model.isEditor onSaveDocument=(action 'onSaveDocument')}}
|
{{document/document-heading document=model.document permissions=model.permissions onSaveDocument=(action 'onSaveDocument')}}
|
||||||
{{document/document-view document=model.document links=model.links pages=model.pages
|
{{document/document-view document=model.document links=model.links pages=model.pages
|
||||||
folder=model.folder folders=model.folders sections=model.sections isEditor=model.isEditor pageId=pageId
|
folder=model.folder folders=model.folders sections=model.sections permissions=model.permissions pageId=pageId
|
||||||
onSavePage=(action 'onSavePage') onInsertSection=(action 'onInsertSection')
|
onSavePage=(action 'onSavePage') onInsertSection=(action 'onInsertSection')
|
||||||
onSavePageAsBlock=(action 'onSavePageAsBlock') onDeleteBlock=(action 'onDeleteBlock') onGotoPage=(action 'onGotoPage')
|
onSavePageAsBlock=(action 'onSavePageAsBlock') onDeleteBlock=(action 'onDeleteBlock') onGotoPage=(action 'onGotoPage')
|
||||||
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
this.set('folder', folder);
|
this.set('folder', folder);
|
||||||
|
|
||||||
this.get('folderService').setCurrentFolder(folder).then(() => {
|
this.get('folderService').setCurrentFolder(folder).then(() => {
|
||||||
this.set('isEditor', this.get('folderService').get('canEditCurrentFolder'));
|
this.set('permissions', this.get('folderService').get('permissions'));
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -49,7 +49,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
folder: this.get('folder'),
|
folder: this.get('folder'),
|
||||||
document: this.get('document'),
|
document: this.get('document'),
|
||||||
page: this.get('pageId'),
|
page: this.get('pageId'),
|
||||||
isEditor: this.get('isEditor'),
|
permissions: this.get('permissions'),
|
||||||
links: this.get('linkService').getDocumentLinks(this.get('documentId')),
|
links: this.get('linkService').getDocumentLinks(this.get('documentId')),
|
||||||
sections: this.get('sectionService').getAll()
|
sections: this.get('sectionService').getAll()
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
folders: this.modelFor('document').folders,
|
folders: this.modelFor('document').folders,
|
||||||
folder: this.modelFor('document').folder,
|
folder: this.modelFor('document').folder,
|
||||||
document: this.modelFor('document').document,
|
document: this.modelFor('document').document,
|
||||||
isEditor: this.get('folderService').get('canEditCurrentFolder'),
|
permissions: this.get('folderService').get('permissions'),
|
||||||
links: this.modelFor('document').links,
|
links: this.modelFor('document').links,
|
||||||
sections: this.modelFor('document').sections,
|
sections: this.modelFor('document').sections,
|
||||||
page: this.get('documentService').getPage(this.modelFor('document').document.get('id'), params.page_id),
|
page: this.get('documentService').getPage(this.modelFor('document').document.get('id'), params.page_id),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</div>
|
</div>
|
||||||
{{document/document-heading document=model.document isEditor=false}}
|
{{document/document-heading document=model.document permissions=model.permissions}}
|
||||||
{{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
{{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folder: this.modelFor('folder').folder,
|
folder: this.modelFor('folder').folder,
|
||||||
isEditor: this.modelFor('folder').isEditor,
|
isEditor: this.modelFor('folder').isEditor,
|
||||||
isFolderOwner: this.modelFor('folder').isFolderOwner,
|
permissions: this.modelFor('folder').permissions,
|
||||||
folders: this.modelFor('folder').folders,
|
folders: this.modelFor('folder').folders,
|
||||||
documents: this.modelFor('folder').documents,
|
documents: this.modelFor('folder').documents,
|
||||||
templates: this.modelFor('folder').templates
|
templates: this.modelFor('folder').templates
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
{{#layout/zone-container}}
|
{{#layout/zone-container}}
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
{{folder/sidebar-zone folders=model.folders folder=model.folder isFolderOwner=model.isFolderOwner isEditor=model.isEditor tab=tab
|
{{folder/sidebar-zone folders=model.folders folder=model.folder
|
||||||
onAddSpace=(action 'onAddSpace')}}
|
permissions=model.permissions tab=tab onAddSpace=(action 'onAddSpace')}}
|
||||||
{{/layout/zone-sidebar}}
|
{{/layout/zone-sidebar}}
|
||||||
{{#layout/zone-content}}
|
{{#layout/zone-content}}
|
||||||
{{folder/folder-heading folder=model.folder isFolderOwner=model.isFolderOwner isEditor=model.isEditor}}
|
{{folder/folder-heading folder=model.folder permissions=model.permissions}}
|
||||||
{{folder/folder-toolbar folders=model.folders isFolderOwner=model.isFolderOwner folder=model.folder hasSelectedDocuments=hasSelectedDocuments
|
|
||||||
|
{{folder/folder-toolbar folders=model.folders folder=model.folder
|
||||||
|
permissions=model.permissions hasSelectedDocuments=hasSelectedDocuments
|
||||||
onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument')}}
|
onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument')}}
|
||||||
|
|
||||||
{{folder/documents-list documents=model.documents folders=model.folders folder=model.folder templates=model.templates
|
{{folder/documents-list documents=model.documents folders=model.folders folder=model.folder templates=model.templates
|
||||||
isFolderOwner=model.isFolderOwner isEditor=model.isEditor selectedDocuments=(mut selectedDocuments)
|
permissions=model.permissions selectedDocuments=(mut selectedDocuments)
|
||||||
onDeleteSpace=(action 'onDeleteSpace') onImport=(action 'onImport')}}
|
onDeleteSpace=(action 'onDeleteSpace') onImport=(action 'onImport')}}
|
||||||
{{/layout/zone-content}}
|
{{/layout/zone-content}}
|
||||||
{{/layout/zone-container}}
|
{{/layout/zone-container}}
|
|
@ -26,10 +26,8 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
this.get('folderService').getFolder(this.get('folderId')).then((folder) => {
|
this.get('folderService').getFolder(this.get('folderId')).then((folder) => {
|
||||||
this.set('folder', folder);
|
this.set('folder', folder);
|
||||||
|
|
||||||
this.get('folderService').setCurrentFolder(folder).then(() => {
|
this.get('folderService').setCurrentFolder(folder).then((data) => {
|
||||||
this.set('isEditor', this.get('folderService').get('canEditCurrentFolder'));
|
this.set('permissions', data);
|
||||||
this.set('isFolderOwner', this.get('session.user.id') === folder.get('userId'));
|
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,8 +37,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
model(params) {
|
model(params) {
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folder: this.get('folder'),
|
folder: this.get('folder'),
|
||||||
isEditor: this.get('isEditor'),
|
permissions: this.get('permissions'),
|
||||||
isFolderOwner: this.get('isFolderOwner'),
|
|
||||||
folders: this.get('folderService').getAll(),
|
folders: this.get('folderService').getAll(),
|
||||||
documents: this.get('documentService').getAllByFolder(params.folder_id),
|
documents: this.get('documentService').getAllByFolder(params.folder_id),
|
||||||
templates: this.get('templateService').getSavedTemplates(params.folder_id)
|
templates: this.get('templateService').getSavedTemplates(params.folder_id)
|
||||||
|
|
|
@ -18,8 +18,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folder: this.modelFor('folder').folder,
|
folder: this.modelFor('folder').folder,
|
||||||
isEditor: this.modelFor('folder').isEditor,
|
permissions: this.modelFor('folder').permissions,
|
||||||
isFolderOwner: this.modelFor('folder').isFolderOwner,
|
|
||||||
folders: this.modelFor('folder').folders
|
folders: this.modelFor('folder').folders
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default BaseService.extend({
|
||||||
|
|
||||||
// selected folder
|
// selected folder
|
||||||
currentFolder: null,
|
currentFolder: null,
|
||||||
canEditCurrentFolder: false,
|
permissions: {},
|
||||||
|
|
||||||
// Add a new folder.
|
// Add a new folder.
|
||||||
add(payload) {
|
add(payload) {
|
||||||
|
@ -114,7 +114,6 @@ export default BaseService.extend({
|
||||||
|
|
||||||
// reloads and caches folders.
|
// reloads and caches folders.
|
||||||
reload() {
|
reload() {
|
||||||
|
|
||||||
return this.get('ajax').request(`space`, {
|
return this.get('ajax').request(`space`, {
|
||||||
method: "GET"
|
method: "GET"
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
|
@ -137,7 +136,7 @@ export default BaseService.extend({
|
||||||
let data = [];
|
let data = [];
|
||||||
|
|
||||||
data = response.map((obj) => {
|
data = response.map((obj) => {
|
||||||
let data = this.get('store').normalize('user-permission', obj);
|
let data = this.get('store').normalize('space-permission', obj);
|
||||||
return this.get('store').push(data);
|
return this.get('store').push(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -171,7 +170,6 @@ export default BaseService.extend({
|
||||||
let folderId = folder.get('id');
|
let folderId = folder.get('id');
|
||||||
this.set('currentFolder', folder);
|
this.set('currentFolder', folder);
|
||||||
this.get('localStorage').storeSessionItem("folder", folderId);
|
this.get('localStorage').storeSessionItem("folder", folderId);
|
||||||
this.set('canEditCurrentFolder', false);
|
|
||||||
|
|
||||||
let userId = this.get('sessionService.user.id');
|
let userId = this.get('sessionService.user.id');
|
||||||
if (userId === "") {
|
if (userId === "") {
|
||||||
|
@ -180,37 +178,11 @@ export default BaseService.extend({
|
||||||
|
|
||||||
let url = `space/${folderId}/permissions/user`;
|
let url = `space/${folderId}/permissions/user`;
|
||||||
|
|
||||||
return this.get('ajax').request(url).then((folderPermissions) => {
|
return this.get('ajax').request(url).then((response) => {
|
||||||
// safety check
|
let data = this.get('store').normalize('space-permission', response);
|
||||||
this.set('canEditCurrentFolder', false);
|
let data2 = this.get('store').push(data);
|
||||||
|
this.set('permissions', data2);
|
||||||
if (folderPermissions.length === 0) {
|
return data2;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = [];
|
|
||||||
|
|
||||||
folderPermissions.forEach((item) => {
|
|
||||||
if (item.folderId === folderId) {
|
|
||||||
result.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let canEdit = false;
|
|
||||||
|
|
||||||
result.forEach((permission) => {
|
|
||||||
if (permission.userId === userId) {
|
|
||||||
canEdit = permission.canEdit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permission.userId === "" && !canEdit) {
|
|
||||||
canEdit = permission.canEdit;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ember.run(() => {
|
|
||||||
this.set('canEditCurrentFolder', canEdit && this.get('sessionService.authenticated'));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{#unless editMode}}
|
{{#unless editMode}}
|
||||||
<div class="document-heading {{if isEditor 'cursor-pointer'}}" onclick={{if isEditor (action 'toggleEdit')}}>
|
<div class="document-heading {{if permissions.documentEdit 'cursor-pointer'}}" onclick={{if permissions.documentEdit (action 'toggleEdit')}}>
|
||||||
<h1 class="doc-title">{{document.name}}</h1>
|
<h1 class="doc-title">{{document.name}}</h1>
|
||||||
<div class="doc-excerpt">{{document.excerpt}}</div>
|
<div class="doc-excerpt">{{document.excerpt}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<a href="{{ appMeta.endpoint }}/public/attachments/{{ appMeta.orgId }}/{{ a.id }}">
|
<a href="{{ appMeta.endpoint }}/public/attachments/{{ appMeta.orgId }}/{{ a.id }}">
|
||||||
<span class="file">{{ a.filename }}</span>
|
<span class="file">{{ a.filename }}</span>
|
||||||
</a>
|
</a>
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="action round-button-mono">
|
<div class="action round-button-mono">
|
||||||
<i class="material-icons color-gray delete-attachment-{{a.id}}" title="Delete" {{action 'onConfirmDelete' a.id a.filename}}>delete</i>
|
<i class="material-icons color-gray delete-attachment-{{a.id}}" title="Delete" {{action 'onConfirmDelete' a.id a.filename}}>delete</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="round-button-mono {{if (is-equal tab 'attachments') 'selected'}}" {{action 'onChangeTab' 'attachments'}}>
|
<div class="round-button-mono {{if (is-equal tab 'attachments') 'selected'}}" {{action 'onChangeTab' 'attachments'}}>
|
||||||
<i class="material-icons">attach_file</i>
|
<i class="material-icons">attach_file</i>
|
||||||
</div>
|
</div>
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<div class="margin-top-20"></div>
|
<div class="margin-top-20"></div>
|
||||||
<div class="round-button-mono {{if (is-equal tab 'activity') 'selected'}}" {{action 'onChangeTab' 'activity'}}>
|
<div class="round-button-mono {{if (is-equal tab 'activity') 'selected'}}" {{action 'onChangeTab' 'activity'}}>
|
||||||
<i class="material-icons">timeline</i>
|
<i class="material-icons">timeline</i>
|
||||||
|
@ -22,21 +22,21 @@
|
||||||
{{#if document.template}}
|
{{#if document.template}}
|
||||||
<div class="template-header">Template</div>
|
<div class="template-header">Template</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{document/tag-editor documentTags=document.tags isEditor=isEditor onChange=(action 'onTagChange')}}
|
{{document/tag-editor documentTags=document.tags permissions=permissions onChange=(action 'onTagChange')}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar-wrapper">
|
<div class="sidebar-wrapper">
|
||||||
{{#if (is-equal tab 'index')}}
|
{{#if (is-equal tab 'index')}}
|
||||||
{{document/sidebar-view-index document=document folder=folder pages=pages page=page isEditor=isEditor
|
{{document/sidebar-view-index document=document folder=folder pages=pages page=page permissions=permissions
|
||||||
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange') onGotoPage=(action 'onGotoPage')}}
|
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange') onGotoPage=(action 'onGotoPage')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (is-equal tab 'attachments')}}
|
{{#if (is-equal tab 'attachments')}}
|
||||||
{{document/sidebar-view-attachments document=document isEditor=isEditor}}
|
{{document/sidebar-view-attachments document=document permissions=permissions}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (is-equal tab 'activity')}}
|
{{#if (is-equal tab 'activity')}}
|
||||||
{{document/sidebar-view-activity document=document pages=pages isEditor=isEditor}}
|
{{document/sidebar-view-activity document=document pages=pages permissions=permissions}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
<li class="item" id="pin-document-button">Pin</li>
|
<li class="item" id="pin-document-button">Pin</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentEdit}}
|
||||||
<li class="item">
|
<li class="item">
|
||||||
{{#link-to 'document.history'}}History{{/link-to}}
|
{{#link-to 'document.history'}}History{{/link-to}}
|
||||||
</li>
|
</li>
|
||||||
|
@ -63,14 +63,14 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentTemplate}}
|
||||||
<li class="item" id="save-template-button">Template</li>
|
<li class="item" id="save-template-button">Template</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<li class="item" id="print-document-button" {{action 'onPrintDocument'}}>Print</li>
|
<li class="item" id="print-document-button" {{action 'onPrintDocument'}}>Print</li>
|
||||||
|
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentDelete}}
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li class="item danger" id="delete-document-button">Delete</li>
|
<li class="item danger" id="delete-document-button">Delete</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -90,13 +90,17 @@
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentDelete}}
|
||||||
{{#if menuOpen}}
|
{{#if menuOpen}}
|
||||||
{{#dropdown-dialog target="delete-document-button" position="bottom left" button="Delete" color="flat-red" onAction=(action 'onDeleteDocument')}}
|
{{#dropdown-dialog target="delete-document-button" position="bottom left" button="Delete" color="flat-red" onAction=(action 'onDeleteDocument')}}
|
||||||
<p>Are you sure you want to delete this document?</p>
|
<p>Are you sure you want to delete this document?</p>
|
||||||
<p>There is no undo, so be careful.</p>
|
<p>There is no undo, so be careful.</p>
|
||||||
{{/dropdown-dialog}}
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if permissions.documentTemplate}}
|
||||||
|
{{#if menuOpen}}
|
||||||
{{#dropdown-dialog target="save-template-button" position="bottom left" button="Save as Template" color="flat-green" onAction=(action 'onSaveTemplate') focusOn="new-template-name" }}
|
{{#dropdown-dialog target="save-template-button" position="bottom left" button="Save as Template" color="flat-green" onAction=(action 'onSaveTemplate') focusOn="new-template-name" }}
|
||||||
<div class="input-control">
|
<div class="input-control">
|
||||||
<label>Name</label>
|
<label>Name</label>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{folder/start-document folder=folder templates=templates isEditor=isEditor onImport=(action 'onImport') onHideDocumentWizard=(action 'onHideDocumentWizard')}}
|
{{folder/start-document folder=folder templates=templates permissions=permissions onImport=(action 'onImport') onHideDocumentWizard=(action 'onHideDocumentWizard')}}
|
||||||
|
|
||||||
{{#if emptyState}}
|
{{#if emptyState}}
|
||||||
{{#if canCreate}}
|
{{#if canCreate}}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{#unless editMode}}
|
{{#unless editMode}}
|
||||||
<div class="folder-heading {{if isFolderOwner 'cursor-pointer'}}" onclick={{if isFolderOwner (action 'toggleEdit')}}>
|
<div class="folder-heading {{if permissions.spaceOwner 'cursor-pointer'}}" onclick={{if permissions.spaceOwner (action 'toggleEdit')}}>
|
||||||
<h1 class="folder-title">{{folder.name}}</h1>
|
<h1 class="folder-title">{{folder.name}}</h1>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
{{#if showToolbar}}
|
<div class="pull-right hidden-xs hidden-sm">
|
||||||
<div class="pull-right hidden-xs hidden-sm">
|
|
||||||
{{#if hasSelectedDocuments}}
|
{{#if hasSelectedDocuments}}
|
||||||
|
|
||||||
|
{{#if permissions.documentMove}}
|
||||||
<div class="round-button button-blue" id="move-documents-button" data-tooltip="Move documents" data-tooltip-position="top center">
|
<div class="round-button button-blue" id="move-documents-button" data-tooltip="Move documents" data-tooltip-position="top center">
|
||||||
<i class="material-icons">folder</i>
|
<i class="material-icons">folder</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-gap"></div>
|
|
||||||
<div class="round-button button-red" id="delete-documents-button" data-tooltip="Delete documents" data-tooltip-position="top center">
|
|
||||||
<i class="material-icons">delete</i>
|
|
||||||
</div>
|
|
||||||
{{#dropdown-dialog target="delete-documents-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'deleteDocuments')}}
|
|
||||||
<p>Are you sure you want to delete selected documents?</p>
|
|
||||||
<p>There is no undo!</p>
|
|
||||||
{{/dropdown-dialog}}
|
|
||||||
{{#dropdown-dialog target="move-documents-button" position="bottom right" button="Move" color="flat-blue" onAction=(action 'moveDocuments')}}
|
{{#dropdown-dialog target="move-documents-button" position="bottom right" button="Move" color="flat-blue" onAction=(action 'moveDocuments')}}
|
||||||
<p class="heading">Select destination space</p>
|
<p class="heading">Select destination space</p>
|
||||||
<ul class="move-document-options">
|
<ul class="move-document-options">
|
||||||
|
@ -27,22 +20,38 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
{{/dropdown-dialog}}
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if permissions.documentDelete}}
|
||||||
|
<div class="button-gap"></div>
|
||||||
|
<div class="round-button button-red" id="delete-documents-button" data-tooltip="Delete documents" data-tooltip-position="top center">
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</div>
|
||||||
|
{{#dropdown-dialog target="delete-documents-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'deleteDocuments')}}
|
||||||
|
<p>Are you sure you want to delete selected documents?</p>
|
||||||
|
<p>There is no undo!</p>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if isFolderOwner}}
|
|
||||||
|
{{#if permissions.spaceManage}}
|
||||||
{{#link-to 'folder.settings' folder.id folder.slug}}{{model.document.name}}
|
{{#link-to 'folder.settings' folder.id folder.slug}}{{model.document.name}}
|
||||||
<div class="round-button button-gray" id="space-settings-button" data-tooltip="Manage permissions" data-tooltip-position="top center">
|
<div class="round-button button-gray" id="space-settings-button" data-tooltip="Manage permissions" data-tooltip-position="top center">
|
||||||
<i class="material-icons">settings</i>
|
<i class="material-icons">settings</i>
|
||||||
</div>
|
</div>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if permissions.spaceOwner}}
|
||||||
<div class="button-gap"></div>
|
<div class="button-gap"></div>
|
||||||
<div class="round-button button-gray" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
|
<div class="round-button button-gray" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
|
||||||
<div class="margin-top-35"></div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="margin-top-35" />
|
||||||
<div class="margin-bottom-20 clearfix" />
|
<div class="margin-bottom-20 clearfix" />
|
||||||
|
|
|
@ -11,25 +11,25 @@
|
||||||
<div class="permission-name-cell">{{permission.fullname}}</div>
|
<div class="permission-name-cell">{{permission.fullname}}</div>
|
||||||
<div class="permission-roles-cell">
|
<div class="permission-roles-cell">
|
||||||
<span class="role-category">Space: </span>
|
<span class="role-category">Space: </span>
|
||||||
<input type="checkbox" id="space-role-view-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="space-role-view-{{permission.userId}}" checked={{permission.spaceView}} />
|
||||||
<label for="space-role-view-{{permission.userId}}">view</label>
|
<label for="space-role-view-{{permission.userId}}">view</label>
|
||||||
<input type="checkbox" id="space-role-manage-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="space-role-manage-{{permission.userId}}" checked={{permission.spaceManage}} />
|
||||||
<label for="space-role-manage-{{permission.userId}}">manage</label>
|
<label for="space-role-manage-{{permission.userId}}">manage</label>
|
||||||
<input type="checkbox" id="space-role-owner-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="space-role-owner-{{permission.userId}}" checked={{permission.spaceOwner}} />
|
||||||
<label for="space-role-owner-{{permission.userId}}">owner</label>
|
<label for="space-role-owner-{{permission.userId}}">owner</label>
|
||||||
|
|
||||||
<span class="role-category">Document: </span>
|
<span class="role-category">Document: </span>
|
||||||
<input type="checkbox" id="doc-role-add-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-add-{{permission.userId}}" checked={{permission.documentAdd}} />
|
||||||
<label for="doc-role-add-{{permission.userId}}">create</label>
|
<label for="doc-role-add-{{permission.userId}}">create</label>
|
||||||
<input type="checkbox" id="doc-role-edit-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-edit-{{permission.userId}}" checked={{permission.documentEdit}} />
|
||||||
<label for="doc-role-edit-{{permission.userId}}">edit</label>
|
<label for="doc-role-edit-{{permission.userId}}">edit</label>
|
||||||
<input type="checkbox" id="doc-role-delete-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-delete-{{permission.userId}}" checked={{permission.documentDelete}} />
|
||||||
<label for="doc-role-delete-{{permission.userId}}">delete</label>
|
<label for="doc-role-delete-{{permission.userId}}">delete</label>
|
||||||
<input type="checkbox" id="doc-role-move-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-move-{{permission.userId}}" checked={{permission.documentMove}} />
|
||||||
<label for="doc-role-move-{{permission.userId}}">move</label>
|
<label for="doc-role-move-{{permission.userId}}">move</label>
|
||||||
<input type="checkbox" id="doc-role-copy-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-copy-{{permission.userId}}" checked={{permission.documentCopy}} />
|
||||||
<label for="doc-role-copy-{{permission.userId}}">copy</label>
|
<label for="doc-role-copy-{{permission.userId}}">copy</label>
|
||||||
<input type="checkbox" id="doc-role-template-{{permission.userId}}" checked={{permission.canView}} />
|
<input type="checkbox" id="doc-role-template-{{permission.userId}}" checked={{permission.documentTemplate}} />
|
||||||
<label for="doc-role-template-{{permission.userId}}">templates</label>
|
<label for="doc-role-template-{{permission.userId}}">templates</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="margin-top-20"></div>
|
<div class="margin-top-20"></div>
|
||||||
|
|
||||||
{{#if session.authenticated}}
|
{{#if session.authenticated}}
|
||||||
{{#if isFolderOwner}}
|
{{#if permissions.spaceManage}}
|
||||||
{{#if isAuthProviderDocumize}}
|
{{#if isAuthProviderDocumize}}
|
||||||
<div class="round-button-mono {{if (is-equal tab 'share') 'selected'}}" {{action 'onChangeTab' 'share'}}>
|
<div class="round-button-mono {{if (is-equal tab 'share') 'selected'}}" {{action 'onChangeTab' 'share'}}>
|
||||||
<i class="material-icons">person_add</i>
|
<i class="material-icons">person_add</i>
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
<div class="sidebar-wrapper">
|
<div class="sidebar-wrapper">
|
||||||
{{#if (is-equal tab 'index')}}
|
{{#if (is-equal tab 'index')}}
|
||||||
{{folder/sidebar-folders-list folders=folders folder=folder isFolderOwner=isFolderOwner onAddSpace=(action 'onAddSpace')}}
|
{{folder/sidebar-folders-list folders=folders folder=folder permissions=permissions onAddSpace=(action 'onAddSpace')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (is-equal tab 'share')}}
|
{{#if (is-equal tab 'share')}}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<ul class="template-list">
|
<ul class="template-list">
|
||||||
{{#each savedTemplates key="id" as |template|}}
|
{{#each savedTemplates key="id" as |template|}}
|
||||||
<li class="item">
|
<li class="item">
|
||||||
{{#if isEditor}}
|
{{#if permissions.documentTemplate}}
|
||||||
{{#unless template.locked}}
|
{{#unless template.locked}}
|
||||||
<div class="template-actions">
|
<div class="template-actions">
|
||||||
<i class="material-icons" {{action 'editTemplate' template}}>mode_edit</i>
|
<i class="material-icons" {{action 'editTemplate' template}}>mode_edit</i>
|
||||||
|
|
116
model/space/permissions.go
Normal file
116
model/space/permissions.go
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
package space
|
||||||
|
|
||||||
|
// PermissionRecord represents space permissions for a user on a space.
|
||||||
|
// This data structure is made from database permission records for the space,
|
||||||
|
// and it is designed to be sent to HTTP clients (web, mobile).
|
||||||
|
type PermissionRecord struct {
|
||||||
|
OrgID string `json:"orgId"`
|
||||||
|
SpaceID string `json:"folderId"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
SpaceView bool `json:"spaceView"`
|
||||||
|
SpaceManage bool `json:"spaceManage"`
|
||||||
|
SpaceOwner bool `json:"spaceOwner"`
|
||||||
|
DocumentAdd bool `json:"documentAdd"`
|
||||||
|
DocumentEdit bool `json:"documentEdit"`
|
||||||
|
DocumentDelete bool `json:"documentDelete"`
|
||||||
|
DocumentMove bool `json:"documentMove"`
|
||||||
|
DocumentCopy bool `json:"documentCopy"`
|
||||||
|
DocumentTemplate bool `json:"documentTemplate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeUserPermissions returns a flat, usable permission summary record
|
||||||
|
// from multiple user permission records for a given space.
|
||||||
|
func DecodeUserPermissions(perm []Permission) (r PermissionRecord) {
|
||||||
|
r = PermissionRecord{}
|
||||||
|
|
||||||
|
if len(perm) > 0 {
|
||||||
|
r.OrgID = perm[0].OrgID
|
||||||
|
r.UserID = perm[0].WhoID
|
||||||
|
r.SpaceID = perm[0].RefID
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range perm {
|
||||||
|
switch p.Action {
|
||||||
|
case SpaceView:
|
||||||
|
r.SpaceView = true
|
||||||
|
case SpaceManage:
|
||||||
|
r.SpaceManage = true
|
||||||
|
case SpaceOwner:
|
||||||
|
r.SpaceOwner = true
|
||||||
|
|
||||||
|
case DocumentAdd:
|
||||||
|
r.DocumentAdd = true
|
||||||
|
case DocumentEdit:
|
||||||
|
r.DocumentEdit = true
|
||||||
|
case DocumentDelete:
|
||||||
|
r.DocumentDelete = true
|
||||||
|
case DocumentMove:
|
||||||
|
r.DocumentMove = true
|
||||||
|
case DocumentCopy:
|
||||||
|
r.DocumentCopy = true
|
||||||
|
case DocumentTemplate:
|
||||||
|
r.DocumentTemplate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeUserPermissions returns multiple user permission records
|
||||||
|
// for a given space, using flat permission summary record.
|
||||||
|
func EncodeUserPermissions(r PermissionRecord) (perm []Permission) {
|
||||||
|
if r.SpaceView {
|
||||||
|
perm = append(perm, encodeRecord(r, SpaceView))
|
||||||
|
}
|
||||||
|
if r.SpaceManage {
|
||||||
|
perm = append(perm, encodeRecord(r, SpaceManage))
|
||||||
|
}
|
||||||
|
if r.SpaceOwner {
|
||||||
|
perm = append(perm, encodeRecord(r, SpaceOwner))
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.DocumentAdd {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentAdd))
|
||||||
|
}
|
||||||
|
if r.DocumentEdit {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentEdit))
|
||||||
|
}
|
||||||
|
if r.DocumentDelete {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentDelete))
|
||||||
|
}
|
||||||
|
if r.DocumentMove {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentMove))
|
||||||
|
}
|
||||||
|
if r.DocumentCopy {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentCopy))
|
||||||
|
}
|
||||||
|
if r.DocumentTemplate {
|
||||||
|
perm = append(perm, encodeRecord(r, DocumentTemplate))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates standard permission record representing user permissions for a space.
|
||||||
|
func encodeRecord(r PermissionRecord, a PermissionAction) (p Permission) {
|
||||||
|
p = Permission{}
|
||||||
|
p.OrgID = r.OrgID
|
||||||
|
p.Who = "user"
|
||||||
|
p.WhoID = r.UserID
|
||||||
|
p.Location = "space"
|
||||||
|
p.RefID = r.SpaceID
|
||||||
|
p.Action = a
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ type Permission struct {
|
||||||
OrgID string `json:"-"`
|
OrgID string `json:"-"`
|
||||||
Who string `json:"who"` // user, role
|
Who string `json:"who"` // user, role
|
||||||
WhoID string `json:"whoId"` // either a user or role ID
|
WhoID string `json:"whoId"` // either a user or role ID
|
||||||
Action string `json:"action"` // view, edit, delete
|
Action PermissionAction `json:"action"` // view, edit, delete
|
||||||
Scope string `json:"scope"` // object, table
|
Scope string `json:"scope"` // object, table
|
||||||
Location string `json:"location"` // table name
|
Location string `json:"location"` // table name
|
||||||
RefID string `json:"refId"` // id of row in table / blank when scope=table
|
RefID string `json:"refId"` // id of row in table / blank when scope=table
|
||||||
|
@ -77,7 +77,7 @@ const (
|
||||||
// SpaceManage action means you can add, remove users, set permissions, but not delete that space
|
// SpaceManage action means you can add, remove users, set permissions, but not delete that space
|
||||||
SpaceManage PermissionAction = "manage"
|
SpaceManage PermissionAction = "manage"
|
||||||
// SpaceOwner action means you can delete a space and do all SpaceManage functions
|
// SpaceOwner action means you can delete a space and do all SpaceManage functions
|
||||||
SpaceOwner PermissionAction = "owner"
|
SpaceOwner PermissionAction = "own"
|
||||||
|
|
||||||
// DocumentAdd action means you can create/upload documents to a space
|
// DocumentAdd action means you can create/upload documents to a space
|
||||||
DocumentAdd PermissionAction = "doc-add"
|
DocumentAdd PermissionAction = "doc-add"
|
||||||
|
@ -93,16 +93,6 @@ const (
|
||||||
DocumentTemplate PermissionAction = "doc-template"
|
DocumentTemplate PermissionAction = "doc-template"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Role determines user permissions for a folder.
|
|
||||||
type Role struct {
|
|
||||||
model.BaseEntityObfuscated
|
|
||||||
OrgID string `json:"-"`
|
|
||||||
LabelID string `json:"folderId"`
|
|
||||||
UserID string `json:"userId"`
|
|
||||||
CanView bool `json:"canView"`
|
|
||||||
CanEdit bool `json:"canEdit"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Viewer details who can see a particular space
|
// Viewer details who can see a particular space
|
||||||
type Viewer struct {
|
type Viewer struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@ -144,9 +134,9 @@ type NewSpaceRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasPermission checks if action matches one of the required actions?
|
// HasPermission checks if action matches one of the required actions?
|
||||||
func HasPermission(action string, actions ...PermissionAction) bool {
|
func HasPermission(action PermissionAction, actions ...PermissionAction) bool {
|
||||||
for _, a := range actions {
|
for _, a := range actions {
|
||||||
if action == string(a) {
|
if action == a {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue