refac: debt on role backend

This commit is contained in:
Florian Sylvain committed 2026-10-26 23:34:35 +01:00
1 parent de142f6c5f
commit a043f7f41a
130 files changed
+3591 -512

No files matched your search

+35 -60
View File
@@ -1,8 +1,8 @@
package article
import (
"RenewCMS/api/pkg/access"
"RenewCMS/api/pkg/apperr"
"RenewCMS/api/pkg/claims"
validator "RenewCMS/api/pkg/validator"
domain "RenewCMS/internal/domain/article"
"RenewCMS/internal/domain/author"
@@ -26,12 +26,11 @@ import (
)
type Handler struct {
CreateUseCase *useCases.CreateArticleUseCase
GetUseCase *useCases.GetArticleUseCase
ListUseCase *useCases.ListArticlesUseCase
DeleteUseCase *useCases.DeleteArticleUseCase
UpdateUseCase *useCases.UpdateArticleUseCase
GetUserUseCase *useCases.GetUserUseCase
CreateUseCase *useCases.CreateArticleUseCase
GetUseCase *useCases.GetArticleUseCase
ListUseCase *useCases.ListArticlesUseCase
DeleteUseCase *useCases.DeleteArticleUseCase
UpdateUseCase *useCases.UpdateArticleUseCase
}
type PostArticle struct {
@@ -39,14 +38,13 @@ type PostArticle struct {
Body string `json:"body"`
}
func NewHandler(create *useCases.CreateArticleUseCase, get *useCases.GetArticleUseCase, list *useCases.ListArticlesUseCase, delete *useCases.DeleteArticleUseCase, update *useCases.UpdateArticleUseCase, getUser *useCases.GetUserUseCase) *Handler {
func NewHandler(create *useCases.CreateArticleUseCase, get *useCases.GetArticleUseCase, list *useCases.ListArticlesUseCase, delete *useCases.DeleteArticleUseCase, update *useCases.UpdateArticleUseCase) *Handler {
return &Handler{
CreateUseCase: create,
GetUseCase: get,
ListUseCase: list,
DeleteUseCase: delete,
UpdateUseCase: update,
GetUserUseCase: getUser,
CreateUseCase: create,
GetUseCase: get,
ListUseCase: list,
DeleteUseCase: delete,
UpdateUseCase: update,
}
}
@@ -180,12 +178,7 @@ func (h *Handler) GetArticle(w http.ResponseWriter, r *http.Request) {
return
}
var article domain.Article
if h.callerIsVerified(r) {
article, err = h.GetUseCase.GetArticle(id, format)
} else {
article, err = h.GetUseCase.GetOnlineArticle(id, format)
}
article, err := h.GetUseCase.GetArticle(id, format, access.CallerOf(r))
if err != nil {
if errors.Is(err, domain.ErrArticleNotFound) {
http.Error(w, apperr.ArticleNotFoundErrorMessage, http.StatusNotFound)
@@ -223,12 +216,11 @@ func (h *Handler) PostArticle(w http.ResponseWriter, r *http.Request) {
return
}
creatorId, _ := claims.UserId(r)
createdArticle, err := h.CreateUseCase.CreateArticle(r.Context(), useCases.CreateArticleCommand{
Title: localArticle.Title,
Body: localArticle.Body,
Format: format,
CreatedBy: creatorId,
Title: localArticle.Title,
Body: localArticle.Body,
Format: format,
Caller: access.CallerOf(r),
})
if err != nil {
if errors.Is(err, domain.ErrInvalidTitle) {
@@ -251,6 +243,9 @@ func writeArticleErrorResponse(w http.ResponseWriter, err error) {
}
func writeKnownArticleError(w http.ResponseWriter, err error) bool {
if access.WriteIfMissingPermission(w, err) {
return true
}
if errors.Is(err, domain.ErrArticleNotFound) {
http.Error(w, apperr.ArticleNotFoundErrorMessage, http.StatusNotFound)
return true
@@ -330,7 +325,7 @@ func (h *Handler) setIsOnline(w http.ResponseWriter, r *http.Request, isOnline b
return
}
updatedArticle, err := h.UpdateUseCase.UpdateIsOnline(r.Context(), id, isOnline, format)
updatedArticle, err := h.UpdateUseCase.UpdateIsOnline(r.Context(), id, access.CallerOf(r), isOnline, format)
if err != nil {
writeArticleErrorResponse(w, err)
return
@@ -457,7 +452,7 @@ func (h *Handler) UpdateArticleBody(w http.ResponseWriter, r *http.Request) {
return
}
updatedArticle, err := h.UpdateUseCase.Update(r.Context(), id, useCases.UpdateArticleCommand{
updatedArticle, err := h.UpdateUseCase.Update(r.Context(), id, access.CallerOf(r), useCases.UpdateArticleCommand{
Body: request.Body,
SiteID: request.SiteID,
AuthorIDs: request.AuthorIDs,
@@ -491,29 +486,6 @@ func (h *Handler) UnpublishArticle(w http.ResponseWriter, r *http.Request) {
h.setIsOnline(w, r, false)
}
func (h *Handler) callerIsVerified(r *http.Request) bool {
return isVerifiedCaller(r, h.GetUserUseCase)
}
func isVerifiedCaller(r *http.Request, getUser *useCases.GetUserUseCase) bool {
userId, ok := claims.UserId(r)
if !ok {
return false
}
currentUser, err := getUser.GetUser(userId)
if err != nil {
return false
}
tokenVersion, ok := claims.TokenVersion(r)
if !ok || tokenVersion != currentUser.TokenVersion {
return false
}
return currentUser.IsVerified
}
const (
defaultListPage = 1
defaultListSize = 25
@@ -596,15 +568,15 @@ func (h *Handler) ListArticles(w http.ResponseWriter, r *http.Request) {
}
page, err := h.ListUseCase.ListArticlesPage(useCases.ListArticlesCommand{
Format: format,
Verified: h.callerIsVerified(r),
Page: query.Page,
Size: query.Size,
Q: query.Q,
Status: query.Status,
Sort: parseSort(query.Sort),
SiteKey: query.Site,
SEO: query.SEO,
Format: format,
Caller: access.CallerOf(r),
Page: query.Page,
Size: query.Size,
Q: query.Q,
Status: query.Status,
Sort: parseSort(query.Sort),
SiteKey: query.Site,
SEO: query.SEO,
})
if err != nil {
http.Error(w, "Failed to retrieve articles", http.StatusInternalServerError)
@@ -639,11 +611,14 @@ func (h *Handler) DeleteArticle(w http.ResponseWriter, r *http.Request) {
return
}
if err := h.DeleteUseCase.DeleteArticle(r.Context(), id); err != nil {
if err := h.DeleteUseCase.DeleteArticle(r.Context(), id, access.CallerOf(r)); err != nil {
if errors.Is(err, domain.ErrArticleNotFound) {
http.Error(w, apperr.ArticleNotFoundErrorMessage, http.StatusNotFound)
return
}
if access.WriteIfMissingPermission(w, err) {
return
}
http.Error(w, "Failed to delete article", http.StatusInternalServerError)
return
}
+5 -5
View File
@@ -1,6 +1,7 @@
package article
import (
"RenewCMS/api/pkg/access"
"RenewCMS/api/pkg/apperr"
validator "RenewCMS/api/pkg/validator"
"RenewCMS/internal/infrastructure/useCases"
@@ -14,11 +15,10 @@ import (
type SEOHandler struct {
ResolveUseCase *useCases.ResolveArticleSEOUseCase
CheckUseCase *useCases.CheckArticleSEOUseCase
GetUserUseCase *useCases.GetUserUseCase
}
func NewSEOHandler(resolve *useCases.ResolveArticleSEOUseCase, check *useCases.CheckArticleSEOUseCase, getUser *useCases.GetUserUseCase) *SEOHandler {
return &SEOHandler{ResolveUseCase: resolve, CheckUseCase: check, GetUserUseCase: getUser}
func NewSEOHandler(resolve *useCases.ResolveArticleSEOUseCase, check *useCases.CheckArticleSEOUseCase) *SEOHandler {
return &SEOHandler{ResolveUseCase: resolve, CheckUseCase: check}
}
type CheckArticleSEOBody struct {
@@ -68,7 +68,7 @@ func (h *SEOHandler) Resolve(w http.ResponseWriter, r *http.Request) {
return
}
resolved, err := h.ResolveUseCase.Resolve(id, isVerifiedCaller(r, h.GetUserUseCase))
resolved, err := h.ResolveUseCase.Resolve(id, access.CallerOf(r))
if err != nil {
writeArticleErrorResponse(w, err)
return
@@ -93,7 +93,7 @@ func (h *SEOHandler) Check(w http.ResponseWriter, r *http.Request) {
return
}
checked, err := h.CheckUseCase.Check(id, useCases.CheckArticleSEOCommand{
checked, err := h.CheckUseCase.Check(id, access.CallerOf(r), useCases.CheckArticleSEOCommand{
Body: request.Body,
Slug: request.Slug,
Excerpt: request.Excerpt,
+9 -22
View File
@@ -1,8 +1,8 @@
package entry
import (
"RenewCMS/api/pkg/access"
"RenewCMS/api/pkg/apperr"
"RenewCMS/api/pkg/claims"
"RenewCMS/api/pkg/response"
validator "RenewCMS/api/pkg/validator"
"RenewCMS/internal/domain/contenttype"
@@ -178,6 +178,9 @@ func parseEntryId(r *http.Request) (uint32, error) {
}
func writeEntryError(w http.ResponseWriter, err error) {
if access.WriteIfMissingPermission(w, err) {
return
}
var fieldError domain.FieldError
switch {
case errors.Is(err, contenttype.ErrContentTypeNotFound):
@@ -211,21 +214,13 @@ func readBody(w http.ResponseWriter, r *http.Request) (EntryBody, bool) {
return body, true
}
func currentUserId(w http.ResponseWriter, r *http.Request) (uint32, bool) {
userId, ok := claims.UserId(r)
if !ok {
http.Error(w, apperr.UnauthorizedErrorMessage, http.StatusUnauthorized)
}
return userId, ok
}
func (h *Handler) List(w http.ResponseWriter, r *http.Request) {
query, err := readListQuery(r.URL.Query())
if err != nil || validator.Validate.Struct(query) != nil {
http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest)
return
}
page, err := h.ListUseCase.ListPage(useCases.ListEntriesCommand{ContentTypeKey: chi.URLParam(r, "key"), Page: query.Page, Size: query.Size, Sort: query.Sort, Query: r.URL.Query().Get("q")})
page, err := h.ListUseCase.ListPage(useCases.ListEntriesCommand{ContentTypeKey: chi.URLParam(r, "key"), Page: query.Page, Size: query.Size, Sort: query.Sort, Query: r.URL.Query().Get("q"), Caller: access.CallerOf(r)})
if err != nil {
writeEntryError(w, err)
return
@@ -243,7 +238,7 @@ func (h *Handler) Get(w http.ResponseWriter, r *http.Request) {
http.Error(w, apperr.IdUint32ErrorMessage, http.StatusBadRequest)
return
}
found, err := h.GetUseCase.Get(chi.URLParam(r, "key"), id)
found, err := h.GetUseCase.Get(chi.URLParam(r, "key"), id, access.CallerOf(r))
if err != nil {
writeEntryError(w, err)
return
@@ -252,15 +247,11 @@ func (h *Handler) Get(w http.ResponseWriter, r *http.Request) {
}
func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
userId, ok := currentUserId(w, r)
if !ok {
return
}
body, ok := readBody(w, r)
if !ok {
return
}
created, err := h.CreateUseCase.Create(useCases.CreateEntryCommand{ContentTypeKey: chi.URLParam(r, "key"), Data: body.Data, UserID: userId})
created, err := h.CreateUseCase.Create(useCases.CreateEntryCommand{ContentTypeKey: chi.URLParam(r, "key"), Data: body.Data, Caller: access.CallerOf(r)})
if err != nil {
writeEntryError(w, err)
return
@@ -274,15 +265,11 @@ func (h *Handler) Update(w http.ResponseWriter, r *http.Request) {
http.Error(w, apperr.IdUint32ErrorMessage, http.StatusBadRequest)
return
}
userId, ok := currentUserId(w, r)
if !ok {
return
}
body, ok := readBody(w, r)
if !ok {
return
}
updated, err := h.UpdateUseCase.Update(useCases.UpdateEntryCommand{ContentTypeKey: chi.URLParam(r, "key"), ID: id, Data: body.Data, UserID: userId})
updated, err := h.UpdateUseCase.Update(useCases.UpdateEntryCommand{ContentTypeKey: chi.URLParam(r, "key"), ID: id, Data: body.Data, Caller: access.CallerOf(r)})
if err != nil {
writeEntryError(w, err)
return
@@ -296,7 +283,7 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) {
http.Error(w, apperr.IdUint32ErrorMessage, http.StatusBadRequest)
return
}
if err := h.DeleteUseCase.Delete(chi.URLParam(r, "key"), id); err != nil {
if err := h.DeleteUseCase.Delete(chi.URLParam(r, "key"), id, access.CallerOf(r)); err != nil {
writeEntryError(w, err)
return
}
+1 -1
View File
@@ -97,7 +97,7 @@ func decodeRestartKind(w http.ResponseWriter, r *http.Request) (string, bool) {
}
func canApply(r *http.Request) bool {
return access.Grants(r).Holds(role.KeyApplyUpdates)
return access.Grants(r).Holds(role.KeySystemApplyUpdates)
}
func writeDownloadError(w http.ResponseWriter, err error) {