add user management functionality with OTP verification and consent handling, DI introduced

This commit is contained in:
2025-08-10 10:38:49 +03:00
parent 6a9061a3de
commit 5d80a68b44
30 changed files with 828 additions and 528 deletions

View File

@ -14,6 +14,9 @@ import (
type AcceptConsentRequest struct {
// ConsentChallenge The consent challenge to accept
ConsentChallenge string `json:"consent_challenge"`
// PhoneNumber Phone number associated with the consent
PhoneNumber string `json:"phone_number"`
}
// AcceptConsentResponse defines model for AcceptConsentResponse.
@ -56,6 +59,9 @@ type VerifyOTPRequest struct {
// VerifyOTPResponse defines model for VerifyOTPResponse.
type VerifyOTPResponse struct {
// Message Confirmation message
Message string `json:"message"`
// Ok Status of the verification
Ok bool `json:"ok"`

View File

@ -2,113 +2,68 @@ package handler
import (
"context"
"fmt"
"git.logidex.ru/fakz9/logidex-id/internal/hydra_client"
"git.logidex.ru/fakz9/logidex-id/internal/redis"
"git.logidex.ru/fakz9/logidex-id/internal/api/auth/service"
"github.com/gofiber/fiber/v2"
hydraApi "github.com/ory/hydra-client-go"
)
type AuthHandler struct{}
func (a AuthHandler) PostAuthConsentAccept(ctx context.Context, request PostAuthConsentAcceptRequestObject) (PostAuthConsentAcceptResponseObject, error) {
hydraClient := hydra_client.GetClient()
hydraRequest := hydraApi.AcceptConsentRequest{}
hydraRequest.SetGrantScope([]string{"openid"})
hydraRequest.SetRemember(true)
hydraRequest.SetRememberFor(3600) // 1 hour
hydraResponse, r, err := hydraClient.AdminApi.
AcceptConsentRequest(ctx).
ConsentChallenge(request.Body.ConsentChallenge).
AcceptConsentRequest(hydraRequest).
Execute()
if err != nil {
return PostAuthConsentAccept400JSONResponse{
RedirectUrl: "",
Ok: false,
Message: "Failed to accept consent request",
}, nil
}
fmt.Println(r)
return PostAuthConsentAccept200JSONResponse{
RedirectUrl: hydraResponse.RedirectTo,
Ok: true,
Message: "Успешно",
}, nil
type AuthHandler struct {
service service.AuthService
}
func (a AuthHandler) PostAuthOtpRequest(ctx context.Context, request PostAuthOtpRequestRequestObject) (PostAuthOtpRequestResponseObject, error) {
redisClient := redis.GetClient()
// TODO implement OTP request logic
err := redisClient.Do(ctx, redisClient.B().Set().Key("otp:"+request.Body.PhoneNumber).Value("123456").Build()).Error()
func (h AuthHandler) PostAuthOtpRequest(ctx context.Context, request PostAuthOtpRequestRequestObject) (PostAuthOtpRequestResponseObject, error) {
err := h.service.OtpRequest(ctx, request.Body.PhoneNumber)
if err != nil {
return PostAuthOtpRequest400JSONResponse{
Message: "Failed to set OTP in Redis",
Message: err.Error(),
Ok: false,
}, nil
}
return PostAuthOtpRequest200JSONResponse{
Message: "Код успешно отправлен",
Message: "OTP request successful",
Ok: true,
}, nil
}
func (a AuthHandler) PostAuthOtpVerify(ctx context.Context, request PostAuthOtpVerifyRequestObject) (PostAuthOtpVerifyResponseObject, error) {
redisClient := redis.GetClient()
hydraClient := hydra_client.GetClient()
sentOtp, err := redisClient.Do(ctx, redisClient.B().Get().Key("otp:"+request.Body.PhoneNumber).Build()).ToString()
func (h AuthHandler) PostAuthOtpVerify(ctx context.Context, request PostAuthOtpVerifyRequestObject) (PostAuthOtpVerifyResponseObject, error) {
redirectUrl, err := h.service.OtpVerify(ctx, request.Body.PhoneNumber, request.Body.Otp, request.Body.LoginChallenge)
if err != nil {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Message: err.Error(),
Ok: false,
}, nil
}
if sentOtp != request.Body.Otp {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Ok: false,
}, nil
}
hydraRequest := hydraApi.AcceptLoginRequest{}
// TODO read user from database by phone number
hydraRequest.SetSubject("some-user-id") // Replace with actual user ID
hydraRequest.SetRemember(true)
hydraRequest.SetRememberFor(3600) // 1 hour
hydraResponse, r, err := hydraClient.AdminApi.
AcceptLoginRequest(ctx).
LoginChallenge(request.Body.LoginChallenge).
AcceptLoginRequest(hydraRequest).
Execute()
fmt.Println(r)
if err != nil {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Ok: false,
}, nil
}
return PostAuthOtpVerify200JSONResponse{
RedirectUrl: hydraResponse.RedirectTo,
Message: "OTP verification successful",
Ok: true,
RedirectUrl: redirectUrl,
}, nil
}
func (h AuthHandler) PostAuthConsentAccept(ctx context.Context, request PostAuthConsentAcceptRequestObject) (PostAuthConsentAcceptResponseObject, error) {
redirectUrl, err := h.service.AcceptConsent(ctx, request.Body.PhoneNumber, request.Body.ConsentChallenge)
if err != nil {
return PostAuthConsentAccept400JSONResponse{
Message: err.Error(),
Ok: false,
RedirectUrl: "",
}, nil
}
return PostAuthConsentAccept200JSONResponse{
Message: "Consent accepted successfully",
Ok: true,
RedirectUrl: redirectUrl,
}, nil
}
var _ StrictServerInterface = (*AuthHandler)(nil)
func NewAuthHandler() *AuthHandler {
return &AuthHandler{}
func NewAuthHandler(service service.AuthService) *AuthHandler {
return &AuthHandler{service: service}
}
func RegisterApp(router fiber.Router) {
//authGroup := router.Group("/auth")
server := NewStrictHandler(NewAuthHandler(), nil)
func (h AuthHandler) RegisterRoutes(router fiber.Router) {
server := NewStrictHandler(h, nil)
RegisterHandlers(router, server)
}