store

package
v1.8.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 29, 2021 License: GPL-3.0 Imports: 34 Imported by: 0

Documentation

Overview

Package store communicates with API and caches metadata in a local database.

Index

Constants

View Source
const (
	// PathDelimiter for IMAP.
	PathDelimiter = "/"
	// UserLabelsMailboxName for IMAP.
	UserLabelsMailboxName = "Labels"
	// UserLabelsPrefix contains name with delimiter for IMAP.
	UserLabelsPrefix = UserLabelsMailboxName + PathDelimiter
	// UserFoldersMailboxName for IMAP.
	UserFoldersMailboxName = "Folders"
	// UserFoldersPrefix contains name with delimiter for IMAP.
	UserFoldersPrefix = UserFoldersMailboxName + PathDelimiter
)

Variables

View Source
var (

	// ErrNoSuchAPIID when mailbox does not have API ID.
	ErrNoSuchAPIID = errors.New("no such api id") //nolint[gochecknoglobals]
	// ErrNoSuchUID when mailbox does not have IMAP UID.
	ErrNoSuchUID = errors.New("no such uid") //nolint[gochecknoglobals]
	// ErrNoSuchSeqNum when mailbox does not have IMAP ID.
	ErrNoSuchSeqNum = errors.New("no such sequence number") //nolint[gochecknoglobals]
)
View Source
var ErrAllMailOpNotAllowed = errors.New("operation not allowed for 'All Mail' folder")

ErrAllMailOpNotAllowed is error user when user tries to do unsupported operation on All Mail folder.

Functions

func RemoveStore

func RemoveStore(cache *Cache, path, userID string) error

RemoveStore removes the database file and clears the cache file.

Types

type Address

type Address struct {
	// contains filtered or unexported fields
}

Address holds mailboxes for IMAP user (login address). In combined mode there is only one address, in split mode there is one object per address.

func (*Address) APIAddress

func (storeAddress *Address) APIAddress() *pmapi.Address

APIAddress returns the `pmapi.Address` struct.

func (*Address) AddressID

func (storeAddress *Address) AddressID() string

AddressID returns the address ID.

func (*Address) AddressString

func (storeAddress *Address) AddressString() string

AddressString returns the address.

func (*Address) CreateMailbox

func (storeAddress *Address) CreateMailbox(name string) error

CreateMailbox creates the mailbox by calling an API. Mailbox is created in the structure by processing event.

func (*Address) GetMailbox

func (storeAddress *Address) GetMailbox(name string) (*Mailbox, error)

GetMailbox returns mailbox with the given IMAP name.

func (*Address) ListMailboxes

func (storeAddress *Address) ListMailboxes() []*Mailbox

ListMailboxes returns all mailboxes.

type AddressInfo

type AddressInfo struct {
	Address, AddressID string
}

AddressInfo is the format of the data held in the addresses bucket in the store. It allows us to easily keep an address and its ID together and serialisation/deserialisation to []byte.

type BridgeUser

type BridgeUser interface {
	ID() string
	GetAddressID(address string) (string, error)
	IsConnected() bool
	IsCombinedAddressMode() bool
	GetPrimaryAddress() string
	GetStoreAddresses() []string
	GetClient() pmapi.Client
	UpdateUser(context.Context) error
	CloseAllConnections()
	CloseConnection(string)
	Logout() error
}

BridgeUser is subset of bridge.User for use by the Store.

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache caches the last event IDs for all accounts (there should be only one instance).

func NewCache

func NewCache(path string) *Cache

NewCache constructs a new cache at the given path.

type ChangeNotifier

type ChangeNotifier interface {
	Notice(address, notice string)
	UpdateMessage(
		address, mailboxName string,
		uid, sequenceNumber uint32,
		msg *pmapi.Message, hasDeletedFlag bool)
	DeleteMessage(address, mailboxName string, sequenceNumber uint32)
	MailboxCreated(address, mailboxName string)
	MailboxStatus(address, mailboxName string, total, unread, unreadSeqNum uint32)

	CanDelete(mailboxID string) (bool, func())
}

type Mailbox

type Mailbox struct {
	// contains filtered or unexported fields
}

Mailbox is mailbox for specific address and mailbox.

func (*Mailbox) Color

func (storeMailbox *Mailbox) Color() string

Color returns the color of mailbox.

func (*Mailbox) Delete

func (storeMailbox *Mailbox) Delete() error

Delete deletes the mailbox by calling an API. Deletion has to be propagated to all the same mailboxes in all addresses. The propagation is processed by the event loop.

func (*Mailbox) FetchMessage

func (storeMailbox *Mailbox) FetchMessage(apiID string) (*Message, error)

FetchMessage fetches the message with the given `apiID`, stores it in the database, and returns a new store message wrapping it.

func (*Mailbox) GetAPIIDsFromSequenceRange

func (storeMailbox *Mailbox) GetAPIIDsFromSequenceRange(start, stop uint32) (apiIDs []string, err error)

GetAPIIDsFromSequenceRange returns API IDs by IMAP sequence number range.

func (*Mailbox) GetAPIIDsFromUIDRange

func (storeMailbox *Mailbox) GetAPIIDsFromUIDRange(start, stop uint32) (apiIDs []string, err error)

GetAPIIDsFromUIDRange returns API IDs by IMAP UID range.

API IDs are the long base64 strings that the API uses to identify messages. UIDs are unique increasing integers that must be unique within a mailbox.

func (*Mailbox) GetCounts

func (storeMailbox *Mailbox) GetCounts() (total, unread, unseenSeqNum uint, err error)

GetCounts returns numbers of total and unread messages in this mailbox bucket.

func (*Mailbox) GetDeletedAPIIDs

func (storeMailbox *Mailbox) GetDeletedAPIIDs() (apiIDs []string, err error)

GetDeletedAPIIDs returns API IDs in this mailbox for message ID.

func (*Mailbox) GetDelimiter

func (storeMailbox *Mailbox) GetDelimiter() string

GetDelimiter returns the path separator.

func (*Mailbox) GetLatestAPIID

func (storeMailbox *Mailbox) GetLatestAPIID() (apiID string, err error)

GetLatestAPIID returns the latest message API ID which still exists. Info: not the latest IMAP UID which can be already removed.

func (*Mailbox) GetMessage

func (storeMailbox *Mailbox) GetMessage(apiID string) (*Message, error)

GetMessage returns the `pmapi.Message` struct wrapped in `StoreMessage` tied to this mailbox.

func (*Mailbox) GetNextUID

func (storeMailbox *Mailbox) GetNextUID() (uid uint32, err error)

GetNextUID returns the next IMAP UID.

func (*Mailbox) GetUIDByHeader

func (storeMailbox *Mailbox) GetUIDByHeader(header *mail.Header) (foundUID uint32)

GetUIDByHeader returns UID of message existing in mailbox or zero if no match found.

func (*Mailbox) GetUIDList

func (storeMailbox *Mailbox) GetUIDList(apiIDs []string) *uidplus.OrderedSeq

GetUIDList returns UID list corresponding to messageIDs in a requested order.

func (*Mailbox) ImportMessage

func (storeMailbox *Mailbox) ImportMessage(enc []byte, seen bool, labelIDs []string, flags, time int64) (string, error)

func (*Mailbox) IsFolder

func (storeMailbox *Mailbox) IsFolder() bool

IsFolder returns whether the mailbox is a folder (has "Folders/" prefix).

func (*Mailbox) IsLabel

func (storeMailbox *Mailbox) IsLabel() bool

IsLabel returns whether the mailbox is a label (has "Labels/" prefix).

func (*Mailbox) IsSystem

func (storeMailbox *Mailbox) IsSystem() bool

IsSystem returns whether the mailbox is one of the specific system mailboxes (has no prefix).

func (*Mailbox) LabelID

func (storeMailbox *Mailbox) LabelID() string

LabelID returns ID of mailbox.

func (*Mailbox) LabelMessages

func (storeMailbox *Mailbox) LabelMessages(apiIDs []string) error

LabelMessages adds the label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.

func (*Mailbox) MarkMessagesDeleted

func (storeMailbox *Mailbox) MarkMessagesDeleted(apiIDs []string) error

MarkMessagesDeleted adds local flag \Deleted. This is not propagated to API until RemoveDeleted is called.

func (*Mailbox) MarkMessagesRead

func (storeMailbox *Mailbox) MarkMessagesRead(apiIDs []string) error

MarkMessagesRead marks the message read by calling an API. It has to be propagated to metadata mailbox which is done by the event loop.

func (*Mailbox) MarkMessagesStarred

func (storeMailbox *Mailbox) MarkMessagesStarred(apiIDs []string) error

MarkMessagesStarred adds the Starred label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.

func (*Mailbox) MarkMessagesUndeleted

func (storeMailbox *Mailbox) MarkMessagesUndeleted(apiIDs []string) error

MarkMessagesUndeleted removes local flag \Deleted. This is not propagated to API.

func (*Mailbox) MarkMessagesUnread

func (storeMailbox *Mailbox) MarkMessagesUnread(apiIDs []string) error

MarkMessagesUnread marks the message unread by calling an API. It has to be propagated to metadata mailbox which is done by the event loop.

func (*Mailbox) MarkMessagesUnstarred

func (storeMailbox *Mailbox) MarkMessagesUnstarred(apiIDs []string) error

MarkMessagesUnstarred removes the Starred label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.

func (*Mailbox) Name

func (storeMailbox *Mailbox) Name() string

Name returns the name of mailbox.

func (*Mailbox) RemoveDeleted

func (storeMailbox *Mailbox) RemoveDeleted(apiIDs []string) error

RemoveDeleted sends request to API to remove message from mailbox. If the mailbox is All Mail or All Sent, it does nothing. If the mailbox is Trash or Spam and message is not in any other mailbox, messages is deleted. In all other cases the message is only removed from the mailbox. If nil is passed, all messages with \Deleted flag are removed. In other cases only messages with \Deleted flag and included in the passed list.

func (*Mailbox) Rename

func (storeMailbox *Mailbox) Rename(newName string) error

Rename updates the mailbox by calling an API. Change has to be propagated to all the same mailboxes in all addresses. The propagation is processed by the event loop.

func (*Mailbox) UIDValidity

func (storeMailbox *Mailbox) UIDValidity() uint32

UIDValidity returns the current value of structure version.

func (*Mailbox) UnlabelMessages

func (storeMailbox *Mailbox) UnlabelMessages(apiIDs []string) error

UnlabelMessages removes the label by calling an API. It has to be propagated to all the same messages in all mailboxes. The propagation is processed by the event loop.

type Message

type Message struct {
	// contains filtered or unexported fields
}

Message is wrapper around `pmapi.Message` with connection to a specific mailbox with helper functions to get IMAP UID, sequence numbers and similar.

func (*Message) GetBodyStructure added in v1.6.3

func (message *Message) GetBodyStructure() (bs *pkgMsg.BodyStructure, err error)

GetBodyStructure deserializes body structure from database. If body structure is not in database it returns nil error and nil body structure. If error occurs it returns nil body structure.

func (*Message) GetHeader added in v1.7.0

func (message *Message) GetHeader() []byte

GetHeader will return cached header from DB.

func (*Message) GetMIMEHeader added in v1.8.0

func (message *Message) GetMIMEHeader() textproto.MIMEHeader

GetMIMEHeader will return cached header from DB, parsed as a textproto.MIMEHeader.

func (*Message) ID

func (message *Message) ID() string

ID returns message ID on our API (always the same ID for all mailboxes).

func (*Message) IncreaseBuildCount added in v1.7.0

func (message *Message) IncreaseBuildCount() (times uint32, err error)

func (*Message) IsFullHeaderCached added in v1.7.0

func (message *Message) IsFullHeaderCached() bool

IsFullHeaderCached will check that valid full header is stored in DB.

func (*Message) IsMarkedDeleted

func (message *Message) IsMarkedDeleted() bool

IsMarkedDeleted returns true if message is marked as deleted for specific mailbox.

func (*Message) Message

func (message *Message) Message() *pmapi.Message

Message returns message struct from pmapi.

func (*Message) SequenceNumber

func (message *Message) SequenceNumber() (uint32, error)

SequenceNumber returns index of message in used mailbox.

func (*Message) SetBodyStructure added in v1.6.3

func (message *Message) SetBodyStructure(bs *pkgMsg.BodyStructure) error

SetBodyStructure stores serialized body structure in database.

func (*Message) SetContentTypeAndHeader deprecated

func (message *Message) SetContentTypeAndHeader(mimeType string, header mail.Header) error

SetContentTypeAndHeader updates the information about content type and header of decrypted message. This should not trigger any IMAP update. NOTE: Content type depends on details of decrypted message which we want to cache.

Deprecated: Use SetHeader instead.

func (*Message) SetHeader added in v1.7.0

func (message *Message) SetHeader(header []byte) error

SetHeader checks header can be parsed and if yes it stores header bytes in database.

func (*Message) SetSize

func (message *Message) SetSize(size int64) error

SetSize updates the information about size of decrypted message which can be used for IMAP. This should not trigger any IMAP update. NOTE: The size from the server corresponds to pure body bytes. Hence it should not be used. The correct size has to be calculated from decrypted and built message.

func (*Message) UID

func (message *Message) UID() (uint32, error)

UID returns message UID for IMAP, specific for mailbox used to get the message.

type PanicHandler

type PanicHandler interface {
	HandlePanic()
}

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is local user storage, which handles the synchronization between IMAP and PM API.

func New

func New(
	sentryReporter *sentry.Reporter,
	panicHandler PanicHandler,
	user BridgeUser,
	events listener.Listener,
	path string,
	cache *Cache,
) (store *Store, err error)

New creates or opens a store for the given `user`.

func (*Store) Close

func (store *Store) Close() error

Close stops the event loop and closes the database to free the file.

func (*Store) CloseEventLoop

func (store *Store) CloseEventLoop()

CloseEventLoop stops the eventloop (if it is present).

func (*Store) CreateDraft

func (store *Store) CreateDraft(
	kr *crypto.KeyRing,
	message *pmapi.Message,
	attachmentReaders []io.Reader,
	attachedPublicKey,
	attachedPublicKeyName string,
	parentID string) (*pmapi.Message, []*pmapi.Attachment, error)

CreateDraft creates draft with attachments. If `attachedPublicKey` is passed, it's added to attachments. Both draft and attachments are encrypted with passed `kr` key.

func (*Store) GetAddress

func (store *Store) GetAddress(addressID string) (*Address, error)

GetAddress returns the store address by given ID.

func (*Store) GetAddressID

func (store *Store) GetAddressID(addr string) (id string, err error)

GetAddressID returns the ID of the given address.

func (*Store) GetAddressInfo

func (store *Store) GetAddressInfo() (addrs []AddressInfo, err error)

GetAddressInfo returns information about all addresses owned by the user. The first element is the user's primary address and the rest (if present) are aliases. It tries to source the information from the store but if the store doesn't yet have it, it fetches it from the API and caches it for later.

func (*Store) GetMaxUpload

func (store *Store) GetMaxUpload() (int64, error)

GetMaxUpload returns max size of message + all attachments in bytes.

func (*Store) GetSpace

func (store *Store) GetSpace() (usedSpace, maxSpace uint, err error)

GetSpace returns used and total space in bytes.

func (*Store) IsCombinedMode

func (store *Store) IsCombinedMode() bool

IsCombinedMode returns whether the store is set to combined mode.

func (*Store) RebuildMailboxes

func (store *Store) RebuildMailboxes() (err error)

RebuildMailboxes truncates all mailbox buckets and recreates them from the metadata bucket again.

func (*Store) Remove

func (store *Store) Remove() (err error)

Remove closes and removes the database file and clears the cache file.

func (*Store) SendMessage

func (store *Store) SendMessage(messageID string, req *pmapi.SendMessageReq) error

SendMessage sends the message.

func (*Store) SetChangeNotifier

func (store *Store) SetChangeNotifier(notifier ChangeNotifier)

SetChangeNotifier sets notifier to be called once mailbox or message changes.

func (*Store) TestDumpDB

func (store *Store) TestDumpDB(tb assert.TestingT)

TestDumpDB will dump store database content.

func (*Store) TestGetEventLoop

func (store *Store) TestGetEventLoop() *eventLoop

TestGetEventLoop returns the store's event loop.

func (*Store) TestGetLastEvent

func (store *Store) TestGetLastEvent() *pmapi.Event

TestGetLastEvent returns last event processed by the store's event loop.

func (*Store) TestGetStoreFilePath

func (store *Store) TestGetStoreFilePath() string

TestGetStoreFilePath returns the filepath of the store's database file.

func (*Store) TestIsSyncRunning

func (store *Store) TestIsSyncRunning() bool

TestIsSyncRunning returns whether the sync is currently ongoing.

func (*Store) TestPollNow

func (store *Store) TestPollNow()

TestPollNow triggers a loop of the event loop.

func (*Store) TestSync

func (store *Store) TestSync()

TestSync triggers a sync of the store.

func (*Store) UseCombinedMode

func (store *Store) UseCombinedMode(useCombined bool) (err error)

UseCombinedMode sets whether the store should be set to combined mode.

func (*Store) UserID

func (store *Store) UserID() string

UserID returns user ID.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL