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

Persist space permissions for groups and users

This commit is contained in:
sauls8t 2018-03-03 17:46:29 +00:00
parent 0d39f7251e
commit 7ccb3b4658
16 changed files with 320 additions and 157 deletions

View file

@ -1,4 +1,3 @@
gui/public/tinymce/**
gui/public/tinymce/
gui/public/tinymce

View file

@ -28,8 +28,10 @@ import (
"github.com/documize/community/domain"
"github.com/documize/community/domain/mail"
"github.com/documize/community/model/audit"
"github.com/documize/community/model/group"
"github.com/documize/community/model/permission"
"github.com/documize/community/model/space"
"github.com/documize/community/model/user"
)
// Handler contains the runtime information such as logging and database.
@ -122,47 +124,79 @@ func (h *Handler) SetSpacePermissions(w http.ResponseWriter, r *http.Request) {
hasEveryoneRole := false
roleCount := 0
// Permissions can be assigned to both groups and individual users.
// Pre-fetch users with group membership to help us work out
// if user belongs to a group with permissions.
groupMembers, err := h.Store.Group.GetMembers(ctx)
if err != nil {
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
for _, perm := range model.Permissions {
perm.OrgID = ctx.OrgID
perm.SpaceID = id
isGroup := perm.Who == permission.GroupPermission
groupRecords := []group.Record{}
if isGroup {
// get group records for just this group
groupRecords = group.FilterGroupRecords(groupMembers, perm.WhoID)
}
// Ensure the space owner always has access!
if perm.UserID == ctx.UserID {
if (!isGroup && perm.WhoID == ctx.UserID) ||
(isGroup && group.UserHasGroupMembership(groupMembers, perm.WhoID, ctx.UserID)) {
me = true
}
// Only persist if there is a role!
if permission.HasAnyPermission(perm) {
// identify publically shared spaces
if perm.UserID == "" {
perm.UserID = "0"
if perm.WhoID == "" {
perm.WhoID = user.EveryoneUserID
}
if perm.UserID == "0" {
if perm.WhoID == user.EveryoneUserID {
hasEveryoneRole = true
}
// Encode group/user permission and save to store.
r := permission.EncodeUserPermissions(perm)
roleCount++
for _, p := range r {
err = h.Store.Permission.AddPermission(ctx, p)
if err != nil {
h.Runtime.Log.Error("set permission", err)
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
}
}
// We send out space invitation emails to those users
// that have *just* been given permissions.
if _, isExisting := previousRoleUsers[perm.UserID]; !isExisting {
if _, isExisting := previousRoleUsers[perm.WhoID]; !isExisting {
// we skip 'everyone'
if perm.WhoID != user.EveryoneUserID {
whoToEmail := []string{}
// we skip 'everyone' (user id != empty string)
if perm.UserID != "0" && perm.UserID != "" {
existingUser, err := h.Store.User.Get(ctx, perm.UserID)
if isGroup {
// send email to each group member
for i := range groupRecords {
whoToEmail = append(whoToEmail, groupRecords[i].UserID)
}
} else {
// send email to individual user
whoToEmail = append(whoToEmail, perm.WhoID)
}
for i := range whoToEmail {
existingUser, err := h.Store.User.Get(ctx, whoToEmail[i])
if err != nil {
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
break
continue
}
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
@ -172,6 +206,7 @@ func (h *Handler) SetSpacePermissions(w http.ResponseWriter, r *http.Request) {
}
}
}
}
// Do we need to ensure permissions for space owner when shared?
if !me {
@ -233,6 +268,7 @@ func (h *Handler) GetSpacePermissions(w http.ResponseWriter, r *http.Request) {
perms, err := h.Store.Permission.GetSpacePermissions(ctx, spaceID)
if err != nil && err != sql.ErrNoRows {
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
@ -246,6 +282,40 @@ func (h *Handler) GetSpacePermissions(w http.ResponseWriter, r *http.Request) {
records = append(records, permission.DecodeUserPermissions(up))
}
// populate user/group name for thing that has permission record
groups, err := h.Store.Group.GetAll(ctx)
if err != nil && err != sql.ErrNoRows {
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
for i := range records {
if records[i].Who == permission.GroupPermission {
for j := range groups {
if records[i].WhoID == groups[j].RefID {
records[i].Name = groups[j].Name
break
}
}
}
if records[i].Who == permission.UserPermission {
if records[i].WhoID == user.EveryoneUserID {
records[i].Name = "Everyone"
} else {
u, err := h.Store.User.Get(ctx, records[i].WhoID)
if err != nil {
h.Runtime.Log.Info(fmt.Sprintf("user not found %s", records[i].WhoID))
h.Runtime.Log.Error(method, err)
continue
}
records[i].Name = u.Fullname()
}
}
}
response.WriteJSON(w, records)
}
@ -261,7 +331,7 @@ func (h *Handler) GetUserSpacePermissions(w http.ResponseWriter, r *http.Request
}
perms, err := h.Store.Permission.GetUserSpacePermissions(ctx, spaceID)
if err != nil && err != sql.ErrNoRows {
if err != nil {
response.WriteServerError(w, method, err)
return
}
@ -464,11 +534,6 @@ func (h *Handler) SetDocumentPermissions(w http.ResponseWriter, r *http.Request)
return
}
// if !HasPermission(ctx, *h.Store, doc.LabelID, permission.SpaceManage, permission.SpaceOwner) {
// response.WriteForbiddenError(w)
// return
// }
defer streamutil.Close(r.Body)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
@ -528,17 +593,38 @@ func (h *Handler) SetDocumentPermissions(w http.ResponseWriter, r *http.Request)
return
}
url := ctx.GetAppURL(fmt.Sprintf("s/%s/%s/d/%s/%s",
sp.RefID, stringutil.MakeSlug(sp.Name), doc.RefID, stringutil.MakeSlug(doc.Title)))
url := ctx.GetAppURL(fmt.Sprintf("s/%s/%s/d/%s/%s", sp.RefID, stringutil.MakeSlug(sp.Name), doc.RefID, stringutil.MakeSlug(doc.Title)))
// Permissions can be assigned to both groups and individual users.
// Pre-fetch users with group membership to help us work out
// if user belongs to a group with permissions.
groupMembers, err := h.Store.Group.GetMembers(ctx)
if err != nil {
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)
h.Runtime.Log.Error(method, err)
return
}
for _, perm := range model {
perm.OrgID = ctx.OrgID
perm.DocumentID = id
isGroup := perm.Who == permission.GroupPermission
groupRecords := []group.Record{}
if isGroup {
// get group records for just this group
groupRecords = group.FilterGroupRecords(groupMembers, perm.WhoID)
}
// Only persist if there is a role!
if permission.HasAnyDocumentPermission(perm) {
r := permission.EncodeUserDocumentPermissions(perm)
if perm.WhoID == "" {
perm.WhoID = user.EveryoneUserID
}
r := permission.EncodeUserDocumentPermissions(perm)
for _, p := range r {
err = h.Store.Permission.AddPermission(ctx, p)
if err != nil {
@ -547,14 +633,26 @@ func (h *Handler) SetDocumentPermissions(w http.ResponseWriter, r *http.Request)
}
// Send email notification to users who have been given document approver role
if _, isExisting := previousRoleUsers[perm.UserID]; !isExisting {
if _, isExisting := previousRoleUsers[perm.WhoID]; !isExisting {
// we skip 'everyone' as it has no email address!
if perm.WhoID != user.EveryoneUserID && perm.DocumentRoleApprove {
whoToEmail := []string{}
// we skip 'everyone' (user id != empty string)
if perm.UserID != "0" && perm.UserID != "" && perm.DocumentRoleApprove {
existingUser, err := h.Store.User.Get(ctx, perm.UserID)
if isGroup {
// send email to each group member
for i := range groupRecords {
whoToEmail = append(whoToEmail, groupRecords[i].UserID)
}
} else {
// send email to individual user
whoToEmail = append(whoToEmail, perm.WhoID)
}
for i := range whoToEmail {
existingUser, err := h.Store.User.Get(ctx, whoToEmail[i])
if err != nil {
response.WriteServerError(w, method, err)
break
h.Runtime.Log.Error(method, err)
continue
}
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
@ -564,6 +662,7 @@ func (h *Handler) SetDocumentPermissions(w http.ResponseWriter, r *http.Request)
}
}
}
}
ctx.Transaction.Commit()

View file

@ -35,7 +35,7 @@ func (s Scope) AddPermission(ctx domain.RequestContext, r permission.Permission)
r.Created = time.Now().UTC()
_, err = ctx.Transaction.Exec("INSERT INTO permission (orgid, who, whoid, action, scope, location, refid, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
r.OrgID, r.Who, r.WhoID, string(r.Action), r.Scope, r.Location, r.RefID, r.Created)
r.OrgID, string(r.Who), r.WhoID, string(r.Action), string(r.Scope), string(r.Location), r.RefID, r.Created)
if err != nil {
err = errors.Wrap(err, "unable to execute insert permission")
@ -64,7 +64,8 @@ func (s Scope) AddPermissions(ctx domain.RequestContext, r permission.Permission
func (s Scope) GetUserSpacePermissions(ctx domain.RequestContext, spaceID string) (r []permission.Permission, err error) {
err = s.Runtime.Db.Select(&r, `
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='0')
FROM permission
WHERE orgid=? AND location='space' AND refid=? AND who='user' AND (whoid=? OR whoid='0')
UNION ALL
SELECT p.id, p.orgid, p.who, p.whoid, p.action, p.scope, p.location, p.refid
FROM permission p

View file

@ -203,7 +203,6 @@ export default Component.extend(AuthProvider, ModalMixin, {
group.set('isMember', false);
if (is.undefined(groupId) || is.undefined(userId)) {
console.log(groupId, userId);
return;
}
@ -218,7 +217,6 @@ export default Component.extend(AuthProvider, ModalMixin, {
group.set('isMember', true);
if (is.undefined(groupId) || is.undefined(userId)) {
console.log(groupId, userId);
return;
}

View file

@ -9,80 +9,78 @@
//
// https://documize.com
import { setProperties } from '@ember/object';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { A } from "@ember/array"
import ModalMixin from '../../mixins/modal';
import Component from '@ember/component';
export default Component.extend(ModalMixin, {
folderService: service('folder'),
userService: service('user'),
groupSvc: service('group'),
spaceSvc: service('folder'),
userSvc: service('user'),
appMeta: service(),
store: service(),
spacePermissions: null,
didReceiveAttrs() {
this.get('userService').getSpaceUsers(this.get('folder.id')).then((users) => {
this.set('users', users);
let spacePermissions = A([]);
let constants = this.get('constants');
// set up users
let folderPermissions = [];
// get groups
this.get('groupSvc').getAll().then((groups) => {
this.set('groups', groups);
users.forEach((user) => {
let u = {
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
userId: user.get('id'),
fullname: user.get('fullname'),
spaceView: false,
spaceManage: false,
spaceOwner: false,
documentAdd: false,
documentEdit: false,
documentDelete: false,
documentMove: false,
documentCopy: false,
documentTemplate: false,
documentApprove: false,
};
let data = this.get('store').normalize('space-permission', u)
folderPermissions.pushObject(this.get('store').push(data));
groups.forEach((g) => {
let pr = this.permissionRecord(constants.WhoType.Group, g.get('id'), g.get('name'));
spacePermissions.pushObject(pr);
});
// set up Everyone user
let u = {
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
userId: '0',
fullname: ' Everyone',
spaceView: false,
spaceManage: false,
spaceOwner: false,
documentAdd: false,
documentEdit: false,
documentDelete: false,
documentMove: false,
documentCopy: false,
documentTemplate: false,
documentApprove: false,
};
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) => {
permissions.forEach((permission, index) => { // eslint-disable-line no-unused-vars
let record = folderPermissions.findBy('userId', permission.get('userId'));
if (is.not.undefined(record)) {
record = setProperties(record, permission);
// get space permissions
this.get('spaceSvc').getPermissions(this.get('folder.id')).then((permissions) => {
permissions.forEach((perm, index) => { // eslint-disable-line no-unused-vars
// is this permission for group or user?
if (perm.get('who') === constants.WhoType.Group) {
// group permission
spacePermissions.forEach((sp) => {
if (sp.get('whoId') == perm.get('whoId')) {
sp.setProperties(perm);
}
});
} else {
// user permission
spacePermissions.pushObject(perm);
}
});
this.set('permissions', folderPermissions.sortBy('fullname'));
this.set('spacePermissions', spacePermissions.sortBy('who', 'name'));
});
});
},
permissionRecord(who, whoId, name) {
let raw = {
id: whoId,
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
whoId: whoId,
who: who,
name: name,
spaceView: false,
spaceManage: false,
spaceOwner: false,
documentAdd: false,
documentEdit: false,
documentDelete: false,
documentMove: false,
documentCopy: false,
documentTemplate: false,
documentApprove: false,
};
let rec = this.get('store').normalize('space-permission', raw);
return this.get('store').push(rec);
},
getDefaultInvitationMessage() {
return "Hey there, I am sharing the " + this.get('folder.name') + " space (in " + this.get("appMeta.title") + ") with you so we can both collaborate on documents.";
},
@ -90,12 +88,13 @@ export default Component.extend(ModalMixin, {
actions: {
setPermissions() {
let message = this.getDefaultInvitationMessage();
let permissions = this.get('permissions');
let permissions = this.get('spacePermissions');
let folder = this.get('folder');
let payload = { Message: message, Permissions: permissions };
let constants = this.get('constants');
let hasEveryone = _.find(permissions, function (permission) {
return permission.get('userId') === "0" &&
let hasEveryone = _.find(permissions, (permission) => {
return permission.get('whoId') === constants.EveryoneUserId &&
(permission.get('spaceView') || permission.get('documentAdd') || permission.get('documentEdit') || permission.get('documentDelete') ||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') || permission.get('documentApprove'));
});
@ -103,7 +102,7 @@ export default Component.extend(ModalMixin, {
// see if more than oen user is granted access to space (excluding everyone)
let roleCount = 0;
permissions.forEach((permission) => {
if (permission.get('userId') !== "0" &&
if (permission.get('whoId') !== constants.EveryoneUserId &&
(permission.get('spaceView') || permission.get('documentAdd') || permission.get('documentEdit') || permission.get('documentDelete') ||
permission.get('documentMove') || permission.get('documentCopy') || permission.get('documentTemplate') || permission.get('documentApprove'))) {
roleCount += 1;
@ -120,7 +119,7 @@ export default Component.extend(ModalMixin, {
}
}
this.get('folderService').savePermissions(folder.get('id'), payload).then(() => {
this.get('spaceSvc').savePermissions(folder.get('id'), payload).then(() => {
this.modalClose('#space-permission-modal');
});
}

View file

@ -10,7 +10,6 @@
// https://documize.com
import $ from 'jquery';
import Component from '@ember/component';
import { computed } from '@ember/object';
import { schedule } from '@ember/runloop';
import { inject as service } from '@ember/service';
@ -18,6 +17,7 @@ import TooltipMixin from '../../mixins/tooltip';
import ModalMixin from '../../mixins/modal';
import AuthMixin from '../../mixins/auth';
import stringUtil from '../../utils/string';
import Component from '@ember/component';
export default Component.extend(ModalMixin, TooltipMixin, AuthMixin, {
spaceService: service('folder'),

View file

@ -11,6 +11,9 @@
import EmberObject from "@ember/object";
// access like so:
// let constants = this.get('constants');
let constants = EmberObject.extend({
// Document
ProtectionType: { // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
@ -48,7 +51,15 @@ let constants = EmberObject.extend({
PageType: { // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
Tab: 'tab',
Section: 'section'
}
},
// Who a permission record relates to
WhoType: { // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
User: 'user',
Group: 'role'
},
EveryoneUserId: "0"
});
export default { constants }

View file

@ -11,14 +11,12 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
// import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
orgId: attr('string'),
folderId: attr('string'),
userId: attr('string'),
fullname: attr('string'), // client-side usage only, not from API
whoId: attr('string'),
who: attr('string'),
spaceView: attr('boolean'),
spaceManage: attr('boolean'),
spaceOwner: attr('boolean'),
@ -28,5 +26,6 @@ export default Model.extend({
documentMove: attr('boolean'),
documentCopy: attr('boolean'),
documentTemplate: attr('boolean'),
documentApprove: attr('boolean')
documentApprove: attr('boolean'),
name: attr('string') // read-only
});

View file

@ -4,7 +4,7 @@ export default ApplicationSerializer.extend({
normalize(modelClass, resourceHash) {
return {
data: {
id: resourceHash.userId ? resourceHash.userId : 0,
id: resourceHash.whoId ? resourceHash.whoId : 0,
type: modelClass.modelName,
attributes: resourceHash
}

View file

@ -20,6 +20,7 @@ export default BaseService.extend({
localStorage: service(),
store: service(),
currentFolder: null,
permissions: null,
init() {
this._super(...arguments);

View file

@ -27,38 +27,50 @@
</tr>
</thead>
<tbody>
{{#each permissions as |permission|}}
{{#each spacePermissions as |permission|}}
<tr>
<td>{{permission.fullname}} {{if (eq permission.userId session.user.id) '(you)'}}</td>
<td>
{{input type="checkbox" id=(concat 'space-role-view-' permission.userId) checked=permission.spaceView}}
{{#if (eq permission.who "role")}}
<span class="button-icon-gray button-icon-small align-middle">
<i class="material-icons">people</i>
</span>
&nbsp;<b>{{permission.name}}</b>
{{else}}
<span class="button-icon-gray button-icon-small align-middle">
<i class="material-icons">person</i>
</span>
&nbsp;<b>{{permission.name}}</b> {{if (eq permission.whoId session.user.id) '(you)'}}
{{/if}}
</td>
<td>
{{input type="checkbox" id=(concat 'space-role-manage-' permission.userId) checked=permission.spaceManage}}
{{input type="checkbox" id=(concat 'space-role-view-' permission.whoId) checked=permission.spaceView}}
</td>
<td>
{{input type="checkbox" id=(concat 'space-role-owner-' permission.userId) checked=permission.spaceOwner}}
{{input type="checkbox" id=(concat 'space-role-manage-' permission.whoId) checked=permission.spaceManage}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-add-' permission.userId) checked=permission.documentAdd}}
{{input type="checkbox" id=(concat 'space-role-owner-' permission.whoId) checked=permission.spaceOwner}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-edit-' permission.userId) checked=permission.documentEdit}}
{{input type="checkbox" id=(concat 'doc-role-add-' permission.whoId) checked=permission.documentAdd}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-delete-' permission.userId) checked=permission.documentDelete}}
{{input type="checkbox" id=(concat 'doc-role-edit-' permission.whoId) checked=permission.documentEdit}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-move-' permission.userId) checked=permission.documentMove}}
{{input type="checkbox" id=(concat 'doc-role-delete-' permission.whoId) checked=permission.documentDelete}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-copy-' permission.userId) checked=permission.documentCopy}}
{{input type="checkbox" id=(concat 'doc-role-move-' permission.whoId) checked=permission.documentMove}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-template-' permission.userId) checked=permission.documentTemplate}}
{{input type="checkbox" id=(concat 'doc-role-copy-' permission.whoId) checked=permission.documentCopy}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-approve-' permission.userId) checked=permission.documentApprove}}
{{input type="checkbox" id=(concat 'doc-role-template-' permission.whoId) checked=permission.documentTemplate}}
</td>
<td>
{{input type="checkbox" id=(concat 'doc-role-approve-' permission.whoId) checked=permission.documentApprove}}
</td>
</tr>
{{/each}}

View file

@ -41,3 +41,27 @@ type Record struct {
Name string `json:"name"`
Purpose string `json:"purpose"`
}
// UserHasGroupMembership returns true if user belongs to specified group.
func UserHasGroupMembership(r []Record, groupID, userID string) bool {
for i := range r {
if r[i].RoleID == groupID && r[i].UserID == userID {
return true
}
}
return false
}
// FilterGroupRecords returns only those records matching group ID.
func FilterGroupRecords(r []Record, groupID string) (m []Record) {
m = []Record{}
for i := range r {
if r[i].RoleID == groupID {
m = append(m, r[i])
}
}
return
}

View file

@ -17,7 +17,8 @@ package permission
type DocumentRecord struct {
OrgID string `json:"orgId"`
DocumentID string `json:"documentId"`
UserID string `json:"userId"`
WhoID string `json:"whoId"`
Who WhoType `json:"who"`
DocumentRoleEdit bool `json:"documentRoleEdit"`
DocumentRoleApprove bool `json:"documentRoleApprove"`
}
@ -29,7 +30,8 @@ func DecodeUserDocumentPermissions(perm []Permission) (r DocumentRecord) {
if len(perm) > 0 {
r.OrgID = perm[0].OrgID
r.UserID = perm[0].WhoID
r.WhoID = perm[0].WhoID
r.Who = perm[0].Who
r.DocumentID = perm[0].RefID
}
@ -67,8 +69,8 @@ func HasAnyDocumentPermission(p DocumentRecord) bool {
func EncodeDocumentRecord(r DocumentRecord, a Action) (p Permission) {
p = Permission{}
p.OrgID = r.OrgID
p.Who = UserPermission
p.WhoID = r.UserID
p.WhoID = r.WhoID
p.Who = r.Who
p.Location = LocationDocument
p.RefID = r.DocumentID
p.Action = a

View file

@ -17,7 +17,8 @@ package permission
type Record struct {
OrgID string `json:"orgId"`
SpaceID string `json:"folderId"`
UserID string `json:"userId"`
WhoID string `json:"whoId"`
Who WhoType `json:"who"`
SpaceView bool `json:"spaceView"`
SpaceManage bool `json:"spaceManage"`
SpaceOwner bool `json:"spaceOwner"`
@ -28,6 +29,7 @@ type Record struct {
DocumentCopy bool `json:"documentCopy"`
DocumentTemplate bool `json:"documentTemplate"`
DocumentApprove bool `json:"documentApprove"`
Name string `json:"name"` // read-only, user or group name
}
// DecodeUserPermissions returns a flat, usable permission summary record
@ -37,7 +39,8 @@ func DecodeUserPermissions(perm []Permission) (r Record) {
if len(perm) > 0 {
r.OrgID = perm[0].OrgID
r.UserID = perm[0].WhoID
r.WhoID = perm[0].WhoID
r.Who = perm[0].Who
r.SpaceID = perm[0].RefID
}
@ -118,8 +121,8 @@ func HasAnyPermission(p Record) bool {
func EncodeRecord(r Record, a Action) (p Permission) {
p = Permission{}
p.OrgID = r.OrgID
p.Who = UserPermission
p.WhoID = r.UserID
p.Who = r.Who
p.WhoID = r.WhoID
p.Location = LocationSpace
p.RefID = r.SpaceID
p.Action = a

View file

@ -71,3 +71,8 @@ func Exists(users []User, userID string) bool {
return false
}
const (
// EveryoneUserID provides a shortcut to state "all authenticated users".
EveryoneUserID string = "0"
)

View file

@ -91,9 +91,9 @@ func RegisterEndpoints(rt *env.Runtime, s *domain.Store) {
Add(rt, RoutePrefixPrivate, "documents/{documentID}", []string{"GET", "OPTIONS"}, nil, document.Get)
Add(rt, RoutePrefixPrivate, "documents/{documentID}", []string{"PUT", "OPTIONS"}, nil, document.Update)
Add(rt, RoutePrefixPrivate, "documents/{documentID}", []string{"DELETE", "OPTIONS"}, nil, document.Delete)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetDocumentPermissions)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetDocumentPermissions)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserDocumentPermissions)
// Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetDocumentPermissions)
// Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetDocumentPermissions)
// Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserDocumentPermissions)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/pages/level", []string{"POST", "OPTIONS"}, nil, page.ChangePageLevel)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/pages/sequence", []string{"POST", "OPTIONS"}, nil, page.ChangePageSequence)
@ -119,9 +119,9 @@ func RegisterEndpoints(rt *env.Runtime, s *domain.Store) {
Add(rt, RoutePrefixPrivate, "space/{spaceID}", []string{"DELETE", "OPTIONS"}, nil, space.Delete)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/move/{moveToId}", []string{"DELETE", "OPTIONS"}, nil, space.Remove)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetSpacePermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserSpacePermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetSpacePermissions)
// Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetSpacePermissions)
// Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserSpacePermissions)
// Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetSpacePermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/invitation", []string{"POST", "OPTIONS"}, nil, space.Invite)
Add(rt, RoutePrefixPrivate, "space/manage", []string{"GET", "OPTIONS"}, nil, space.GetAll)
Add(rt, RoutePrefixPrivate, "space/{spaceID}", []string{"GET", "OPTIONS"}, nil, space.Get)
@ -131,11 +131,11 @@ func RegisterEndpoints(rt *env.Runtime, s *domain.Store) {
Add(rt, RoutePrefixPrivate, "category/space/{spaceID}/summary", []string{"GET", "OPTIONS"}, nil, category.GetSummary)
Add(rt, RoutePrefixPrivate, "category/document/{documentID}", []string{"GET", "OPTIONS"}, nil, category.GetDocumentCategoryMembership)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"PUT", "OPTIONS"}, nil, permission.SetCategoryPermissions)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryPermissions)
// Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"PUT", "OPTIONS"}, nil, permission.SetCategoryPermissions)
// Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryPermissions)
Add(rt, RoutePrefixPrivate, "category/space/{spaceID}", []string{"GET", "OPTIONS"}, []string{"filter", "all"}, category.GetAll)
Add(rt, RoutePrefixPrivate, "category/space/{spaceID}", []string{"GET", "OPTIONS"}, nil, category.Get)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/user", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryViewers)
// Add(rt, RoutePrefixPrivate, "category/{categoryID}/user", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryViewers)
Add(rt, RoutePrefixPrivate, "category/member/space/{spaceID}", []string{"GET", "OPTIONS"}, nil, category.GetSpaceCategoryMembers)
Add(rt, RoutePrefixPrivate, "category/member", []string{"POST", "OPTIONS"}, nil, category.SetDocumentCategoryMembership)
Add(rt, RoutePrefixPrivate, "category/{categoryID}", []string{"PUT", "OPTIONS"}, nil, category.Update)
@ -192,6 +192,16 @@ func RegisterEndpoints(rt *env.Runtime, s *domain.Store) {
Add(rt, RoutePrefixPrivate, "group/{groupID}/join/{userID}", []string{"POST", "OPTIONS"}, nil, group.JoinGroup)
Add(rt, RoutePrefixPrivate, "group/{groupID}/leave/{userID}", []string{"DELETE", "OPTIONS"}, nil, group.LeaveGroup)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetDocumentPermissions)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetDocumentPermissions)
Add(rt, RoutePrefixPrivate, "documents/{documentID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserDocumentPermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"PUT", "OPTIONS"}, nil, permission.SetSpacePermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions/user", []string{"GET", "OPTIONS"}, nil, permission.GetUserSpacePermissions)
Add(rt, RoutePrefixPrivate, "space/{spaceID}/permissions", []string{"GET", "OPTIONS"}, nil, permission.GetSpacePermissions)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"PUT", "OPTIONS"}, nil, permission.SetCategoryPermissions)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryPermissions)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/user", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryViewers)
// fetch methods exist to speed up UI rendering by returning data in bulk
Add(rt, RoutePrefixPrivate, "fetch/category/space/{spaceID}", []string{"GET", "OPTIONS"}, nil, category.FetchSpaceData)
Add(rt, RoutePrefixPrivate, "fetch/document/{documentID}", []string{"GET", "OPTIONS"}, nil, document.FetchDocumentData)