1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-02 20:15:26 +02:00

persist permissions

WIP
This commit is contained in:
Harvey Kandola 2017-09-15 11:08:05 +01:00
parent 5f7c6d211f
commit ef285c91de
13 changed files with 764 additions and 829 deletions

View file

@ -36,7 +36,6 @@ import (
"github.com/documize/community/model/doc"
"github.com/documize/community/model/page"
"github.com/documize/community/model/space"
"github.com/documize/community/model/user"
uuid "github.com/nu7hatch/gouuid"
)
@ -553,7 +552,7 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
sp, err := h.Store.Space.Get(ctx, id)
if err != nil {
response.WriteNotFoundError(w, method, "No such space")
response.WriteNotFoundError(w, method, "space not found")
return
}
@ -570,7 +569,7 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
return
}
var model = space.RolesModel{}
var model = space.PermissionsModel{}
err = json.Unmarshal(body, &model)
if err != nil {
response.WriteServerError(w, method, err)
@ -597,7 +596,6 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
// Store all previous roles as map for easy querying
previousRoleUsers := make(map[string]bool)
for _, v := range previousRoles {
previousRoleUsers[v.WhoID] = true
}
@ -628,42 +626,45 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
for _, perm := range model.Permissions {
perm.OrgID = ctx.OrgID
perm.RefID = id
perm.SpaceID = id
// Ensure the space owner always has access!
if perm.WhoID == ctx.UserID {
if perm.UserID == ctx.UserID {
me = true
}
if len(perm.WhoID) == 0 {
if len(perm.UserID) == 0 {
hasEveryoneRole = true
}
// Only persist if there is a role!
if perm.Action == "TBC" {
err = h.Store.Space.AddPermission(ctx, perm)
if err != nil {
h.Runtime.Log.Error("add role", err)
}
if space.HasAnyPermission(perm) {
r := space.EncodeUserPermissions(perm)
roleCount++
for _, p := range r {
err = h.Store.Space.AddPermission(ctx, p)
if err != nil {
h.Runtime.Log.Error("set permission", err)
}
roleCount++
}
// We send out space invitation emails to those users
// that have *just* been given permissions.
if _, isExisting := previousRoleUsers[perm.WhoID]; !isExisting {
if _, isExisting := previousRoleUsers[perm.UserID]; !isExisting {
// we skip 'everyone' (user id != empty string)
if len(perm.WhoID) > 0 {
var existingUser user.User
existingUser, err = h.Store.User.Get(ctx, perm.WhoID)
if err == nil {
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
go mailer.ShareSpaceExistingUser(existingUser.Email, inviter.Fullname(), url, sp.Name, model.Message)
h.Runtime.Log.Info(fmt.Sprintf("%s is sharing space %s with existing user %s", inviter.Email, sp.Name, existingUser.Email))
} else {
if len(perm.UserID) > 0 {
existingUser, err := h.Store.User.Get(ctx, perm.UserID)
if err != nil {
response.WriteServerError(w, method, err)
break
}
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
go mailer.ShareSpaceExistingUser(existingUser.Email, inviter.Fullname(), url, sp.Name, model.Message)
h.Runtime.Log.Info(fmt.Sprintf("%s is sharing space %s with existing user %s", inviter.Email, sp.Name, existingUser.Email))
}
}
}
@ -680,7 +681,7 @@ func (h *Handler) SetPermissions(w http.ResponseWriter, r *http.Request) {
perm.RefID = id
perm.Action = "" // we send array for actions below
err = h.Store.Space.AddPermission(ctx, perm)
err = h.Store.Space.AddPermissions(ctx, perm, space.SpaceView, space.SpaceManage)
if err != nil {
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)

View file

@ -90,26 +90,25 @@ func (s Scope) PublicSpaces(ctx domain.RequestContext, orgID string) (sp []space
// Also handles which spaces can be seen by anonymous users.
func (s Scope) GetAll(ctx domain.RequestContext) (sp []space.Space, err error) {
sql := `
(SELECT id,refid,label as name,orgid,userid,type,created,revised from label WHERE orgid=? AND type=2 AND userid=?)
UNION ALL
(SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label a where orgid=? AND type=1 AND refid in
(SELECT labelid from labelrole WHERE orgid=? AND userid='' AND (canedit=1 OR canview=1)))
UNION ALL
(SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label a where orgid=? AND type=3 AND refid in
(SELECT labelid from labelrole WHERE orgid=? AND userid=? AND (canedit=1 OR canview=1)))
SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label
WHERE orgid=?
AND refid IN (SELECT refid FROM permission WHERE orgid=? AND location='space' AND refid IN (
SELECT refid from permission WHERE orgid=? AND who='user' AND whoid=? AND location='space' UNION ALL
SELECT p.refid from permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role'
AND p.location='space' AND p.action='view' AND r.userid=?
))
ORDER BY name`
err = s.Runtime.Db.Select(&sp, sql,
ctx.OrgID,
ctx.OrgID,
ctx.OrgID,
ctx.UserID,
ctx.OrgID,
ctx.OrgID,
ctx.OrgID,
ctx.OrgID,
ctx.UserID)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("Unable to execute select labels for org %s", ctx.OrgID))
err = errors.Wrap(err, fmt.Sprintf("failed space.GetAll org %s", ctx.OrgID))
return
}
@ -137,25 +136,6 @@ func (s Scope) Update(ctx domain.RequestContext, sp space.Space) (err error) {
return
}
// ChangeOwner transfer space ownership.
func (s Scope) ChangeOwner(ctx domain.RequestContext, currentOwner, newOwner string) (err error) {
stmt, err := ctx.Transaction.Preparex("UPDATE label SET userid=? WHERE userid=? AND orgid=?")
defer streamutil.Close(stmt)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("unable to prepare change space owner for %s", currentOwner))
return
}
_, err = stmt.Exec(newOwner, currentOwner, ctx.OrgID)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("unable to execute change space owner for %s", currentOwner))
return
}
return
}
// Viewers returns the list of people who can see shared spaces.
func (s Scope) Viewers(ctx domain.RequestContext) (v []space.Viewer, err error) {
sql := `
@ -184,11 +164,11 @@ func (s Scope) Delete(ctx domain.RequestContext, id string) (rows int64, err err
return b.DeleteConstrained(ctx.Transaction, "label", ctx.OrgID, id)
}
// AddPermission inserts the given record into the labelrole database table.
// AddPermission inserts the given record into the permisssion table.
func (s Scope) AddPermission(ctx domain.RequestContext, r space.Permission) (err error) {
r.Created = time.Now().UTC()
stmt, err := ctx.Transaction.Preparex("INSERT INTO labelrole (orgid, who, whoid, action, scope, location, refid, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
stmt, err := ctx.Transaction.Preparex("INSERT INTO permission (orgid, who, whoid, action, scope, location, refid, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
defer streamutil.Close(stmt)
if err != nil {
@ -196,7 +176,7 @@ func (s Scope) AddPermission(ctx domain.RequestContext, r space.Permission) (err
return
}
_, err = stmt.Exec(r.OrgID, r.Who, r.WhoID, r.Action, r.Scope, r.Location, r.RefID, r.Created)
_, err = stmt.Exec(r.OrgID, r.Who, r.WhoID, string(r.Action), r.Scope, r.Location, r.RefID, r.Created)
if err != nil {
err = errors.Wrap(err, "unable to execute insert for space permission")
return
@ -279,3 +259,13 @@ func (s Scope) DeleteUserPermissions(ctx domain.RequestContext, spaceID, userID
return b.DeleteWhere(ctx.Transaction, sql)
}
// DeleteAllUserPermissions removes all roles for the specified user, for the specified space.
func (s Scope) DeleteAllUserPermissions(ctx domain.RequestContext, userID string) (rows int64, err error) {
b := mysql.BaseQuery{}
sql := fmt.Sprintf("DELETE FROM permission WHERE orgid='%s' AND who='user' AND whoid='%s'",
ctx.OrgID, userID)
return b.DeleteWhere(ctx.Transaction, sql)
}

View file

@ -53,7 +53,6 @@ type SpaceStorer interface {
PublicSpaces(ctx RequestContext, orgID string) (sp []space.Space, err error)
GetAll(ctx RequestContext) (sp []space.Space, err error)
Update(ctx RequestContext, sp space.Space) (err error)
ChangeOwner(ctx RequestContext, currentOwner, newOwner string) (err error)
Viewers(ctx RequestContext) (v []space.Viewer, err error)
Delete(ctx RequestContext, id string) (rows int64, err error)
@ -61,8 +60,9 @@ type SpaceStorer interface {
AddPermissions(ctx RequestContext, r space.Permission, actions ...space.PermissionAction) (err error)
GetUserPermissions(ctx RequestContext, spaceID string) (r []space.Permission, err error)
GetPermissions(ctx RequestContext, spaceID string) (r []space.Permission, err error)
DeleteUserPermissions(ctx RequestContext, spaceID, userID string) (rows int64, err error)
DeletePermissions(ctx RequestContext, spaceID string) (rows int64, err error)
DeleteUserPermissions(ctx RequestContext, spaceID, userID string) (rows int64, err error)
DeleteAllUserPermissions(ctx RequestContext, userID string) (rows int64, err error)
}
// UserStorer defines required methods for user management

View file

@ -377,7 +377,8 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
return
}
err = h.Store.Space.ChangeOwner(ctx, userID, ctx.UserID)
// remove all associated roles for this user
_, err = h.Store.Space.DeleteAllUserPermissions(ctx, userID)
if err != nil {
ctx.Transaction.Rollback()
response.WriteServerError(w, method, err)