Documentation ¶
Index ¶
- Constants
- Variables
- func IsStateError(err error) bool
- func NewExpunge(messageID imap.InternalMessageID) *expunge
- func NewFetch(messageID imap.InternalMessageID, flags imap.FlagSet, ...) *fetch
- func NewStateContext(ctx context.Context, s *State) context.Context
- type AllStateFilter
- type AnyMessageIDStateFilter
- type AppendOnlyMailbox
- type Connector
- type ExistsStateUpdate
- type MBoxIDStateFilter
- type Mailbox
- func (m *Mailbox) Append(ctx context.Context, literal []byte, flags imap.FlagSet, date time.Time) (imap.UID, error)
- func (m *Mailbox) AppendRegular(ctx context.Context, literal []byte, flags imap.FlagSet, date time.Time) (imap.UID, error)
- func (m *Mailbox) Attributes(ctx context.Context) (imap.FlagSet, error)
- func (m *Mailbox) Close(ctx context.Context) error
- func (m *Mailbox) Copy(ctx context.Context, seq []command.SeqRange, name string) (response.Item, error)
- func (m *Mailbox) Count() int
- func (m *Mailbox) Expunge(ctx context.Context, seq []command.SeqRange) error
- func (m *Mailbox) ExpungeIssued() bool
- func (m *Mailbox) Fetch(ctx context.Context, cmd *command.Fetch, ch chan response.Response) error
- func (m *Mailbox) Flags(ctx context.Context) (imap.FlagSet, error)
- func (m *Mailbox) Flush(ctx context.Context, permitExpunge bool) ([]response.Response, error)
- func (m *Mailbox) GetFirstMessageWithFlag(flag string) (snapMsgWithSeq, bool)
- func (m *Mailbox) GetFirstMessageWithoutFlag(flag string) (snapMsgWithSeq, bool)
- func (m *Mailbox) GetMessagesWithFlag(flag string) []imap.SeqID
- func (m *Mailbox) GetMessagesWithFlagCount(flag string) int
- func (m *Mailbox) GetMessagesWithoutFlag(flag string) []imap.SeqID
- func (m *Mailbox) GetMessagesWithoutFlagCount(flag string) int
- func (m *Mailbox) Move(ctx context.Context, seq []command.SeqRange, name string) (response.Item, error)
- func (m *Mailbox) Name() string
- func (m *Mailbox) PermanentFlags(ctx context.Context) (imap.FlagSet, error)
- func (m *Mailbox) ReadOnly() bool
- func (m *Mailbox) Search(ctx context.Context, keys []command.SearchKey, decoder *encoding.Decoder) ([]uint32, error)
- func (m *Mailbox) Selected() bool
- func (m *Mailbox) Store(ctx context.Context, seqSet []command.SeqRange, action command.StoreAction, ...) error
- func (m *Mailbox) Subscribed() bool
- func (m *Mailbox) UIDNext() imap.UID
- func (m *Mailbox) UIDValidity() imap.UID
- type Match
- type MessageAndMBoxIDStateFilter
- type MessageIDStateFilter
- type RemoteAddMessageFlagsStateUpdate
- type RemoteMessageDeletedStateUpdate
- type RemoteRemoveMessageFlagsStateUpdate
- type Responder
- type SeqInterval
- type SnapFilter
- type State
- func (state *State) AppendOnlyMailbox(ctx context.Context, name string, fn func(AppendOnlyMailbox, bool) error) error
- func (state *State) ApplyUpdate(ctx context.Context, update Update) error
- func (state *State) Close(ctx context.Context) error
- func (state *State) Create(ctx context.Context, name string) error
- func (state *State) Delete(ctx context.Context, name string) (bool, error)
- func (state *State) Done() <-chan struct{}
- func (state *State) Examine(ctx context.Context, name string, fn func(*Mailbox) error) error
- func (state *State) GetStateUpdatesCh() <-chan Update
- func (state *State) HasMessage(id imap.InternalMessageID) bool
- func (state *State) Idle(ctx context.Context, ...) error
- func (state *State) IsSelected() bool
- func (state *State) IsValid() bool
- func (state *State) List(ctx context.Context, ref, pattern string, lsub bool, ...) error
- func (state *State) Mailbox(ctx context.Context, name string, fn func(*Mailbox) error) error
- func (state *State) PushResponder(ctx context.Context, tx *ent.Tx, responder ...Responder) error
- func (state *State) QueueUpdates(updates ...Update) bool
- func (state *State) ReleaseState(ctx context.Context) error
- func (state *State) Rename(ctx context.Context, oldName, newName string) error
- func (state *State) Select(ctx context.Context, name string, fn func(*Mailbox) error) error
- func (state *State) Selected(ctx context.Context, fn func(*Mailbox) error) error
- func (state *State) SetConnMetadataKeyValue(key string, value any)
- func (state *State) SignalClose()
- func (state *State) Subscribe(ctx context.Context, name string) error
- func (state *State) Unsubscribe(ctx context.Context, name string) error
- func (state *State) UpdateMailboxRemoteID(internalID imap.InternalMailboxID, remoteID imap.MailboxID) error
- func (state *State) UpdateMessageRemoteID(internalID imap.InternalMessageID, remoteID imap.MessageID) error
- func (state *State) UserID() string
- type StateID
- type UIDInterval
- type Update
- func AddMessagesToMailbox(ctx context.Context, tx *ent.Tx, mboxID imap.InternalMailboxID, ...) ([]db.UIDWithFlags, Update, error)
- func MoveMessagesFromMailbox(ctx context.Context, tx *ent.Tx, mboxFromID, mboxToID imap.InternalMailboxID, ...) ([]db.UIDWithFlags, []Update, error)
- func NewMailboxDeletedStateUpdate(mboxID imap.InternalMailboxID) Update
- func NewMailboxIDResponderStateUpdate(id imap.InternalMailboxID, responders ...Responder) Update
- func NewMailboxRemoteIDUpdateStateUpdate(internalID imap.InternalMailboxID, remoteID imap.MailboxID) Update
- func NewMessageFlagsRemovedStateUpdate(flags imap.FlagSet, mboxID ids.MailboxIDPair, ...) Update
- func NewMessageFlagsSetStateUpdate(flags imap.FlagSet, mboxID ids.MailboxIDPair, ...) Update
- func NewMessageIDAndMailboxIDResponderStateUpdate(messageID imap.InternalMessageID, mboxID imap.InternalMailboxID, ...) Update
- func NewMessageIDResponderStateUpdate(id imap.InternalMessageID, responders ...Responder) Update
- func NewRemoteAddMessageFlagsStateUpdate(messageID imap.InternalMessageID, flag string) Update
- func NewRemoteMessageDeletedStateUpdate(messageID imap.InternalMessageID, remoteID imap.MessageID) Update
- func NewRemoteRemoveMessageFlagsStateUpdate(messageID imap.InternalMessageID, flag string) Update
- func NewUIDValidityBumpedStateUpdate() Update
- func RemoveMessagesFromMailbox(ctx context.Context, tx *ent.Tx, mboxID imap.InternalMailboxID, ...) ([]Update, error)
- type UserInterface
Constants ¶
const ( FetchFlagOpAdd = iota FetchFlagOpRem FetchFlagOpSet )
Variables ¶
var ( ErrNoSuchMessage = errors.New("no such message") ErrNoSuchMailbox = errors.New("no such mailbox") ErrExistingMailbox = errors.New("a mailbox with that name already exists") ErrAlreadySubscribed = errors.New("already subscribed to this mailbox") ErrAlreadyUnsubscribed = errors.New("not subscribed to this mailbox") ErrSessionNotSelected = errors.New("session is not selected") ErrOperationNotAllowed = errors.New("operation not allowed") ErrMailboxNameBeginsWithSeparator = errors.New("invalid mailbox name: begins with hierarchy separator") ErrMailboxNameAdjacentSeparator = errors.New("invalid mailbox name: has adjacent hierarchy separators") )
var ErrOutOfOrderUIDInsertion = fmt.Errorf("UIDs must be strictly ascending")
Functions ¶
func IsStateError ¶ added in v0.16.0
func NewExpunge ¶
func NewExpunge(messageID imap.InternalMessageID) *expunge
Types ¶
type AllStateFilter ¶
type AllStateFilter struct{}
func (*AllStateFilter) Filter ¶
func (*AllStateFilter) Filter(s *State) bool
func (*AllStateFilter) String ¶
func (*AllStateFilter) String() string
type AnyMessageIDStateFilter ¶
type AnyMessageIDStateFilter struct {
MessageIDs []imap.InternalMessageID
}
func (*AnyMessageIDStateFilter) Filter ¶
func (f *AnyMessageIDStateFilter) Filter(s *State) bool
type AppendOnlyMailbox ¶
type Connector ¶
type Connector interface { // SetConnMetadataValue sets a metadata value associated with the current connector. SetConnMetadataValue(key string, value any) // ClearConnMetadataValue clears a metadata value associated with the current connector. ClearConnMetadataValue(key string) // ClearAllConnMetadata clears all metadata values associated with the current connector. ClearAllConnMetadata() // CreateMailbox creates a new mailbox with the given name. CreateMailbox(ctx context.Context, name []string) (imap.Mailbox, error) // UpdateMailbox sets the name of the mailbox with the given ID to the given new name. UpdateMailbox(ctx context.Context, mboxID imap.MailboxID, newName []string) error // DeleteMailbox deletes the mailbox with the given ID and name. DeleteMailbox(ctx context.Context, mboxID imap.MailboxID) error // CreateMessage appends a message literal to the mailbox with the given ID. CreateMessage( ctx context.Context, mboxID imap.MailboxID, literal []byte, flags imap.FlagSet, date time.Time, ) (imap.InternalMessageID, imap.Message, []byte, error) // GetMessageLiteral retrieves the message literal from the connector. // Note: this can get called from different go routines. GetMessageLiteral(ctx context.Context, id imap.MessageID) ([]byte, error) // AddMessagesToMailbox adds the message with the given ID to the mailbox with the given ID. AddMessagesToMailbox( ctx context.Context, messageIDs []imap.MessageID, mboxID imap.MailboxID, ) error // RemoveMessagesFromMailbox removes the message with the given ID from the mailbox with the given ID. RemoveMessagesFromMailbox( ctx context.Context, messageIDs []imap.MessageID, mboxID imap.MailboxID, ) error // MoveMessagesFromMailbox removes the message with the given ID from the mailbox with the given ID. MoveMessagesFromMailbox( ctx context.Context, messageIDs []imap.MessageID, mboxFromID imap.MailboxID, mboxToID imap.MailboxID, ) (bool, error) // SetMessagesSeen marks the message with the given ID as seen or unseen. SetMessagesSeen(ctx context.Context, messageIDs []imap.MessageID, seen bool) error // SetMessagesFlagged marks the message with the given ID as seen or unseen. SetMessagesFlagged(ctx context.Context, messageIDs []imap.MessageID, flagged bool) error // GetMailboxVisibility retrieves the visibility status of a mailbox for a client. GetMailboxVisibility(ctx context.Context, id imap.MailboxID) imap.MailboxVisibility }
Connector interface for State differs slightly from the connector.Connector interface as it needs the ability to generate internal IDs for each request as well as track local metadata associated with each state. The local metadata (e.g.: IMAP ID extension info) should be injected into the context before each call to ensure the connector.Connector can receive this information. Sadly, due to Go's cyclic dependencies, this needs to be an interface. The implementation of this interface is available in the backend package.
type ExistsStateUpdate ¶
type ExistsStateUpdate struct { MBoxIDStateFilter // contains filtered or unexported fields }
ExistsStateUpdate needs to be a separate update since it has to deal with a Recent flag propagation. If a session with a selected state appends a message, only that state should see the recent flag. If a message is appended to a non-selected mailbox or arrives from remote, the first state with the selected mailbox should get the flag. See ExistsStateUpdate.Apply() for more info.
func (*ExistsStateUpdate) String ¶
func (e *ExistsStateUpdate) String() string
type MBoxIDStateFilter ¶
type MBoxIDStateFilter struct {
MboxID imap.InternalMailboxID
}
func (*MBoxIDStateFilter) Filter ¶
func (f *MBoxIDStateFilter) Filter(s *State) bool
func (*MBoxIDStateFilter) String ¶
func (f *MBoxIDStateFilter) String() string
type Mailbox ¶
type Mailbox struct {
// contains filtered or unexported fields
}
func (*Mailbox) AppendRegular ¶ added in v0.14.0
func (*Mailbox) Attributes ¶
func (*Mailbox) Copy ¶
func (m *Mailbox) Copy(ctx context.Context, seq []command.SeqRange, name string) (response.Item, error)
Copy copies the messages represented by the given sequence set into the mailbox with the given name. If the context is a UID context, the sequence set refers to message UIDs. If no items are copied the response object will be nil.
func (*Mailbox) ExpungeIssued ¶
func (*Mailbox) GetFirstMessageWithFlag ¶
func (*Mailbox) GetFirstMessageWithoutFlag ¶
func (*Mailbox) GetMessagesWithFlag ¶
func (*Mailbox) GetMessagesWithFlagCount ¶
func (*Mailbox) GetMessagesWithoutFlag ¶
func (*Mailbox) GetMessagesWithoutFlagCount ¶
func (*Mailbox) Move ¶
func (m *Mailbox) Move(ctx context.Context, seq []command.SeqRange, name string) (response.Item, error)
Move moves the messages represented by the given sequence set into the mailbox with the given name. If the context is a UID context, the sequence set refers to message UIDs. If no items are moved the response object will be nil.
func (*Mailbox) PermanentFlags ¶
func (*Mailbox) Subscribed ¶
func (*Mailbox) UIDValidity ¶
type MessageAndMBoxIDStateFilter ¶
type MessageAndMBoxIDStateFilter struct { MessageID imap.InternalMessageID MBoxID imap.InternalMailboxID }
func (*MessageAndMBoxIDStateFilter) Filter ¶
func (f *MessageAndMBoxIDStateFilter) Filter(s *State) bool
func (*MessageAndMBoxIDStateFilter) String ¶
func (f *MessageAndMBoxIDStateFilter) String() string
type MessageIDStateFilter ¶
type MessageIDStateFilter struct {
MessageID imap.InternalMessageID
}
func (*MessageIDStateFilter) Filter ¶
func (f *MessageIDStateFilter) Filter(s *State) bool
func (*MessageIDStateFilter) String ¶
func (f *MessageIDStateFilter) String() string
type RemoteAddMessageFlagsStateUpdate ¶
type RemoteAddMessageFlagsStateUpdate struct { MessageIDStateFilter // contains filtered or unexported fields }
func (*RemoteAddMessageFlagsStateUpdate) String ¶
func (u *RemoteAddMessageFlagsStateUpdate) String() string
type RemoteMessageDeletedStateUpdate ¶
type RemoteMessageDeletedStateUpdate struct { MessageIDStateFilter // contains filtered or unexported fields }
func (*RemoteMessageDeletedStateUpdate) String ¶
func (u *RemoteMessageDeletedStateUpdate) String() string
type RemoteRemoveMessageFlagsStateUpdate ¶
type RemoteRemoveMessageFlagsStateUpdate struct { MessageIDStateFilter // contains filtered or unexported fields }
func (*RemoteRemoveMessageFlagsStateUpdate) String ¶
func (u *RemoteRemoveMessageFlagsStateUpdate) String() string
type Responder ¶
type Responder interface { String() string // contains filtered or unexported methods }
type SeqInterval ¶
type SeqInterval struct {
// contains filtered or unexported fields
}
type SnapFilter ¶
func NewAllStateFilter ¶
func NewAllStateFilter() SnapFilter
func NewMBoxIDStateFilter ¶
func NewMBoxIDStateFilter(mboxID imap.InternalMailboxID) SnapFilter
func NewMessageAndMBoxIDStateFilter ¶
func NewMessageAndMBoxIDStateFilter(msgID imap.InternalMessageID, mboxID imap.InternalMailboxID) SnapFilter
func NewMessageIDStateFilter ¶
func NewMessageIDStateFilter(msgID imap.InternalMessageID) SnapFilter
type State ¶
type State struct { StateID StateID // contains filtered or unexported fields }
State represents the active session's state after a user has been authenticated. This code is expected to run on one single goroutine/thread and should some interaction be required with other states from other session, they shall happen through updates (state.Update) which are queued via the UserInterface. Similarly, the state also accepts incoming updates via the ApplyUpdate method.
func NewState ¶
func NewState(user UserInterface, delimiter string, imapLimits limits.IMAP, panicHandler async.PanicHandler) *State
func (*State) AppendOnlyMailbox ¶
func (state *State) AppendOnlyMailbox(ctx context.Context, name string, fn func(AppendOnlyMailbox, bool) error) error
AppendOnlyMailbox does not guarantee that the mailbox snapshot is loaded data from the database and passes true into the function if the currently selected mailbox matches the requested mailbox. It can only be used for appending.
func (*State) ApplyUpdate ¶
func (*State) Delete ¶
Delete returns true if the mailbox that was deleted was the same as the one that was currently selected.
func (*State) GetStateUpdatesCh ¶
func (*State) HasMessage ¶
func (state *State) HasMessage(id imap.InternalMessageID) bool
func (*State) IsSelected ¶
func (*State) PushResponder ¶
func (*State) QueueUpdates ¶
func (*State) SetConnMetadataKeyValue ¶
func (*State) SignalClose ¶
func (state *State) SignalClose()
func (*State) UpdateMailboxRemoteID ¶
func (*State) UpdateMessageRemoteID ¶
type UIDInterval ¶
type UIDInterval struct {
// contains filtered or unexported fields
}
type Update ¶
type Update interface { // Filter returns true when the state can be passed into A. Filter(s *State) bool // Apply the update to a given state. Apply(cxt context.Context, tx *ent.Tx, s *State) error String() string }
func AddMessagesToMailbox ¶
func AddMessagesToMailbox(ctx context.Context, tx *ent.Tx, mboxID imap.InternalMailboxID, messageIDs []imap.InternalMessageID, s *State, imapLimits limits.IMAP) ([]db.UIDWithFlags, Update, error)
AddMessagesToMailbox adds the messages to the given mailbox.
func MoveMessagesFromMailbox ¶
func MoveMessagesFromMailbox( ctx context.Context, tx *ent.Tx, mboxFromID, mboxToID imap.InternalMailboxID, messageIDs []imap.InternalMessageID, s *State, imapLimits limits.IMAP, removeOldMessages bool, ) ([]db.UIDWithFlags, []Update, error)
MoveMessagesFromMailbox moves messages from one mailbox to the other.
func NewMailboxDeletedStateUpdate ¶
func NewMailboxDeletedStateUpdate(mboxID imap.InternalMailboxID) Update
func NewMailboxIDResponderStateUpdate ¶
func NewMailboxIDResponderStateUpdate(id imap.InternalMailboxID, responders ...Responder) Update
func NewMailboxRemoteIDUpdateStateUpdate ¶
func NewMailboxRemoteIDUpdateStateUpdate(internalID imap.InternalMailboxID, remoteID imap.MailboxID) Update
func NewMessageFlagsRemovedStateUpdate ¶
func NewMessageFlagsRemovedStateUpdate(flags imap.FlagSet, mboxID ids.MailboxIDPair, messageIDs []imap.InternalMessageID, stateID StateID) Update
func NewMessageFlagsSetStateUpdate ¶
func NewMessageFlagsSetStateUpdate(flags imap.FlagSet, mboxID ids.MailboxIDPair, messageIDs []imap.InternalMessageID, stateID StateID) Update
func NewMessageIDAndMailboxIDResponderStateUpdate ¶
func NewMessageIDAndMailboxIDResponderStateUpdate(messageID imap.InternalMessageID, mboxID imap.InternalMailboxID, responders ...Responder) Update
func NewMessageIDResponderStateUpdate ¶
func NewMessageIDResponderStateUpdate(id imap.InternalMessageID, responders ...Responder) Update
func NewRemoteAddMessageFlagsStateUpdate ¶
func NewRemoteAddMessageFlagsStateUpdate(messageID imap.InternalMessageID, flag string) Update
func NewRemoteMessageDeletedStateUpdate ¶
func NewRemoteMessageDeletedStateUpdate(messageID imap.InternalMessageID, remoteID imap.MessageID) Update
func NewRemoteRemoveMessageFlagsStateUpdate ¶
func NewRemoteRemoveMessageFlagsStateUpdate(messageID imap.InternalMessageID, flag string) Update
func NewUIDValidityBumpedStateUpdate ¶ added in v0.14.0
func NewUIDValidityBumpedStateUpdate() Update
func RemoveMessagesFromMailbox ¶
func RemoveMessagesFromMailbox(ctx context.Context, tx *ent.Tx, mboxID imap.InternalMailboxID, messageIDs []imap.InternalMessageID) ([]Update, error)
RemoveMessagesFromMailbox removes the messages from the given mailbox.
type UserInterface ¶
type UserInterface interface { GetUserID() string GetDelimiter() string GetDB() *db.DB GetRemote() Connector GetStore() *store.WriteControlledStore QueueOrApplyStateUpdate(ctx context.Context, tx *ent.Tx, update ...Update) error ReleaseState(ctx context.Context, st *State) error GetRecoveryMailboxID() ids.MailboxIDPair GenerateUIDValidity() (imap.UID, error) }
UserInterface represents the expected behaviour for interacting with a remote user. Sadly, due to Go's cyclic dependencies, this needs to be an interface. The implementation of this interface is available in the backend package.