mirror of
https://github.com/documize/community.git
synced 2025-07-19 13:19:43 +02:00
Persist space permissions for groups and users
This commit is contained in:
parent
0d39f7251e
commit
7ccb3b4658
16 changed files with 320 additions and 157 deletions
|
@ -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,52 +124,85 @@ 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 err != nil {
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
break
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
for i := range whoToEmail {
|
||||
existingUser, err := h.Store.User.Get(ctx, whoToEmail[i])
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error(method, err)
|
||||
continue
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,19 +633,32 @@ 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 err != nil {
|
||||
response.WriteServerError(w, method, err)
|
||||
break
|
||||
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)
|
||||
}
|
||||
|
||||
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
|
||||
go mailer.DocumentApprover(existingUser.Email, inviter.Fullname(), url, doc.Title)
|
||||
h.Runtime.Log.Info(fmt.Sprintf("%s has made %s document approver for: %s", inviter.Email, existingUser.Email, doc.Title))
|
||||
for i := range whoToEmail {
|
||||
existingUser, err := h.Store.User.Get(ctx, whoToEmail[i])
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error(method, err)
|
||||
continue
|
||||
}
|
||||
|
||||
mailer := mail.Mailer{Runtime: h.Runtime, Store: h.Store, Context: ctx}
|
||||
go mailer.DocumentApprover(existingUser.Email, inviter.Fullname(), url, doc.Title)
|
||||
h.Runtime.Log.Info(fmt.Sprintf("%s has made %s document approver for: %s", inviter.Email, existingUser.Email, doc.Title))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue