package mail import ( "errors" "net/http" "github.com/ultisuite/ulti-backend/internal/api/apiresponse" "github.com/ultisuite/ulti-backend/internal/api/apivalidate" "github.com/ultisuite/ulti-backend/internal/api/middleware" ) func (h *Handler) applyMailListScope(filter *MessageListFilter, r *http.Request) { filter.ScopedAccountIDs = middleware.MailScopeAccountIDs(r.Context()) } func (h *Handler) applyMailSearchScope(filter *MessageSearchFilter, r *http.Request) { filter.ScopedAccountIDs = middleware.MailScopeAccountIDs(r.Context()) } func (h *Handler) denyUnlessMessageInScope(w http.ResponseWriter, r *http.Request, messageID string) bool { if middleware.MailScopeAccountIDs(r.Context()) == nil { return false } claims := middleware.ClaimsFromContext(r.Context()) accountID, err := h.svc.MessageAccountID(r.Context(), claims.Sub, messageID) if err != nil { if errors.Is(err, ErrNotFound) { apivalidate.WriteNotFound(w, r, "not found") return true } h.logger.Error("resolve message account", "message_id", messageID, "error", err) apivalidate.WriteInternal(w, r) return true } if middleware.DenyIfMailAccountOutOfScope(w, r, accountID) { return true } return false } func (h *Handler) denyUnlessAttachmentInScope(w http.ResponseWriter, r *http.Request, attachmentID string) bool { if middleware.MailScopeAccountIDs(r.Context()) == nil { return false } claims := middleware.ClaimsFromContext(r.Context()) accountID, err := h.svc.AttachmentAccountID(r.Context(), claims.Sub, attachmentID) if err != nil { if errors.Is(err, ErrAttachmentNotFound) || errors.Is(err, ErrNotFound) { apivalidate.WriteNotFound(w, r, "not found") return true } h.logger.Error("resolve attachment account", "attachment_id", attachmentID, "error", err) apivalidate.WriteInternal(w, r) return true } if middleware.DenyIfMailAccountOutOfScope(w, r, accountID) { return true } return false } func (h *Handler) denyUnlessThreadInScope(w http.ResponseWriter, r *http.Request, threadID string) bool { scoped := middleware.MailScopeAccountIDs(r.Context()) if scoped == nil { return false } claims := middleware.ClaimsFromContext(r.Context()) ok, err := h.svc.ThreadAccessible(r.Context(), claims.Sub, threadID, scoped) if err != nil { h.logger.Error("resolve thread scope", "thread_id", threadID, "error", err) apivalidate.WriteInternal(w, r) return true } if !ok { apiresponse.WriteError(w, r, http.StatusForbidden, apiresponse.CodeAuthForbidden, "mail account out of token scope", nil) return true } return false }