mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-07 20:15:31 -05:00
groupware: add quota API + add support for Accept-Language and Content-Language
This commit is contained in:
@@ -35,6 +35,9 @@ tags:
|
||||
- name: task
|
||||
x-displayName: Tasks
|
||||
description: APIs about tasks
|
||||
- name: quota
|
||||
x-displayName: Quota
|
||||
description: APIs about quotas
|
||||
- name: vacation
|
||||
x-displayName: Vacation Responses
|
||||
description: APIs about vacation responses
|
||||
@@ -63,6 +66,9 @@ x-tagGroups:
|
||||
tags:
|
||||
- tasklist
|
||||
- task
|
||||
- name: Quotas
|
||||
tags:
|
||||
- quota
|
||||
components:
|
||||
securitySchemes:
|
||||
api:
|
||||
|
||||
@@ -32,7 +32,7 @@ func (g *Groupware) GetAccount(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
return errorResponse(err)
|
||||
}
|
||||
return response(account, req.session.State)
|
||||
return response(account, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ type SwaggerGetAccountsResponse struct {
|
||||
// 500: ErrorResponse500
|
||||
func (g *Groupware) GetAccounts(w http.ResponseWriter, r *http.Request) {
|
||||
g.respond(w, r, func(req Request) Response {
|
||||
return response(req.session.Accounts, req.session.State)
|
||||
return response(req.session.Accounts, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func (g *Groupware) GetAccountBootstrap(w http.ResponseWriter, r *http.Request)
|
||||
logger := log.From(req.logger.With().Str(logAccountId, mailAccountId))
|
||||
accountIds := structs.Keys(req.session.Accounts)
|
||||
|
||||
resp, sessionState, jerr := g.jmap.GetIdentitiesAndMailboxes(mailAccountId, accountIds, req.session, req.ctx, logger)
|
||||
resp, sessionState, lang, jerr := g.jmap.GetIdentitiesAndMailboxes(mailAccountId, accountIds, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -121,6 +121,6 @@ func (g *Groupware) GetAccountBootstrap(w http.ResponseWriter, r *http.Request)
|
||||
Mailboxes: map[string][]jmap.Mailbox{
|
||||
mailAccountId: resp.Mailboxes,
|
||||
},
|
||||
}, sessionState)
|
||||
}, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func (g *Groupware) GetBlobMeta(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
res, sessionState, jerr := g.jmap.GetBlobMetadata(accountId, req.session, req.ctx, logger, blobId)
|
||||
res, sessionState, lang, jerr := g.jmap.GetBlobMetadata(accountId, req.session, req.ctx, logger, req.language(), blobId)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -38,9 +38,9 @@ func (g *Groupware) GetBlobMeta(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
digest := blob.Digest()
|
||||
if digest != "" {
|
||||
return etagResponse(res, sessionState, jmap.State(digest))
|
||||
return etagResponse(res, sessionState, jmap.State(digest), lang)
|
||||
} else {
|
||||
return response(res, sessionState)
|
||||
return response(res, sessionState, lang)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -64,12 +64,12 @@ func (g *Groupware) UploadBlob(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
resp, jerr := g.jmap.UploadBlobStream(accountId, req.session, req.ctx, logger, contentType, body)
|
||||
resp, lang, jerr := g.jmap.UploadBlobStream(accountId, req.session, req.ctx, logger, contentType, req.language(), body)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagOnlyResponse(resp, jmap.State(resp.Sha512))
|
||||
return etagOnlyResponse(resp, jmap.State(resp.Sha512), lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (g *Groupware) DownloadBlob(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
blob, jerr := g.jmap.DownloadBlobStream(accountId, blobId, name, typ, req.session, req.ctx, logger)
|
||||
blob, lang, jerr := g.jmap.DownloadBlobStream(accountId, blobId, name, typ, req.session, req.ctx, logger, req.language())
|
||||
if blob != nil && blob.Body != nil {
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
@@ -118,6 +118,9 @@ func (g *Groupware) DownloadBlob(w http.ResponseWriter, r *http.Request) {
|
||||
if blob.Size >= 0 {
|
||||
w.Header().Add("Content-Size", strconv.Itoa(blob.Size))
|
||||
}
|
||||
if lang != "" {
|
||||
w.Header().Add("Content-Language", string(lang))
|
||||
}
|
||||
|
||||
_, err := io.Copy(w, blob.Body)
|
||||
if err != nil {
|
||||
|
||||
@@ -31,7 +31,7 @@ func (g *Groupware) GetCalendars(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
var _ string = accountId
|
||||
|
||||
return response(AllCalendars, req.session.State)
|
||||
return response(AllCalendars, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (g *Groupware) GetCalendarById(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO replace with proper implementation
|
||||
for _, calendar := range AllCalendars {
|
||||
if calendar.Id == calendarId {
|
||||
return response(calendar, req.session.State)
|
||||
return response(calendar, req.session.State, "")
|
||||
}
|
||||
}
|
||||
return notFoundResponse(req.session.State)
|
||||
@@ -102,6 +102,6 @@ func (g *Groupware) GetEventsInCalendar(w http.ResponseWriter, r *http.Request)
|
||||
if !ok {
|
||||
return notFoundResponse(req.session.State)
|
||||
}
|
||||
return response(events, req.session.State)
|
||||
return response(events, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (g *Groupware) GetAddressbooks(w http.ResponseWriter, r *http.Request) {
|
||||
var _ string = accountId
|
||||
|
||||
// TODO replace with proper implementation
|
||||
return response(AllAddressBooks, req.session.State)
|
||||
return response(AllAddressBooks, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func (g *Groupware) GetAddressbook(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO replace with proper implementation
|
||||
for _, ab := range AllAddressBooks {
|
||||
if ab.Id == addressBookId {
|
||||
return response(ab, req.session.State)
|
||||
return response(ab, req.session.State, "")
|
||||
}
|
||||
}
|
||||
return notFoundResponse(req.session.State)
|
||||
@@ -104,6 +104,6 @@ func (g *Groupware) GetContactsInAddressbook(w http.ResponseWriter, r *http.Requ
|
||||
if !ok {
|
||||
return notFoundResponse(req.session.State)
|
||||
}
|
||||
return response(contactCards, req.session.State)
|
||||
return response(contactCards, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -77,12 +77,12 @@ func (g *Groupware) GetAllEmailsInMailbox(w http.ResponseWriter, r *http.Request
|
||||
|
||||
logger := log.From(req.logger.With().Str(HeaderSince, since).Str(logAccountId, accountId))
|
||||
|
||||
emails, sessionState, jerr := g.jmap.GetMailboxChanges(accountId, req.session, req.ctx, logger, mailboxId, since, true, g.maxBodyValueBytes, maxChanges)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetMailboxChanges(accountId, req.session, req.ctx, logger, req.language(), mailboxId, since, true, g.maxBodyValueBytes, maxChanges)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagResponse(emails, sessionState, emails.State)
|
||||
return etagResponse(emails, sessionState, emails.State, lang)
|
||||
})
|
||||
} else {
|
||||
g.respond(w, r, func(req Request) Response {
|
||||
@@ -114,12 +114,12 @@ func (g *Groupware) GetAllEmailsInMailbox(w http.ResponseWriter, r *http.Request
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
emails, sessionState, jerr := g.jmap.GetAllEmailsInMailbox(accountId, req.session, req.ctx, logger, mailboxId, offset, limit, true, g.maxBodyValueBytes)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetAllEmailsInMailbox(accountId, req.session, req.ctx, logger, req.language(), mailboxId, offset, limit, true, g.maxBodyValueBytes)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagResponse(emails, sessionState, emails.State)
|
||||
return etagResponse(emails, sessionState, emails.State, lang)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -140,25 +140,25 @@ func (g *Groupware) GetEmailsById(w http.ResponseWriter, r *http.Request) {
|
||||
l := req.logger.With().Str(logAccountId, log.SafeString(accountId))
|
||||
if len(ids) == 1 {
|
||||
logger := log.From(l.Str("id", log.SafeString(id)))
|
||||
emails, sessionState, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, ids, true, g.maxBodyValueBytes)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, req.language(), ids, true, g.maxBodyValueBytes)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
if len(emails.Emails) < 1 {
|
||||
return notFoundResponse(sessionState)
|
||||
} else {
|
||||
return etagResponse(emails.Emails[0], sessionState, emails.State)
|
||||
return etagResponse(emails.Emails[0], sessionState, emails.State, lang)
|
||||
}
|
||||
} else {
|
||||
logger := log.From(l.Array("ids", log.SafeStringArray(ids)))
|
||||
emails, sessionState, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, ids, true, g.maxBodyValueBytes)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, req.language(), ids, true, g.maxBodyValueBytes)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
if len(emails.Emails) < 1 {
|
||||
return notFoundResponse(sessionState)
|
||||
} else {
|
||||
return etagResponse(emails.Emails, sessionState, emails.State)
|
||||
return etagResponse(emails.Emails, sessionState, emails.State, lang)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -196,7 +196,7 @@ func (g *Groupware) GetEmailAttachments(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
l := req.logger.With().Str(logAccountId, accountId)
|
||||
logger := log.From(l)
|
||||
emails, sessionState, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, []string{id}, false, 0)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, req.language(), []string{id}, false, 0)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -204,7 +204,7 @@ func (g *Groupware) GetEmailAttachments(w http.ResponseWriter, r *http.Request)
|
||||
return notFoundResponse(sessionState)
|
||||
}
|
||||
email := emails.Emails[0]
|
||||
return etagResponse(email.Attachments, sessionState, emails.State)
|
||||
return etagResponse(email.Attachments, sessionState, emails.State, lang)
|
||||
})
|
||||
} else {
|
||||
g.stream(w, r, func(req Request, w http.ResponseWriter) *Error {
|
||||
@@ -221,7 +221,7 @@ func (g *Groupware) GetEmailAttachments(w http.ResponseWriter, r *http.Request)
|
||||
l = contextAppender(l)
|
||||
logger := log.From(l)
|
||||
|
||||
emails, _, jerr := g.jmap.GetEmails(mailAccountId, req.session, req.ctx, logger, []string{id}, false, 0)
|
||||
emails, _, lang, jerr := g.jmap.GetEmails(mailAccountId, req.session, req.ctx, logger, req.language(), []string{id}, false, 0)
|
||||
if jerr != nil {
|
||||
return req.apiErrorFromJmap(req.observeJmapError(jerr))
|
||||
}
|
||||
@@ -241,7 +241,7 @@ func (g *Groupware) GetEmailAttachments(w http.ResponseWriter, r *http.Request)
|
||||
return nil
|
||||
}
|
||||
|
||||
blob, jerr := g.jmap.DownloadBlobStream(blobAccountId, attachment.BlobId, attachment.Name, attachment.Type, req.session, req.ctx, logger)
|
||||
blob, lang, jerr := g.jmap.DownloadBlobStream(blobAccountId, attachment.BlobId, attachment.Name, attachment.Type, req.session, req.ctx, logger, req.language())
|
||||
if blob != nil && blob.Body != nil {
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
@@ -270,7 +270,9 @@ func (g *Groupware) GetEmailAttachments(w http.ResponseWriter, r *http.Request)
|
||||
if blob.Size >= 0 {
|
||||
w.Header().Add("Content-Size", strconv.Itoa(blob.Size))
|
||||
}
|
||||
|
||||
if lang != "" {
|
||||
w.Header().Add("Content-Language", string(lang))
|
||||
}
|
||||
_, err := io.Copy(w, blob.Body)
|
||||
if err != nil {
|
||||
return req.observedParameterError(ErrorStreamingResponse)
|
||||
@@ -300,12 +302,12 @@ func (g *Groupware) getEmailsSince(w http.ResponseWriter, r *http.Request, since
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
emails, sessionState, jerr := g.jmap.GetEmailsSince(accountId, req.session, req.ctx, logger, since, true, g.maxBodyValueBytes, maxChanges)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetEmailsSince(accountId, req.session, req.ctx, logger, req.language(), since, true, g.maxBodyValueBytes, maxChanges)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagResponse(emails, sessionState, emails.State)
|
||||
return etagResponse(emails, sessionState, emails.State, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -497,7 +499,7 @@ func (g *Groupware) searchEmails(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger = log.From(logger.With().Str(logAccountId, accountId))
|
||||
|
||||
results, sessionState, jerr := g.jmap.QueryEmailsWithSnippets(accountId, filter, req.session, req.ctx, logger, offset, limit, fetchBodies, g.maxBodyValueBytes)
|
||||
results, sessionState, lang, jerr := g.jmap.QueryEmailsWithSnippets(accountId, filter, req.session, req.ctx, logger, req.language(), offset, limit, fetchBodies, g.maxBodyValueBytes)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -522,7 +524,7 @@ func (g *Groupware) searchEmails(w http.ResponseWriter, r *http.Request) {
|
||||
Total: results.Total,
|
||||
Limit: results.Limit,
|
||||
QueryState: results.QueryState,
|
||||
}, sessionState, results.QueryState)
|
||||
}, sessionState, results.QueryState, lang)
|
||||
} else {
|
||||
accountId, err := req.GetAccountIdForMail()
|
||||
if err != nil {
|
||||
@@ -530,7 +532,7 @@ func (g *Groupware) searchEmails(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger = log.From(logger.With().Str(logAccountId, accountId))
|
||||
|
||||
results, sessionState, jerr := g.jmap.QueryEmailSnippets(accountId, filter, req.session, req.ctx, logger, offset, limit)
|
||||
results, sessionState, lang, jerr := g.jmap.QueryEmailSnippets(accountId, filter, req.session, req.ctx, logger, req.language(), offset, limit)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -540,7 +542,7 @@ func (g *Groupware) searchEmails(w http.ResponseWriter, r *http.Request) {
|
||||
Total: results.Total,
|
||||
Limit: results.Limit,
|
||||
QueryState: results.QueryState,
|
||||
}, sessionState, results.QueryState)
|
||||
}, sessionState, results.QueryState, lang)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -608,12 +610,12 @@ func (g *Groupware) CreateEmail(w http.ResponseWriter, r *http.Request) {
|
||||
BodyValues: body.BodyValues,
|
||||
}
|
||||
|
||||
created, sessionState, jerr := g.jmap.CreateEmail(accountId, create, req.session, req.ctx, logger)
|
||||
created, sessionState, lang, jerr := g.jmap.CreateEmail(accountId, create, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return response(created.Email, sessionState)
|
||||
return response(created.Email, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -642,7 +644,7 @@ func (g *Groupware) UpdateEmail(w http.ResponseWriter, r *http.Request) {
|
||||
emailId: body,
|
||||
}
|
||||
|
||||
result, sessionState, jerr := g.jmap.UpdateEmails(accountId, updates, req.session, req.ctx, logger)
|
||||
result, sessionState, lang, jerr := g.jmap.UpdateEmails(accountId, updates, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -657,7 +659,7 @@ func (g *Groupware) UpdateEmail(w http.ResponseWriter, r *http.Request) {
|
||||
"An internal API behaved unexpectedly: wrong Email update ID response from JMAP endpoint")))
|
||||
}
|
||||
|
||||
return response(updatedEmail, sessionState)
|
||||
return response(updatedEmail, sessionState, lang)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -677,7 +679,7 @@ func (g *Groupware) DeleteEmail(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
_, sessionState, jerr := g.jmap.DeleteEmails(accountId, []string{emailId}, req.session, req.ctx, logger)
|
||||
_, sessionState, _, jerr := g.jmap.DeleteEmails(accountId, []string{emailId}, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -687,14 +689,16 @@ func (g *Groupware) DeleteEmail(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type AboutEmailsEvent struct {
|
||||
Id string `json:"id"`
|
||||
Source string `json:"source"`
|
||||
Emails []jmap.Email `json:"emails"`
|
||||
Id string `json:"id"`
|
||||
Source string `json:"source"`
|
||||
Emails []jmap.Email `json:"emails"`
|
||||
Language jmap.Language `json:"lang"`
|
||||
}
|
||||
|
||||
type AboutEmailResponse struct {
|
||||
Email jmap.Email `json:"email"`
|
||||
RequestId string `json:"requestId"`
|
||||
Email jmap.Email `json:"email"`
|
||||
RequestId string `json:"requestId"`
|
||||
Language jmap.Language `json:"lang"`
|
||||
}
|
||||
|
||||
func relatedEmails(email jmap.Email, beacon time.Time, days uint) jmap.EmailFilterElement {
|
||||
@@ -766,7 +770,7 @@ func (g *Groupware) RelatedToEmail(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
reqId := req.GetRequestId()
|
||||
getEmailsBefore := time.Now()
|
||||
emails, sessionState, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, []string{id}, true, g.maxBodyValueBytes)
|
||||
emails, sessionState, lang, jerr := g.jmap.GetEmails(accountId, req.session, req.ctx, logger, req.language(), []string{id}, true, g.maxBodyValueBytes)
|
||||
getEmailsDuration := time.Since(getEmailsBefore)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
@@ -791,7 +795,7 @@ func (g *Groupware) RelatedToEmail(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
g.job(logger, RelationTypeSameSender, func(jobId uint64, l *log.Logger) {
|
||||
before := time.Now()
|
||||
results, _, jerr := g.jmap.QueryEmails(accountId, filter, req.session, bgctx, l, 0, limit, false, g.maxBodyValueBytes)
|
||||
results, _, lang, jerr := g.jmap.QueryEmails(accountId, filter, req.session, bgctx, l, req.language(), 0, limit, false, g.maxBodyValueBytes)
|
||||
duration := time.Since(before)
|
||||
if jerr != nil {
|
||||
req.observeJmapError(jerr)
|
||||
@@ -801,14 +805,14 @@ func (g *Groupware) RelatedToEmail(w http.ResponseWriter, r *http.Request) {
|
||||
related := filterEmails(results.Emails, email)
|
||||
l.Trace().Msgf("'%v' found %v other emails", RelationTypeSameSender, len(related))
|
||||
if len(related) > 0 {
|
||||
req.push(RelationEntityEmail, AboutEmailsEvent{Id: reqId, Emails: related, Source: RelationTypeSameSender})
|
||||
req.push(RelationEntityEmail, AboutEmailsEvent{Id: reqId, Emails: related, Source: RelationTypeSameSender, Language: lang})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
g.job(logger, RelationTypeSameThread, func(jobId uint64, l *log.Logger) {
|
||||
before := time.Now()
|
||||
emails, _, jerr := g.jmap.EmailsInThread(accountId, email.ThreadId, req.session, bgctx, l, false, g.maxBodyValueBytes)
|
||||
emails, _, _, jerr := g.jmap.EmailsInThread(accountId, email.ThreadId, req.session, bgctx, l, req.language(), false, g.maxBodyValueBytes)
|
||||
duration := time.Since(before)
|
||||
if jerr != nil {
|
||||
req.observeJmapError(jerr)
|
||||
@@ -818,7 +822,7 @@ func (g *Groupware) RelatedToEmail(w http.ResponseWriter, r *http.Request) {
|
||||
related := filterEmails(emails, email)
|
||||
l.Trace().Msgf("'%v' found %v other emails", RelationTypeSameThread, len(related))
|
||||
if len(related) > 0 {
|
||||
req.push(RelationEntityEmail, AboutEmailsEvent{Id: reqId, Emails: related, Source: RelationTypeSameThread})
|
||||
req.push(RelationEntityEmail, AboutEmailsEvent{Id: reqId, Emails: related, Source: RelationTypeSameThread, Language: lang})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -826,7 +830,7 @@ func (g *Groupware) RelatedToEmail(w http.ResponseWriter, r *http.Request) {
|
||||
return etagResponse(AboutEmailResponse{
|
||||
Email: email,
|
||||
RequestId: reqId,
|
||||
}, sessionState, emails.State)
|
||||
}, sessionState, emails.State, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1113,7 +1117,7 @@ func (g *Groupware) GetLatestEmailsSummaryForAllAccounts(w http.ResponseWriter,
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
emailsSummariesByAccount, sessionState, jerr := g.jmap.QueryEmailSummaries(allAccountIds, req.session, req.ctx, logger, filter, limit)
|
||||
emailsSummariesByAccount, sessionState, lang, jerr := g.jmap.QueryEmailSummaries(allAccountIds, req.session, req.ctx, logger, req.language(), filter, limit)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
@@ -1141,7 +1145,7 @@ func (g *Groupware) GetLatestEmailsSummaryForAllAccounts(w http.ResponseWriter,
|
||||
summaries[i] = summarizeEmail(all[i].accountId, all[i].email)
|
||||
}
|
||||
|
||||
return response(summaries, sessionState)
|
||||
return response(summaries, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ func (g *Groupware) GetIdentities(w http.ResponseWriter, r *http.Request) {
|
||||
return errorResponse(err)
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
res, sessionState, jerr := g.jmap.GetIdentity(accountId, req.session, req.ctx, logger)
|
||||
res, sessionState, lang, jerr := g.jmap.GetIdentity(accountId, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
return etagResponse(res, sessionState, res.State)
|
||||
return etagResponse(res, sessionState, res.State, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func (g *Groupware) Index(w http.ResponseWriter, r *http.Request) {
|
||||
g.respond(w, r, func(req Request) Response {
|
||||
accountIds := structs.Keys(req.session.Accounts)
|
||||
|
||||
identitiesResponse, sessionState, err := g.jmap.GetIdentities(accountIds, req.session, req.ctx, req.logger)
|
||||
identitiesResponse, sessionState, lang, err := g.jmap.GetIdentities(accountIds, req.session, req.ctx, req.logger, req.language())
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
@@ -163,7 +163,7 @@ func (g *Groupware) Index(w http.ResponseWriter, r *http.Request) {
|
||||
Limits: buildIndexLimits(req.session),
|
||||
Accounts: buildIndexAccount(req.session, identitiesResponse.Identities),
|
||||
PrimaryAccounts: buildIndexPrimaryAccounts(req.session),
|
||||
}, sessionState)
|
||||
}, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@ func (g *Groupware) GetMailbox(w http.ResponseWriter, r *http.Request) {
|
||||
return errorResponse(err)
|
||||
}
|
||||
|
||||
mailboxes, sessionState, jerr := g.jmap.GetMailbox(accountId, req.session, req.ctx, req.logger, []string{mailboxId})
|
||||
mailboxes, sessionState, lang, jerr := g.jmap.GetMailbox(accountId, req.session, req.ctx, req.logger, req.language(), []string{mailboxId})
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
if len(mailboxes.Mailboxes) == 1 {
|
||||
return etagResponse(mailboxes.Mailboxes[0], sessionState, mailboxes.State)
|
||||
return etagResponse(mailboxes.Mailboxes[0], sessionState, mailboxes.State, lang)
|
||||
} else {
|
||||
return notFoundResponse(sessionState)
|
||||
}
|
||||
@@ -123,25 +123,25 @@ func (g *Groupware) GetMailboxes(w http.ResponseWriter, r *http.Request) {
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
if hasCriteria {
|
||||
mailboxesByAccountId, sessionState, err := g.jmap.SearchMailboxes([]string{accountId}, req.session, req.ctx, logger, filter)
|
||||
mailboxesByAccountId, sessionState, lang, err := g.jmap.SearchMailboxes([]string{accountId}, req.session, req.ctx, logger, req.language(), filter)
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
|
||||
mailboxes, ok := mailboxesByAccountId[accountId]
|
||||
if ok {
|
||||
return etagResponse(mailboxes.Mailboxes, sessionState, mailboxes.State)
|
||||
return etagResponse(mailboxes.Mailboxes, sessionState, mailboxes.State, lang)
|
||||
} else {
|
||||
return notFoundResponse(sessionState)
|
||||
}
|
||||
} else {
|
||||
mailboxesByAccountId, sessionState, err := g.jmap.GetAllMailboxes([]string{accountId}, req.session, req.ctx, logger)
|
||||
mailboxesByAccountId, sessionState, lang, err := g.jmap.GetAllMailboxes([]string{accountId}, req.session, req.ctx, logger, req.language())
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
mailboxes, ok := mailboxesByAccountId[accountId]
|
||||
if ok {
|
||||
return etagResponse(mailboxes.Mailboxes, sessionState, mailboxes.State)
|
||||
return etagResponse(mailboxes.Mailboxes, sessionState, mailboxes.State, lang)
|
||||
} else {
|
||||
return notFoundResponse(sessionState)
|
||||
}
|
||||
@@ -193,17 +193,17 @@ func (g *Groupware) GetMailboxesForAllAccounts(w http.ResponseWriter, r *http.Re
|
||||
logger := log.From(req.logger.With().Array(logAccountId, log.SafeStringArray(accountIds)))
|
||||
|
||||
if hasCriteria {
|
||||
mailboxesByAccountId, sessionState, err := g.jmap.SearchMailboxes(accountIds, req.session, req.ctx, logger, filter)
|
||||
mailboxesByAccountId, sessionState, lang, err := g.jmap.SearchMailboxes(accountIds, req.session, req.ctx, logger, req.language(), filter)
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
return response(mailboxesByAccountId, sessionState)
|
||||
return response(mailboxesByAccountId, sessionState, lang)
|
||||
} else {
|
||||
mailboxesByAccountId, sessionState, err := g.jmap.GetAllMailboxes(accountIds, req.session, req.ctx, logger)
|
||||
mailboxesByAccountId, sessionState, lang, err := g.jmap.GetAllMailboxes(accountIds, req.session, req.ctx, logger, req.language())
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
return response(mailboxesByAccountId, sessionState)
|
||||
return response(mailboxesByAccountId, sessionState, lang)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -221,11 +221,11 @@ func (g *Groupware) GetMailboxByRoleForAllAccounts(w http.ResponseWriter, r *htt
|
||||
Role: role,
|
||||
}
|
||||
|
||||
mailboxesByAccountId, sessionState, err := g.jmap.SearchMailboxes(accountIds, req.session, req.ctx, logger, filter)
|
||||
mailboxesByAccountId, sessionState, lang, err := g.jmap.SearchMailboxes(accountIds, req.session, req.ctx, logger, req.language(), filter)
|
||||
if err != nil {
|
||||
return req.errorResponseFromJmap(err)
|
||||
}
|
||||
return response(mailboxesByAccountId, sessionState)
|
||||
return response(mailboxesByAccountId, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -267,12 +267,12 @@ func (g *Groupware) GetMailboxChanges(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
changes, sessionState, jerr := g.jmap.GetMailboxChanges(accountId, req.session, req.ctx, logger, mailboxId, sinceState, true, g.maxBodyValueBytes, maxChanges)
|
||||
changes, sessionState, lang, jerr := g.jmap.GetMailboxChanges(accountId, req.session, req.ctx, logger, req.language(), mailboxId, sinceState, true, g.maxBodyValueBytes, maxChanges)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagResponse(changes, sessionState, changes.State)
|
||||
return etagResponse(changes, sessionState, changes.State, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -320,12 +320,12 @@ func (g *Groupware) GetMailboxChangesForAllAccounts(w http.ResponseWriter, r *ht
|
||||
|
||||
logger := log.From(l)
|
||||
|
||||
changesByAccountId, sessionState, jerr := g.jmap.GetMailboxChangesForMultipleAccounts(allAccountIds, req.session, req.ctx, logger, sinceStateMap, true, g.maxBodyValueBytes, maxChanges)
|
||||
changesByAccountId, sessionState, lang, jerr := g.jmap.GetMailboxChangesForMultipleAccounts(allAccountIds, req.session, req.ctx, logger, req.language(), sinceStateMap, true, g.maxBodyValueBytes, maxChanges)
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return response(changesByAccountId, sessionState)
|
||||
return response(changesByAccountId, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -336,11 +336,11 @@ func (g *Groupware) GetMailboxRoles(w http.ResponseWriter, r *http.Request) {
|
||||
l.Array(logAccountId, log.SafeStringArray(allAccountIds))
|
||||
logger := log.From(l)
|
||||
|
||||
rolesByAccountId, sessionState, jerr := g.jmap.GetMailboxRolesForMultipleAccounts(allAccountIds, req.session, req.ctx, logger)
|
||||
rolesByAccountId, sessionState, lang, jerr := g.jmap.GetMailboxRolesForMultipleAccounts(allAccountIds, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return response(rolesByAccountId, sessionState)
|
||||
return response(rolesByAccountId, sessionState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package groupware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/opencloud-eu/opencloud/pkg/jmap"
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
)
|
||||
|
||||
// When the request succeeds.
|
||||
// swagger:response GetQuotaResponse200
|
||||
type SwaggerGetQuotaResponse200 struct {
|
||||
// in: body
|
||||
Body []jmap.Quota
|
||||
}
|
||||
|
||||
// swagger:route GET /groupware/accounts/{account}/quota quota getquota
|
||||
// Get quota limits.
|
||||
//
|
||||
// responses:
|
||||
//
|
||||
// 200: GetQuotaResponse200
|
||||
// 400: ErrorResponse400
|
||||
// 500: ErrorResponse500
|
||||
func (g *Groupware) GetQuota(w http.ResponseWriter, r *http.Request) {
|
||||
g.respond(w, r, func(req Request) Response {
|
||||
accountId, err := req.GetAccountIdForQuota()
|
||||
if err != nil {
|
||||
return errorResponse(err)
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
res, sessionState, lang, jerr := g.jmap.GetQuotas(accountId, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
return etagResponse(res.List, sessionState, res.State, lang)
|
||||
})
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func (g *Groupware) GetTaskLists(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
var _ string = accountId
|
||||
|
||||
return response(AllTaskLists, req.session.State)
|
||||
return response(AllTaskLists, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (g *Groupware) GetTaskListById(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO replace with proper implementation
|
||||
for _, tasklist := range AllTaskLists {
|
||||
if tasklist.Id == tasklistId {
|
||||
return response(tasklist, req.session.State)
|
||||
return response(tasklist, req.session.State, "")
|
||||
}
|
||||
}
|
||||
return notFoundResponse(req.session.State)
|
||||
@@ -102,6 +102,6 @@ func (g *Groupware) GetTasksInTaskList(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok {
|
||||
return notFoundResponse(req.session.State)
|
||||
}
|
||||
return response(tasks, req.session.State)
|
||||
return response(tasks, req.session.State, "")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ func (g *Groupware) GetVacation(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
res, sessionState, jerr := g.jmap.GetVacationResponse(accountId, req.session, req.ctx, logger)
|
||||
res, sessionState, lang, jerr := g.jmap.GetVacationResponse(accountId, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
return etagResponse(res, sessionState, res.State)
|
||||
return etagResponse(res, sessionState, res.State, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,11 +79,11 @@ func (g *Groupware) SetVacation(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
logger := log.From(req.logger.With().Str(logAccountId, accountId))
|
||||
|
||||
res, sessionState, jerr := g.jmap.SetVacationResponse(accountId, body, req.session, req.ctx, logger)
|
||||
res, sessionState, lang, jerr := g.jmap.SetVacationResponse(accountId, body, req.session, req.ctx, logger, req.language())
|
||||
if jerr != nil {
|
||||
return req.errorResponseFromJmap(jerr)
|
||||
}
|
||||
|
||||
return etagResponse(res, sessionState, res.ResponseState)
|
||||
return etagResponse(res, sessionState, res.ResponseState, lang)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -575,6 +575,10 @@ func (g *Groupware) sendResponse(w http.ResponseWriter, r *http.Request, respons
|
||||
w.Header().Add("Session-State", string(sessionState))
|
||||
}
|
||||
|
||||
if response.contentLanguage != "" {
|
||||
w.Header().Add("Content-Language", string(response.contentLanguage))
|
||||
}
|
||||
|
||||
notModified := false
|
||||
if etag != "" {
|
||||
challenge := r.Header.Get("if-none-match")
|
||||
|
||||
@@ -65,8 +65,8 @@ var (
|
||||
errNoPrimaryAccountForTask = errors.New("no primary account for task")
|
||||
errNoPrimaryAccountForCalendar = errors.New("no primary account for calendar")
|
||||
errNoPrimaryAccountForContact = errors.New("no primary account for contact")
|
||||
errNoPrimaryAccountForQuota = errors.New("no primary account for quota")
|
||||
// errNoPrimaryAccountForSieve = errors.New("no primary account for sieve")
|
||||
// errNoPrimaryAccountForQuota = errors.New("no primary account for quota")
|
||||
// errNoPrimaryAccountForWebsocket = errors.New("no primary account for websocket")
|
||||
)
|
||||
|
||||
@@ -109,6 +109,10 @@ func (r Request) GetAccountIdForVacationResponse() (string, *Error) {
|
||||
return r.getAccountId(r.session.PrimaryAccounts.VacationResponse, errNoPrimaryAccountForVacationResponse)
|
||||
}
|
||||
|
||||
func (r Request) GetAccountIdForQuota() (string, *Error) {
|
||||
return r.getAccountId(r.session.PrimaryAccounts.Quota, errNoPrimaryAccountForQuota)
|
||||
}
|
||||
|
||||
func (r Request) GetAccountIdForSubmission() (string, *Error) {
|
||||
return r.getAccountId(r.session.PrimaryAccounts.Blob, errNoPrimaryAccountForSubmission)
|
||||
}
|
||||
@@ -280,6 +284,10 @@ func (r Request) body(target any) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r Request) language() string {
|
||||
return r.r.Header.Get("Accept-Language")
|
||||
}
|
||||
|
||||
func (r Request) observe(obs prometheus.Observer, value float64) {
|
||||
metrics.WithExemplar(obs, value, r.GetRequestId(), r.GetTraceId())
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ import (
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
body any
|
||||
status int
|
||||
err *Error
|
||||
etag jmap.State
|
||||
sessionState jmap.SessionState
|
||||
body any
|
||||
status int
|
||||
err *Error
|
||||
etag jmap.State
|
||||
sessionState jmap.SessionState
|
||||
contentLanguage jmap.Language
|
||||
}
|
||||
|
||||
func errorResponse(err *Error) Response {
|
||||
@@ -32,30 +33,33 @@ func errorResponseWithSessionState(err *Error, sessionState jmap.SessionState) R
|
||||
}
|
||||
}
|
||||
|
||||
func response(body any, sessionState jmap.SessionState) Response {
|
||||
func response(body any, sessionState jmap.SessionState, contentLanguage jmap.Language) Response {
|
||||
return Response{
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: jmap.State(sessionState),
|
||||
sessionState: sessionState,
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: jmap.State(sessionState),
|
||||
sessionState: sessionState,
|
||||
contentLanguage: contentLanguage,
|
||||
}
|
||||
}
|
||||
|
||||
func etagResponse(body any, sessionState jmap.SessionState, etag jmap.State) Response {
|
||||
func etagResponse(body any, sessionState jmap.SessionState, etag jmap.State, contentLanguage jmap.Language) Response {
|
||||
return Response{
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: etag,
|
||||
sessionState: sessionState,
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: etag,
|
||||
sessionState: sessionState,
|
||||
contentLanguage: contentLanguage,
|
||||
}
|
||||
}
|
||||
|
||||
func etagOnlyResponse(body any, etag jmap.State) Response {
|
||||
func etagOnlyResponse(body any, etag jmap.State, contentLanguage jmap.Language) Response {
|
||||
return Response{
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: etag,
|
||||
sessionState: "",
|
||||
body: body,
|
||||
err: nil,
|
||||
etag: etag,
|
||||
sessionState: "",
|
||||
contentLanguage: contentLanguage,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ func (g *Groupware) Route(r chi.Router) {
|
||||
r.Get("/identities", g.GetIdentities)
|
||||
r.Get("/vacation", g.GetVacation)
|
||||
r.Put("/vacation", g.SetVacation)
|
||||
r.Get("/quota", g.GetQuota)
|
||||
r.Route("/mailboxes", func(r chi.Router) {
|
||||
r.Get("/", g.GetMailboxes) // ?name=&role=&subcribed=
|
||||
r.Get("/{mailbox}", g.GetMailbox)
|
||||
|
||||
Reference in New Issue
Block a user