mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-11 13:28:57 +00:00
76 lines
3.0 KiB
Go
76 lines
3.0 KiB
Go
package authz
|
|
|
|
import (
|
|
"slices"
|
|
|
|
authzmodels "github.com/abhinavxd/libredesk/internal/authz/models"
|
|
cmodels "github.com/abhinavxd/libredesk/internal/conversation/models"
|
|
"github.com/abhinavxd/libredesk/internal/envelope"
|
|
umodels "github.com/abhinavxd/libredesk/internal/user/models"
|
|
"github.com/knadh/go-i18n"
|
|
"github.com/volatiletech/null/v9"
|
|
"github.com/zerodha/logf"
|
|
)
|
|
|
|
type Enforcer struct {
|
|
lo *logf.Logger
|
|
i18n *i18n.I18n
|
|
}
|
|
|
|
func NewEnforcer(lo *logf.Logger, i18n *i18n.I18n) (*Enforcer, error) {
|
|
return &Enforcer{lo: lo, i18n: i18n}, nil
|
|
}
|
|
|
|
// Enforce returns true if the user's permission list contains "obj:act".
|
|
func (e *Enforcer) Enforce(user umodels.User, obj, act string) (bool, error) {
|
|
return slices.Contains(user.Permissions, obj+":"+act), nil
|
|
}
|
|
|
|
// EnforceConversationAccess determines if a user has access to a specific conversation based on their permissions.
|
|
// Requires basic "read" permission AND one of the following conditions:
|
|
// 1. User has the "read_all" permission, allowing access to all conversations.
|
|
// 2. User has the "read_assigned" permission and is the assigned user.
|
|
// 3. User has the "read_team_inbox" permission and is part of the assigned team, with the conversation NOT assigned to any user.
|
|
// 4. User has the "read_unassigned" permission and the conversation is not assigned to any user or team.
|
|
// Returns true if access is granted, false otherwise. In case of an error while checking permissions returns false and the error.
|
|
func (e *Enforcer) EnforceConversationAccess(user umodels.User, conversation cmodels.Conversation) (bool, error) {
|
|
return CanReadAssignment(user, conversation.AssignedUserID, conversation.AssignedTeamID), nil
|
|
}
|
|
|
|
func CanReadAssignment(user umodels.User, assignedUserID, assignedTeamID null.Int) bool {
|
|
if !slices.Contains(user.Permissions, authzmodels.PermConversationsRead) {
|
|
return false
|
|
}
|
|
if slices.Contains(user.Permissions, authzmodels.PermConversationsReadAll) {
|
|
return true
|
|
}
|
|
if assignedUserID.Valid && assignedUserID.Int == user.ID &&
|
|
slices.Contains(user.Permissions, authzmodels.PermConversationsReadAssigned) {
|
|
return true
|
|
}
|
|
if assignedTeamID.Valid && slices.Contains(user.Teams.IDs(), assignedTeamID.Int) {
|
|
if slices.Contains(user.Permissions, authzmodels.PermConversationsReadTeamAll) {
|
|
return true
|
|
}
|
|
if !assignedUserID.Valid && slices.Contains(user.Permissions, authzmodels.PermConversationsReadTeamInbox) {
|
|
return true
|
|
}
|
|
}
|
|
if !assignedUserID.Valid && !assignedTeamID.Valid &&
|
|
slices.Contains(user.Permissions, authzmodels.PermConversationsReadUnassigned) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// EnforceMediaAccess checks read access on the model linked to a media item.
|
|
func (e *Enforcer) EnforceMediaAccess(user umodels.User, model string) (bool, error) {
|
|
if model != "messages" {
|
|
return true, nil
|
|
}
|
|
if !slices.Contains(user.Permissions, "messages:read") {
|
|
return false, envelope.NewError(envelope.UnauthorizedError, e.i18n.T("status.deniedPermission"), nil)
|
|
}
|
|
return true, nil
|
|
}
|