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

refined category permission checks

This commit is contained in:
Harvey Kandola 2017-09-21 18:59:43 +01:00
parent 4d989e2497
commit 3a9675eb14
11 changed files with 149 additions and 22 deletions

View file

@ -278,6 +278,37 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
response.WriteEmpty(w) response.WriteEmpty(w)
} }
// GetSummary returns number of documents and users for space categories.
func (h *Handler) GetSummary(w http.ResponseWriter, r *http.Request) {
method := "category.GetSummary"
ctx := domain.GetRequestContext(r)
spaceID := request.Param(r, "spaceID")
if len(spaceID) == 0 {
response.WriteMissingDataError(w, method, "spaceID")
return
}
ok := permission.HasPermission(ctx, *h.Store, spaceID, pm.SpaceManage, pm.SpaceOwner)
if !ok || !ctx.Authenticated {
response.WriteForbiddenError(w)
return
}
s, err := h.Store.Category.GetSpaceCategorySummary(ctx, spaceID)
if err != nil {
h.Runtime.Log.Error("get space category summary failed", err)
response.WriteServerError(w, method, err)
return
}
if len(s) == 0 {
s = []category.SummaryModel{}
}
response.WriteJSON(w, s)
}
/* /*
- category view permission handling - category view permission handling
- filter users using new permission - filter users using new permission

View file

@ -199,3 +199,29 @@ func (s Scope) DeleteBySpace(ctx domain.RequestContext, spaceID string) (rows in
s2 := fmt.Sprintf("DELETE FROM category WHERE orgid='%s' AND labelid='%s'", ctx.OrgID, spaceID) s2 := fmt.Sprintf("DELETE FROM category WHERE orgid='%s' AND labelid='%s'", ctx.OrgID, spaceID)
return b.DeleteWhere(ctx.Transaction, s2) return b.DeleteWhere(ctx.Transaction, s2)
} }
// GetSpaceCategorySummary returns number of documents and users for space categories.
func (s Scope) GetSpaceCategorySummary(ctx domain.RequestContext, spaceID string) (c []category.SummaryModel, err error) {
err = s.Runtime.Db.Select(&c, `
SELECT 'documents' as type, categoryid, COUNT(*) as count FROM categorymember WHERE orgid=? AND labelid=? GROUP BY categoryid, type
UNION ALL
SELECT 'users' as type, refid AS categoryid, count(*) AS count FROM permission WHERE orgid=? AND who='user' AND location='category'
AND refid IN (SELECT refid FROM category WHERE orgid=? AND labelid=?)
GROUP BY refid, type
UNION ALL
SELECT 'users' as type, p.refid AS categoryid, count(*) AS count FROM rolemember r LEFT JOIN permission p ON p.whoid=r.roleid
WHERE p.orgid=? AND p.who='role' AND p.location='category'
AND p.refid IN (SELECT refid FROM category WHERE orgid=? AND labelid=?)
GROUP BY p.refid, type`,
ctx.OrgID, spaceID, ctx.OrgID, ctx.OrgID, spaceID, ctx.OrgID, ctx.OrgID, spaceID)
if err == sql.ErrNoRows {
err = nil
}
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("unable to execute select category summary for space %s", spaceID))
return
}
return
}

View file

@ -273,9 +273,9 @@ func (h *Handler) GetUserSpacePermissions(w http.ResponseWriter, r *http.Request
response.WriteJSON(w, record) response.WriteJSON(w, record)
} }
// GetCategoryPermissions returns user permissions for given category. // GetCategoryViewers returns user permissions for given category.
func (h *Handler) GetCategoryPermissions(w http.ResponseWriter, r *http.Request) { func (h *Handler) GetCategoryViewers(w http.ResponseWriter, r *http.Request) {
method := "space.GetCategoryPermissions" method := "space.GetCategoryViewers"
ctx := domain.GetRequestContext(r) ctx := domain.GetRequestContext(r)
categoryID := request.Param(r, "categoryID") categoryID := request.Param(r, "categoryID")
@ -296,6 +296,29 @@ func (h *Handler) GetCategoryPermissions(w http.ResponseWriter, r *http.Request)
response.WriteJSON(w, u) response.WriteJSON(w, u)
} }
// GetCategoryPermissions returns user permissions for given category.
func (h *Handler) GetCategoryPermissions(w http.ResponseWriter, r *http.Request) {
method := "space.GetCategoryPermissions"
ctx := domain.GetRequestContext(r)
categoryID := request.Param(r, "categoryID")
if len(categoryID) == 0 {
response.WriteMissingDataError(w, method, "categoryID")
return
}
u, err := h.Store.Permission.GetCategoryPermissions(ctx, categoryID)
if err != nil && err != sql.ErrNoRows {
response.WriteServerError(w, method, err)
return
}
if len(u) == 0 {
u = []permission.Permission{}
}
response.WriteJSON(w, u)
}
// SetCategoryPermissions persists specified category permissions // SetCategoryPermissions persists specified category permissions
func (h *Handler) SetCategoryPermissions(w http.ResponseWriter, r *http.Request) { func (h *Handler) SetCategoryPermissions(w http.ResponseWriter, r *http.Request) {
method := "permission.SetCategoryPermissions" method := "permission.SetCategoryPermissions"

View file

@ -182,9 +182,9 @@ func (s Scope) GetCategoryPermissions(ctx domain.RequestContext, catID string) (
// GetCategoryUsers returns space permissions for all users. // GetCategoryUsers returns space permissions for all users.
func (s Scope) GetCategoryUsers(ctx domain.RequestContext, catID string) (u []user.User, err error) { func (s Scope) GetCategoryUsers(ctx domain.RequestContext, catID string) (u []user.User, err error) {
err = s.Runtime.Db.Select(&u, ` err = s.Runtime.Db.Select(&u, `
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised SELECT u.id, IFNULL(u.refid, '') AS refid, IFNULL(u.firstname, '') AS firstname, IFNULL(u.lastname, '') as lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised
FROM user u, account a FROM user u LEFT JOIN account a ON u.refid = a.userid
WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN ( WHERE a.orgid=? AND a.active=1 AND u.refid IN (
SELECT whoid from permission WHERE orgid=? AND who='user' AND location='category' AND refid=? UNION ALL SELECT whoid from permission WHERE orgid=? AND who='user' AND location='category' AND refid=? UNION ALL
SELECT r.userid from rolemember r LEFT JOIN permission p ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' SELECT r.userid from rolemember r LEFT JOIN permission p ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role'
AND p.location='category' AND p.refid=? AND p.location='category' AND p.refid=?
@ -197,7 +197,7 @@ func (s Scope) GetCategoryUsers(ctx domain.RequestContext, catID string) (u []us
err = nil err = nil
} }
if err != nil { if err != nil {
err = errors.Wrap(err, fmt.Sprintf("unable to execute select category user %s", catID)) err = errors.Wrap(err, fmt.Sprintf("unable to execute select users for category %s", catID))
return return
} }

View file

@ -68,6 +68,7 @@ type CategoryStorer interface {
Get(ctx RequestContext, id string) (c category.Category, err error) Get(ctx RequestContext, id string) (c category.Category, err error)
GetBySpace(ctx RequestContext, spaceID string) (c []category.Category, err error) GetBySpace(ctx RequestContext, spaceID string) (c []category.Category, err error)
GetAllBySpace(ctx RequestContext, spaceID string) (c []category.Category, err error) GetAllBySpace(ctx RequestContext, spaceID string) (c []category.Category, err error)
GetSpaceCategorySummary(ctx RequestContext, spaceID string) (c []category.SummaryModel, err error)
Delete(ctx RequestContext, id string) (rows int64, err error) Delete(ctx RequestContext, id string) (rows int64, err error)
AssociateDocument(ctx RequestContext, m category.Member) (err error) AssociateDocument(ctx RequestContext, m category.Member) (err error)
DisassociateDocument(ctx RequestContext, categoryID, documentID string) (rows int64, err error) DisassociateDocument(ctx RequestContext, categoryID, documentID string) (rows int64, err error)

View file

@ -44,6 +44,20 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, DropdownMixin
this.get('categoryService').getAll(this.get('folder.id')).then((c) => { this.get('categoryService').getAll(this.get('folder.id')).then((c) => {
this.set('category', c); this.set('category', c);
// get summary of documents and users for each category in space
this.get('categoryService').getSummary(this.get('folder.id')).then((s) => {
c.forEach((cat) => {
let docs = _.findWhere(s, {categoryId: cat.get('id'), type: 'documents'});
let docCount = is.not.undefined(docs) ? docs.count : 0;
let users = _.findWhere(s, {categoryId: cat.get('id'), type: 'users'});
let userCount = is.not.undefined(users) ? users.count : 0;
cat.set('documents', docCount);
cat.set('users', userCount);
});
});
// get users that this space admin user can see // get users that this space admin user can see
this.get('userService').getAll().then((users) => { this.get('userService').getAll().then((users) => {
// set up Everyone user // set up Everyone user
@ -132,12 +146,12 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, DropdownMixin
let users = this.get('users'); let users = this.get('users');
let category = this.get('category').findBy('id', catId); let category = this.get('category').findBy('id', catId);
this.get('categoryService').getViewers(category.get('id')).then((viewers) => { this.get('categoryService').getPermissions(category.get('id')).then((viewers) => {
// mark those users as selected that have already been given permission // mark those users as selected that have already been given permission
// to see the current category; // to see the current category;
users.forEach((user) => { users.forEach((user) => {
let selected = viewers.isAny('id', user.get('id')); let userId = user.get('id') === '0' ? '' : user.get('id');
let selected = viewers.isAny('whoId', userId);
user.set('selected', selected); user.set('selected', selected);
}); });
@ -173,17 +187,22 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, DropdownMixin
let viewers = []; let viewers = [];
users.forEach((user) => { users.forEach((user) => {
let userId = user.get('id');
if (userId === "0") userId = '';
let v = { let v = {
orgId: this.get('folder.orgId'), orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'), folderId: this.get('folder.id'),
categoryId: category.get('id'), categoryId: category.get('id'),
userId: user.get('id') userId: userId
}; };
viewers.push(v); viewers.push(v);
}); });
this.get('categoryService').setViewers(category.get('id'), viewers).then( () => {}); this.get('categoryService').setViewers(category.get('id'), viewers).then(() => {
this.load();
});
this.closeDropdown(); this.closeDropdown();
} }

View file

@ -17,5 +17,9 @@ export default Model.extend({
folderId: attr('string'), folderId: attr('string'),
category: attr('string'), category: attr('string'),
created: attr(), created: attr(),
revised: attr() revised: attr(),
// fields used by UI only
documents: attr(),
users: attr(),
}); });

View file

@ -85,10 +85,19 @@ export default BaseService.extend({
}); });
}, },
// Get list of users who can see given category // Get viewer permission records for given category
getViewers(categoryId) { getPermissions(categoryId) {
return this.get('ajax').request(`category/${categoryId}/permission`, { return this.get('ajax').request(`category/${categoryId}/permission`, {
method: 'GET' method: 'GET'
}).then((response) => {
return response;
});
},
// Get list of users who can see given category
getUsers(categoryId) {
return this.get('ajax').request(`category/${categoryId}/user`, {
method: 'GET'
}).then((response) => { }).then((response) => {
let data = []; let data = [];
@ -109,4 +118,13 @@ export default BaseService.extend({
data: JSON.stringify(viewers) data: JSON.stringify(viewers)
}); });
}, },
// Get count of documents and users associated with each category in given space.
getSummary(spaceId) {
return this.get('ajax').request(`category/space/${spaceId}/summary`, {
method: 'GET'
}).then((response) => {
return response;
});
}
}); });

View file

@ -16,7 +16,7 @@
{{else}} {{else}}
<div class="category"> <div class="category">
<div class="name">{{cat.category}}</div> <div class="name">{{cat.category}}</div>
<div class="info">7 documents, 14 people</div> <div class="info">{{cat.documents}} documents, {{cat.users}} people</div>
</div> </div>
{{/if}} {{/if}}
<div class="pull-right buttons"> <div class="pull-right buttons">
@ -66,12 +66,8 @@
{{ui/ui-list-picker items=categoryUsers nameField='fullname'}} {{ui/ui-list-picker items=categoryUsers nameField='fullname'}}
</div> </div>
<div class="actions"> <div class="actions">
<div class="flat-button" {{action 'onGrantCancel'}}> <div class="flat-button" {{action 'onGrantCancel'}}>cancel</div>
cancel <div class="flat-button flat-blue" {{action 'onGrantAccess'}}>grant access</div>
</div>
<div class="flat-button flat-blue" {{action 'onGrantAccess'}}>
grant access
</div>
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>

View file

@ -29,3 +29,10 @@ type Member struct {
LabelID string `json:"folderId"` LabelID string `json:"folderId"`
DocumentID string `json:"documentId"` DocumentID string `json:"documentId"`
} }
// SummaryModel holds number of documents and users for space categories.
type SummaryModel struct {
Type string `json:"type"` // documents or users
CategoryID string `json:"categoryId"`
Count int64 `json:"count"`
}

View file

@ -132,8 +132,10 @@ func RegisterEndpoints(rt *env.Runtime, s *domain.Store) {
Add(rt, RoutePrefixPrivate, "category", []string{"POST", "OPTIONS"}, nil, category.Add) Add(rt, RoutePrefixPrivate, "category", []string{"POST", "OPTIONS"}, nil, category.Add)
Add(rt, RoutePrefixPrivate, "category/{categoryID}", []string{"PUT", "OPTIONS"}, nil, category.Update) Add(rt, RoutePrefixPrivate, "category/{categoryID}", []string{"PUT", "OPTIONS"}, nil, category.Update)
Add(rt, RoutePrefixPrivate, "category/{categoryID}", []string{"DELETE", "OPTIONS"}, nil, category.Delete) Add(rt, RoutePrefixPrivate, "category/{categoryID}", []string{"DELETE", "OPTIONS"}, nil, category.Delete)
Add(rt, RoutePrefixPrivate, "category/space/{spaceID}/summary", []string{"GET", "OPTIONS"}, nil, category.GetSummary)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/permission", []string{"PUT", "OPTIONS"}, nil, permission.SetCategoryPermissions) 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{"GET", "OPTIONS"}, nil, permission.GetCategoryPermissions)
Add(rt, RoutePrefixPrivate, "category/{categoryID}/user", []string{"GET", "OPTIONS"}, nil, permission.GetCategoryViewers)
Add(rt, RoutePrefixPrivate, "users/{userID}/password", []string{"POST", "OPTIONS"}, nil, user.ChangePassword) Add(rt, RoutePrefixPrivate, "users/{userID}/password", []string{"POST", "OPTIONS"}, nil, user.ChangePassword)
Add(rt, RoutePrefixPrivate, "users", []string{"POST", "OPTIONS"}, nil, user.Add) Add(rt, RoutePrefixPrivate, "users", []string{"POST", "OPTIONS"}, nil, user.Add)