mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-01 12:43:08 -04:00
groupware: add changes support for quotas, identities, submissions
This commit is contained in:
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func (j *Client) GetBlobMetadata(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, id string) (*Blob, SessionState, State, Language, Error) {
|
||||
cmd, jerr := j.request(session, logger,
|
||||
cmd, jerr := j.request(session, logger, ns(JmapBlob),
|
||||
invocation(CommandBlobGet, BlobGetCommand{
|
||||
AccountId: accountId,
|
||||
Ids: []string{id},
|
||||
@@ -89,7 +89,7 @@ func (j *Client) UploadBlob(accountId string, session *Session, ctx context.Cont
|
||||
Properties: []string{BlobPropertyDigestSha512},
|
||||
}
|
||||
|
||||
cmd, jerr := j.request(session, logger,
|
||||
cmd, jerr := j.request(session, logger, ns(JmapBlob),
|
||||
invocation(CommandBlobUpload, upload, "0"),
|
||||
invocation(CommandBlobGet, getHash, "1"),
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ type AccountBootstrapResult struct {
|
||||
Quotas []Quota `json:"quotas,omitempty"`
|
||||
}
|
||||
|
||||
var NS_MAIL_QUOTA = ns(JmapMail, JmapQuota)
|
||||
|
||||
func (j *Client) GetBootstrap(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]AccountBootstrapResult, SessionState, State, Language, Error) { //NOSONAR
|
||||
uniqueAccountIds := structs.Uniq(accountIds)
|
||||
|
||||
@@ -23,7 +25,7 @@ func (j *Client) GetBootstrap(accountIds []string, session *Session, ctx context
|
||||
calls[i*2+1] = invocation(CommandQuotaGet, QuotaGetCommand{AccountId: accountId}, mcid(accountId, "Q"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, calls...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL_QUOTA, calls...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/structs"
|
||||
)
|
||||
|
||||
var NS_CALENDARS = ns(JmapCalendars)
|
||||
|
||||
func (j *Client) ParseICalendarBlob(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, blobIds []string) (CalendarEventParseResponse, SessionState, State, Language, Error) {
|
||||
logger = j.logger("ParseICalendarBlob", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_CALENDARS,
|
||||
invocation(CommandCalendarEventParse, CalendarEventParseCommand{AccountId: accountId, BlobIds: blobIds}, "0"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -33,7 +35,7 @@ type CalendarsResponse struct {
|
||||
}
|
||||
|
||||
func (j *Client) GetCalendars(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ids []string) (CalendarsResponse, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetCalendars", CommandCalendarGet,
|
||||
return getTemplate(j, "GetCalendars", NS_CALENDARS, CommandCalendarGet,
|
||||
func(accountId string, ids []string) CalendarGetCommand {
|
||||
return CalendarGetCommand{AccountId: accountId, Ids: ids}
|
||||
},
|
||||
@@ -57,7 +59,7 @@ type CalendarChanges struct {
|
||||
// Retrieve Calendar changes since a given state.
|
||||
// @apidoc calendar,changes
|
||||
func (j *Client) GetCalendarChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, sinceState State, maxChanges uint) (CalendarChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetCalendarChanges",
|
||||
return changesTemplate(j, "GetCalendarChanges", NS_CALENDARS,
|
||||
CommandCalendarChanges, CommandCalendarGet,
|
||||
func() CalendarChangesCommand {
|
||||
return CalendarChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -126,7 +128,7 @@ func (j *Client) QueryCalendarEvents(accountIds []string, session *Session, ctx
|
||||
// Properties: CalendarEventProperties, // to also retrieve UTCStart and UTCEnd
|
||||
}, mcid(accountId, "1"))
|
||||
}
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_CALENDARS, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -161,7 +163,7 @@ type CalendarEventChanges struct {
|
||||
|
||||
func (j *Client) GetCalendarEventChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (CalendarEventChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetCalendarEventChanges",
|
||||
return changesTemplate(j, "GetCalendarEventChanges", NS_CALENDARS,
|
||||
CommandCalendarEventChanges, CommandCalendarEventGet,
|
||||
func() CalendarEventChangesCommand {
|
||||
return CalendarEventChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -196,7 +198,7 @@ func (j *Client) GetCalendarEventChanges(accountId string, session *Session, ctx
|
||||
}
|
||||
|
||||
func (j *Client) CreateCalendarEvent(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, create CalendarEvent) (*CalendarEvent, SessionState, State, Language, Error) {
|
||||
return createTemplate(j, "CreateCalendarEvent", CalendarEventType, CommandCalendarEventSet, CommandCalendarEventGet,
|
||||
return createTemplate(j, "CreateCalendarEvent", NS_CALENDARS, CalendarEventType, CommandCalendarEventSet, CommandCalendarEventGet,
|
||||
func(accountId string, create map[string]CalendarEvent) CalendarEventSetCommand {
|
||||
return CalendarEventSetCommand{AccountId: accountId, Create: create}
|
||||
},
|
||||
@@ -219,7 +221,7 @@ func (j *Client) CreateCalendarEvent(accountId string, session *Session, ctx con
|
||||
}
|
||||
|
||||
func (j *Client) DeleteCalendarEvent(accountId string, destroy []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]SetError, SessionState, State, Language, Error) {
|
||||
return deleteTemplate(j, "DeleteCalendarEvent", CommandCalendarEventSet,
|
||||
return deleteTemplate(j, "DeleteCalendarEvent", NS_CALENDARS, CommandCalendarEventSet,
|
||||
func(accountId string, destroy []string) CalendarEventSetCommand {
|
||||
return CalendarEventSetCommand{AccountId: accountId, Destroy: destroy}
|
||||
},
|
||||
|
||||
@@ -7,30 +7,43 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// Note that Quota/changes is currently not supported in Stalwart, as it always gives a
|
||||
// cannotCalculateChanges error back.
|
||||
|
||||
var NS_CHANGES = ns(JmapMail, JmapContacts, JmapCalendars) //, JmapQuota)
|
||||
|
||||
type Changes struct {
|
||||
MaxChanges uint `json:"maxchanges,omitzero"`
|
||||
Mailboxes *MailboxChangesResponse `json:"mailboxes,omitempty"`
|
||||
Emails *EmailChangesResponse `json:"emails,omitempty"`
|
||||
Calendars *CalendarChangesResponse `json:"calendars,omitempty"`
|
||||
Events *CalendarEventChangesResponse `json:"events,omitempty"`
|
||||
Addressbooks *AddressBookChangesResponse `json:"addressbooks,omitempty"`
|
||||
Contacts *ContactCardChangesResponse `json:"contacts,omitempty"`
|
||||
MaxChanges uint `json:"maxchanges,omitzero"`
|
||||
Mailboxes *MailboxChangesResponse `json:"mailboxes,omitempty"`
|
||||
Emails *EmailChangesResponse `json:"emails,omitempty"`
|
||||
Calendars *CalendarChangesResponse `json:"calendars,omitempty"`
|
||||
Events *CalendarEventChangesResponse `json:"events,omitempty"`
|
||||
Addressbooks *AddressBookChangesResponse `json:"addressbooks,omitempty"`
|
||||
Contacts *ContactCardChangesResponse `json:"contacts,omitempty"`
|
||||
Identities *IdentityChangesResponse `json:"identities,omitempty"`
|
||||
EmailSubmissions *EmailSubmissionChangesResponse `json:"submissions,omitempty"`
|
||||
// Quotas *QuotaChangesResponse `json:"quotas,omitempty"`
|
||||
}
|
||||
|
||||
type StateMap struct {
|
||||
Mailboxes *State `json:"mailboxes,omitempty"`
|
||||
Emails *State `json:"emails,omitempty"`
|
||||
Calendars *State `json:"calendars,omitempty"`
|
||||
Events *State `json:"events,omitempty"`
|
||||
Addressbooks *State `json:"addressbooks,omitempty"`
|
||||
Contacts *State `json:"contacts,omitempty"`
|
||||
Mailboxes *State `json:"mailboxes,omitempty"`
|
||||
Emails *State `json:"emails,omitempty"`
|
||||
Calendars *State `json:"calendars,omitempty"`
|
||||
Events *State `json:"events,omitempty"`
|
||||
Addressbooks *State `json:"addressbooks,omitempty"`
|
||||
Contacts *State `json:"contacts,omitempty"`
|
||||
Identities *State `json:"identities,omitempty"`
|
||||
EmailSubmissions *State `json:"submissions,omitempty"`
|
||||
// Quotas *State `json:"quotas,omitempty"`
|
||||
}
|
||||
|
||||
var _ zerolog.LogObjectMarshaler = StateMap{}
|
||||
|
||||
func (s StateMap) IsZero() bool {
|
||||
return s.Mailboxes == nil && s.Emails == nil && s.Calendars == nil &&
|
||||
s.Events == nil && s.Addressbooks == nil && s.Contacts == nil
|
||||
s.Events == nil && s.Addressbooks == nil && s.Contacts == nil &&
|
||||
s.Identities == nil && s.EmailSubmissions == nil
|
||||
//s.Quotas == nil
|
||||
}
|
||||
|
||||
func (s StateMap) MarshalZerologObject(e *zerolog.Event) {
|
||||
@@ -52,6 +65,13 @@ func (s StateMap) MarshalZerologObject(e *zerolog.Event) {
|
||||
if s.Contacts != nil {
|
||||
e.Str("contacts", string(*s.Contacts))
|
||||
}
|
||||
if s.Identities != nil {
|
||||
e.Str("identities", string(*s.Identities))
|
||||
}
|
||||
if s.EmailSubmissions != nil {
|
||||
e.Str("submissions", string(*s.EmailSubmissions))
|
||||
}
|
||||
// if s.Quotas != nil { e.Str("quotas", string(*s.Quotas)) }
|
||||
}
|
||||
|
||||
func (j *Client) GetChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, stateMap StateMap, maxChanges uint) (Changes, SessionState, State, Language, Error) { //NOSONAR
|
||||
@@ -79,8 +99,15 @@ func (j *Client) GetChanges(accountId string, session *Session, ctx context.Cont
|
||||
if stateMap.Contacts != nil {
|
||||
methodCalls = append(methodCalls, invocation(CommandContactCardChanges, ContactCardChangesCommand{AccountId: accountId, SinceState: *stateMap.Contacts, MaxChanges: posUIntPtr(maxChanges)}, "contacts"))
|
||||
}
|
||||
if stateMap.Identities != nil {
|
||||
methodCalls = append(methodCalls, invocation(CommandIdentityChanges, IdentityChangesCommand{AccountId: accountId, SinceState: *stateMap.Identities, MaxChanges: posUIntPtr(maxChanges)}, "identities"))
|
||||
}
|
||||
if stateMap.EmailSubmissions != nil {
|
||||
methodCalls = append(methodCalls, invocation(CommandEmailSubmissionChanges, EmailSubmissionChangesCommand{AccountId: accountId, SinceState: *stateMap.EmailSubmissions, MaxChanges: posUIntPtr(maxChanges)}, "submissions"))
|
||||
}
|
||||
// if stateMap.Quotas != nil { methodCalls = append(methodCalls, invocation(CommandQuotaChanges, QuotaChangesCommand{AccountId: accountId, SinceState: *stateMap.Quotas, MaxChanges: posUIntPtr(maxChanges)}, "quotas")) }
|
||||
|
||||
cmd, err := j.request(session, logger, methodCalls...)
|
||||
cmd, err := j.request(session, logger, NS_CHANGES, methodCalls...)
|
||||
if err != nil {
|
||||
return Changes{}, "", "", "", err
|
||||
}
|
||||
@@ -139,6 +166,32 @@ func (j *Client) GetChanges(accountId string, session *Session, ctx context.Cont
|
||||
states["contacts"] = contacts.NewState
|
||||
}
|
||||
|
||||
var identities IdentityChangesResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandIdentityChanges, "identities", &identities); err != nil {
|
||||
return Changes{}, "", err
|
||||
} else if ok {
|
||||
changes.Identities = &identities
|
||||
states["identities"] = identities.NewState
|
||||
}
|
||||
|
||||
var submissions EmailSubmissionChangesResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandEmailSubmissionChanges, "submissions", &submissions); err != nil {
|
||||
return Changes{}, "", err
|
||||
} else if ok {
|
||||
changes.EmailSubmissions = &submissions
|
||||
states["submissions"] = submissions.NewState
|
||||
}
|
||||
|
||||
/*
|
||||
var quotas QuotaChangesResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandQuotaChanges, "quotas", "as); err != nil {
|
||||
return Changes{}, "", err
|
||||
} else if ok {
|
||||
changes.Quotas = "as
|
||||
states["quotas"] = quotas.NewState
|
||||
}
|
||||
*/
|
||||
|
||||
return changes, squashKeyedStates(states), nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/structs"
|
||||
)
|
||||
|
||||
var NS_CONTACTS = ns(JmapContacts)
|
||||
|
||||
type AddressBooksResponse struct {
|
||||
AddressBooks []AddressBook `json:"addressbooks"`
|
||||
NotFound []string `json:"notFound,omitempty"`
|
||||
@@ -17,7 +19,7 @@ type AddressBooksResponse struct {
|
||||
func (j *Client) GetAddressbooks(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ids []string) (AddressBooksResponse, SessionState, State, Language, Error) {
|
||||
logger = j.logger("GetAddressbooks", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_CONTACTS,
|
||||
invocation(CommandAddressBookGet, AddressBookGetCommand{AccountId: accountId, Ids: ids}, "0"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -49,7 +51,7 @@ type AddressBookChanges struct {
|
||||
// Retrieve Address Book changes since a given state.
|
||||
// @apidoc addressbook,changes
|
||||
func (j *Client) GetAddressbookChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, sinceState State, maxChanges uint) (AddressBookChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetAddressbookChanges",
|
||||
return changesTemplate(j, "GetAddressbookChanges", NS_CONTACTS,
|
||||
CommandAddressBookChanges, CommandAddressBookGet,
|
||||
func() AddressBookChangesCommand {
|
||||
return AddressBookChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -87,7 +89,7 @@ func (j *Client) GetContactCardsById(accountId string, session *Session, ctx con
|
||||
acceptLanguage string, contactIds []string) (map[string]jscontact.ContactCard, SessionState, State, Language, Error) {
|
||||
logger = j.logger("GetContactCardsById", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger, invocation(CommandContactCardGet, ContactCardGetCommand{
|
||||
cmd, err := j.request(session, logger, NS_CONTACTS, invocation(CommandContactCardGet, ContactCardGetCommand{
|
||||
Ids: contactIds,
|
||||
AccountId: accountId,
|
||||
}, "0"))
|
||||
@@ -111,7 +113,7 @@ func (j *Client) GetContactCardsById(accountId string, session *Session, ctx con
|
||||
|
||||
func (j *Client) GetContactCards(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, contactIds []string) ([]jscontact.ContactCard, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetContactCards", CommandContactCardGet,
|
||||
return getTemplate(j, "GetContactCards", NS_CONTACTS, CommandContactCardGet,
|
||||
func(accountId string, ids []string) ContactCardGetCommand {
|
||||
return ContactCardGetCommand{AccountId: accountId, Ids: contactIds}
|
||||
},
|
||||
@@ -132,7 +134,7 @@ type ContactCardChanges struct {
|
||||
|
||||
func (j *Client) GetContactCardChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (ContactCardChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetContactCardChanges",
|
||||
return changesTemplate(j, "GetContactCardChanges", NS_CONTACTS,
|
||||
CommandContactCardChanges, CommandContactCardGet,
|
||||
func() ContactCardChangesCommand {
|
||||
return ContactCardChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -200,7 +202,7 @@ func (j *Client) QueryContactCards(accountIds []string, session *Session, ctx co
|
||||
},
|
||||
}, mcid(accountId, "1"))
|
||||
}
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_CONTACTS, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -227,7 +229,7 @@ func (j *Client) QueryContactCards(accountIds []string, session *Session, ctx co
|
||||
func (j *Client) CreateContactCard(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, create jscontact.ContactCard) (*jscontact.ContactCard, SessionState, State, Language, Error) {
|
||||
logger = j.logger("CreateContactCard", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_CONTACTS,
|
||||
invocation(CommandContactCardSet, ContactCardSetCommand{
|
||||
AccountId: accountId,
|
||||
Create: map[string]jscontact.ContactCard{
|
||||
@@ -281,7 +283,7 @@ func (j *Client) CreateContactCard(accountId string, session *Session, ctx conte
|
||||
func (j *Client) DeleteContactCard(accountId string, destroy []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]SetError, SessionState, State, Language, Error) {
|
||||
logger = j.logger("DeleteContactCard", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_CONTACTS,
|
||||
invocation(CommandContactCardSet, ContactCardSetCommand{
|
||||
AccountId: accountId,
|
||||
Destroy: destroy,
|
||||
|
||||
@@ -11,6 +11,9 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
var NS_MAIL = ns(JmapMail)
|
||||
var NS_MAIL_SUBMISSION = ns(JmapMail, JmapSubmission)
|
||||
|
||||
type Emails struct {
|
||||
Emails []Email `json:"emails,omitempty"`
|
||||
Total uint `json:"total,omitzero"`
|
||||
@@ -54,7 +57,7 @@ func (j *Client) GetEmails(accountId string, session *Session, ctx context.Conte
|
||||
methodCalls = append(methodCalls, invocation(CommandThreadGet, threads, "2"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, methodCalls...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, methodCalls...)
|
||||
if err != nil {
|
||||
return nil, nil, "", "", "", err
|
||||
}
|
||||
@@ -92,7 +95,7 @@ func (j *Client) GetEmailBlobId(accountId string, session *Session, ctx context.
|
||||
logger = j.logger("GetEmailBlobId", session, logger)
|
||||
|
||||
get := EmailGetCommand{AccountId: accountId, Ids: []string{id}, FetchAllBodyValues: false, Properties: []string{"blobId"}}
|
||||
cmd, err := j.request(session, logger, invocation(CommandEmailGet, get, "0"))
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocation(CommandEmailGet, get, "0"))
|
||||
if err != nil {
|
||||
return "", "", "", "", err
|
||||
}
|
||||
@@ -156,7 +159,7 @@ func (j *Client) GetAllEmailsInMailbox(accountId string, session *Session, ctx c
|
||||
invocations = append(invocations, invocation(CommandThreadGet, threads, "2"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocations...)
|
||||
if err != nil {
|
||||
return Emails{}, "", "", "", err
|
||||
}
|
||||
@@ -232,7 +235,7 @@ func (j *Client) GetEmailChanges(accountId string, session *Session, ctx context
|
||||
getUpdated.MaxBodyValueBytes = maxBodyValueBytes
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandEmailChanges, changes, "0"),
|
||||
invocation(CommandEmailGet, getCreated, "1"),
|
||||
invocation(CommandEmailGet, getUpdated, "2"),
|
||||
@@ -336,7 +339,7 @@ func (j *Client) QueryEmailSnippets(accountIds []string, filter EmailFilterEleme
|
||||
invocations[i*3+2] = invocation(CommandSearchSnippetGet, snippet, mcid(accountId, "2"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -440,7 +443,7 @@ func (j *Client) QueryEmails(accountIds []string, filter EmailFilterElement, ses
|
||||
invocations[i*2+1] = invocation(CommandEmailGet, mails, mcid(accountId, "1"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -532,7 +535,7 @@ func (j *Client) QueryEmailsWithSnippets(accountIds []string, filter EmailFilter
|
||||
invocations[i*3+2] = invocation(CommandEmailGet, mails, mcid(accountId, "2"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -623,7 +626,7 @@ func (j *Client) ImportEmail(accountId string, session *Session, ctx context.Con
|
||||
Properties: []string{BlobPropertyDigestSha512},
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandBlobUpload, upload, "0"),
|
||||
invocation(CommandBlobGet, getHash, "1"),
|
||||
)
|
||||
@@ -682,7 +685,7 @@ func (j *Client) CreateEmail(accountId string, email EmailCreate, replaceId stri
|
||||
set.Destroy = []string{replaceId}
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandEmailSet, set, "0"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -727,7 +730,7 @@ func (j *Client) CreateEmail(accountId string, email EmailCreate, replaceId stri
|
||||
//
|
||||
// To delete mails, use the DeleteEmails function instead.
|
||||
func (j *Client) UpdateEmails(accountId string, updates map[string]EmailUpdate, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]*Email, SessionState, State, Language, Error) {
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandEmailSet, EmailSetCommand{
|
||||
AccountId: accountId,
|
||||
Update: updates,
|
||||
@@ -754,7 +757,7 @@ func (j *Client) UpdateEmails(accountId string, updates map[string]EmailUpdate,
|
||||
}
|
||||
|
||||
func (j *Client) DeleteEmails(accountId string, destroy []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]SetError, SessionState, State, Language, Error) {
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandEmailSet, EmailSetCommand{
|
||||
AccountId: accountId,
|
||||
Destroy: destroy,
|
||||
@@ -836,7 +839,7 @@ func (j *Client) SubmitEmail(accountId string, identityId string, emailId string
|
||||
Ids: []string{"#" + id},
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL_SUBMISSION,
|
||||
invocation(CommandEmailSubmissionSet, set, "0"),
|
||||
invocation(CommandEmailSubmissionGet, get, "1"),
|
||||
)
|
||||
@@ -897,7 +900,7 @@ type emailSubmissionResult struct {
|
||||
func (j *Client) GetEmailSubmissionStatus(accountId string, submissionIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]EmailSubmission, []string, SessionState, State, Language, Error) {
|
||||
logger = j.logger("GetEmailSubmissionStatus", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger, invocation(CommandEmailSubmissionGet, EmailSubmissionGetCommand{
|
||||
cmd, err := j.request(session, logger, NS_MAIL_SUBMISSION, invocation(CommandEmailSubmissionGet, EmailSubmissionGetCommand{
|
||||
AccountId: accountId,
|
||||
Ids: submissionIds,
|
||||
}, "0"))
|
||||
@@ -926,7 +929,7 @@ func (j *Client) EmailsInThread(accountId string, threadId string, session *Sess
|
||||
return z.Bool(logFetchBodies, fetchBodies).Str("threadId", log.SafeString(threadId))
|
||||
})
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_MAIL,
|
||||
invocation(CommandThreadGet, ThreadGetCommand{
|
||||
AccountId: accountId,
|
||||
Ids: []string{threadId},
|
||||
@@ -1025,7 +1028,7 @@ func (j *Client) QueryEmailSummaries(accountIds []string, session *Session, ctx
|
||||
}, mcid(accountId, "2"))
|
||||
}
|
||||
}
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAIL, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -1068,6 +1071,51 @@ func (j *Client) QueryEmailSummaries(accountIds []string, session *Session, ctx
|
||||
})
|
||||
}
|
||||
|
||||
type EmailSubmissionChanges struct {
|
||||
OldState State `json:"oldState,omitempty"`
|
||||
NewState State `json:"newState"`
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
Created []EmailSubmission `json:"created,omitempty"`
|
||||
Updated []EmailSubmission `json:"updated,omitempty"`
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
func (j *Client) GetEmailSubmissionChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (EmailSubmissionChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetEmailSubmissionChanges", NS_MAIL_SUBMISSION,
|
||||
CommandEmailSubmissionChanges, CommandEmailSubmissionGet,
|
||||
func() EmailSubmissionChangesCommand {
|
||||
return EmailSubmissionChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
},
|
||||
func(path string, rof string) EmailSubmissionGetRefCommand {
|
||||
return EmailSubmissionGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{
|
||||
Name: CommandEmailSubmissionChanges,
|
||||
Path: path,
|
||||
ResultOf: rof,
|
||||
},
|
||||
}
|
||||
},
|
||||
func(resp EmailSubmissionChangesResponse) (State, State, bool, []string) {
|
||||
return resp.OldState, resp.NewState, resp.HasMoreChanges, resp.Destroyed
|
||||
},
|
||||
func(resp EmailSubmissionGetResponse) []EmailSubmission { return resp.List },
|
||||
func(oldState, newState State, hasMoreChanges bool, created, updated []EmailSubmission, destroyed []string) EmailSubmissionChanges {
|
||||
return EmailSubmissionChanges{
|
||||
OldState: oldState,
|
||||
NewState: newState,
|
||||
HasMoreChanges: hasMoreChanges,
|
||||
Created: created,
|
||||
Updated: updated,
|
||||
Destroyed: destroyed,
|
||||
}
|
||||
},
|
||||
func(resp EmailSubmissionGetResponse) State { return resp.State },
|
||||
session, ctx, logger, acceptLanguage,
|
||||
)
|
||||
}
|
||||
|
||||
func setThreadSize(threads *ThreadGetResponse, emails []Email) {
|
||||
threadSizeById := make(map[string]int, len(threads.List))
|
||||
for _, thread := range threads.List {
|
||||
|
||||
@@ -8,8 +8,10 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/structs"
|
||||
)
|
||||
|
||||
var NS_IDENTITY = ns(JmapMail)
|
||||
|
||||
func (j *Client) GetAllIdentities(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) ([]Identity, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetAllIdentities", CommandIdentityGet,
|
||||
return getTemplate(j, "GetAllIdentities", NS_IDENTITY, CommandIdentityGet,
|
||||
func(accountId string, ids []string) IdentityGetCommand {
|
||||
return IdentityGetCommand{AccountId: accountId}
|
||||
},
|
||||
@@ -20,7 +22,7 @@ func (j *Client) GetAllIdentities(accountId string, session *Session, ctx contex
|
||||
}
|
||||
|
||||
func (j *Client) GetIdentities(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, identityIds []string) ([]Identity, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetIdentities", CommandIdentityGet,
|
||||
return getTemplate(j, "GetIdentities", NS_IDENTITY, CommandIdentityGet,
|
||||
func(accountId string, ids []string) IdentityGetCommand {
|
||||
return IdentityGetCommand{AccountId: accountId, Ids: ids}
|
||||
},
|
||||
@@ -31,7 +33,7 @@ func (j *Client) GetIdentities(accountId string, session *Session, ctx context.C
|
||||
}
|
||||
|
||||
func (j *Client) GetIdentitiesForAllAccounts(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string][]Identity, SessionState, State, Language, Error) {
|
||||
return getTemplateN(j, "GetIdentitiesForAllAccounts", CommandIdentityGet,
|
||||
return getTemplateN(j, "GetIdentitiesForAllAccounts", NS_IDENTITY, CommandIdentityGet,
|
||||
func(accountId string, ids []string) IdentityGetCommand {
|
||||
return IdentityGetCommand{AccountId: accountId}
|
||||
},
|
||||
@@ -59,7 +61,7 @@ func (j *Client) GetIdentitiesAndMailboxes(mailboxAccountId string, accountIds [
|
||||
calls[i+1] = invocation(CommandIdentityGet, IdentityGetCommand{AccountId: accountId}, strconv.Itoa(i+1))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, calls...)
|
||||
cmd, err := j.request(session, logger, NS_IDENTITY, calls...)
|
||||
if err != nil {
|
||||
return IdentitiesAndMailboxesGetResponse{}, "", "", "", err
|
||||
}
|
||||
@@ -95,7 +97,7 @@ func (j *Client) GetIdentitiesAndMailboxes(mailboxAccountId string, accountIds [
|
||||
|
||||
func (j *Client) CreateIdentity(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, identity Identity) (Identity, SessionState, State, Language, Error) {
|
||||
logger = j.logger("CreateIdentity", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
cmd, err := j.request(session, logger, NS_IDENTITY, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
AccountId: accountId,
|
||||
Create: map[string]Identity{
|
||||
"c": identity,
|
||||
@@ -121,7 +123,7 @@ func (j *Client) CreateIdentity(accountId string, session *Session, ctx context.
|
||||
|
||||
func (j *Client) UpdateIdentity(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, identity Identity) (Identity, SessionState, State, Language, Error) {
|
||||
logger = j.logger("UpdateIdentity", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
cmd, err := j.request(session, logger, NS_IDENTITY, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
AccountId: accountId,
|
||||
Update: map[string]PatchObject{
|
||||
"c": identity.AsPatch(),
|
||||
@@ -147,7 +149,7 @@ func (j *Client) UpdateIdentity(accountId string, session *Session, ctx context.
|
||||
|
||||
func (j *Client) DeleteIdentity(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ids []string) ([]string, SessionState, State, Language, Error) {
|
||||
logger = j.logger("DeleteIdentity", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
cmd, err := j.request(session, logger, NS_IDENTITY, invocation(CommandIdentitySet, IdentitySetCommand{
|
||||
AccountId: accountId,
|
||||
Destroy: ids,
|
||||
}, "0"))
|
||||
@@ -168,3 +170,48 @@ func (j *Client) DeleteIdentity(accountId string, session *Session, ctx context.
|
||||
return response.Destroyed, response.NewState, nil
|
||||
})
|
||||
}
|
||||
|
||||
type IdentityChanges struct {
|
||||
OldState State `json:"oldState,omitempty"`
|
||||
NewState State `json:"newState"`
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
Created []Identity `json:"created,omitempty"`
|
||||
Updated []Identity `json:"updated,omitempty"`
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
func (j *Client) GetIdentityChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (IdentityChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetIdentityChanges", NS_IDENTITY,
|
||||
CommandIdentityChanges, CommandIdentityGet,
|
||||
func() IdentityChangesCommand {
|
||||
return IdentityChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
},
|
||||
func(path string, rof string) IdentityGetRefCommand {
|
||||
return IdentityGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{
|
||||
Name: CommandIdentityChanges,
|
||||
Path: path,
|
||||
ResultOf: rof,
|
||||
},
|
||||
}
|
||||
},
|
||||
func(resp IdentityChangesResponse) (State, State, bool, []string) {
|
||||
return resp.OldState, resp.NewState, resp.HasMoreChanges, resp.Destroyed
|
||||
},
|
||||
func(resp IdentityGetResponse) []Identity { return resp.List },
|
||||
func(oldState, newState State, hasMoreChanges bool, created, updated []Identity, destroyed []string) IdentityChanges {
|
||||
return IdentityChanges{
|
||||
OldState: oldState,
|
||||
NewState: newState,
|
||||
HasMoreChanges: hasMoreChanges,
|
||||
Created: created,
|
||||
Updated: updated,
|
||||
Destroyed: destroyed,
|
||||
}
|
||||
},
|
||||
func(resp IdentityGetResponse) State { return resp.State },
|
||||
session, ctx, logger, acceptLanguage,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,13 +9,15 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/structs"
|
||||
)
|
||||
|
||||
var NS_MAILBOX = ns(JmapMail)
|
||||
|
||||
type MailboxesResponse struct {
|
||||
Mailboxes []Mailbox `json:"mailboxes"`
|
||||
NotFound []any `json:"notFound"`
|
||||
}
|
||||
|
||||
func (j *Client) GetMailbox(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ids []string) (MailboxesResponse, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetMailbox", CommandCalendarGet,
|
||||
return getTemplate(j, "GetMailbox", NS_MAILBOX, CommandCalendarGet,
|
||||
func(accountId string, ids []string) MailboxGetCommand {
|
||||
return MailboxGetCommand{AccountId: accountId, Ids: ids}
|
||||
},
|
||||
@@ -31,7 +33,7 @@ func (j *Client) GetMailbox(accountId string, session *Session, ctx context.Cont
|
||||
}
|
||||
|
||||
func (j *Client) GetAllMailboxes(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string][]Mailbox, SessionState, State, Language, Error) {
|
||||
return getTemplateN(j, "GetAllMailboxes", CommandCalendarGet,
|
||||
return getTemplateN(j, "GetAllMailboxes", NS_MAILBOX, CommandCalendarGet,
|
||||
func(accountId string, ids []string) MailboxGetCommand {
|
||||
return MailboxGetCommand{AccountId: accountId}
|
||||
},
|
||||
@@ -59,7 +61,7 @@ func (j *Client) SearchMailboxes(accountIds []string, session *Session, ctx cont
|
||||
},
|
||||
}, mcid(accountId, "1"))
|
||||
}
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -92,7 +94,7 @@ func (j *Client) SearchMailboxIdsPerRole(accountIds []string, session *Session,
|
||||
invocations[i*len(roles)+j] = invocation(CommandMailboxQuery, MailboxQueryCommand{AccountId: accountId, Filter: MailboxFilterCondition{Role: role}}, mcid(accountId, role))
|
||||
}
|
||||
}
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -144,7 +146,7 @@ func newMailboxChanges(oldState, newState State, hasMoreChanges bool, created, u
|
||||
// Retrieve Mailbox changes since a given state.
|
||||
// @apidoc mailboxes,changes
|
||||
func (j *Client) GetMailboxChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, sinceState State, maxChanges uint) (MailboxChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetMailboxChanges",
|
||||
return changesTemplate(j, "GetMailboxChanges", NS_MAILBOX,
|
||||
CommandMailboxChanges, CommandMailboxGet,
|
||||
func() MailboxChangesCommand {
|
||||
return MailboxChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -171,7 +173,7 @@ func (j *Client) GetMailboxChanges(accountId string, session *Session, ctx conte
|
||||
|
||||
// Retrieve Mailbox changes of multiple Accounts.
|
||||
func (j *Client) GetMailboxChangesForMultipleAccounts(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, sinceStateMap map[string]State, maxChanges uint) (map[string]MailboxChanges, SessionState, State, Language, Error) { //NOSONAR
|
||||
return changesTemplateN(j, "GetMailboxChangesForMultipleAccounts",
|
||||
return changesTemplateN(j, "GetMailboxChangesForMultipleAccounts", NS_MAILBOX,
|
||||
accountIds, sinceStateMap, CommandMailboxChanges, CommandMailboxGet,
|
||||
func(accountId string, state State) MailboxChangesCommand {
|
||||
return MailboxChangesCommand{AccountId: accountId, SinceState: state, MaxChanges: posUIntPtr(maxChanges)}
|
||||
@@ -188,91 +190,6 @@ func (j *Client) GetMailboxChangesForMultipleAccounts(accountIds []string, sessi
|
||||
func(resp MailboxGetResponse) State { return resp.State },
|
||||
session, ctx, logger, acceptLanguage,
|
||||
)
|
||||
|
||||
/*
|
||||
logger = j.loggerParams("GetMailboxChangesForMultipleAccounts", session, logger, func(z zerolog.Context) zerolog.Context {
|
||||
sinceStateLogDict := zerolog.Dict()
|
||||
for k, v := range sinceStateMap {
|
||||
sinceStateLogDict.Str(log.SafeString(k), log.SafeString(v))
|
||||
}
|
||||
return z.Dict(logSinceState, sinceStateLogDict)
|
||||
})
|
||||
|
||||
uniqueAccountIds := structs.Uniq(accountIds)
|
||||
n := len(uniqueAccountIds)
|
||||
if n < 1 {
|
||||
return map[string]MailboxChanges{}, "", "", "", nil
|
||||
}
|
||||
|
||||
invocations := make([]Invocation, n*3)
|
||||
for i, accountId := range uniqueAccountIds {
|
||||
changes := MailboxChangesCommand{
|
||||
AccountId: accountId,
|
||||
}
|
||||
|
||||
sinceState, ok := sinceStateMap[accountId]
|
||||
if ok {
|
||||
changes.SinceState = sinceState
|
||||
}
|
||||
|
||||
if maxChanges > 0 {
|
||||
changes.MaxChanges = &maxChanges
|
||||
}
|
||||
|
||||
getCreated := MailboxGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{Name: CommandMailboxChanges, Path: "/created", ResultOf: mcid(accountId, "0")},
|
||||
}
|
||||
getUpdated := MailboxGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{Name: CommandMailboxChanges, Path: "/updated", ResultOf: mcid(accountId, "0")},
|
||||
}
|
||||
|
||||
invocations[i*3+0] = invocation(CommandMailboxChanges, changes, mcid(accountId, "0"))
|
||||
invocations[i*3+1] = invocation(CommandMailboxGet, getCreated, mcid(accountId, "1"))
|
||||
invocations[i*3+2] = invocation(CommandMailboxGet, getUpdated, mcid(accountId, "2"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, acceptLanguage, func(body *Response) (map[string]MailboxChanges, State, Error) {
|
||||
resp := make(map[string]MailboxChanges, n)
|
||||
stateByAccountId := make(map[string]State, n)
|
||||
for _, accountId := range uniqueAccountIds {
|
||||
var mailboxResponse MailboxChangesResponse
|
||||
err = retrieveResponseMatchParameters(logger, body, CommandMailboxChanges, mcid(accountId, "0"), &mailboxResponse)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var createdResponse MailboxGetResponse
|
||||
err = retrieveResponseMatchParameters(logger, body, CommandMailboxGet, mcid(accountId, "1"), &createdResponse)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var updatedResponse MailboxGetResponse
|
||||
err = retrieveResponseMatchParameters(logger, body, CommandMailboxGet, mcid(accountId, "2"), &updatedResponse)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
resp[accountId] = MailboxChanges{
|
||||
Destroyed: mailboxResponse.Destroyed,
|
||||
HasMoreChanges: mailboxResponse.HasMoreChanges,
|
||||
NewState: mailboxResponse.NewState,
|
||||
Created: createdResponse.List,
|
||||
Updated: updatedResponse.List,
|
||||
}
|
||||
stateByAccountId[accountId] = createdResponse.State
|
||||
}
|
||||
|
||||
return resp, squashState(stateByAccountId), nil
|
||||
})
|
||||
*/
|
||||
}
|
||||
|
||||
func (j *Client) GetMailboxRolesForMultipleAccounts(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string][]string, SessionState, State, Language, Error) {
|
||||
@@ -304,7 +221,7 @@ func (j *Client) GetMailboxRolesForMultipleAccounts(accountIds []string, session
|
||||
}, mcid(accountId, "1"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -349,7 +266,7 @@ func (j *Client) GetInboxNameForMultipleAccounts(accountIds []string, session *S
|
||||
}, mcid(accountId, "0"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, invocations...)
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocations...)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
@@ -381,7 +298,7 @@ func (j *Client) GetInboxNameForMultipleAccounts(accountIds []string, session *S
|
||||
|
||||
func (j *Client) UpdateMailbox(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, mailboxId string, ifInState string, update MailboxChange) (Mailbox, SessionState, State, Language, Error) { //NOSONAR
|
||||
logger = j.logger("UpdateMailbox", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
AccountId: accountId,
|
||||
IfInState: ifInState,
|
||||
Update: map[string]PatchObject{
|
||||
@@ -409,7 +326,7 @@ func (j *Client) UpdateMailbox(accountId string, session *Session, ctx context.C
|
||||
|
||||
func (j *Client) CreateMailbox(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ifInState string, create MailboxChange) (Mailbox, SessionState, State, Language, Error) {
|
||||
logger = j.logger("CreateMailbox", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
AccountId: accountId,
|
||||
IfInState: ifInState,
|
||||
Create: map[string]MailboxChange{
|
||||
@@ -441,7 +358,7 @@ func (j *Client) CreateMailbox(accountId string, session *Session, ctx context.C
|
||||
|
||||
func (j *Client) DeleteMailboxes(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ifInState string, mailboxIds []string) ([]string, SessionState, State, Language, Error) {
|
||||
logger = j.logger("DeleteMailbox", session, logger)
|
||||
cmd, err := j.request(session, logger, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
cmd, err := j.request(session, logger, NS_MAILBOX, invocation(CommandMailboxSet, MailboxSetCommand{
|
||||
AccountId: accountId,
|
||||
IfInState: ifInState,
|
||||
Destroy: mailboxIds,
|
||||
|
||||
@@ -6,19 +6,26 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
)
|
||||
|
||||
var NS_OBJECTS = ns(JmapMail, JmapSubmission, JmapContacts, JmapCalendars, JmapQuota)
|
||||
|
||||
type Objects struct {
|
||||
Mailboxes *MailboxGetResponse `json:"mailboxes,omitempty"`
|
||||
Emails *EmailGetResponse `json:"emails,omitempty"`
|
||||
Calendars *CalendarGetResponse `json:"calendars,omitempty"`
|
||||
Events *CalendarEventGetResponse `json:"events,omitempty"`
|
||||
Addressbooks *AddressBookGetResponse `json:"addressbooks,omitempty"`
|
||||
Contacts *ContactCardGetResponse `json:"contacts,omitempty"`
|
||||
Mailboxes *MailboxGetResponse `json:"mailboxes,omitempty"`
|
||||
Emails *EmailGetResponse `json:"emails,omitempty"`
|
||||
Calendars *CalendarGetResponse `json:"calendars,omitempty"`
|
||||
Events *CalendarEventGetResponse `json:"events,omitempty"`
|
||||
Addressbooks *AddressBookGetResponse `json:"addressbooks,omitempty"`
|
||||
Contacts *ContactCardGetResponse `json:"contacts,omitempty"`
|
||||
Quotas *QuotaGetResponse `json:"quotas,omitempty"`
|
||||
Identities *IdentityGetResponse `json:"identities,omitempty"`
|
||||
EmailSubmissions *EmailSubmissionGetResponse `json:"submissions,omitempty"`
|
||||
}
|
||||
|
||||
func (j *Client) GetObjects(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, //NOSONAR
|
||||
mailboxIds []string, emailIds []string,
|
||||
addressbookIds []string, contactIds []string,
|
||||
calendarIds []string, eventIds []string,
|
||||
quotaIds []string, identityIds []string,
|
||||
emailSubmissionIds []string,
|
||||
) (Objects, SessionState, State, Language, Error) {
|
||||
l := j.logger("GetObjects", session, logger).With()
|
||||
if len(mailboxIds) > 0 {
|
||||
@@ -39,6 +46,15 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
if len(eventIds) > 0 {
|
||||
l = l.Array("eventIds", log.SafeStringArray(eventIds))
|
||||
}
|
||||
if len(quotaIds) > 0 {
|
||||
l = l.Array("quotaIds", log.SafeStringArray(quotaIds))
|
||||
}
|
||||
if len(identityIds) > 0 {
|
||||
l = l.Array("identityIds", log.SafeStringArray(identityIds))
|
||||
}
|
||||
if len(emailSubmissionIds) > 0 {
|
||||
l = l.Array("emailSubmissionIds", log.SafeStringArray(emailSubmissionIds))
|
||||
}
|
||||
logger = log.From(l)
|
||||
|
||||
methodCalls := []Invocation{}
|
||||
@@ -60,20 +76,31 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
if len(eventIds) > 0 {
|
||||
methodCalls = append(methodCalls, invocation(CommandCalendarEventGet, CalendarEventGetCommand{AccountId: accountId, Ids: eventIds}, "events"))
|
||||
}
|
||||
if len(quotaIds) > 0 {
|
||||
methodCalls = append(methodCalls, invocation(CommandQuotaGet, QuotaGetCommand{AccountId: accountId, Ids: quotaIds}, "quotas"))
|
||||
}
|
||||
if len(identityIds) > 0 {
|
||||
methodCalls = append(methodCalls, invocation(CommandIdentityGet, IdentityGetCommand{AccountId: accountId, Ids: identityIds}, "identities"))
|
||||
}
|
||||
if len(emailSubmissionIds) > 0 {
|
||||
methodCalls = append(methodCalls, invocation(CommandEmailSubmissionGet, EmailSubmissionGetCommand{AccountId: accountId, Ids: emailSubmissionIds}, "emailSubmissionIds"))
|
||||
}
|
||||
|
||||
cmd, err := j.request(session, logger, methodCalls...)
|
||||
cmd, err := j.request(session, logger, NS_OBJECTS, methodCalls...)
|
||||
if err != nil {
|
||||
return Objects{}, "", "", "", err
|
||||
}
|
||||
|
||||
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, acceptLanguage, func(body *Response) (Objects, State, Error) {
|
||||
objs := Objects{}
|
||||
states := map[string]State{}
|
||||
|
||||
var mailboxes MailboxGetResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandMailboxGet, "mailboxes", &mailboxes); err != nil {
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Mailboxes = &mailboxes
|
||||
states["mailbox"] = mailboxes.State
|
||||
}
|
||||
|
||||
var emails EmailGetResponse
|
||||
@@ -81,6 +108,7 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Emails = &emails
|
||||
states["email"] = emails.State
|
||||
}
|
||||
|
||||
var calendars CalendarGetResponse
|
||||
@@ -88,6 +116,7 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Calendars = &calendars
|
||||
states["calendar"] = calendars.State
|
||||
}
|
||||
|
||||
var events CalendarEventGetResponse
|
||||
@@ -95,6 +124,7 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Events = &events
|
||||
states["event"] = events.State
|
||||
}
|
||||
|
||||
var addressbooks AddressBookGetResponse
|
||||
@@ -102,6 +132,7 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Addressbooks = &addressbooks
|
||||
states["addressbook"] = addressbooks.State
|
||||
}
|
||||
|
||||
var contacts ContactCardGetResponse
|
||||
@@ -109,10 +140,33 @@ func (j *Client) GetObjects(accountId string, session *Session, ctx context.Cont
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Contacts = &contacts
|
||||
states["contact"] = contacts.State
|
||||
}
|
||||
|
||||
state := squashStates(mailboxes.State, emails.State, calendars.State, events.State, addressbooks.State, contacts.State)
|
||||
var quotas QuotaGetResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandQuotaGet, "quotas", "as); err != nil {
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Quotas = "as
|
||||
states["quota"] = quotas.State
|
||||
}
|
||||
|
||||
return objs, state, nil
|
||||
var identities IdentityGetResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandIdentityGet, "identities", &identities); err != nil {
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.Identities = &identities
|
||||
states["identity"] = identities.State
|
||||
}
|
||||
|
||||
var submissions EmailSubmissionGetResponse
|
||||
if ok, err := tryRetrieveResponseMatchParameters(logger, body, CommandEmailSubmissionGet, "submissions", &submissions); err != nil {
|
||||
return Objects{}, "", err
|
||||
} else if ok {
|
||||
objs.EmailSubmissions = &submissions
|
||||
states["submissions"] = submissions.State
|
||||
}
|
||||
|
||||
return objs, squashKeyedStates(states), nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
)
|
||||
|
||||
var NS_QUOTA = ns(JmapQuota)
|
||||
|
||||
func (j *Client) GetQuotas(accountIds []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]QuotaGetResponse, SessionState, State, Language, Error) {
|
||||
return getTemplateN(j, "GetQuotas", CommandQuotaGet,
|
||||
return getTemplateN(j, "GetQuotas", NS_QUOTA, CommandQuotaGet,
|
||||
func(accountId string, ids []string) QuotaGetCommand {
|
||||
return QuotaGetCommand{AccountId: accountId}
|
||||
},
|
||||
@@ -17,3 +19,87 @@ func (j *Client) GetQuotas(accountIds []string, session *Session, ctx context.Co
|
||||
accountIds, session, ctx, logger, acceptLanguage, []string{},
|
||||
)
|
||||
}
|
||||
|
||||
type QuotaChanges struct {
|
||||
OldState State `json:"oldState,omitempty"`
|
||||
NewState State `json:"newState"`
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
Created []Quota `json:"created,omitempty"`
|
||||
Updated []Quota `json:"updated,omitempty"`
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
func (j *Client) GetQuotaChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (QuotaChanges, SessionState, State, Language, Error) {
|
||||
return changesTemplate(j, "GetQuotaChanges", NS_QUOTA,
|
||||
CommandQuotaChanges, CommandQuotaGet,
|
||||
func() QuotaChangesCommand {
|
||||
return QuotaChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
},
|
||||
func(path string, rof string) QuotaGetRefCommand {
|
||||
return QuotaGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{
|
||||
Name: CommandQuotaChanges,
|
||||
Path: path,
|
||||
ResultOf: rof,
|
||||
},
|
||||
}
|
||||
},
|
||||
func(resp QuotaChangesResponse) (State, State, bool, []string) {
|
||||
return resp.OldState, resp.NewState, resp.HasMoreChanges, resp.Destroyed
|
||||
},
|
||||
func(resp QuotaGetResponse) []Quota { return resp.List },
|
||||
func(oldState, newState State, hasMoreChanges bool, created, updated []Quota, destroyed []string) QuotaChanges {
|
||||
return QuotaChanges{
|
||||
OldState: oldState,
|
||||
NewState: newState,
|
||||
HasMoreChanges: hasMoreChanges,
|
||||
Created: created,
|
||||
Updated: updated,
|
||||
Destroyed: destroyed,
|
||||
}
|
||||
},
|
||||
func(resp QuotaGetResponse) State { return resp.State },
|
||||
session, ctx, logger, acceptLanguage,
|
||||
)
|
||||
}
|
||||
|
||||
func (j *Client) GetQuotaUsageChanges(accountId string, session *Session, ctx context.Context, logger *log.Logger,
|
||||
acceptLanguage string, sinceState State, maxChanges uint) (QuotaChanges, SessionState, State, Language, Error) {
|
||||
return updatedTemplate(j, "GetQuotaUsageChanges", NS_QUOTA,
|
||||
CommandQuotaChanges, CommandQuotaGet,
|
||||
func() QuotaChangesCommand {
|
||||
return QuotaChangesCommand{AccountId: accountId, SinceState: sinceState, MaxChanges: posUIntPtr(maxChanges)}
|
||||
},
|
||||
func(path string, rof string) QuotaGetRefCommand {
|
||||
return QuotaGetRefCommand{
|
||||
AccountId: accountId,
|
||||
IdsRef: &ResultReference{
|
||||
Name: CommandQuotaChanges,
|
||||
Path: path,
|
||||
ResultOf: rof,
|
||||
},
|
||||
PropertiesRef: &ResultReference{
|
||||
Name: CommandQuotaChanges,
|
||||
Path: "/updatedProperties",
|
||||
ResultOf: rof,
|
||||
},
|
||||
}
|
||||
},
|
||||
func(resp QuotaChangesResponse) (State, State, bool) {
|
||||
return resp.OldState, resp.NewState, resp.HasMoreChanges
|
||||
},
|
||||
func(resp QuotaGetResponse) []Quota { return resp.List },
|
||||
func(oldState, newState State, hasMoreChanges bool, updated []Quota) QuotaChanges {
|
||||
return QuotaChanges{
|
||||
OldState: oldState,
|
||||
NewState: newState,
|
||||
HasMoreChanges: hasMoreChanges,
|
||||
Updated: updated,
|
||||
}
|
||||
},
|
||||
func(resp QuotaGetResponse) State { return resp.State },
|
||||
session, ctx, logger, acceptLanguage,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
)
|
||||
|
||||
var NS_VACATION = ns(JmapVacationResponse)
|
||||
|
||||
const (
|
||||
vacationResponseId = "singleton"
|
||||
)
|
||||
|
||||
func (j *Client) GetVacationResponse(accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (VacationResponseGetResponse, SessionState, State, Language, Error) {
|
||||
return getTemplate(j, "GetVacationResponse", CommandVacationResponseGet,
|
||||
return getTemplate(j, "GetVacationResponse", NS_VACATION, CommandVacationResponseGet,
|
||||
func(accountId string, ids []string) VacationResponseGetCommand {
|
||||
return VacationResponseGetCommand{AccountId: accountId}
|
||||
},
|
||||
@@ -50,7 +52,7 @@ type VacationResponsePayload struct {
|
||||
func (j *Client) SetVacationResponse(accountId string, vacation VacationResponsePayload, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (VacationResponse, SessionState, State, Language, Error) {
|
||||
logger = j.logger("SetVacationResponse", session, logger)
|
||||
|
||||
cmd, err := j.request(session, logger,
|
||||
cmd, err := j.request(session, logger, NS_VACATION,
|
||||
invocation(CommandVacationResponseSet, VacationResponseSetCommand{
|
||||
AccountId: accountId,
|
||||
Create: map[string]VacationResponse{
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"slices"
|
||||
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
"github.com/rs/zerolog"
|
||||
@@ -91,13 +92,20 @@ func (j *Client) maxCallsCheck(calls int, session *Session, logger *log.Logger)
|
||||
// Construct a Request from the given list of Invocation objects.
|
||||
//
|
||||
// If an issue occurs, then it is logged prior to returning it.
|
||||
func (j *Client) request(session *Session, logger *log.Logger, methodCalls ...Invocation) (Request, Error) {
|
||||
func (j *Client) request(session *Session, logger *log.Logger, using []JmapNamespace, methodCalls ...Invocation) (Request, Error) {
|
||||
err := j.maxCallsCheck(len(methodCalls), session, logger)
|
||||
if err != nil {
|
||||
return Request{}, err
|
||||
}
|
||||
|
||||
if using == nil {
|
||||
using = JmapNamespaces
|
||||
}
|
||||
if !slices.Contains(using, JmapCore) {
|
||||
using = slices.Insert(using, 0, JmapCore)
|
||||
}
|
||||
return Request{
|
||||
Using: []string{JmapCore, JmapMail, JmapContacts},
|
||||
Using: using,
|
||||
MethodCalls: methodCalls,
|
||||
CreatedIds: nil,
|
||||
}, nil
|
||||
|
||||
@@ -708,9 +708,9 @@ func (j *TestJmapClient) create(id string, objectType ObjectType, body map[strin
|
||||
}).command(body)
|
||||
}
|
||||
|
||||
func (j *TestJmapClient) create1(accountId string, objectType ObjectType, ns string, obj map[string]any) (string, error) {
|
||||
func (j *TestJmapClient) create1(accountId string, objectType ObjectType, ns JmapNamespace, obj map[string]any) (string, error) {
|
||||
body := map[string]any{
|
||||
"using": []string{JmapCore, ns},
|
||||
"using": []string{string(JmapCore), string(ns)},
|
||||
"methodCalls": []any{
|
||||
[]any{
|
||||
objectType + "/set",
|
||||
@@ -727,11 +727,11 @@ func (j *TestJmapClient) create1(accountId string, objectType ObjectType, ns str
|
||||
return j.create("c", objectType, body)
|
||||
}
|
||||
|
||||
func (j *TestJmapClient) objectsById(accountId string, objectType ObjectType, scope string) (map[string]map[string]any, error) {
|
||||
func (j *TestJmapClient) objectsById(accountId string, objectType ObjectType, scope JmapNamespace) (map[string]map[string]any, error) {
|
||||
m := map[string]map[string]any{}
|
||||
{
|
||||
body := map[string]any{
|
||||
"using": []string{JmapCore, scope},
|
||||
"using": []string{string(JmapCore), string(scope)},
|
||||
"methodCalls": []any{
|
||||
[]any{
|
||||
objectType + "/get",
|
||||
|
||||
@@ -89,26 +89,28 @@ type DispositionTypeOption string
|
||||
|
||||
type Duration string
|
||||
|
||||
type JmapNamespace string
|
||||
|
||||
const (
|
||||
JmapCore = "urn:ietf:params:jmap:core"
|
||||
JmapMail = "urn:ietf:params:jmap:mail"
|
||||
JmapMDN = "urn:ietf:params:jmap:mdn" // https://datatracker.ietf.org/doc/rfc9007/
|
||||
JmapSubmission = "urn:ietf:params:jmap:submission"
|
||||
JmapVacationResponse = "urn:ietf:params:jmap:vacationresponse"
|
||||
JmapCalendars = "urn:ietf:params:jmap:calendars"
|
||||
JmapContacts = "urn:ietf:params:jmap:contacts"
|
||||
JmapSieve = "urn:ietf:params:jmap:sieve"
|
||||
JmapBlob = "urn:ietf:params:jmap:blob"
|
||||
JmapQuota = "urn:ietf:params:jmap:quota"
|
||||
JmapWebsocket = "urn:ietf:params:jmap:websocket" // #nosec G101 false positive: these are not credentials
|
||||
JmapPrincipals = "urn:ietf:params:jmap:principals"
|
||||
JmapPrincipalsOwner = "urn:ietf:params:jmap:principals:owner"
|
||||
JmapTasks = "urn:ietf:params:jmap:tasks"
|
||||
JmapTasksRecurrences = "urn:ietf:params:jmap:tasks:recurrences"
|
||||
JmapTasksAssignees = "urn:ietf:params:jmap:tasks:assignees"
|
||||
JmapTasksAlerts = "urn:ietf:params:jmap:tasks:alerts"
|
||||
JmapTasksMultilingual = "urn:ietf:params:jmap:tasks:multilingual"
|
||||
JmapTasksCustomTimezones = "urn:ietf:params:jmap:tasks:customtimezones"
|
||||
JmapCore = JmapNamespace("urn:ietf:params:jmap:core")
|
||||
JmapMail = JmapNamespace("urn:ietf:params:jmap:mail")
|
||||
JmapMDN = JmapNamespace("urn:ietf:params:jmap:mdn") // https://datatracker.ietf.org/doc/rfc9007/
|
||||
JmapSubmission = JmapNamespace("urn:ietf:params:jmap:submission")
|
||||
JmapVacationResponse = JmapNamespace("urn:ietf:params:jmap:vacationresponse")
|
||||
JmapCalendars = JmapNamespace("urn:ietf:params:jmap:calendars")
|
||||
JmapContacts = JmapNamespace("urn:ietf:params:jmap:contacts")
|
||||
JmapSieve = JmapNamespace("urn:ietf:params:jmap:sieve")
|
||||
JmapBlob = JmapNamespace("urn:ietf:params:jmap:blob")
|
||||
JmapQuota = JmapNamespace("urn:ietf:params:jmap:quota")
|
||||
JmapWebsocket = JmapNamespace("urn:ietf:params:jmap:websocket") // #nosec G101 false positive: these are not credentials
|
||||
JmapPrincipals = JmapNamespace("urn:ietf:params:jmap:principals")
|
||||
JmapPrincipalsOwner = JmapNamespace("urn:ietf:params:jmap:principals:owner")
|
||||
JmapTasks = JmapNamespace("urn:ietf:params:jmap:tasks")
|
||||
JmapTasksRecurrences = JmapNamespace("urn:ietf:params:jmap:tasks:recurrences")
|
||||
JmapTasksAssignees = JmapNamespace("urn:ietf:params:jmap:tasks:assignees")
|
||||
JmapTasksAlerts = JmapNamespace("urn:ietf:params:jmap:tasks:alerts")
|
||||
JmapTasksMultilingual = JmapNamespace("urn:ietf:params:jmap:tasks:multilingual")
|
||||
JmapTasksCustomTimezones = JmapNamespace("urn:ietf:params:jmap:tasks:customtimezones")
|
||||
|
||||
CoreType = ObjectType("Core")
|
||||
PushSubscriptionType = ObjectType("PushSubscription")
|
||||
@@ -260,6 +262,28 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
JmapNamespaces = []JmapNamespace{
|
||||
JmapCore,
|
||||
JmapMail,
|
||||
JmapMDN,
|
||||
JmapSubmission,
|
||||
JmapVacationResponse,
|
||||
JmapCalendars,
|
||||
JmapContacts,
|
||||
JmapSieve,
|
||||
JmapBlob,
|
||||
JmapQuota,
|
||||
JmapWebsocket,
|
||||
JmapPrincipals,
|
||||
JmapPrincipalsOwner,
|
||||
JmapTasks,
|
||||
JmapTasksRecurrences,
|
||||
JmapTasksAssignees,
|
||||
JmapTasksAlerts,
|
||||
JmapTasksMultilingual,
|
||||
JmapTasksCustomTimezones,
|
||||
}
|
||||
|
||||
ObjectTypes = []ObjectType{
|
||||
CoreType,
|
||||
PushSubscriptionType,
|
||||
@@ -1334,29 +1358,6 @@ type MailboxSetResponse struct {
|
||||
NotDestroyed map[string]SetError `json:"notDestroyed,omitempty"`
|
||||
}
|
||||
|
||||
type MailboxChangesCommand struct {
|
||||
// The id of the account to use.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// The current state of the client.
|
||||
//
|
||||
// This is the string that was returned as the state argument in the Mailbox/get response.
|
||||
//
|
||||
// The server will return the changes that have occurred since this state.
|
||||
SinceState State `json:"sinceState,omitempty"`
|
||||
|
||||
// The maximum number of ids to return in the response.
|
||||
//
|
||||
// The server MAY choose to return fewer than this value but MUST NOT return more.
|
||||
//
|
||||
// If not given by the client, the server may choose how many to return.
|
||||
//
|
||||
// If supplied by the client, the value MUST be a positive integer greater than 0.
|
||||
//
|
||||
// If a value outside of this range is given, the server MUST reject the call with an invalidArguments error.
|
||||
MaxChanges *uint `json:"maxChanges,omitzero"`
|
||||
}
|
||||
|
||||
type MailboxFilterElement interface {
|
||||
_isAMailboxFilterElement() // marker method
|
||||
}
|
||||
@@ -2490,7 +2491,7 @@ type EmailSubmissionGetRefCommand struct {
|
||||
//
|
||||
// If null, then all records of the data type are returned, if this is supported for that data
|
||||
// type and the number of records does not exceed the maxObjectsInGet limit.
|
||||
IdRef *ResultReference `json:"#ids,omitempty"`
|
||||
IdsRef *ResultReference `json:"#ids,omitempty"`
|
||||
|
||||
// If supplied, only the properties listed in the array are returned for each EmailSubmission object.
|
||||
//
|
||||
@@ -2532,6 +2533,54 @@ type EmailSubmissionGetResponse struct {
|
||||
NotFound []string `json:"notFound,omitempty"`
|
||||
}
|
||||
|
||||
type EmailSubmissionChangesCommand struct {
|
||||
// The id of the account to use.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// The current state of the client.
|
||||
//
|
||||
// This is the string that was returned as the state argument in the EmailSubmission/get response.
|
||||
//
|
||||
// The server will return the changes that have occurred since this state.
|
||||
SinceState State `json:"sinceState,omitempty"`
|
||||
|
||||
// The maximum number of ids to return in the response.
|
||||
//
|
||||
// The server MAY choose to return fewer than this value but MUST NOT return more.
|
||||
//
|
||||
// If not given by the client, the server may choose how many to return.
|
||||
//
|
||||
// If supplied by the client, the value MUST be a positive integer greater than 0.
|
||||
//
|
||||
// If a value outside of this range is given, the server MUST reject the call with an invalidArguments error.
|
||||
MaxChanges *uint `json:"maxChanges,omitzero"`
|
||||
}
|
||||
|
||||
type EmailSubmissionChangesResponse struct {
|
||||
// The id of the account used for the call.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// This is the sinceState argument echoed back; it’s the state from which the server is returning changes.
|
||||
OldState State `json:"oldState"`
|
||||
|
||||
// This is the state the client will be in after applying the set of changes to the old state.
|
||||
NewState State `json:"newState"`
|
||||
|
||||
// If true, the client may call EmailSubmission/changes again with the newState returned to get further updates.
|
||||
//
|
||||
// If false, newState is the current server state.
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
|
||||
// An array of ids for records that have been created since the old state.
|
||||
Created []string `json:"created,omitempty"`
|
||||
|
||||
// An array of ids for records that have been updated since the old state.
|
||||
Updated []string `json:"updated,omitempty"`
|
||||
|
||||
// An array of ids for records that have been destroyed since the old state.
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
// Patch Object.
|
||||
//
|
||||
// Example:
|
||||
@@ -2643,7 +2692,7 @@ type Request struct {
|
||||
// The client MAY include capability identifiers even if the method calls it makes do not utilise those capabilities.
|
||||
// The server advertises the set of specifications it supports in the Session object
|
||||
// (see [Section 2](https://jmap.io/spec-core.html#the-jmap-session-resource)), as keys on the capabilities property.
|
||||
Using []string `json:"using"`
|
||||
Using []JmapNamespace `json:"using"`
|
||||
|
||||
// An array of method calls to process on the server.
|
||||
//
|
||||
@@ -2815,6 +2864,29 @@ type MailboxGetResponse struct {
|
||||
NotFound []any `json:"notFound"`
|
||||
}
|
||||
|
||||
type MailboxChangesCommand struct {
|
||||
// The id of the account to use.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// The current state of the client.
|
||||
//
|
||||
// This is the string that was returned as the state argument in the Mailbox/get response.
|
||||
//
|
||||
// The server will return the changes that have occurred since this state.
|
||||
SinceState State `json:"sinceState,omitempty"`
|
||||
|
||||
// The maximum number of ids to return in the response.
|
||||
//
|
||||
// The server MAY choose to return fewer than this value but MUST NOT return more.
|
||||
//
|
||||
// If not given by the client, the server may choose how many to return.
|
||||
//
|
||||
// If supplied by the client, the value MUST be a positive integer greater than 0.
|
||||
//
|
||||
// If a value outside of this range is given, the server MUST reject the call with an invalidArguments error.
|
||||
MaxChanges *uint `json:"maxChanges,omitzero"`
|
||||
}
|
||||
|
||||
type MailboxChangesResponse struct {
|
||||
// The id of the account used for the call.
|
||||
AccountId string `json:"accountId"`
|
||||
@@ -3209,6 +3281,60 @@ type IdentityGetCommand struct {
|
||||
Ids []string `json:"ids,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityGetRefCommand struct {
|
||||
AccountId string `json:"accountId"`
|
||||
IdsRef *ResultReference `json:"#ids,omitempty"`
|
||||
PropertiesRef *ResultReference `json:"#properties,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityChangesCommand struct {
|
||||
// The id of the account to use.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// The current state of the client.
|
||||
//
|
||||
// This is the string that was returned as the state argument in the Mailbox/get response.
|
||||
//
|
||||
// The server will return the changes that have occurred since this state.
|
||||
SinceState State `json:"sinceState,omitempty"`
|
||||
|
||||
// The maximum number of ids to return in the response.
|
||||
//
|
||||
// The server MAY choose to return fewer than this value but MUST NOT return more.
|
||||
//
|
||||
// If not given by the client, the server may choose how many to return.
|
||||
//
|
||||
// If supplied by the client, the value MUST be a positive integer greater than 0.
|
||||
//
|
||||
// If a value outside of this range is given, the server MUST reject the call with an invalidArguments error.
|
||||
MaxChanges *uint `json:"maxChanges,omitzero"`
|
||||
}
|
||||
|
||||
type IdentityChangesResponse struct {
|
||||
// The id of the account used for the call.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// This is the sinceState argument echoed back; it’s the state from which the server is returning changes.
|
||||
OldState State `json:"oldState"`
|
||||
|
||||
// This is the state the client will be in after applying the set of changes to the old state.
|
||||
NewState State `json:"newState"`
|
||||
|
||||
// If true, the client may call Mailbox/changes again with the newState returned to get further updates.
|
||||
//
|
||||
// If false, newState is the current server state.
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
|
||||
// An array of ids for records that have been created since the old state.
|
||||
Created []string `json:"created,omitempty"`
|
||||
|
||||
// An array of ids for records that have been updated since the old state.
|
||||
Updated []string `json:"updated,omitempty"`
|
||||
|
||||
// An array of ids for records that have been destroyed since the old state.
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
type IdentitySetCommand struct {
|
||||
AccountId string `json:"accountId"`
|
||||
IfInState string `json:"ifInState,omitempty"`
|
||||
@@ -4948,6 +5074,12 @@ type QuotaGetCommand struct {
|
||||
Ids []string `json:"ids,omitempty"`
|
||||
}
|
||||
|
||||
type QuotaGetRefCommand struct {
|
||||
AccountId string `json:"accountId"`
|
||||
IdsRef *ResultReference `json:"#ids,omitempty"`
|
||||
PropertiesRef *ResultReference `json:"#properties,omitempty"`
|
||||
}
|
||||
|
||||
type QuotaGetResponse struct {
|
||||
AccountId string `json:"accountId"`
|
||||
State State `json:"state,omitempty"`
|
||||
@@ -4955,6 +5087,52 @@ type QuotaGetResponse struct {
|
||||
NotFound []string `json:"notFound,omitempty"`
|
||||
}
|
||||
|
||||
type QuotaChangesCommand struct {
|
||||
// The id of the account to use.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// The current state of the client.
|
||||
// This is the string that was returned as the "state" argument in the "Quota/get" response.
|
||||
// The server will return the changes that have occurred since this state.
|
||||
SinceState State `json:"sinceState,omitempty"`
|
||||
|
||||
// The maximum number of ids to return in the response.
|
||||
// The server MAY choose to return fewer than this value but MUST NOT return more.
|
||||
// If not given by the client, the server may choose how many to return.
|
||||
// If supplied by the client, the value MUST be a positive integer greater than 0.
|
||||
// If a value outside of this range is given, the server MUST reject the call with an `invalidArguments` error.
|
||||
MaxChanges *uint `json:"maxChanges,omitempty"`
|
||||
|
||||
// If only the "used" Quota property has changed since the old state, this will be a list containing only that property.
|
||||
//
|
||||
// If the server is unable to tell if only "used" has changed, it MUST be null.
|
||||
UpdatedProperties []string `json:"updatedProperties,omitempty"`
|
||||
}
|
||||
|
||||
type QuotaChangesResponse struct {
|
||||
// The id of the account used for the call.
|
||||
AccountId string `json:"accountId"`
|
||||
|
||||
// This is the "sinceState" argument echoed back; it's the state from which the server is returning changes.
|
||||
OldState State `json:"oldState"`
|
||||
|
||||
// This is the state the client will be in after applying the set of changes to the old state.
|
||||
NewState State `json:"newState"`
|
||||
|
||||
// If true, the client may call "Quota/changes" again with the "newState" returned to get further updates.
|
||||
// If false, "newState" is the current server state.
|
||||
HasMoreChanges bool `json:"hasMoreChanges"`
|
||||
|
||||
// An array of ids for records that have been created since the old state.
|
||||
Created []string `json:"created,omitempty"`
|
||||
|
||||
// An array of ids for records that have been updated since the old state.
|
||||
Updated []string `json:"updated,omitempty"`
|
||||
|
||||
// An array of ids for records that have been destroyed since the old state.
|
||||
Destroyed []string `json:"destroyed,omitempty"`
|
||||
}
|
||||
|
||||
type AddressBookGetCommand struct {
|
||||
AccountId string `json:"accountId"`
|
||||
Ids []string `json:"ids,omitempty"`
|
||||
@@ -6067,74 +6245,80 @@ type ErrorResponse struct {
|
||||
}
|
||||
|
||||
const (
|
||||
ErrorCommand Command = "error" // only occurs in responses
|
||||
CommandBlobGet Command = "Blob/get"
|
||||
CommandBlobUpload Command = "Blob/upload"
|
||||
CommandEmailGet Command = "Email/get"
|
||||
CommandEmailQuery Command = "Email/query"
|
||||
CommandEmailChanges Command = "Email/changes"
|
||||
CommandEmailSet Command = "Email/set"
|
||||
CommandEmailImport Command = "Email/import"
|
||||
CommandEmailSubmissionGet Command = "EmailSubmission/get"
|
||||
CommandEmailSubmissionSet Command = "EmailSubmission/set"
|
||||
CommandThreadGet Command = "Thread/get"
|
||||
CommandMailboxGet Command = "Mailbox/get"
|
||||
CommandMailboxSet Command = "Mailbox/set"
|
||||
CommandMailboxQuery Command = "Mailbox/query"
|
||||
CommandMailboxChanges Command = "Mailbox/changes"
|
||||
CommandIdentityGet Command = "Identity/get"
|
||||
CommandIdentitySet Command = "Identity/set"
|
||||
CommandVacationResponseGet Command = "VacationResponse/get"
|
||||
CommandVacationResponseSet Command = "VacationResponse/set"
|
||||
CommandSearchSnippetGet Command = "SearchSnippet/get"
|
||||
CommandQuotaGet Command = "Quota/get"
|
||||
CommandAddressBookGet Command = "AddressBook/get"
|
||||
CommandAddressBookChanges Command = "AddressBook/changes"
|
||||
CommandContactCardQuery Command = "ContactCard/query"
|
||||
CommandContactCardGet Command = "ContactCard/get"
|
||||
CommandContactCardChanges Command = "ContactCard/changes"
|
||||
CommandContactCardSet Command = "ContactCard/set"
|
||||
CommandCalendarEventParse Command = "CalendarEvent/parse"
|
||||
CommandCalendarGet Command = "Calendar/get"
|
||||
CommandCalendarChanges Command = "Calendar/changes"
|
||||
CommandCalendarEventQuery Command = "CalendarEvent/query"
|
||||
CommandCalendarEventGet Command = "CalendarEvent/get"
|
||||
CommandCalendarEventSet Command = "CalendarEvent/set"
|
||||
CommandCalendarEventChanges Command = "CalendarEvent/changes"
|
||||
ErrorCommand Command = "error" // only occurs in responses
|
||||
CommandBlobGet Command = "Blob/get"
|
||||
CommandBlobUpload Command = "Blob/upload"
|
||||
CommandEmailGet Command = "Email/get"
|
||||
CommandEmailQuery Command = "Email/query"
|
||||
CommandEmailChanges Command = "Email/changes"
|
||||
CommandEmailSet Command = "Email/set"
|
||||
CommandEmailImport Command = "Email/import"
|
||||
CommandEmailSubmissionGet Command = "EmailSubmission/get"
|
||||
CommandEmailSubmissionSet Command = "EmailSubmission/set"
|
||||
CommandEmailSubmissionChanges Command = "EmailSubmission/changes"
|
||||
CommandThreadGet Command = "Thread/get"
|
||||
CommandMailboxGet Command = "Mailbox/get"
|
||||
CommandMailboxSet Command = "Mailbox/set"
|
||||
CommandMailboxQuery Command = "Mailbox/query"
|
||||
CommandMailboxChanges Command = "Mailbox/changes"
|
||||
CommandIdentityGet Command = "Identity/get"
|
||||
CommandIdentitySet Command = "Identity/set"
|
||||
CommandIdentityChanges Command = "Identity/changes"
|
||||
CommandVacationResponseGet Command = "VacationResponse/get"
|
||||
CommandVacationResponseSet Command = "VacationResponse/set"
|
||||
CommandSearchSnippetGet Command = "SearchSnippet/get"
|
||||
CommandQuotaGet Command = "Quota/get"
|
||||
CommandQuotaChanges Command = "Quota/changes"
|
||||
CommandAddressBookGet Command = "AddressBook/get"
|
||||
CommandAddressBookChanges Command = "AddressBook/changes"
|
||||
CommandContactCardQuery Command = "ContactCard/query"
|
||||
CommandContactCardGet Command = "ContactCard/get"
|
||||
CommandContactCardChanges Command = "ContactCard/changes"
|
||||
CommandContactCardSet Command = "ContactCard/set"
|
||||
CommandCalendarEventParse Command = "CalendarEvent/parse"
|
||||
CommandCalendarGet Command = "Calendar/get"
|
||||
CommandCalendarChanges Command = "Calendar/changes"
|
||||
CommandCalendarEventQuery Command = "CalendarEvent/query"
|
||||
CommandCalendarEventGet Command = "CalendarEvent/get"
|
||||
CommandCalendarEventSet Command = "CalendarEvent/set"
|
||||
CommandCalendarEventChanges Command = "CalendarEvent/changes"
|
||||
)
|
||||
|
||||
var CommandResponseTypeMap = map[Command]func() any{
|
||||
ErrorCommand: func() any { return ErrorResponse{} },
|
||||
CommandBlobGet: func() any { return BlobGetResponse{} },
|
||||
CommandBlobUpload: func() any { return BlobUploadResponse{} },
|
||||
CommandMailboxQuery: func() any { return MailboxQueryResponse{} },
|
||||
CommandMailboxGet: func() any { return MailboxGetResponse{} },
|
||||
CommandMailboxSet: func() any { return MailboxSetResponse{} },
|
||||
CommandMailboxChanges: func() any { return MailboxChangesResponse{} },
|
||||
CommandEmailQuery: func() any { return EmailQueryResponse{} },
|
||||
CommandEmailChanges: func() any { return EmailChangesResponse{} },
|
||||
CommandEmailGet: func() any { return EmailGetResponse{} },
|
||||
CommandEmailSet: func() any { return EmailSetResponse{} },
|
||||
CommandEmailSubmissionGet: func() any { return EmailSubmissionGetResponse{} },
|
||||
CommandEmailSubmissionSet: func() any { return EmailSubmissionSetResponse{} },
|
||||
CommandThreadGet: func() any { return ThreadGetResponse{} },
|
||||
CommandIdentityGet: func() any { return IdentityGetResponse{} },
|
||||
CommandIdentitySet: func() any { return IdentitySetResponse{} },
|
||||
CommandVacationResponseGet: func() any { return VacationResponseGetResponse{} },
|
||||
CommandVacationResponseSet: func() any { return VacationResponseSetResponse{} },
|
||||
CommandSearchSnippetGet: func() any { return SearchSnippetGetResponse{} },
|
||||
CommandQuotaGet: func() any { return QuotaGetResponse{} },
|
||||
CommandAddressBookGet: func() any { return AddressBookGetResponse{} },
|
||||
CommandAddressBookChanges: func() any { return AddressBookChangesResponse{} },
|
||||
CommandContactCardQuery: func() any { return ContactCardQueryResponse{} },
|
||||
CommandContactCardGet: func() any { return ContactCardGetResponse{} },
|
||||
CommandContactCardChanges: func() any { return ContactCardChangesResponse{} },
|
||||
CommandContactCardSet: func() any { return ContactCardSetResponse{} },
|
||||
CommandCalendarEventParse: func() any { return CalendarEventParseResponse{} },
|
||||
CommandCalendarGet: func() any { return CalendarGetResponse{} },
|
||||
CommandCalendarChanges: func() any { return CalendarChangesResponse{} },
|
||||
CommandCalendarEventQuery: func() any { return CalendarEventQueryResponse{} },
|
||||
CommandCalendarEventGet: func() any { return CalendarEventGetResponse{} },
|
||||
CommandCalendarEventSet: func() any { return CalendarEventSetResponse{} },
|
||||
CommandCalendarEventChanges: func() any { return CalendarEventChangesResponse{} },
|
||||
ErrorCommand: func() any { return ErrorResponse{} },
|
||||
CommandBlobGet: func() any { return BlobGetResponse{} },
|
||||
CommandBlobUpload: func() any { return BlobUploadResponse{} },
|
||||
CommandMailboxQuery: func() any { return MailboxQueryResponse{} },
|
||||
CommandMailboxGet: func() any { return MailboxGetResponse{} },
|
||||
CommandMailboxSet: func() any { return MailboxSetResponse{} },
|
||||
CommandMailboxChanges: func() any { return MailboxChangesResponse{} },
|
||||
CommandEmailQuery: func() any { return EmailQueryResponse{} },
|
||||
CommandEmailChanges: func() any { return EmailChangesResponse{} },
|
||||
CommandEmailGet: func() any { return EmailGetResponse{} },
|
||||
CommandEmailSet: func() any { return EmailSetResponse{} },
|
||||
CommandEmailSubmissionGet: func() any { return EmailSubmissionGetResponse{} },
|
||||
CommandEmailSubmissionSet: func() any { return EmailSubmissionSetResponse{} },
|
||||
CommandEmailSubmissionChanges: func() any { return EmailSubmissionChangesResponse{} },
|
||||
CommandThreadGet: func() any { return ThreadGetResponse{} },
|
||||
CommandIdentityGet: func() any { return IdentityGetResponse{} },
|
||||
CommandIdentityChanges: func() any { return IdentityChangesResponse{} },
|
||||
CommandIdentitySet: func() any { return IdentitySetResponse{} },
|
||||
CommandVacationResponseGet: func() any { return VacationResponseGetResponse{} },
|
||||
CommandVacationResponseSet: func() any { return VacationResponseSetResponse{} },
|
||||
CommandSearchSnippetGet: func() any { return SearchSnippetGetResponse{} },
|
||||
CommandQuotaGet: func() any { return QuotaGetResponse{} },
|
||||
CommandQuotaChanges: func() any { return QuotaChangesResponse{} },
|
||||
CommandAddressBookGet: func() any { return AddressBookGetResponse{} },
|
||||
CommandAddressBookChanges: func() any { return AddressBookChangesResponse{} },
|
||||
CommandContactCardQuery: func() any { return ContactCardQueryResponse{} },
|
||||
CommandContactCardGet: func() any { return ContactCardGetResponse{} },
|
||||
CommandContactCardChanges: func() any { return ContactCardChangesResponse{} },
|
||||
CommandContactCardSet: func() any { return ContactCardSetResponse{} },
|
||||
CommandCalendarEventParse: func() any { return CalendarEventParseResponse{} },
|
||||
CommandCalendarGet: func() any { return CalendarGetResponse{} },
|
||||
CommandCalendarChanges: func() any { return CalendarChangesResponse{} },
|
||||
CommandCalendarEventQuery: func() any { return CalendarEventQueryResponse{} },
|
||||
CommandCalendarEventGet: func() any { return CalendarEventGetResponse{} },
|
||||
CommandCalendarEventSet: func() any { return CalendarEventSetResponse{} },
|
||||
CommandCalendarEventChanges: func() any { return CalendarEventChangesResponse{} },
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
func getTemplate[GETREQ any, GETRESP any, RESP any]( //NOSONAR
|
||||
client *Client, name string, getCommand Command,
|
||||
getCommandFactory func(string, []string) GETREQ,
|
||||
client *Client, name string, using []JmapNamespace,
|
||||
getCommand Command, getCommandFactory func(string, []string) GETREQ,
|
||||
mapper func(GETRESP) RESP,
|
||||
stateMapper func(GETRESP) State,
|
||||
accountId string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string, ids []string) (RESP, SessionState, State, Language, Error) {
|
||||
@@ -19,7 +19,7 @@ func getTemplate[GETREQ any, GETRESP any, RESP any]( //NOSONAR
|
||||
|
||||
var zero RESP
|
||||
|
||||
cmd, err := client.request(session, logger,
|
||||
cmd, err := client.request(session, logger, using,
|
||||
invocation(getCommand, getCommandFactory(accountId, ids), "0"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -38,8 +38,8 @@ func getTemplate[GETREQ any, GETRESP any, RESP any]( //NOSONAR
|
||||
}
|
||||
|
||||
func getTemplateN[GETREQ any, GETRESP any, ITEM any, RESP any]( //NOSONAR
|
||||
client *Client, name string, getCommand Command,
|
||||
getCommandFactory func(string, []string) GETREQ,
|
||||
client *Client, name string, using []JmapNamespace,
|
||||
getCommand Command, getCommandFactory func(string, []string) GETREQ,
|
||||
itemMapper func(GETRESP) ITEM,
|
||||
respMapper func(map[string]ITEM) RESP,
|
||||
stateMapper func(GETRESP) State,
|
||||
@@ -55,7 +55,7 @@ func getTemplateN[GETREQ any, GETRESP any, ITEM any, RESP any]( //NOSONAR
|
||||
invocations[i] = invocation(getCommand, getCommandFactory(accountId, ids), mcid(accountId, "0"))
|
||||
}
|
||||
|
||||
cmd, err := client.request(session, logger, invocations...)
|
||||
cmd, err := client.request(session, logger, using, invocations...)
|
||||
if err != nil {
|
||||
return zero, "", "", "", err
|
||||
}
|
||||
@@ -77,7 +77,8 @@ func getTemplateN[GETREQ any, GETRESP any, ITEM any, RESP any]( //NOSONAR
|
||||
}
|
||||
|
||||
func createTemplate[T any, SETREQ any, GETREQ any, SETRESP any, GETRESP any]( //NOSONAR
|
||||
client *Client, name string, t ObjectType, setCommand Command, getCommand Command,
|
||||
client *Client, name string, using []JmapNamespace, t ObjectType,
|
||||
setCommand Command, getCommand Command,
|
||||
setCommandFactory func(string, map[string]T) SETREQ,
|
||||
getCommandFactory func(string, string) GETREQ,
|
||||
createdMapper func(SETRESP) map[string]*T,
|
||||
@@ -88,7 +89,7 @@ func createTemplate[T any, SETREQ any, GETREQ any, SETRESP any, GETRESP any]( //
|
||||
logger = client.logger(name, session, logger)
|
||||
|
||||
createMap := map[string]T{"c": create}
|
||||
cmd, err := client.request(session, logger,
|
||||
cmd, err := client.request(session, logger, using,
|
||||
invocation(setCommand, setCommandFactory(accountId, createMap), "0"),
|
||||
invocation(getCommand, getCommandFactory(accountId, "#c"), "1"),
|
||||
)
|
||||
@@ -135,14 +136,14 @@ func createTemplate[T any, SETREQ any, GETREQ any, SETRESP any, GETRESP any]( //
|
||||
})
|
||||
}
|
||||
|
||||
func deleteTemplate[REQ any, RESP any](client *Client, name string, c Command, //NOSONAR
|
||||
commandFactory func(string, []string) REQ,
|
||||
func deleteTemplate[REQ any, RESP any](client *Client, name string, using []JmapNamespace, //NOSONAR
|
||||
c Command, commandFactory func(string, []string) REQ,
|
||||
notDestroyedMapper func(RESP) map[string]SetError,
|
||||
stateMapper func(RESP) State,
|
||||
accountId string, destroy []string, session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (map[string]SetError, SessionState, State, Language, Error) {
|
||||
logger = client.logger(name, session, logger)
|
||||
|
||||
cmd, err := client.request(session, logger,
|
||||
cmd, err := client.request(session, logger, using,
|
||||
invocation(c, commandFactory(accountId, destroy), "0"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -160,7 +161,7 @@ func deleteTemplate[REQ any, RESP any](client *Client, name string, c Command, /
|
||||
}
|
||||
|
||||
func changesTemplate[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any, ITEM any, RESP any]( //NOSONAR
|
||||
client *Client, name string,
|
||||
client *Client, name string, using []JmapNamespace,
|
||||
changesCommand Command, getCommand Command,
|
||||
changesCommandFactory func() CHANGESREQ,
|
||||
getCommandFactory func(string, string) GETREQ,
|
||||
@@ -175,7 +176,7 @@ func changesTemplate[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any, I
|
||||
changes := changesCommandFactory()
|
||||
getCreated := getCommandFactory("/created", "0") //NOSONAR
|
||||
getUpdated := getCommandFactory("/updated", "0") //NOSONAR
|
||||
cmd, err := client.request(session, logger,
|
||||
cmd, err := client.request(session, logger, using,
|
||||
invocation(changesCommand, changes, "0"),
|
||||
invocation(getCommand, getCreated, "1"),
|
||||
invocation(getCommand, getUpdated, "2"),
|
||||
@@ -215,8 +216,54 @@ func changesTemplate[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any, I
|
||||
})
|
||||
}
|
||||
|
||||
func updatedTemplate[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any, ITEM any, RESP any]( //NOSONAR
|
||||
client *Client, name string, using []JmapNamespace,
|
||||
changesCommand Command, getCommand Command,
|
||||
changesCommandFactory func() CHANGESREQ,
|
||||
getCommandFactory func(string, string) GETREQ,
|
||||
changesMapper func(CHANGESRESP) (State, State, bool),
|
||||
getMapper func(GETRESP) []ITEM,
|
||||
respMapper func(State, State, bool, []ITEM) RESP,
|
||||
stateMapper func(GETRESP) State,
|
||||
session *Session, ctx context.Context, logger *log.Logger, acceptLanguage string) (RESP, SessionState, State, Language, Error) {
|
||||
logger = client.logger(name, session, logger)
|
||||
var zero RESP
|
||||
|
||||
changes := changesCommandFactory()
|
||||
getUpdated := getCommandFactory("/updated", "0") //NOSONAR
|
||||
cmd, err := client.request(session, logger, using,
|
||||
invocation(changesCommand, changes, "0"),
|
||||
invocation(getCommand, getUpdated, "1"),
|
||||
)
|
||||
if err != nil {
|
||||
return zero, "", "", "", err
|
||||
}
|
||||
|
||||
return command(client.api, logger, ctx, session, client.onSessionOutdated, cmd, acceptLanguage, func(body *Response) (RESP, State, Error) {
|
||||
var changesResponse CHANGESRESP
|
||||
err = retrieveResponseMatchParameters(logger, body, changesCommand, "0", &changesResponse)
|
||||
if err != nil {
|
||||
return zero, "", err
|
||||
}
|
||||
|
||||
var updatedResponse GETRESP
|
||||
err = retrieveResponseMatchParameters(logger, body, getCommand, "1", &updatedResponse)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Send()
|
||||
return zero, "", err
|
||||
}
|
||||
|
||||
oldState, newState, hasMoreChanges := changesMapper(changesResponse)
|
||||
updated := getMapper(updatedResponse)
|
||||
|
||||
result := respMapper(oldState, newState, hasMoreChanges, updated)
|
||||
|
||||
return result, stateMapper(updatedResponse), nil
|
||||
})
|
||||
}
|
||||
|
||||
func changesTemplateN[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any, ITEM any, CHANGESITEM any, RESP any]( //NOSONAR
|
||||
client *Client, name string,
|
||||
client *Client, name string, using []JmapNamespace,
|
||||
accountIds []string, sinceStateMap map[string]State,
|
||||
changesCommand Command, getCommand Command,
|
||||
changesCommandFactory func(string, State) CHANGESREQ,
|
||||
@@ -260,7 +307,7 @@ func changesTemplateN[CHANGESREQ any, GETREQ any, CHANGESRESP any, GETRESP any,
|
||||
invocations[i*3+2] = invocation(getCommand, getUpdated, mcid(accountId, "2"))
|
||||
}
|
||||
|
||||
cmd, err := client.request(session, logger, invocations...)
|
||||
cmd, err := client.request(session, logger, using, invocations...)
|
||||
if err != nil {
|
||||
return zero, "", "", "", err
|
||||
}
|
||||
|
||||
@@ -382,3 +382,12 @@ func posUIntPtr(i uint) *uint {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ns(namespaces ...JmapNamespace) []JmapNamespace {
|
||||
result := make([]JmapNamespace, len(namespaces)+1)
|
||||
result[0] = JmapCore
|
||||
for i, n := range namespaces {
|
||||
result[i+1] = n
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ func (g *Groupware) GetChanges(w http.ResponseWriter, r *http.Request) { //NOSON
|
||||
if state, ok := req.getStringParam(QueryParamEvents, ""); ok {
|
||||
sinceState.Events = ptr(toState(state))
|
||||
}
|
||||
if state, ok := req.getStringParam(QueryParamIdentities, ""); ok {
|
||||
sinceState.Identities = ptr(toState(state))
|
||||
}
|
||||
if state, ok := req.getStringParam(QueryParamEmailSubmissions, ""); ok {
|
||||
sinceState.EmailSubmissions = ptr(toState(state))
|
||||
}
|
||||
//if state, ok := req.getStringParam(QueryParamQuotas, ""); ok { sinceState.Quotas = ptr(toState(state)) }
|
||||
if sinceState.IsZero() {
|
||||
return req.noop(accountId)
|
||||
}
|
||||
|
||||
@@ -8,12 +8,15 @@ import (
|
||||
)
|
||||
|
||||
type ObjectsRequest struct {
|
||||
Mailboxes []string `json:"mailboxes,omitempty"`
|
||||
Emails []string `json:"emails,omitempty"`
|
||||
Addressbooks []string `json:"addressbooks,omitempty"`
|
||||
Contacts []string `json:"contacts,omitempty"`
|
||||
Calendars []string `json:"calendars,omitempty"`
|
||||
Events []string `json:"events,omitempty"`
|
||||
Mailboxes []string `json:"mailboxes,omitempty"`
|
||||
Emails []string `json:"emails,omitempty"`
|
||||
Addressbooks []string `json:"addressbooks,omitempty"`
|
||||
Contacts []string `json:"contacts,omitempty"`
|
||||
Calendars []string `json:"calendars,omitempty"`
|
||||
Events []string `json:"events,omitempty"`
|
||||
Quotas []string `json:"quotas,omitempty"`
|
||||
Identities []string `json:"identities,omitempty"`
|
||||
EmailSubmissions []string `json:"submissions,omitempty"`
|
||||
}
|
||||
|
||||
// Retrieve changes for multiple or all Groupware objects, based on their respective state token.
|
||||
@@ -48,17 +51,23 @@ func (g *Groupware) GetObjects(w http.ResponseWriter, r *http.Request) { //NOSON
|
||||
contactIds := []string{}
|
||||
calendarIds := []string{}
|
||||
eventIds := []string{}
|
||||
quotaIds := []string{}
|
||||
identityIds := []string{}
|
||||
emailSubmissionIds := []string{}
|
||||
{
|
||||
var objects ObjectsRequest
|
||||
if ok, err := req.optBody(&objects); err != nil {
|
||||
return req.error(accountId, err)
|
||||
} else if ok {
|
||||
mailboxIds = append(mailboxIds, objects.Mailboxes...)
|
||||
emailIds = append(mailboxIds, objects.Emails...)
|
||||
addressbookIds = append(mailboxIds, objects.Addressbooks...)
|
||||
contactIds = append(mailboxIds, objects.Contacts...)
|
||||
calendarIds = append(mailboxIds, objects.Calendars...)
|
||||
eventIds = append(mailboxIds, objects.Events...)
|
||||
emailIds = append(emailIds, objects.Emails...)
|
||||
addressbookIds = append(addressbookIds, objects.Addressbooks...)
|
||||
contactIds = append(contactIds, objects.Contacts...)
|
||||
calendarIds = append(calendarIds, objects.Calendars...)
|
||||
eventIds = append(eventIds, objects.Events...)
|
||||
quotaIds = append(quotaIds, objects.Quotas...)
|
||||
identityIds = append(identityIds, objects.Identities...)
|
||||
emailSubmissionIds = append(emailSubmissionIds, objects.EmailSubmissions...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,10 +101,25 @@ func (g *Groupware) GetObjects(w http.ResponseWriter, r *http.Request) { //NOSON
|
||||
} else if ok {
|
||||
eventIds = append(eventIds, list...)
|
||||
}
|
||||
if list, ok, err := req.parseOptStringListParam(QueryParamQuotas); err != nil {
|
||||
return req.error(accountId, err)
|
||||
} else if ok {
|
||||
quotaIds = append(quotaIds, list...)
|
||||
}
|
||||
if list, ok, err := req.parseOptStringListParam(QueryParamIdentities); err != nil {
|
||||
return req.error(accountId, err)
|
||||
} else if ok {
|
||||
identityIds = append(identityIds, list...)
|
||||
}
|
||||
if list, ok, err := req.parseOptStringListParam(QueryParamEmailSubmissions); err != nil {
|
||||
return req.error(accountId, err)
|
||||
} else if ok {
|
||||
emailSubmissionIds = append(emailSubmissionIds, list...)
|
||||
}
|
||||
|
||||
logger := log.From(l)
|
||||
objs, sessionState, state, lang, jerr := g.jmap.GetObjects(accountId, req.session, req.ctx, logger, req.language(),
|
||||
mailboxIds, emailIds, addressbookIds, contactIds, calendarIds, eventIds)
|
||||
mailboxIds, emailIds, addressbookIds, contactIds, calendarIds, eventIds, quotaIds, identityIds, emailSubmissionIds)
|
||||
if jerr != nil {
|
||||
return req.jmapError(accountId, jerr, sessionState, lang)
|
||||
}
|
||||
|
||||
@@ -64,3 +64,36 @@ func (g *Groupware) GetQuotaForAllAccounts(w http.ResponseWriter, r *http.Reques
|
||||
return req.respondN(accountIds, result, sessionState, QuotaResponseObjectType, state)
|
||||
})
|
||||
}
|
||||
|
||||
// Get changes to Contacts since a given State
|
||||
// @api:tags contact,changes
|
||||
func (g *Groupware) GetQuotaChanges(w http.ResponseWriter, r *http.Request) {
|
||||
g.respond(w, r, func(req Request) Response {
|
||||
accountId, err := req.GetAccountIdForQuota()
|
||||
if err != nil {
|
||||
return req.error(accountId, err)
|
||||
}
|
||||
|
||||
l := req.logger.With().Str(logAccountId, accountId)
|
||||
|
||||
var maxChanges uint = 0
|
||||
if v, ok, err := req.parseUIntParam(QueryParamMaxChanges, 0); err != nil {
|
||||
return req.error(accountId, err)
|
||||
} else if ok {
|
||||
maxChanges = v
|
||||
l = l.Uint(QueryParamMaxChanges, v)
|
||||
}
|
||||
|
||||
sinceState := jmap.State(req.OptHeaderParamDoc(HeaderParamSince, "Specifies the state identifier from which on to list quota changes"))
|
||||
l = l.Str(HeaderParamSince, log.SafeString(string(sinceState)))
|
||||
|
||||
logger := log.From(l)
|
||||
changes, sessionState, state, lang, jerr := g.jmap.GetQuotaChanges(accountId, req.session, req.ctx, logger, req.language(), sinceState, maxChanges)
|
||||
if jerr != nil {
|
||||
return req.jmapError(accountId, jerr, sessionState, lang)
|
||||
}
|
||||
var body jmap.QuotaChanges = changes
|
||||
|
||||
return req.respond(accountId, body, sessionState, QuotaResponseObjectType, state)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ const (
|
||||
QueryParamContacts = "contacts"
|
||||
QueryParamCalendars = "calendars"
|
||||
QueryParamEvents = "events"
|
||||
QueryParamQuotas = "quotas"
|
||||
QueryParamIdentities = "identities"
|
||||
QueryParamEmailSubmissions = "submissions"
|
||||
HeaderParamSince = "if-none-match"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user