105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
package imap
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// IMAP4 ACL extension (RFC 2086)
|
|
|
|
// Right describes a set of operations controlled by the IMAP ACL extension.
|
|
type Right byte
|
|
|
|
const (
|
|
// Standard rights
|
|
RightLookup = Right('l') // mailbox is visible to LIST/LSUB commands
|
|
RightRead = Right('r') // SELECT the mailbox, perform CHECK, FETCH, PARTIAL, SEARCH, COPY from mailbox
|
|
RightSeen = Right('s') // keep seen/unseen information across sessions (STORE SEEN flag)
|
|
RightWrite = Right('w') // STORE flags other than SEEN and DELETED
|
|
RightInsert = Right('i') // perform APPEND, COPY into mailbox
|
|
RightPost = Right('p') // send mail to submission address for mailbox, not enforced by IMAP4 itself
|
|
RightCreate = Right('c') // CREATE new sub-mailboxes in any implementation-defined hierarchy
|
|
RightDelete = Right('d') // STORE DELETED flag, perform EXPUNGE
|
|
RightAdminister = Right('a') // perform SETACL
|
|
)
|
|
|
|
// RightSetAll contains all standard rights.
|
|
var RightSetAll = RightSet("lrswipcda")
|
|
|
|
// RightsIdentifier is an ACL identifier.
|
|
type RightsIdentifier string
|
|
|
|
// RightsIdentifierAnyone is the universal identity (matches everyone).
|
|
const RightsIdentifierAnyone = RightsIdentifier("anyone")
|
|
|
|
// NewRightsIdentifierUsername returns a rights identifier referring to a
|
|
// username, checking for reserved values.
|
|
func NewRightsIdentifierUsername(username string) (RightsIdentifier, error) {
|
|
if username == string(RightsIdentifierAnyone) || strings.HasPrefix(username, "-") {
|
|
return "", fmt.Errorf("imap: reserved rights identifier")
|
|
}
|
|
return RightsIdentifier(username), nil
|
|
}
|
|
|
|
// RightModification indicates how to mutate a right set.
|
|
type RightModification byte
|
|
|
|
const (
|
|
RightModificationReplace = RightModification(0)
|
|
RightModificationAdd = RightModification('+')
|
|
RightModificationRemove = RightModification('-')
|
|
)
|
|
|
|
// A RightSet is a set of rights.
|
|
type RightSet []Right
|
|
|
|
// String returns a string representation of the right set.
|
|
func (r RightSet) String() string {
|
|
return string(r)
|
|
}
|
|
|
|
// Add returns a new right set containing rights from both sets.
|
|
func (r RightSet) Add(rights RightSet) RightSet {
|
|
newRights := make(RightSet, len(r), len(r)+len(rights))
|
|
copy(newRights, r)
|
|
|
|
for _, right := range rights {
|
|
if !strings.ContainsRune(string(r), rune(right)) {
|
|
newRights = append(newRights, right)
|
|
}
|
|
}
|
|
|
|
return newRights
|
|
}
|
|
|
|
// Remove returns a new right set containing all rights in r except these in
|
|
// the provided set.
|
|
func (r RightSet) Remove(rights RightSet) RightSet {
|
|
newRights := make(RightSet, 0, len(r))
|
|
|
|
for _, right := range r {
|
|
if !strings.ContainsRune(string(rights), rune(right)) {
|
|
newRights = append(newRights, right)
|
|
}
|
|
}
|
|
|
|
return newRights
|
|
}
|
|
|
|
// Equal returns true if both right sets contain exactly the same rights.
|
|
func (rs1 RightSet) Equal(rs2 RightSet) bool {
|
|
for _, r := range rs1 {
|
|
if !strings.ContainsRune(string(rs2), rune(r)) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
for _, r := range rs2 {
|
|
if !strings.ContainsRune(string(rs1), rune(r)) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|