54 lines
1.5 KiB
Go
54 lines
1.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"RenewCMS/api/pkg/access"
|
|
"RenewCMS/api/pkg/claims"
|
|
"RenewCMS/internal/domain/user"
|
|
"RenewCMS/internal/infrastructure/useCases"
|
|
"errors"
|
|
"net/http"
|
|
)
|
|
|
|
func OptionalAccess(getUser *useCases.GetUserUseCase, check *useCases.CheckPermissionUseCase) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
r = access.WithCurrentUser(r)
|
|
account, signedIn, err := verifiedAccount(getUser, r)
|
|
if err != nil {
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !signedIn {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
grants, err := check.Grants(account)
|
|
if err != nil {
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
caller := access.Caller{UserID: account.ID, Grants: grants}
|
|
next.ServeHTTP(w, r.WithContext(access.WithCaller(r.Context(), caller)))
|
|
})
|
|
}
|
|
}
|
|
|
|
func verifiedAccount(getUser *useCases.GetUserUseCase, r *http.Request) (user.User, bool, error) {
|
|
userID, ok := claims.UserId(r)
|
|
if !ok {
|
|
return user.User{}, false, nil
|
|
}
|
|
account, err := access.LoadUser(getUser, r, userID)
|
|
if errors.Is(err, user.ErrUserNotFound) {
|
|
return user.User{}, false, nil
|
|
}
|
|
if err != nil {
|
|
return user.User{}, false, err
|
|
}
|
|
tokenVersion, ok := claims.TokenVersion(r)
|
|
if !ok || tokenVersion != account.TokenVersion {
|
|
return user.User{}, false, nil
|
|
}
|
|
return account, account.IsVerified, nil
|
|
}
|