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)
}
// 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
- 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)
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)
}
// GetCategoryPermissions returns user permissions for given category.
func (h *Handler) GetCategoryPermissions(w http.ResponseWriter, r *http.Request) {
method := "space.GetCategoryPermissions"
// GetCategoryViewers returns user permissions for given category.
func (h *Handler) GetCategoryViewers(w http.ResponseWriter, r *http.Request) {
method := "space.GetCategoryViewers"
ctx := domain.GetRequestContext(r)
categoryID := request.Param(r, "categoryID")
@ -296,6 +296,29 @@ func (h *Handler) GetCategoryPermissions(w http.ResponseWriter, r *http.Request)
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
func (h *Handler) SetCategoryPermissions(w http.ResponseWriter, r *http.Request) {
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.
func (s Scope) GetCategoryUsers(ctx domain.RequestContext, catID string) (u []user.User, err error) {
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
FROM user u, account a
WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN (
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 LEFT JOIN account a ON u.refid = a.userid
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 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=?
@ -197,7 +197,7 @@ func (s Scope) GetCategoryUsers(ctx domain.RequestContext, catID string) (u []us
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
}

View file

@ -68,6 +68,7 @@ type CategoryStorer interface {
Get(ctx RequestContext, id 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)
GetSpaceCategorySummary(ctx RequestContext, spaceID string) (c []category.SummaryModel, err error)
Delete(ctx RequestContext, id string) (rows int64, err error)
AssociateDocument(ctx RequestContext, m category.Member) (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.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
this.get('userService').getAll().then((users) => {
// set up Everyone user
@ -132,12 +146,12 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, DropdownMixin
let users = this.get('users');
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
// to see the current category;
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);
});
@ -173,17 +187,22 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, DropdownMixin
let viewers = [];
users.forEach((user) => {
let userId = user.get('id');
if (userId === "0") userId = '';
let v = {
orgId: this.get('folder.orgId'),
folderId: this.get('folder.id'),
categoryId: category.get('id'),
userId: user.get('id')
userId: userId
};
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();
}

View file

@ -17,5 +17,9 @@ export default Model.extend({
folderId: attr('string'),
category: attr('string'),
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
getViewers(categoryId) {
// Get viewer permission records for given category
getPermissions(categoryId) {
return this.get('ajax').request(`category/${categoryId}/permission`, {
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) => {
let data = [];
@ -109,4 +118,13 @@ export default BaseService.extend({
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}}
<div class="category">
<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>
{{/if}}
<div class="pull-right buttons">
@ -66,12 +66,8 @@
{{ui/ui-list-picker items=categoryUsers nameField='fullname'}}
</div>
<div class="actions">
<div class="flat-button" {{action 'onGrantCancel'}}>
cancel
</div>
<div class="flat-button flat-blue" {{action 'onGrantAccess'}}>
grant access
</div>
<div class="flat-button" {{action 'onGrantCancel'}}>cancel</div>
<div class="flat-button flat-blue" {{action 'onGrantAccess'}}>grant access</div>
</div>
<div class="clearfix"></div>
</div>

View file

@ -29,3 +29,10 @@ type Member struct {
LabelID string `json:"folderId"`
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/{categoryID}", []string{"PUT", "OPTIONS"}, nil, category.Update)
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{"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", []string{"POST", "OPTIONS"}, nil, user.Add)