75 lines
2.9 KiB
Go
75 lines
2.9 KiB
Go
package routers
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/jwtauth/v5"
|
|
api "github.com/tech/sendico/pkg/api/http"
|
|
"github.com/tech/sendico/pkg/api/http/response"
|
|
"github.com/tech/sendico/pkg/merrors"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/pkg/mservice"
|
|
"github.com/tech/sendico/pkg/mutil/mzap"
|
|
"github.com/tech/sendico/server/interface/api/sresponse"
|
|
emodel "github.com/tech/sendico/server/interface/model"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type tokenHandlerFunc = func(r *http.Request, t *emodel.AccountToken) http.HandlerFunc
|
|
|
|
func (ar *AuthorizedRouter) tokenHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler tokenHandlerFunc) {
|
|
hndlr := func(r *http.Request) http.HandlerFunc {
|
|
_, claims, err := jwtauth.FromContext(r.Context())
|
|
if err != nil {
|
|
ar.logger.Debug("Authorization failed", zap.Error(err), zap.String("request", r.URL.Path))
|
|
return response.Unauthorized(ar.logger, ar.service, "credentials required")
|
|
}
|
|
t, err := emodel.Claims2Token(claims)
|
|
if err != nil {
|
|
ar.logger.Debug("Failed to decode account token", zap.Error(err))
|
|
return response.BadRequest(ar.logger, ar.service, "credentials_unreadable", "faild to parse credentials")
|
|
}
|
|
return handler(r, t)
|
|
}
|
|
ar.imp.InstallHandler(service, endpoint, method, hndlr)
|
|
}
|
|
|
|
func (ar *AuthorizedRouter) AccountHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.AccountHandlerFunc) {
|
|
hndlr := func(r *http.Request, t *emodel.AccountToken) http.HandlerFunc {
|
|
if t.Pending {
|
|
return response.Unauthorized(ar.logger, ar.service, "additional verification required")
|
|
}
|
|
var a model.Account
|
|
if err := ar.db.Get(r.Context(), t.AccountRef, &a); err != nil {
|
|
if errors.Is(err, merrors.ErrNoData) {
|
|
ar.logger.Debug("Failed to find related user", zap.Error(err), mzap.AccRef(t.AccountRef))
|
|
return response.NotFound(ar.logger, ar.service, err.Error())
|
|
}
|
|
return response.Internal(ar.logger, ar.service, err)
|
|
}
|
|
accessToken, err := ar.imp.CreateAccessToken(&a)
|
|
if err != nil {
|
|
ar.logger.Warn("Failed to generate access token", zap.Error(err))
|
|
return response.Internal(ar.logger, ar.service, err)
|
|
}
|
|
return handler(r, &a, &accessToken)
|
|
}
|
|
ar.tokenHandler(service, endpoint, method, hndlr)
|
|
}
|
|
|
|
func (ar *AuthorizedRouter) PendingAccountHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.PendingAccountHandlerFunc) {
|
|
hndlr := func(r *http.Request, t *emodel.AccountToken) http.HandlerFunc {
|
|
var a model.Account
|
|
if err := ar.db.Get(r.Context(), t.AccountRef, &a); err != nil {
|
|
if errors.Is(err, merrors.ErrNoData) {
|
|
ar.logger.Debug("Failed to find related user", zap.Error(err), mzap.AccRef(t.AccountRef))
|
|
return response.NotFound(ar.logger, ar.service, err.Error())
|
|
}
|
|
return response.Internal(ar.logger, ar.service, err)
|
|
}
|
|
return handler(r, &a, t)
|
|
}
|
|
ar.tokenHandler(service, endpoint, method, hndlr)
|
|
}
|