src.dualinventive.com/go/authentication-service/cmd/authentication-service-rest/handlers.go

296 lines
9.8 KiB
Go

package main
import (
"github.com/go-openapi/runtime/middleware"
"src.dualinventive.com/go/authentication-service/internal/authtokens"
"src.dualinventive.com/go/authentication-service/internal/domain"
"src.dualinventive.com/go/authentication-service/internal/pwreset"
"src.dualinventive.com/go/authentication-service/rest/models"
"src.dualinventive.com/go/authentication-service/rest/server/operations"
"src.dualinventive.com/go/authentication-service/rest/server/operations/authentication"
)
func initHandlers(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.TokenAuthAuth = func(token string) (interface{}, error) {
return token, nil
}
registerLoginHandler(api, tokenService)
registerLogoutHandler(api, tokenService)
registerVerifyHandler(api, tokenService)
registerPasswordResetRequestHandler(api, tokenService)
registerPasswordResetRedeemHandler(api, tokenService)
registerMeHandler(api, tokenService)
registerListTokensHandler(api, tokenService)
registerDeleteTokenHandler(api, tokenService)
}
func registerLoginHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationPostLoginHandler = authentication.PostLoginHandlerFunc(
func(params authentication.PostLoginParams) middleware.Responder {
credentials := domain.Credentials{
User: params.Body.User,
CompanyCode: params.Body.CompanyCode,
Password: params.Body.Password,
}
token, err := tokenService.CreateToken(credentials, params.HTTPRequest.UserAgent())
if err != nil {
switch err.(type) {
case *authtokens.ErrInvalidCredentials:
resp := authentication.NewPostLoginUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewPostLoginInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
}
return authentication.NewPostLoginOK().WithPayload(&models.SecurityToken{
Token: token.Secret,
})
})
}
func registerLogoutHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationLogoutHandler = authentication.LogoutHandlerFunc(
func(params authentication.LogoutParams, secret interface{}) middleware.Responder {
token := &domain.Token{Secret: secret.(string)}
err := tokenService.DeleteToken(token)
if err != nil {
switch err.(type) {
case *authtokens.ErrNilToken:
resp := authentication.NewLogoutUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *authtokens.ErrTokenNotFound:
resp := authentication.NewLogoutUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
return authentication.NewLogoutInternalServerError()
}
}
return authentication.NewLogoutNoContent()
})
}
func registerVerifyHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationVerifyHandler = authentication.VerifyHandlerFunc(
func(params authentication.VerifyParams, secret interface{}) middleware.Responder {
token := &domain.Token{Secret: secret.(string)}
var rights []string
if params.Body != nil {
rights = params.Body.Rights
} else {
rights = []string{}
}
_, err := tokenService.VerifyToken(token, rights...)
if err != nil {
switch err.(type) {
case *authtokens.ErrTokenNotFound:
return &authentication.VerifyOK{Payload: false}
case *authtokens.ErrInvalidToken:
return &authentication.VerifyOK{Payload: false}
case *authtokens.ErrUnauthorized:
return &authentication.VerifyOK{Payload: false}
default:
return &authentication.VerifyInternalServerError{
Payload: &models.ErrResponse{ErrMsg: err.Error()}}
}
}
return &authentication.VerifyOK{Payload: true}
})
}
func registerMeHandler( //nolint:dupl
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationGetMeHandler = authentication.GetMeHandlerFunc(
func(params authentication.GetMeParams, secret interface{}) middleware.Responder {
token := &domain.Token{Secret: secret.(string)}
user, err := tokenService.GetUserByToken(token)
if err != nil {
switch err.(type) {
case *authtokens.ErrTokenNotFound:
resp := authentication.NewGetMeUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *authtokens.ErrUserNotFound:
resp := authentication.NewGetMeUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewGetMeInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
}
resp := authentication.NewGetMeOK()
resp.SetPayload(mapUser(user))
return resp
})
}
func registerPasswordResetRequestHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationPostPasswordResetRequestHandler = authentication.PostPasswordResetRequestHandlerFunc(
func(params authentication.PostPasswordResetRequestParams) middleware.Responder {
err := pwreset.RequestPasswordReset(
tokenService.CredentialsRepository,
tokenService.EmailSender,
tokenService.TemplateRepository,
tokenService.ResetCodeRepository,
params.Body.User,
)
// dupl: Preferred to keep this autonomous for future use.
if err != nil { //nolint:dupl
switch err.(type) {
case *pwreset.ErrFailedToCreateResetCode:
resp := authentication.NewPostPasswordResetRequestInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *pwreset.ErrUserFetchFailed:
resp := authentication.NewPostPasswordResetRequestInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *pwreset.ErrFailedToSendEmail:
resp := authentication.NewPostPasswordResetRequestInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewPostPasswordResetRequestBadRequest()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
} else {
return authentication.NewPostPasswordResetRequestCreated()
}
})
}
func registerPasswordResetRedeemHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationPostPasswordResetRedeemHandler = authentication.PostPasswordResetRedeemHandlerFunc(
func(params authentication.PostPasswordResetRedeemParams) middleware.Responder {
err := pwreset.RedeemPasswordReset(
tokenService.CredentialsRepository,
tokenService.ResetCodeRepository,
params.Body.User,
params.Body.ResetCode,
params.Body.Password,
params.Body.PasswordVerify,
)
if err != nil {
switch err.(type) {
case *pwreset.ErrFailedToGetResetCode:
resp := authentication.NewPostPasswordResetRedeemInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *pwreset.ErrChangePasswordFailed:
resp := authentication.NewPostPasswordResetRedeemInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewPostPasswordResetRedeemBadRequest()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
} else {
return authentication.NewPostPasswordResetRedeemCreated()
}
})
}
func registerListTokensHandler( //nolint:dupl
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationListTokensHandler = authentication.ListTokensHandlerFunc(
func(params authentication.ListTokensParams, secret interface{}) middleware.Responder {
token := &domain.Token{Secret: secret.(string)}
opaqueTokens, err := tokenService.GetOpaqueTokensByToken(token)
if err != nil {
switch err.(type) {
case *authtokens.ErrNilToken:
resp := authentication.NewListTokensUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *authtokens.ErrInvalidToken:
resp := authentication.NewListTokensUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewListTokensInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
}
resp := authentication.NewListTokensOK()
resp.SetPayload(mapTokenList(opaqueTokens))
return resp
})
}
func registerDeleteTokenHandler(
api *operations.AuthenticationAPI,
tokenService *authtokens.Service,
) {
api.AuthenticationDeleteTokenHandler = authentication.DeleteTokenHandlerFunc(
func(params authentication.DeleteTokenParams, secret interface{}) middleware.Responder {
token := &domain.Token{Secret: secret.(string)}
// dupl: Preferred to keep this autonomous for future use.
err := tokenService.DeleteTokenByOpaqueID(token, params.OpaqueTokenID) //nolint:dupl
if err != nil { //nolint:dupl
switch err.(type) {
case *authtokens.ErrNilToken:
resp := authentication.NewDeleteTokenUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *authtokens.ErrInvalidToken:
resp := authentication.NewDeleteTokenUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
case *authtokens.ErrTokenNotFound:
resp := authentication.NewDeleteTokenUnauthorized()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
default:
resp := authentication.NewDeleteTokenInternalServerError()
resp.SetPayload(&models.ErrResponse{ErrMsg: err.Error()})
return resp
}
}
return authentication.NewDeleteTokenOK()
})
}