refactor: merge http handler back to account api struct

This commit is contained in:
Derrick Hammer 2024-02-16 08:52:30 -05:00
parent 7834471b84
commit cd9cccc2a9
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
2 changed files with 138 additions and 165 deletions

View File

@ -3,6 +3,9 @@ package account
import ( import (
"context" "context"
"crypto/ed25519" "crypto/ed25519"
"net/http"
"go.uber.org/zap"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
@ -21,24 +24,24 @@ var (
type AccountAPI struct { type AccountAPI struct {
config *viper.Viper config *viper.Viper
accounts *account.AccountServiceDefault accounts *account.AccountServiceDefault
httpHandler *HttpHandler
identity ed25519.PrivateKey identity ed25519.PrivateKey
logger *zap.Logger
} }
type AccountAPIParams struct { type AccountAPIParams struct {
fx.In fx.In
Config *viper.Viper Config *viper.Viper
Accounts *account.AccountServiceDefault Accounts *account.AccountServiceDefault
HttpHandler *HttpHandler
Identity ed25519.PrivateKey Identity ed25519.PrivateKey
Logger *zap.Logger
} }
func NewS5(params AccountAPIParams) AccountApiResult { func NewS5(params AccountAPIParams) AccountApiResult {
api := &AccountAPI{ api := &AccountAPI{
config: params.Config, config: params.Config,
accounts: params.Accounts, accounts: params.Accounts,
httpHandler: params.HttpHandler,
identity: params.Identity, identity: params.Identity,
logger: params.Logger,
} }
return AccountApiResult{ return AccountApiResult{
@ -49,7 +52,6 @@ func NewS5(params AccountAPIParams) AccountApiResult {
var Module = fx.Module("s5_api", var Module = fx.Module("s5_api",
fx.Provide(NewS5), fx.Provide(NewS5),
fx.Provide(NewHttpHandler),
) )
type AccountApiResult struct { type AccountApiResult struct {
@ -74,6 +76,123 @@ func (a AccountAPI) Stop(ctx context.Context) error {
return nil return nil
} }
func (a AccountAPI) login(jc jape.Context) {
var request LoginRequest
if jc.Decode(&request) != nil {
return
}
exists, _, err := a.accounts.EmailExists(request.Email)
if !exists {
_ = jc.Error(account.NewAccountError(account.ErrKeyInvalidLogin, nil), http.StatusUnauthorized)
if err != nil {
a.logger.Error("failed to check if email exists", zap.Error(err))
}
return
}
jwt, _, err := a.accounts.LoginPassword(request.Email, request.Password, jc.Request.RemoteAddr)
if err != nil {
return
}
jc.ResponseWriter.Header().Set("Authorization", "Bearer "+jwt)
jc.ResponseWriter.WriteHeader(http.StatusOK)
}
func (a AccountAPI) register(jc jape.Context) {
var request RegisterRequest
if jc.Decode(&request) != nil {
return
}
user, err := a.accounts.CreateAccount(request.Email, request.Password)
if err != nil {
_ = jc.Error(err, http.StatusUnauthorized)
a.logger.Error("failed to update account name", zap.Error(err))
return
}
err = a.accounts.UpdateAccountName(user.ID, request.FirstName, request.LastName)
if err != nil {
_ = jc.Error(account.NewAccountError(account.ErrKeyAccountCreationFailed, err), http.StatusBadRequest)
a.logger.Error("failed to update account name", zap.Error(err))
return
}
}
func (a AccountAPI) otpGenerate(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
otp, err := a.accounts.OTPGenerate(user)
if jc.Check("failed to generate otp", err) != nil {
return
}
jc.Encode(&OTPGenerateResponse{
OTP: otp,
})
}
func (a AccountAPI) otpVerify(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPVerifyRequest
if jc.Decode(&request) != nil {
return
}
err := a.accounts.OTPEnable(user, request.OTP)
if jc.Check("failed to verify otp", err) != nil {
return
}
}
func (a AccountAPI) otpValidate(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPValidateRequest
if jc.Decode(&request) != nil {
return
}
jwt, err := a.accounts.LoginOTP(user, request.OTP)
if jc.Check("failed to validate otp", err) != nil {
return
}
account.SendJWT(jc, jwt)
}
func (a AccountAPI) otpDisable(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPDisableRequest
if jc.Decode(&request) != nil {
return
}
valid, _, err := a.accounts.ValidLoginByUserID(user, request.Password)
if !valid {
_ = jc.Error(account.NewAccountError(account.ErrKeyInvalidLogin, nil), http.StatusUnauthorized)
return
}
err = a.accounts.OTPDisable(user)
if jc.Check("failed to disable otp", err) != nil {
return
}
}
func (a AccountAPI) Routes() *httprouter.Router { func (a AccountAPI) Routes() *httprouter.Router {
authMw2fa := authMiddleware(middleware.AuthMiddlewareOptions{ authMw2fa := authMiddleware(middleware.AuthMiddlewareOptions{
Identity: a.identity, Identity: a.identity,
@ -90,11 +209,11 @@ func (a AccountAPI) Routes() *httprouter.Router {
}) })
return jape.Mux(map[string]jape.Handler{ return jape.Mux(map[string]jape.Handler{
"/api/auth/login": middleware.ApplyMiddlewares(a.httpHandler.login, authMw2fa, middleware.ProxyMiddleware), "/api/auth/login": middleware.ApplyMiddlewares(a.login, authMw2fa, middleware.ProxyMiddleware),
"/api/auth/register": a.httpHandler.register, "/api/auth/register": a.register,
"/api/auth/otp/generate": middleware.ApplyMiddlewares(a.httpHandler.otpGenerate, authMw, middleware.ProxyMiddleware), "/api/auth/otp/generate": middleware.ApplyMiddlewares(a.otpGenerate, authMw, middleware.ProxyMiddleware),
"/api/auth/otp/verify": middleware.ApplyMiddlewares(a.httpHandler.otpVerify, authMw, middleware.ProxyMiddleware), "/api/auth/otp/verify": middleware.ApplyMiddlewares(a.otpVerify, authMw, middleware.ProxyMiddleware),
"/api/auth/otp/validate": middleware.ApplyMiddlewares(a.httpHandler.otpValidate, authMw, middleware.ProxyMiddleware), "/api/auth/otp/validate": middleware.ApplyMiddlewares(a.otpValidate, authMw, middleware.ProxyMiddleware),
"/api/auth/otp/disable": middleware.ApplyMiddlewares(a.httpHandler.otpDisable, authMw, middleware.ProxyMiddleware), "/api/auth/otp/disable": middleware.ApplyMiddlewares(a.otpDisable, authMw, middleware.ProxyMiddleware),
}) })
} }

View File

@ -1,146 +0,0 @@
package account
import (
"net/http"
"git.lumeweb.com/LumeWeb/portal/account"
"git.lumeweb.com/LumeWeb/portal/api/middleware"
"go.sia.tech/jape"
"go.uber.org/fx"
"go.uber.org/zap"
)
type HttpHandler struct {
accounts *account.AccountServiceDefault
logger *zap.Logger
}
type HttpHandlerParams struct {
fx.In
Accounts *account.AccountServiceDefault
Logger *zap.Logger
}
func NewHttpHandler(params HttpHandlerParams) *HttpHandler {
return &HttpHandler{
accounts: params.Accounts,
logger: params.Logger,
}
}
func (h *HttpHandler) login(jc jape.Context) {
var request LoginRequest
if jc.Decode(&request) != nil {
return
}
exists, _, err := h.accounts.EmailExists(request.Email)
if !exists {
_ = jc.Error(account.NewAccountError(account.ErrKeyInvalidLogin, nil), http.StatusUnauthorized)
if err != nil {
h.logger.Error("failed to check if email exists", zap.Error(err))
}
return
}
jwt, _, err := h.accounts.LoginPassword(request.Email, request.Password, jc.Request.RemoteAddr)
if err != nil {
return
}
jc.ResponseWriter.Header().Set("Authorization", "Bearer "+jwt)
jc.ResponseWriter.WriteHeader(http.StatusOK)
}
func (h *HttpHandler) register(jc jape.Context) {
var request RegisterRequest
if jc.Decode(&request) != nil {
return
}
user, err := h.accounts.CreateAccount(request.Email, request.Password)
if err != nil {
_ = jc.Error(err, http.StatusUnauthorized)
h.logger.Error("failed to update account name", zap.Error(err))
return
}
err = h.accounts.UpdateAccountName(user.ID, request.FirstName, request.LastName)
if err != nil {
_ = jc.Error(account.NewAccountError(account.ErrKeyAccountCreationFailed, err), http.StatusBadRequest)
h.logger.Error("failed to update account name", zap.Error(err))
return
}
}
func (h *HttpHandler) otpGenerate(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
otp, err := h.accounts.OTPGenerate(user)
if jc.Check("failed to generate otp", err) != nil {
return
}
jc.Encode(&OTPGenerateResponse{
OTP: otp,
})
}
func (h *HttpHandler) otpVerify(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPVerifyRequest
if jc.Decode(&request) != nil {
return
}
err := h.accounts.OTPEnable(user, request.OTP)
if jc.Check("failed to verify otp", err) != nil {
return
}
}
func (h *HttpHandler) otpValidate(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPValidateRequest
if jc.Decode(&request) != nil {
return
}
jwt, err := h.accounts.LoginOTP(user, request.OTP)
if jc.Check("failed to validate otp", err) != nil {
return
}
account.SendJWT(jc, jwt)
}
func (h *HttpHandler) otpDisable(jc jape.Context) {
user := middleware.GetUserFromContext(jc.Request.Context())
var request OTPDisableRequest
if jc.Decode(&request) != nil {
return
}
valid, _, err := h.accounts.ValidLoginByUserID(user, request.Password)
if !valid {
_ = jc.Error(account.NewAccountError(account.ErrKeyInvalidLogin, nil), http.StatusUnauthorized)
return
}
err = h.accounts.OTPDisable(user)
if jc.Check("failed to disable otp", err) != nil {
return
}
}