mirror of
https://github.com/documize/community.git
synced 2025-08-02 20:15:26 +02:00
document level permissions
This commit is contained in:
parent
f4f32bcfcb
commit
b9394a4967
28 changed files with 983 additions and 355 deletions
|
@ -414,6 +414,17 @@ func (h *Handler) FetchDocumentData(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
record := pm.DecodeUserPermissions(perms)
|
||||
|
||||
roles, err := h.Store.Permission.GetUserDocumentPermissions(ctx, document.RefID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
response.WriteServerError(w, method, err)
|
||||
return
|
||||
}
|
||||
if len(roles) == 0 {
|
||||
roles = []pm.Permission{}
|
||||
}
|
||||
|
||||
rolesRecord := pm.DecodeUserDocumentPermissions(roles)
|
||||
|
||||
// links
|
||||
l, err := h.Store.Link.GetDocumentOutboundLinks(ctx, id)
|
||||
if len(l) == 0 {
|
||||
|
@ -439,6 +450,7 @@ func (h *Handler) FetchDocumentData(w http.ResponseWriter, r *http.Request) {
|
|||
data := documentData{}
|
||||
data.Document = document
|
||||
data.Permissions = record
|
||||
data.Roles = rolesRecord
|
||||
data.Links = l
|
||||
data.Spaces = sp
|
||||
|
||||
|
@ -469,8 +481,9 @@ func (h *Handler) FetchDocumentData(w http.ResponseWriter, r *http.Request) {
|
|||
// documentData represents all data associated for a single document.
|
||||
// Used by FetchDocumentData() bulk data load call.
|
||||
type documentData struct {
|
||||
Document doc.Document `json:"document"`
|
||||
Permissions pm.Record `json:"permissions"`
|
||||
Spaces []space.Space `json:"folders"`
|
||||
Links []link.Link `json:"link"`
|
||||
Document doc.Document `json:"document"`
|
||||
Permissions pm.Record `json:"permissions"`
|
||||
Roles pm.DocumentRecord `json:"roles"`
|
||||
Spaces []space.Space `json:"folders"`
|
||||
Links []link.Link `json:"link"`
|
||||
}
|
||||
|
|
98
domain/mail/document-approver.html
Normal file
98
domain/mail/document-approver.html
Normal file
|
@ -0,0 +1,98 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>{{.Subject}}</title>
|
||||
<style type="text/css">
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6;
|
||||
}
|
||||
body {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
@media only screen and (max-width: 640px) {
|
||||
h1 {
|
||||
font-weight: 600 !important; margin: 20px 0 5px !important;
|
||||
}
|
||||
h2 {
|
||||
font-weight: 600 !important; margin: 20px 0 5px !important;
|
||||
}
|
||||
h3 {
|
||||
font-weight: 600 !important; margin: 20px 0 5px !important;
|
||||
}
|
||||
h4 {
|
||||
font-weight: 600 !important; margin: 20px 0 5px !important;
|
||||
}
|
||||
h1 {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
h2 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
h3 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
.container {
|
||||
width: 100% !important;
|
||||
}
|
||||
.content {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.content-wrap {
|
||||
padding: 10px !important;
|
||||
}
|
||||
.invoice {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6; background: #f6f6f6; margin: 0; padding: 0;">
|
||||
|
||||
<table class="body-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background: #f6f6f6; margin: 0; padding: 0;">
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
|
||||
<td class="container" width="600" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto; padding: 0;" valign="top">
|
||||
<div class="content" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
||||
<table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background: #fff; margin: 0; padding: 0; border: 1px solid #e9e9e9;">
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<td class="alert alert-warning" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background: #1b75bb; margin: 0; padding: 20px;" align="center" valign="top">
|
||||
Document Approval Role Granted
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; margin: 0; padding: 0;">
|
||||
<td class="content-wrap" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
||||
<p>You are requested to approve all changes to the following document:</p>
|
||||
<p style="font-weight: bold;">{{.Document}}</p>
|
||||
<p>{{.Inviter}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
|
||||
<a href="{{.Url}}" class="btn-primary" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; background: #4ccb6a; margin: 0; padding: 0; border-color: #4ccb6a; border-style: solid; border-width: 10px 20px;">View document</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
|
||||
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px; color: #7a8184;" valign="top">
|
||||
Have any questions? <a href="mailto:team@documize.com" style="color: #7a8184;">Contact Documize</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0;" valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
70
domain/mail/document.go
Normal file
70
domain/mail/document.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// jshint ignore:start
|
||||
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// DocumentApprover notifies user who has just been granted document approval rights.
|
||||
func (m *Mailer) DocumentApprover(recipient, inviter, url, document string) {
|
||||
method := "DocumentApprover"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/document-approver.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has granted you document approval", inviter)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Document string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
document,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
|
@ -14,15 +14,11 @@
|
|||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// Mailer provides emailing facilities
|
||||
|
@ -33,241 +29,6 @@ type Mailer struct {
|
|||
Credentials Credentials
|
||||
}
|
||||
|
||||
// InviteNewUser invites someone new providing credentials, explaining the product and stating who is inviting them.
|
||||
func (m *Mailer) InviteNewUser(recipient, inviter, url, username, password string) {
|
||||
method := "InviteNewUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/invite-new-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has invited you to Documize", inviter)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Username string
|
||||
Password string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
recipient,
|
||||
password,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// InviteExistingUser invites a known user to an organization.
|
||||
func (m *Mailer) InviteExistingUser(recipient, inviter, url string) {
|
||||
method := "InviteExistingUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/invite-existing-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has invited you to their Documize account", inviter)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// PasswordReset sends a reset email with an embedded token.
|
||||
func (m *Mailer) PasswordReset(recipient, url string) {
|
||||
method := "PasswordReset"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/password-reset.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
subject := "Documize password reset request"
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender //e.g. "Documize <hello@documize.com>"
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Url string
|
||||
}{
|
||||
subject,
|
||||
url,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// ShareSpaceExistingUser provides an existing user with a link to a newly shared space.
|
||||
func (m *Mailer) ShareSpaceExistingUser(recipient, inviter, url, folder, intro string) {
|
||||
method := "ShareSpaceExistingUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/share-space-existing-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has shared %s with you", inviter, folder)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Folder string
|
||||
Intro string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
folder,
|
||||
intro,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// ShareSpaceNewUser invites new user providing Credentials, explaining the product and stating who is inviting them.
|
||||
func (m *Mailer) ShareSpaceNewUser(recipient, inviter, url, space, invitationMessage string) {
|
||||
method := "ShareSpaceNewUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/share-space-new-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has shared %s with you on Documize", inviter, space)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Invitation string
|
||||
Folder string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
invitationMessage,
|
||||
space,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// Credentials holds SMTP endpoint and authentication methods
|
||||
type Credentials struct {
|
||||
SMTPuserid string
|
||||
|
|
122
domain/mail/space.go
Normal file
122
domain/mail/space.go
Normal file
|
@ -0,0 +1,122 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// jshint ignore:start
|
||||
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// ShareSpaceExistingUser provides an existing user with a link to a newly shared space.
|
||||
func (m *Mailer) ShareSpaceExistingUser(recipient, inviter, url, folder, intro string) {
|
||||
method := "ShareSpaceExistingUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/share-space-existing-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has shared %s with you", inviter, folder)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Folder string
|
||||
Intro string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
folder,
|
||||
intro,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// ShareSpaceNewUser invites new user providing Credentials, explaining the product and stating who is inviting them.
|
||||
func (m *Mailer) ShareSpaceNewUser(recipient, inviter, url, space, invitationMessage string) {
|
||||
method := "ShareSpaceNewUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/share-space-new-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has shared %s with you on Documize", inviter, space)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Invitation string
|
||||
Folder string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
invitationMessage,
|
||||
space,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
157
domain/mail/user.go
Normal file
157
domain/mail/user.go
Normal file
|
@ -0,0 +1,157 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// jshint ignore:start
|
||||
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// InviteNewUser invites someone new providing credentials, explaining the product and stating who is inviting them.
|
||||
func (m *Mailer) InviteNewUser(recipient, inviter, url, username, password string) {
|
||||
method := "InviteNewUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/invite-new-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has invited you to Documize", inviter)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
Username string
|
||||
Password string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
recipient,
|
||||
password,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// InviteExistingUser invites a known user to an organization.
|
||||
func (m *Mailer) InviteExistingUser(recipient, inviter, url string) {
|
||||
method := "InviteExistingUser"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/invite-existing-user.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
// check inviter name
|
||||
if inviter == "Hello You" || len(inviter) == 0 {
|
||||
inviter = "Your colleague"
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("%s has invited you to their Documize account", inviter)
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Inviter string
|
||||
Url string
|
||||
}{
|
||||
subject,
|
||||
inviter,
|
||||
url,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
||||
|
||||
// PasswordReset sends a reset email with an embedded token.
|
||||
func (m *Mailer) PasswordReset(recipient, url string) {
|
||||
method := "PasswordReset"
|
||||
m.LoadCredentials()
|
||||
|
||||
file, err := web.ReadFile("mail/password-reset.html")
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to load email template", method), err)
|
||||
return
|
||||
}
|
||||
|
||||
emailTemplate := string(file)
|
||||
|
||||
subject := "Documize password reset request"
|
||||
|
||||
e := NewEmail()
|
||||
e.From = m.Credentials.SMTPsender //e.g. "Documize <hello@documize.com>"
|
||||
e.To = []string{recipient}
|
||||
e.Subject = subject
|
||||
|
||||
parameters := struct {
|
||||
Subject string
|
||||
Url string
|
||||
}{
|
||||
subject,
|
||||
url,
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
t := template.Must(template.New("emailTemplate").Parse(emailTemplate))
|
||||
t.Execute(buffer, ¶meters)
|
||||
e.HTML = buffer.Bytes()
|
||||
|
||||
err = e.Send(m.GetHost(), m.GetAuth())
|
||||
if err != nil {
|
||||
m.Runtime.Log.Error(fmt.Sprintf("%s - unable to send email", method), err)
|
||||
}
|
||||
}
|
|
@ -54,8 +54,8 @@ func (s Scope) Add(ctx domain.RequestContext, model page.NewPage) (err error) {
|
|||
model.Page.Sequence = maxSeq * 2
|
||||
}
|
||||
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO page (refid, orgid, documentid, userid, contenttype, pagetype, level, title, body, revisions, sequence, blockid, protected, approval, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
model.Page.RefID, model.Page.OrgID, model.Page.DocumentID, model.Page.UserID, model.Page.ContentType, model.Page.PageType, model.Page.Level, model.Page.Title, model.Page.Body, model.Page.Revisions, model.Page.Sequence, model.Page.BlockID, model.Page.Protection, model.Page.Approval, model.Page.Created, model.Page.Revised)
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO page (refid, orgid, documentid, userid, contenttype, pagetype, level, title, body, revisions, sequence, blockid, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
model.Page.RefID, model.Page.OrgID, model.Page.DocumentID, model.Page.UserID, model.Page.ContentType, model.Page.PageType, model.Page.Level, model.Page.Title, model.Page.Body, model.Page.Revisions, model.Page.Sequence, model.Page.BlockID, model.Page.Created, model.Page.Revised)
|
||||
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO pagemeta (pageid, orgid, userid, documentid, rawbody, config, externalsource, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
model.Meta.PageID, model.Meta.OrgID, model.Meta.UserID, model.Meta.DocumentID, model.Meta.RawBody, model.Meta.Config, model.Meta.ExternalSource, model.Meta.Created, model.Meta.Revised)
|
||||
|
@ -69,7 +69,7 @@ func (s Scope) Add(ctx domain.RequestContext, model page.NewPage) (err error) {
|
|||
|
||||
// Get returns the pageID page record from the page table.
|
||||
func (s Scope) Get(ctx domain.RequestContext, pageID string) (p page.Page, err error) {
|
||||
err = s.Runtime.Db.Get(&p, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.blockid, a.protection, a.approval, a.created, a.revised FROM page a WHERE a.orgid=? AND a.refid=?",
|
||||
err = s.Runtime.Db.Get(&p, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.blockid, a.created, a.revised FROM page a WHERE a.orgid=? AND a.refid=?",
|
||||
ctx.OrgID, pageID)
|
||||
|
||||
if err != nil {
|
||||
|
@ -81,7 +81,7 @@ func (s Scope) Get(ctx domain.RequestContext, pageID string) (p page.Page, err e
|
|||
|
||||
// GetPages returns a slice containing all the page records for a given documentID, in presentation sequence.
|
||||
func (s Scope) GetPages(ctx domain.RequestContext, documentID string) (p []page.Page, err error) {
|
||||
err = s.Runtime.Db.Select(&p, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.blockid, a.protection, a.approval, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? ORDER BY a.sequence", ctx.OrgID, documentID)
|
||||
err = s.Runtime.Db.Select(&p, "SELECT a.id, a.refid, a.orgid, a.documentid, a.userid, a.contenttype, a.pagetype, a.level, a.sequence, a.title, a.body, a.revisions, a.blockid, a.created, a.revised FROM page a WHERE a.orgid=? AND a.documentid=? ORDER BY a.sequence", ctx.OrgID, documentID)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "execute get pages")
|
||||
|
@ -93,7 +93,7 @@ func (s Scope) GetPages(ctx domain.RequestContext, documentID string) (p []page.
|
|||
// GetPagesWithoutContent returns a slice containing all the page records for a given documentID, in presentation sequence,
|
||||
// but without the body field (which holds the HTML content).
|
||||
func (s Scope) GetPagesWithoutContent(ctx domain.RequestContext, documentID string) (pages []page.Page, err error) {
|
||||
err = s.Runtime.Db.Select(&pages, "SELECT id, refid, orgid, documentid, userid, contenttype, pagetype, sequence, level, title, revisions, blockid, protection, approval, created, revised FROM page WHERE orgid=? AND documentid=? ORDER BY sequence", ctx.OrgID, documentID)
|
||||
err = s.Runtime.Db.Select(&pages, "SELECT id, refid, orgid, documentid, userid, contenttype, pagetype, sequence, level, title, revisions, blockid, created, revised FROM page WHERE orgid=? AND documentid=? ORDER BY sequence", ctx.OrgID, documentID)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("Unable to execute select pages for org %s and document %s", ctx.OrgID, documentID))
|
||||
|
@ -119,7 +119,7 @@ func (s Scope) Update(ctx domain.RequestContext, page page.Page, refID, userID s
|
|||
}
|
||||
|
||||
// Update page
|
||||
_, err = ctx.Transaction.NamedExec("UPDATE page SET documentid=:documentid, level=:level, title=:title, body=:body, revisions=:revisions, sequence=:sequence, protection=:protection, approval=:approval, revised=:revised WHERE orgid=:orgid AND refid=:refid",
|
||||
_, err = ctx.Transaction.NamedExec("UPDATE page SET documentid=:documentid, level=:level, title=:title, body=:body, revisions=:revisions, sequence=:sequence, revised=:revised WHERE orgid=:orgid AND refid=:refid",
|
||||
&page)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -69,7 +69,7 @@ func (h *Handler) SetSpacePermissions(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
var model = permission.PermissionsModel{}
|
||||
var model = permission.SpaceRequestModel{}
|
||||
err = json.Unmarshal(body, &model)
|
||||
if err != nil {
|
||||
response.WriteServerError(w, method, err)
|
||||
|
@ -398,3 +398,192 @@ func (h *Handler) SetCategoryPermissions(w http.ResponseWriter, r *http.Request)
|
|||
|
||||
response.WriteEmpty(w)
|
||||
}
|
||||
|
||||
// GetDocumentPermissions returns permissions for all users for given document.
|
||||
func (h *Handler) GetDocumentPermissions(w http.ResponseWriter, r *http.Request) {
|
||||
method := "space.GetDocumentPermissions"
|
||||
ctx := domain.GetRequestContext(r)
|
||||
|
||||
documentID := request.Param(r, "documentID")
|
||||
if len(documentID) == 0 {
|
||||
response.WriteMissingDataError(w, method, "documentID")
|
||||
return
|
||||
}
|
||||
|
||||
perms, err := h.Store.Permission.GetDocumentPermissions(ctx, documentID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
response.WriteServerError(w, method, err)
|
||||
return
|
||||
}
|
||||
if len(perms) == 0 {
|
||||
perms = []permission.Permission{}
|
||||
}
|
||||
|
||||
userPerms := make(map[string][]permission.Permission)
|
||||
for _, p := range perms {
|
||||
userPerms[p.WhoID] = append(userPerms[p.WhoID], p)
|
||||
}
|
||||
|
||||
records := []permission.DocumentRecord{}
|
||||
for _, up := range userPerms {
|
||||
records = append(records, permission.DecodeUserDocumentPermissions(up))
|
||||
}
|
||||
|
||||
response.WriteJSON(w, records)
|
||||
}
|
||||
|
||||
// GetUserDocumentPermissions returns permissions for the requested space, for current user.
|
||||
func (h *Handler) GetUserDocumentPermissions(w http.ResponseWriter, r *http.Request) {
|
||||
method := "space.GetUserDocumentPermissions"
|
||||
ctx := domain.GetRequestContext(r)
|
||||
|
||||
documentID := request.Param(r, "documentID")
|
||||
if len(documentID) == 0 {
|
||||
response.WriteMissingDataError(w, method, "documentID")
|
||||
return
|
||||
}
|
||||
|
||||
perms, err := h.Store.Permission.GetUserDocumentPermissions(ctx, documentID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
response.WriteServerError(w, method, err)
|
||||
return
|
||||
}
|
||||
if len(perms) == 0 {
|
||||
perms = []permission.Permission{}
|
||||
}
|
||||
|
||||
record := permission.DecodeUserDocumentPermissions(perms)
|
||||
response.WriteJSON(w, record)
|
||||
}
|
||||
|
||||
// SetDocumentPermissions persists specified document permissions
|
||||
// These permissions override document permissions
|
||||
func (h *Handler) SetDocumentPermissions(w http.ResponseWriter, r *http.Request) {
|
||||
method := "space.SetDocumentPermissions"
|
||||
ctx := domain.GetRequestContext(r)
|
||||
|
||||
id := request.Param(r, "documentID")
|
||||
if len(id) == 0 {
|
||||
response.WriteMissingDataError(w, method, "documentID")
|
||||
return
|
||||
}
|
||||
|
||||
doc, err := h.Store.Document.Get(ctx, id)
|
||||
if err != nil {
|
||||
response.WriteNotFoundError(w, method, "document not found")
|
||||
return
|
||||
}
|
||||
|
||||
sp, err := h.Store.Space.Get(ctx, doc.LabelID)
|
||||
if err != nil {
|
||||
response.WriteNotFoundError(w, method, "space not found")
|
||||
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 {
|
||||
response.WriteBadRequestError(w, method, err.Error())
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
var model = []permission.DocumentRecord{}
|
||||
err = json.Unmarshal(body, &model)
|
||||
if err != nil {
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
||||
if err != nil {
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
// We compare new permisions to what we had before.
|
||||
// Why? So we can send out space invitation emails.
|
||||
previousRoles, err := h.Store.Permission.GetDocumentPermissions(ctx, id)
|
||||
if err != nil {
|
||||
ctx.Transaction.Rollback()
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Store all previous approval roles as map for easy querying
|
||||
previousRoleUsers := make(map[string]bool)
|
||||
for _, v := range previousRoles {
|
||||
if v.Action == permission.DocumentApprove {
|
||||
previousRoleUsers[v.WhoID] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Get user who is setting document permissions so we can send out emails with context
|
||||
inviter, err := h.Store.User.Get(ctx, ctx.UserID)
|
||||
if err != nil {
|
||||
ctx.Transaction.Rollback()
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Nuke all previous permissions for this document
|
||||
_, err = h.Store.Permission.DeleteDocumentPermissions(ctx, id)
|
||||
if err != nil {
|
||||
ctx.Transaction.Rollback()
|
||||
response.WriteServerError(w, method, err)
|
||||
h.Runtime.Log.Error(method, err)
|
||||
return
|
||||
}
|
||||
|
||||
url := ctx.GetAppURL(fmt.Sprintf("s/%s/%s/d/%s/%s",
|
||||
sp.RefID, stringutil.MakeSlug(sp.Name), doc.RefID, stringutil.MakeSlug(doc.Title)))
|
||||
|
||||
for _, perm := range model {
|
||||
perm.OrgID = ctx.OrgID
|
||||
perm.DocumentID = id
|
||||
|
||||
// Only persist if there is a role!
|
||||
if permission.HasAnyDocumentPermission(perm) {
|
||||
r := permission.EncodeUserDocumentPermissions(perm)
|
||||
|
||||
for _, p := range r {
|
||||
err = h.Store.Permission.AddPermission(ctx, p)
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("set document permission", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Send email notification to users who have been given document approver role
|
||||
if _, isExisting := previousRoleUsers[perm.UserID]; !isExisting {
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h.Store.Audit.Record(ctx, audit.EventTypeDocumentPermission)
|
||||
|
||||
ctx.Transaction.Commit()
|
||||
|
||||
response.WriteEmpty(w)
|
||||
}
|
||||
|
|
|
@ -212,3 +212,55 @@ func (s Scope) GetUserCategoryPermissions(ctx domain.RequestContext, userID stri
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserDocumentPermissions returns document permissions for user.
|
||||
// Context is used to for user ID.
|
||||
func (s Scope) GetUserDocumentPermissions(ctx domain.RequestContext, documentID 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='document' 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 LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.location='document' AND refid=?
|
||||
AND p.who='role' AND (r.userid=? OR r.userid='0')`,
|
||||
ctx.OrgID, documentID, ctx.UserID, ctx.OrgID, documentID, ctx.OrgID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("unable to execute select user document permissions %s", ctx.UserID))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetDocumentPermissions returns documents permissions for all users.
|
||||
func (s Scope) GetDocumentPermissions(ctx domain.RequestContext, documentID 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='document' AND refid=? AND who='user'
|
||||
UNION ALL
|
||||
SELECT p.id, p.orgid, p.who, p.whoid, p.action, p.scope, p.location, p.refid
|
||||
FROM permission p LEFT JOIN rolemember r ON p.whoid=r.roleid WHERE p.orgid=? AND p.location='document' AND p.refid=?
|
||||
AND p.who='role'`,
|
||||
ctx.OrgID, documentID, ctx.OrgID, documentID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("unable to execute select document permissions %s", ctx.UserID))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteDocumentPermissions removes records from permissions table for given document.
|
||||
func (s Scope) DeleteDocumentPermissions(ctx domain.RequestContext, documentID string) (rows int64, err error) {
|
||||
b := mysql.BaseQuery{}
|
||||
|
||||
sql := fmt.Sprintf("DELETE FROM permission WHERE orgid='%s' AND location='document' AND refid='%s'", ctx.OrgID, documentID)
|
||||
|
||||
return b.DeleteWhere(ctx.Transaction, sql)
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ type PermissionStorer interface {
|
|||
GetCategoryPermissions(ctx RequestContext, catID string) (r []permission.Permission, err error)
|
||||
GetCategoryUsers(ctx RequestContext, catID string) (u []user.User, err error)
|
||||
GetUserCategoryPermissions(ctx RequestContext, userID string) (r []permission.Permission, err error)
|
||||
GetUserDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error)
|
||||
GetDocumentPermissions(ctx RequestContext, documentID string) (r []permission.Permission, err error)
|
||||
DeleteDocumentPermissions(ctx RequestContext, documentID string) (rows int64, err error)
|
||||
}
|
||||
|
||||
// UserStorer defines required methods for user management
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue