groupware: swagger API documentation improvements

* add more documentation for properties

 * fixes after a bit of trial-and-error with go-swagger

 * fix email filter marshalling when there are no search criteria

 * introduce an apidoc.yml that contains Swagger data and is merged when
   generating the swagger.yml from sources
This commit is contained in:
Pascal Bleser
2025-08-12 16:04:09 +02:00
parent 4d338ff6b8
commit 42a4c5c156
18 changed files with 1271 additions and 334 deletions
+7 -7
View File
@@ -19,7 +19,7 @@ func (j *Client) GetBlob(accountId string, session *Session, ctx context.Context
aid := session.BlobAccountId(accountId)
cmd, err := request(
invocation(BlobUpload, BlobGetCommand{
invocation(CommandBlobUpload, BlobGetCommand{
AccountId: aid,
Ids: []string{id},
Properties: []string{BlobPropertyData, BlobPropertyDigestSha512, BlobPropertySize},
@@ -31,7 +31,7 @@ func (j *Client) GetBlob(accountId string, session *Session, ctx context.Context
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (BlobResponse, Error) {
var response BlobGetResponse
err = retrieveResponseMatchParameters(body, BlobGet, "0", &response)
err = retrieveResponseMatchParameters(body, CommandBlobGet, "0", &response)
if err != nil {
return BlobResponse{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -93,15 +93,15 @@ func (j *Client) UploadBlob(accountId string, session *Session, ctx context.Cont
AccountId: aid,
IdRef: &ResultReference{
ResultOf: "0",
Name: BlobUpload,
Name: CommandBlobUpload,
Path: "/ids",
},
Properties: []string{BlobPropertyDigestSha512},
}
cmd, err := request(
invocation(BlobUpload, upload, "0"),
invocation(BlobGet, getHash, "1"),
invocation(CommandBlobUpload, upload, "0"),
invocation(CommandBlobGet, getHash, "1"),
)
if err != nil {
return UploadedBlob{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -109,13 +109,13 @@ func (j *Client) UploadBlob(accountId string, session *Session, ctx context.Cont
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (UploadedBlob, Error) {
var uploadResponse BlobUploadResponse
err = retrieveResponseMatchParameters(body, BlobUpload, "0", &uploadResponse)
err = retrieveResponseMatchParameters(body, CommandBlobUpload, "0", &uploadResponse)
if err != nil {
return UploadedBlob{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var getResponse BlobGetResponse
err = retrieveResponseMatchParameters(body, BlobGet, "1", &getResponse)
err = retrieveResponseMatchParameters(body, CommandBlobGet, "1", &getResponse)
if err != nil {
return UploadedBlob{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
+59 -59
View File
@@ -40,13 +40,13 @@ func (j *Client) GetEmails(accountId string, session *Session, ctx context.Conte
get.MaxBodyValueBytes = maxBodyValueBytes
}
cmd, err := request(invocation(EmailGet, get, "0"))
cmd, err := request(invocation(CommandEmailGet, get, "0"))
if err != nil {
return Emails{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (Emails, Error) {
var response EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "0", &response)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "0", &response)
if err != nil {
return Emails{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -63,7 +63,7 @@ func (j *Client) GetAllEmails(accountId string, session *Session, ctx context.Co
query := EmailQueryCommand{
AccountId: aid,
Filter: &EmailFilterCondition{InMailbox: mailboxId},
Sort: []Sort{{Property: emailSortByReceivedAt, IsAscending: false}},
Sort: []EmailComparator{{Property: emailSortByReceivedAt, IsAscending: false}},
CollapseThreads: true,
CalculateTotal: true,
}
@@ -77,15 +77,15 @@ func (j *Client) GetAllEmails(accountId string, session *Session, ctx context.Co
get := EmailGetRefCommand{
AccountId: aid,
FetchAllBodyValues: fetchBodies,
IdRef: &ResultReference{Name: EmailQuery, Path: "/ids/*", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandEmailQuery, Path: "/ids/*", ResultOf: "0"},
}
if maxBodyValueBytes >= 0 {
get.MaxBodyValueBytes = maxBodyValueBytes
}
cmd, err := request(
invocation(EmailQuery, query, "0"),
invocation(EmailGet, get, "1"),
invocation(CommandEmailQuery, query, "0"),
invocation(CommandEmailGet, get, "1"),
)
if err != nil {
return Emails{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -93,12 +93,12 @@ func (j *Client) GetAllEmails(accountId string, session *Session, ctx context.Co
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (Emails, Error) {
var queryResponse EmailQueryResponse
err = retrieveResponseMatchParameters(body, EmailQuery, "0", &queryResponse)
err = retrieveResponseMatchParameters(body, CommandEmailQuery, "0", &queryResponse)
if err != nil {
return Emails{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var getResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "1", &getResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "1", &getResponse)
if err != nil {
return Emails{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -141,7 +141,7 @@ func (j *Client) GetEmailsInMailboxSince(accountId string, session *Session, ctx
getCreated := EmailGetRefCommand{
AccountId: aid,
FetchAllBodyValues: fetchBodies,
IdRef: &ResultReference{Name: MailboxChanges, Path: "/created", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandMailboxChanges, Path: "/created", ResultOf: "0"},
}
if maxBodyValueBytes >= 0 {
getCreated.MaxBodyValueBytes = maxBodyValueBytes
@@ -149,16 +149,16 @@ func (j *Client) GetEmailsInMailboxSince(accountId string, session *Session, ctx
getUpdated := EmailGetRefCommand{
AccountId: aid,
FetchAllBodyValues: fetchBodies,
IdRef: &ResultReference{Name: MailboxChanges, Path: "/updated", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandMailboxChanges, Path: "/updated", ResultOf: "0"},
}
if maxBodyValueBytes >= 0 {
getUpdated.MaxBodyValueBytes = maxBodyValueBytes
}
cmd, err := request(
invocation(MailboxChanges, changes, "0"),
invocation(EmailGet, getCreated, "1"),
invocation(EmailGet, getUpdated, "2"),
invocation(CommandMailboxChanges, changes, "0"),
invocation(CommandEmailGet, getCreated, "1"),
invocation(CommandEmailGet, getUpdated, "2"),
)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -166,19 +166,19 @@ func (j *Client) GetEmailsInMailboxSince(accountId string, session *Session, ctx
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (EmailsSince, Error) {
var mailboxResponse MailboxChangesResponse
err = retrieveResponseMatchParameters(body, MailboxChanges, "0", &mailboxResponse)
err = retrieveResponseMatchParameters(body, CommandMailboxChanges, "0", &mailboxResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var createdResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "1", &createdResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "1", &createdResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var updatedResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "2", &updatedResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "2", &updatedResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -212,7 +212,7 @@ func (j *Client) GetEmailsSince(accountId string, session *Session, ctx context.
getCreated := EmailGetRefCommand{
AccountId: aid,
FetchAllBodyValues: fetchBodies,
IdRef: &ResultReference{Name: EmailChanges, Path: "/created", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandEmailChanges, Path: "/created", ResultOf: "0"},
}
if maxBodyValueBytes >= 0 {
getCreated.MaxBodyValueBytes = maxBodyValueBytes
@@ -220,16 +220,16 @@ func (j *Client) GetEmailsSince(accountId string, session *Session, ctx context.
getUpdated := EmailGetRefCommand{
AccountId: aid,
FetchAllBodyValues: fetchBodies,
IdRef: &ResultReference{Name: EmailChanges, Path: "/updated", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandEmailChanges, Path: "/updated", ResultOf: "0"},
}
if maxBodyValueBytes >= 0 {
getUpdated.MaxBodyValueBytes = maxBodyValueBytes
}
cmd, err := request(
invocation(EmailChanges, changes, "0"),
invocation(EmailGet, getCreated, "1"),
invocation(EmailGet, getUpdated, "2"),
invocation(CommandEmailChanges, changes, "0"),
invocation(CommandEmailGet, getCreated, "1"),
invocation(CommandEmailGet, getUpdated, "2"),
)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -237,19 +237,19 @@ func (j *Client) GetEmailsSince(accountId string, session *Session, ctx context.
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (EmailsSince, Error) {
var changesResponse EmailChangesResponse
err = retrieveResponseMatchParameters(body, EmailChanges, "0", &changesResponse)
err = retrieveResponseMatchParameters(body, CommandEmailChanges, "0", &changesResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var createdResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "1", &createdResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "1", &createdResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var updatedResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "2", &updatedResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "2", &updatedResponse)
if err != nil {
return EmailsSince{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -284,7 +284,7 @@ func (j *Client) QueryEmailSnippets(accountId string, filter EmailFilterElement,
query := EmailQueryCommand{
AccountId: aid,
Filter: filter,
Sort: []Sort{{Property: emailSortByReceivedAt, IsAscending: false}},
Sort: []EmailComparator{{Property: emailSortByReceivedAt, IsAscending: false}},
CollapseThreads: true,
CalculateTotal: true,
}
@@ -295,19 +295,19 @@ func (j *Client) QueryEmailSnippets(accountId string, filter EmailFilterElement,
query.Limit = limit
}
snippet := SearchSnippetRefCommand{
snippet := SearchSnippetGetRefCommand{
AccountId: aid,
Filter: filter,
EmailIdRef: &ResultReference{
ResultOf: "0",
Name: EmailQuery,
Name: CommandEmailQuery,
Path: "/ids/*",
},
}
cmd, err := request(
invocation(EmailQuery, query, "0"),
invocation(SearchSnippetGet, snippet, "1"),
invocation(CommandEmailQuery, query, "0"),
invocation(CommandSearchSnippetGet, snippet, "1"),
)
if err != nil {
@@ -316,13 +316,13 @@ func (j *Client) QueryEmailSnippets(accountId string, filter EmailFilterElement,
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (EmailSnippetQueryResult, Error) {
var queryResponse EmailQueryResponse
err = retrieveResponseMatchParameters(body, EmailQuery, "0", &queryResponse)
err = retrieveResponseMatchParameters(body, CommandEmailQuery, "0", &queryResponse)
if err != nil {
return EmailSnippetQueryResult{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var snippetResponse SearchSnippetGetResponse
err = retrieveResponseMatchParameters(body, SearchSnippetGet, "1", &snippetResponse)
err = retrieveResponseMatchParameters(body, CommandSearchSnippetGet, "1", &snippetResponse)
if err != nil {
return EmailSnippetQueryResult{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -362,7 +362,7 @@ func (j *Client) QueryEmails(accountId string, filter EmailFilterElement, sessio
query := EmailQueryCommand{
AccountId: aid,
Filter: filter,
Sort: []Sort{{Property: emailSortByReceivedAt, IsAscending: false}},
Sort: []EmailComparator{{Property: emailSortByReceivedAt, IsAscending: false}},
CollapseThreads: true,
CalculateTotal: true,
}
@@ -373,12 +373,12 @@ func (j *Client) QueryEmails(accountId string, filter EmailFilterElement, sessio
query.Limit = limit
}
snippet := SearchSnippetRefCommand{
snippet := SearchSnippetGetRefCommand{
AccountId: aid,
Filter: filter,
EmailIdRef: &ResultReference{
ResultOf: "0",
Name: EmailQuery,
Name: CommandEmailQuery,
Path: "/ids/*",
},
}
@@ -387,7 +387,7 @@ func (j *Client) QueryEmails(accountId string, filter EmailFilterElement, sessio
AccountId: aid,
IdRef: &ResultReference{
ResultOf: "0",
Name: EmailQuery,
Name: CommandEmailQuery,
Path: "/ids/*",
},
FetchAllBodyValues: fetchBodies,
@@ -395,9 +395,9 @@ func (j *Client) QueryEmails(accountId string, filter EmailFilterElement, sessio
}
cmd, err := request(
invocation(EmailQuery, query, "0"),
invocation(SearchSnippetGet, snippet, "1"),
invocation(EmailGet, mails, "2"),
invocation(CommandEmailQuery, query, "0"),
invocation(CommandSearchSnippetGet, snippet, "1"),
invocation(CommandEmailGet, mails, "2"),
)
if err != nil {
@@ -406,19 +406,19 @@ func (j *Client) QueryEmails(accountId string, filter EmailFilterElement, sessio
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (EmailQueryResult, Error) {
var queryResponse EmailQueryResponse
err = retrieveResponseMatchParameters(body, EmailQuery, "0", &queryResponse)
err = retrieveResponseMatchParameters(body, CommandEmailQuery, "0", &queryResponse)
if err != nil {
return EmailQueryResult{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var snippetResponse SearchSnippetGetResponse
err = retrieveResponseMatchParameters(body, SearchSnippetGet, "1", &snippetResponse)
err = retrieveResponseMatchParameters(body, CommandSearchSnippetGet, "1", &snippetResponse)
if err != nil {
return EmailQueryResult{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var emailsResponse EmailGetResponse
err = retrieveResponseMatchParameters(body, EmailGet, "2", &emailsResponse)
err = retrieveResponseMatchParameters(body, CommandEmailGet, "2", &emailsResponse)
if err != nil {
return EmailQueryResult{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -485,15 +485,15 @@ func (j *Client) ImportEmail(accountId string, session *Session, ctx context.Con
AccountId: aid,
IdRef: &ResultReference{
ResultOf: "0",
Name: BlobUpload,
Name: CommandBlobUpload,
Path: "/ids",
},
Properties: []string{BlobPropertyDigestSha512},
}
cmd, err := request(
invocation(BlobUpload, upload, "0"),
invocation(BlobGet, getHash, "1"),
invocation(CommandBlobUpload, upload, "0"),
invocation(CommandBlobGet, getHash, "1"),
)
if err != nil {
return UploadedEmail{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -501,13 +501,13 @@ func (j *Client) ImportEmail(accountId string, session *Session, ctx context.Con
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (UploadedEmail, Error) {
var uploadResponse BlobUploadResponse
err = retrieveResponseMatchParameters(body, BlobUpload, "0", &uploadResponse)
err = retrieveResponseMatchParameters(body, CommandBlobUpload, "0", &uploadResponse)
if err != nil {
return UploadedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var getResponse BlobGetResponse
err = retrieveResponseMatchParameters(body, BlobGet, "1", &getResponse)
err = retrieveResponseMatchParameters(body, CommandBlobGet, "1", &getResponse)
if err != nil {
return UploadedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -546,7 +546,7 @@ func (j *Client) CreateEmail(accountId string, email EmailCreate, session *Sessi
aid := session.MailAccountId(accountId)
cmd, err := request(
invocation(EmailSubmissionSet, EmailSetCommand{
invocation(CommandEmailSubmissionSet, EmailSetCommand{
AccountId: aid,
Create: map[string]EmailCreate{
"c": email,
@@ -559,7 +559,7 @@ func (j *Client) CreateEmail(accountId string, email EmailCreate, session *Sessi
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (CreatedEmail, Error) {
var setResponse EmailSetResponse
err = retrieveResponseMatchParameters(body, EmailSet, "0", &setResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSet, "0", &setResponse)
if err != nil {
return CreatedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -576,7 +576,7 @@ func (j *Client) CreateEmail(accountId string, email EmailCreate, session *Sessi
created, ok := setResponse.Created["c"]
if !ok {
err = fmt.Errorf("failed to find %s in %s response", string(EmailType), string(EmailSet))
err = fmt.Errorf("failed to find %s in %s response", string(EmailType), string(CommandEmailSet))
return CreatedEmail{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
}
@@ -606,7 +606,7 @@ func (j *Client) UpdateEmails(accountId string, updates map[string]EmailUpdate,
aid := session.MailAccountId(accountId)
cmd, err := request(
invocation(EmailSet, EmailSetCommand{
invocation(CommandEmailSet, EmailSetCommand{
AccountId: aid,
Update: updates,
}, "0"),
@@ -617,7 +617,7 @@ func (j *Client) UpdateEmails(accountId string, updates map[string]EmailUpdate,
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (UpdatedEmails, Error) {
var setResponse EmailSetResponse
err = retrieveResponseMatchParameters(body, EmailSet, "0", &setResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSet, "0", &setResponse)
if err != nil {
return UpdatedEmails{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -642,7 +642,7 @@ func (j *Client) DeleteEmails(accountId string, destroy []string, session *Sessi
aid := session.MailAccountId(accountId)
cmd, err := request(
invocation(EmailSet, EmailSetCommand{
invocation(CommandEmailSet, EmailSetCommand{
AccountId: aid,
Destroy: destroy,
}, "0"),
@@ -653,7 +653,7 @@ func (j *Client) DeleteEmails(accountId string, destroy []string, session *Sessi
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (DeletedEmails, Error) {
var setResponse EmailSetResponse
err = retrieveResponseMatchParameters(body, EmailSet, "0", &setResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSet, "0", &setResponse)
if err != nil {
return DeletedEmails{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -714,14 +714,14 @@ func (j *Client) SubmitEmail(accountId string, identityId string, emailId string
AccountId: aid,
IdRef: &ResultReference{
ResultOf: "0",
Name: EmailSubmissionSet,
Name: CommandEmailSubmissionSet,
Path: "/created/s0/id",
},
}
cmd, err := request(
invocation(EmailSubmissionSet, set, "0"),
invocation(EmailSubmissionGet, get, "1"),
invocation(CommandEmailSubmissionSet, set, "0"),
invocation(CommandEmailSubmissionGet, get, "1"),
)
if err != nil {
return SubmittedEmail{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
@@ -729,7 +729,7 @@ func (j *Client) SubmitEmail(accountId string, identityId string, emailId string
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (SubmittedEmail, Error) {
var submissionResponse EmailSubmissionSetResponse
err = retrieveResponseMatchParameters(body, EmailSubmissionSet, "0", &submissionResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSubmissionSet, "0", &submissionResponse)
if err != nil {
return SubmittedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
@@ -745,13 +745,13 @@ func (j *Client) SubmitEmail(accountId string, identityId string, emailId string
// The response to this MUST be returned after the EmailSubmission/set response."
// from an example in the spec, it has the same tag as the EmailSubmission/set command ("0" in this case)
var setResponse EmailSetResponse
err = retrieveResponseMatchParameters(body, EmailSet, "0", &setResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSet, "0", &setResponse)
if err != nil {
return SubmittedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
var getResponse EmailSubmissionGetResponse
err = retrieveResponseMatchParameters(body, EmailSubmissionGet, "1", &getResponse)
err = retrieveResponseMatchParameters(body, CommandEmailSubmissionGet, "1", &getResponse)
if err != nil {
return SubmittedEmail{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
+4 -4
View File
@@ -19,13 +19,13 @@ type Identities struct {
func (j *Client) GetIdentity(accountId string, session *Session, ctx context.Context, logger *log.Logger) (Identities, Error) {
aid := session.MailAccountId(accountId)
logger = j.logger(aid, "GetIdentity", session, logger)
cmd, err := request(invocation(IdentityGet, IdentityGetCommand{AccountId: aid}, "0"))
cmd, err := request(invocation(CommandIdentityGet, IdentityGetCommand{AccountId: aid}, "0"))
if err != nil {
return Identities{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (Identities, Error) {
var response IdentityGetResponse
err = retrieveResponseMatchParameters(body, IdentityGet, "0", &response)
err = retrieveResponseMatchParameters(body, CommandIdentityGet, "0", &response)
return Identities{
Identities: response.List,
State: response.State,
@@ -50,7 +50,7 @@ func (j *Client) GetIdentities(accountIds []string, session *Session, ctx contex
calls := make([]Invocation, len(uniqueAccountIds))
for i, accountId := range uniqueAccountIds {
calls[i] = invocation(IdentityGet, IdentityGetCommand{AccountId: accountId}, strconv.Itoa(i))
calls[i] = invocation(CommandIdentityGet, IdentityGetCommand{AccountId: accountId}, strconv.Itoa(i))
}
cmd, err := request(calls...)
@@ -63,7 +63,7 @@ func (j *Client) GetIdentities(accountIds []string, session *Session, ctx contex
notFound := []string{}
for i, accountId := range uniqueAccountIds {
var response IdentityGetResponse
err = retrieveResponseMatchParameters(body, IdentityGet, strconv.Itoa(i), &response)
err = retrieveResponseMatchParameters(body, CommandIdentityGet, strconv.Itoa(i), &response)
if err != nil {
return IdentitiesGetResponse{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
} else {
+6 -6
View File
@@ -17,14 +17,14 @@ type MailboxesResponse struct {
func (j *Client) GetMailbox(accountId string, session *Session, ctx context.Context, logger *log.Logger, ids []string) (MailboxesResponse, Error) {
aid := session.MailAccountId(accountId)
logger = j.logger(aid, "GetMailbox", session, logger)
cmd, err := request(invocation(MailboxGet, MailboxGetCommand{AccountId: aid, Ids: ids}, "0"))
cmd, err := request(invocation(CommandMailboxGet, MailboxGetCommand{AccountId: aid, Ids: ids}, "0"))
if err != nil {
return MailboxesResponse{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (MailboxesResponse, Error) {
var response MailboxGetResponse
err = retrieveResponseMatchParameters(body, MailboxGet, "0", &response)
err = retrieveResponseMatchParameters(body, CommandMailboxGet, "0", &response)
if err != nil {
return MailboxesResponse{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
}
@@ -70,10 +70,10 @@ func (j *Client) SearchMailboxes(accountId string, session *Session, ctx context
logger = j.logger(aid, "SearchMailboxes", session, logger)
cmd, err := request(
invocation(MailboxQuery, MailboxQueryCommand{AccountId: aid, Filter: filter}, "0"),
invocation(MailboxGet, MailboxGetRefCommand{
invocation(CommandMailboxQuery, MailboxQueryCommand{AccountId: aid, Filter: filter}, "0"),
invocation(CommandMailboxGet, MailboxGetRefCommand{
AccountId: aid,
IdRef: &ResultReference{Name: MailboxQuery, Path: "/ids/*", ResultOf: "0"},
IdRef: &ResultReference{Name: CommandMailboxQuery, Path: "/ids/*", ResultOf: "0"},
}, "1"),
)
if err != nil {
@@ -82,7 +82,7 @@ func (j *Client) SearchMailboxes(accountId string, session *Session, ctx context
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (Mailboxes, Error) {
var response MailboxGetResponse
err = retrieveResponseMatchParameters(body, MailboxGet, "1", &response)
err = retrieveResponseMatchParameters(body, CommandMailboxGet, "1", &response)
if err != nil {
return Mailboxes{}, SimpleError{code: JmapErrorInvalidJmapResponsePayload, err: err}
}
+7 -7
View File
@@ -16,13 +16,13 @@ const (
func (j *Client) GetVacationResponse(accountId string, session *Session, ctx context.Context, logger *log.Logger) (VacationResponseGetResponse, Error) {
aid := session.MailAccountId(accountId)
logger = j.logger(aid, "GetVacationResponse", session, logger)
cmd, err := request(invocation(VacationResponseGet, VacationResponseGetCommand{AccountId: aid}, "0"))
cmd, err := request(invocation(CommandVacationResponseGet, VacationResponseGetCommand{AccountId: aid}, "0"))
if err != nil {
return VacationResponseGetResponse{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (VacationResponseGetResponse, Error) {
var response VacationResponseGetResponse
err = retrieveResponseMatchParameters(body, VacationResponseGet, "0", &response)
err = retrieveResponseMatchParameters(body, CommandVacationResponseGet, "0", &response)
return response, simpleError(err, JmapErrorInvalidJmapResponsePayload)
})
}
@@ -62,7 +62,7 @@ func (j *Client) SetVacationResponse(accountId string, vacation VacationResponse
logger = j.logger(aid, "SetVacationResponse", session, logger)
cmd, err := request(
invocation(VacationResponseSet, VacationResponseSetCommand{
invocation(CommandVacationResponseSet, VacationResponseSetCommand{
AccountId: aid,
Create: map[string]VacationResponse{
vacationResponseId: {
@@ -77,14 +77,14 @@ func (j *Client) SetVacationResponse(accountId string, vacation VacationResponse
}, "0"),
// chain a second request to get the current complete VacationResponse object
// after performing the changes, as that makes for a better API
invocation(VacationResponseGet, VacationResponseGetCommand{AccountId: aid}, "1"),
invocation(CommandVacationResponseGet, VacationResponseGetCommand{AccountId: aid}, "1"),
)
if err != nil {
return VacationResponseChange{}, SimpleError{code: JmapErrorInvalidJmapRequestPayload, err: err}
}
return command(j.api, logger, ctx, session, j.onSessionOutdated, cmd, func(body *Response) (VacationResponseChange, Error) {
var setResponse VacationResponseSetResponse
err = retrieveResponseMatchParameters(body, VacationResponseSet, "0", &setResponse)
err = retrieveResponseMatchParameters(body, CommandVacationResponseSet, "0", &setResponse)
if err != nil {
return VacationResponseChange{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
}
@@ -96,13 +96,13 @@ func (j *Client) SetVacationResponse(accountId string, vacation VacationResponse
}
var getResponse VacationResponseGetResponse
err = retrieveResponseMatchParameters(body, VacationResponseGet, "1", &getResponse)
err = retrieveResponseMatchParameters(body, CommandVacationResponseGet, "1", &getResponse)
if err != nil {
return VacationResponseChange{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
}
if len(getResponse.List) != 1 {
err = fmt.Errorf("failed to find %s in %s response", string(VacationResponseType), string(VacationResponseGet))
err = fmt.Errorf("failed to find %s in %s response", string(VacationResponseType), string(CommandVacationResponseGet))
return VacationResponseChange{}, simpleError(err, JmapErrorInvalidJmapResponsePayload)
}
+3
View File
@@ -60,5 +60,8 @@ func (j *Client) loggerParams(accountId string, operation string, session *Sessi
if accountId != "" {
l = l.Str(logAccountId, accountId)
}
if params != nil {
l = params(l)
}
return log.From(l)
}
+946 -179
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -1,7 +1,7 @@
package jmap
import (
"fmt"
"errors"
"net/url"
"github.com/opencloud-eu/opencloud/pkg/log"
@@ -43,46 +43,46 @@ type Session struct {
// The upload URL template
DownloadUrlTemplate string
// TODO
DefaultMailAccountId string
SessionResponse
}
var (
invalidSessionResponseErrorMissingUsername = SimpleError{code: JmapErrorInvalidSessionResponse, err: errors.New("JMAP session response does not provide a username")}
invalidSessionResponseErrorMissingApiUrl = SimpleError{code: JmapErrorInvalidSessionResponse, err: errors.New("JMAP session response does not provide an API URL")}
invalidSessionResponseErrorInvalidApiUrl = SimpleError{code: JmapErrorInvalidSessionResponse, err: errors.New("JMAP session response provides an invalid API URL")}
invalidSessionResponseErrorMissingUploadUrl = SimpleError{code: JmapErrorInvalidSessionResponse, err: errors.New("JMAP session response does not provide an upload URL")}
invalidSessionResponseErrorMissingDownloadUrl = SimpleError{code: JmapErrorInvalidSessionResponse, err: errors.New("JMAP session response does not provide a download URL")}
)
// Create a new Session from a SessionResponse.
func newSession(sessionResponse SessionResponse) (Session, Error) {
username := sessionResponse.Username
if username == "" {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response does not provide a username")}
}
mailAccountId := sessionResponse.PrimaryAccounts.Mail
if mailAccountId == "" {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response does not provide a primary mail account")}
return Session{}, invalidSessionResponseErrorMissingUsername
}
apiStr := sessionResponse.ApiUrl
if apiStr == "" {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response does not provide an API URL")}
return Session{}, invalidSessionResponseErrorMissingApiUrl
}
apiUrl, err := url.Parse(apiStr)
if err != nil {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response provides an invalid API URL")}
return Session{}, invalidSessionResponseErrorInvalidApiUrl
}
uploadUrl := sessionResponse.UploadUrl
if uploadUrl == "" {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response does not provide an upload URL")}
return Session{}, invalidSessionResponseErrorMissingUploadUrl
}
downloadUrl := sessionResponse.DownloadUrl
if downloadUrl == "" {
return Session{}, SimpleError{code: JmapErrorInvalidSessionResponse, err: fmt.Errorf("JMAP session response does not provide an download URL")}
return Session{}, invalidSessionResponseErrorMissingDownloadUrl
}
return Session{
Username: username,
DefaultMailAccountId: mailAccountId,
JmapUrl: *apiUrl,
UploadUrlTemplate: uploadUrl,
DownloadUrlTemplate: downloadUrl,
SessionResponse: sessionResponse,
Username: username,
JmapUrl: *apiUrl,
UploadUrlTemplate: uploadUrl,
DownloadUrlTemplate: downloadUrl,
SessionResponse: sessionResponse,
}, nil
}
@@ -91,7 +91,7 @@ func (s *Session) MailAccountId(accountId string) string {
return accountId
}
// TODO(pbleser-oc) handle case where there is no default mail account
return s.DefaultMailAccountId
return s.PrimaryAccounts.Mail
}
func (s *Session) BlobAccountId(accountId string) string {
+3 -3
View File
@@ -115,9 +115,9 @@ func serveTestFile(t *testing.T, name string) ([]byte, Error) {
func (t *TestJmapApiClient) Command(ctx context.Context, logger *log.Logger, session *Session, request Request) ([]byte, Error) {
command := request.MethodCalls[0].Command
switch command {
case MailboxGet:
case CommandMailboxGet:
return serveTestFile(t.t, "mailboxes1.json")
case EmailQuery:
case CommandEmailQuery:
return serveTestFile(t.t, "mails1.json")
default:
require.Fail(t.t, "TestJmapApiClient: unsupported jmap command: %v", command)
@@ -149,7 +149,7 @@ func TestRequests(t *testing.T) {
jmapUrl, err := url.Parse("http://localhost/jmap")
require.NoError(err)
session := Session{DefaultMailAccountId: "123", Username: "user123", JmapUrl: *jmapUrl}
session := Session{Username: "user123", JmapUrl: *jmapUrl}
folders, err := client.GetAllMailboxes("a", &session, ctx, &logger)
require.NoError(err)
+2 -2
View File
@@ -18,7 +18,7 @@ func TestDeserializeMailboxGetResponse(t *testing.T) {
require.Equal("3e25b2a0", data.SessionState)
require.Len(data.MethodResponses, 1)
resp := data.MethodResponses[0]
require.Equal(MailboxGet, resp.Command)
require.Equal(CommandMailboxGet, resp.Command)
require.Equal("0", resp.Tag)
require.IsType(MailboxGetResponse{}, resp.Parameters)
mgr := resp.Parameters.(MailboxGetResponse)
@@ -75,7 +75,7 @@ func TestDeserializeEmailGetResponse(t *testing.T) {
require.Equal("3e25b2a0", data.SessionState)
require.Len(data.MethodResponses, 2)
resp := data.MethodResponses[1]
require.Equal(EmailGet, resp.Command)
require.Equal(CommandEmailGet, resp.Command)
require.Equal("1", resp.Tag)
require.IsType(EmailGetResponse{}, resp.Parameters)
egr := resp.Parameters.(EmailGetResponse)