2017-09-18 17:53:42 +01:00
// 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
2018-09-26 17:59:56 +01:00
package permission
2017-09-18 17:53:42 +01:00
import (
"database/sql"
"fmt"
"time"
"github.com/documize/community/domain"
2018-09-26 17:59:56 +01:00
"github.com/documize/community/domain/store"
2017-09-18 17:53:42 +01:00
"github.com/documize/community/model/permission"
2017-09-21 15:48:00 +01:00
"github.com/documize/community/model/user"
2017-09-18 17:53:42 +01:00
"github.com/pkg/errors"
)
2018-09-26 17:59:56 +01:00
// Store provides data access to user permission information.
type Store struct {
store . Context
2018-09-27 15:14:48 +01:00
store . PermissionStorer
2017-09-18 17:53:42 +01:00
}
// AddPermission inserts the given record into the permisssion table.
2018-09-26 17:59:56 +01:00
func ( s Store ) AddPermission ( ctx domain . RequestContext , r permission . Permission ) ( err error ) {
2017-09-18 17:53:42 +01:00
r . Created = time . Now ( ) . UTC ( )
2018-09-28 16:33:15 +01:00
_ , err = ctx . Transaction . Exec ( s . Bind ( ` INSERT INTO dmz_permission
( c_orgid , c_who , c_whoid , c_action , c_scope , c_location , c_refid , c_created ) VALUES ( ? , ? , ? , ? , ? , ? , ? , ? ) ` ) ,
2018-03-03 17:46:29 +00:00
r . OrgID , string ( r . Who ) , r . WhoID , string ( r . Action ) , string ( r . Scope ) , string ( r . Location ) , r . RefID , r . Created )
2017-09-18 17:53:42 +01:00
if err != nil {
err = errors . Wrap ( err , "unable to execute insert permission" )
}
return
}
// AddPermissions inserts records into permission database table, one per action.
2018-09-26 17:59:56 +01:00
func ( s Store ) AddPermissions ( ctx domain . RequestContext , r permission . Permission , actions ... permission . Action ) ( err error ) {
2017-09-18 17:53:42 +01:00
for _ , a := range actions {
r . Action = a
2018-03-02 14:48:41 +00:00
err := s . AddPermission ( ctx , r )
if err != nil {
return err
}
2017-09-18 17:53:42 +01:00
}
return
}
// GetUserSpacePermissions returns space permissions for user.
2018-03-02 14:48:41 +00:00
// Context is used to for userID because must match by userID
// or everyone ID of 0.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetUserSpacePermissions ( ctx domain . RequestContext , spaceID string ) ( r [ ] permission . Permission , err error ) {
2018-04-05 14:22:23 +01:00
r = [ ] permission . Permission { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-19 16:03:29 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action ,
c_scope AS scope , c_location AS location , c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission
2018-09-19 16:03:29 +01:00
WHERE c_orgid = ? AND c_location = ' space ' AND c_refid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' )
2017-09-18 17:53:42 +01:00
UNION ALL
2018-09-19 16:03:29 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission p
2018-09-19 16:03:29 +01:00
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' space ' AND c_refid = ? AND p . c_who = ' role ' AND ( r . c_userid = ? OR r . c_userid = '0' ) ` ) ,
2018-01-26 15:34:20 +00:00
ctx . OrgID , spaceID , ctx . UserID , ctx . OrgID , spaceID , ctx . UserID )
2017-09-18 17:53:42 +01:00
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-18 17:53:42 +01:00
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select user permissions %s" , ctx . UserID ) )
}
return
}
2018-06-27 13:09:25 +01:00
// GetSpacePermissionsForUser returns space permissions for specified user.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetSpacePermissionsForUser ( ctx domain . RequestContext , spaceID , userID string ) ( r [ ] permission . Permission , err error ) {
2018-06-27 13:09:25 +01:00
r = [ ] permission . Permission { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' space ' AND c_refid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' )
2018-06-27 13:09:25 +01:00
UNION ALL
2018-09-18 20:55:40 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
FROM dmz_permission p
2018-09-19 16:03:29 +01:00
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' space ' AND c_refid = ? AND p . c_who = ' role ' AND ( r . c_userid = ? OR r . c_userid = '0' ) ` ) ,
2018-06-27 13:09:25 +01:00
ctx . OrgID , spaceID , userID , ctx . OrgID , spaceID , userID )
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select user permissions %s" , userID ) )
}
return
}
2017-09-18 17:53:42 +01:00
// GetSpacePermissions returns space permissions for all users.
2018-03-02 14:48:41 +00:00
// We do not filter by userID because we return permissions for all users.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetSpacePermissions ( ctx domain . RequestContext , spaceID string ) ( r [ ] permission . Permission , err error ) {
2018-04-05 14:22:23 +01:00
r = [ ] permission . Permission { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
2018-09-26 17:59:56 +01:00
WHERE c_orgid = ? AND c_location = ' space ' AND c_refid = ? ` ) ,
2018-09-10 17:40:42 +01:00
ctx . OrgID , spaceID )
2017-09-18 17:53:42 +01:00
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select space permissions %s" , ctx . UserID ) )
}
return
}
2017-09-21 15:48:00 +01:00
// GetCategoryPermissions returns category permissions for all users.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetCategoryPermissions ( ctx domain . RequestContext , catID string ) ( r [ ] permission . Permission , err error ) {
2018-04-05 14:22:23 +01:00
r = [ ] permission . Permission { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' category ' AND c_who = ' user ' AND ( c_refid = ? OR c_refid = '0' )
2017-09-21 15:48:00 +01:00
UNION ALL
2018-09-20 12:47:47 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission p
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' category ' AND p . c_who = ' role ' AND ( p . c_refid = ? OR p . c_refid = '0' ) ` ) ,
2017-09-21 15:48:00 +01:00
ctx . OrgID , catID , ctx . OrgID , catID )
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-21 15:48:00 +01:00
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select category permissions %s" , catID ) )
}
return
}
// GetCategoryUsers returns space permissions for all users.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetCategoryUsers ( ctx domain . RequestContext , catID string ) ( u [ ] user . User , err error ) {
2018-04-05 14:22:23 +01:00
u = [ ] user . User { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & u , s . Bind ( `
SELECT u . id , COALESCE ( u . c_refid , ' ' ) AS refid , COALESCE ( u . c_firstname , ' ' ) AS firstname , COALESCE ( u . c_lastname , ' ' ) as lastname , u . email AS email , u . initials AS initials , u . password AS password , u . salt AS salt , u . c_reset AS reset , u . c_created AS created , u . c_revised AS revised
2018-09-20 12:47:47 +01:00
FROM dmz_user u
LEFT JOIN dmz_user_account a ON u . c_refid = a . c_userid
2019-04-01 12:02:23 +01:00
WHERE a . c_orgid = ? AND a . c_active = ` +s.IsTrue()+ ` AND u . c_refid IN (
2018-09-18 20:55:40 +01:00
SELECT c_whoid from dmz_permission
WHERE c_orgid = ? AND c_who = ' user ' AND c_location = ' category ' AND c_refid = ?
2018-03-02 14:48:41 +00:00
UNION ALL
2018-09-18 20:55:40 +01:00
SELECT r . c_userid from dmz_group_member r
LEFT JOIN dmz_permission p ON p . c_whoid = r . c_groupid
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' category ' AND p . c_refid = ?
2017-09-21 15:48:00 +01:00
)
GROUP by u . id
2018-09-26 17:59:56 +01:00
ORDER BY firstname , lastname ` ) ,
2017-09-21 15:48:00 +01:00
ctx . OrgID , ctx . OrgID , catID , ctx . OrgID , catID )
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-21 15:48:00 +01:00
err = nil
2018-03-02 14:48:41 +00:00
u = [ ] user . User { }
2017-09-21 15:48:00 +01:00
}
if err != nil {
2017-09-21 18:59:43 +01:00
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select users for category %s" , catID ) )
2017-09-21 15:48:00 +01:00
}
return
}
2017-10-04 14:42:07 -04:00
// GetUserCategoryPermissions returns category permissions for given user.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetUserCategoryPermissions ( ctx domain . RequestContext , userID string ) ( r [ ] permission . Permission , err error ) {
2018-04-05 14:22:23 +01:00
r = [ ] permission . Permission { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' category ' AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' )
UNION ALL
2018-09-19 16:03:29 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission p
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' category ' AND p . c_who = ' role ' AND ( r . c_userid = ? OR r . c_userid = '0' ) ` ) ,
2018-03-02 14:48:41 +00:00
ctx . OrgID , userID , ctx . OrgID , userID )
2017-10-04 14:42:07 -04:00
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-10-04 14:42:07 -04:00
err = nil
2019-08-27 15:24:59 +01:00
r = [ ] permission . Permission { }
2017-10-04 14:42:07 -04:00
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select category permissions for user %s" , userID ) )
}
return
}
2017-12-26 13:25:10 +00:00
// GetUserDocumentPermissions returns document permissions for user.
// Context is used to for user ID.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetUserDocumentPermissions ( ctx domain . RequestContext , documentID string ) ( r [ ] permission . Permission , err error ) {
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' document ' AND c_refid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' )
2017-12-26 13:25:10 +00:00
UNION ALL
2018-09-19 16:03:29 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission p
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' document ' AND p . c_refid = ? AND p . c_who = ' role ' AND ( r . c_userid = ? OR r . c_userid = '0' ) ` ) ,
2017-12-26 13:25:10 +00:00
ctx . OrgID , documentID , ctx . UserID , ctx . OrgID , documentID , ctx . OrgID )
if err == sql . ErrNoRows {
err = nil
2018-03-02 14:48:41 +00:00
r = [ ] permission . Permission { }
2017-12-26 13:25:10 +00:00
}
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.
2018-03-02 14:48:41 +00:00
// We do not filter by userID because we return permissions for all users.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetDocumentPermissions ( ctx domain . RequestContext , documentID string ) ( r [ ] permission . Permission , err error ) {
err = s . Runtime . Db . Select ( & r , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_orgid AS orgid , c_who AS who , c_whoid AS whoid , c_action AS action , c_scope AS scope , c_location AS location , c_refid AS refid
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' document ' AND c_refid = ? AND c_who = ' user '
2017-12-26 13:25:10 +00:00
UNION ALL
2018-09-20 17:07:40 +01:00
SELECT p . id , p . c_orgid AS orgid , p . c_who AS who , p . c_whoid AS whoid , p . c_action AS action , p . c_scope AS scope , p . c_location AS location , p . c_refid AS refid
2018-09-18 20:55:40 +01:00
FROM dmz_permission p
LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-26 17:59:56 +01:00
WHERE p . c_orgid = ? AND p . c_location = ' document ' AND p . c_refid = ? AND p . c_who = ' role ' ` ) ,
2017-12-26 13:25:10 +00:00
ctx . OrgID , documentID , ctx . OrgID , documentID )
if err == sql . ErrNoRows {
err = nil
2018-03-02 14:48:41 +00:00
r = [ ] permission . Permission { }
2017-12-26 13:25:10 +00:00
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select document permissions %s" , ctx . UserID ) )
}
return
}
2018-09-18 20:55:40 +01:00
// DeleteDocumentPermissions removes records from dmz_permissions table for given document.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteDocumentPermissions ( ctx domain . RequestContext , documentID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_location='document' AND c_refid=?" ) ,
ctx . OrgID , documentID )
2017-12-26 13:25:10 +00:00
2023-05-15 13:47:22 -04:00
return
2017-12-26 13:25:10 +00:00
}
2018-03-02 14:48:41 +00:00
2018-09-18 20:55:40 +01:00
// DeleteSpacePermissions removes records from dmz_permissions table for given space ID.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteSpacePermissions ( ctx domain . RequestContext , spaceID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_location='space' AND c_refid=?" ) ,
ctx . OrgID , spaceID )
2018-03-02 14:48:41 +00:00
2023-05-15 13:47:22 -04:00
return
2018-03-02 14:48:41 +00:00
}
// DeleteUserSpacePermissions removes all roles for the specified user, for the specified space.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteUserSpacePermissions ( ctx domain . RequestContext , spaceID , userID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_location='space' AND c_refid=? AND c_who='user' AND c_whoid=?" ) ,
2018-03-02 14:48:41 +00:00
ctx . OrgID , spaceID , userID )
2023-05-15 13:47:22 -04:00
return
2018-03-02 14:48:41 +00:00
}
// DeleteUserPermissions removes all roles for the specified user, for the specified space.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteUserPermissions ( ctx domain . RequestContext , userID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_who='user' AND c_whoid=?" ) ,
2018-03-02 14:48:41 +00:00
ctx . OrgID , userID )
2023-05-15 13:47:22 -04:00
return
2018-03-02 14:48:41 +00:00
}
2018-09-18 20:55:40 +01:00
// DeleteCategoryPermissions removes records from dmz_permissions table for given category ID.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteCategoryPermissions ( ctx domain . RequestContext , categoryID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_location='category' AND c_refid=?" ) ,
ctx . OrgID , categoryID )
2018-03-02 14:48:41 +00:00
2023-05-15 13:47:22 -04:00
return
2018-03-02 14:48:41 +00:00
}
// DeleteSpaceCategoryPermissions removes all category permission for for given space.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteSpaceCategoryPermissions ( ctx domain . RequestContext , spaceID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_location='category' AND c_refid IN (SELECT c_refid FROM dmz_category WHERE c_orgid=? AND c_spaceid=?)" ) ,
2018-03-02 14:48:41 +00:00
ctx . OrgID , ctx . OrgID , spaceID )
2023-05-15 13:47:22 -04:00
return
2018-03-02 14:48:41 +00:00
}
2018-03-09 09:51:44 +00:00
// DeleteGroupPermissions removes all roles for the specified group
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteGroupPermissions ( ctx domain . RequestContext , groupID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_permission WHERE c_orgid=? AND c_who='role' AND c_whoid=?" ) ,
2018-03-09 09:51:44 +00:00
ctx . OrgID , groupID )
2023-05-15 13:47:22 -04:00
return
2018-03-09 09:51:44 +00:00
}