85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
|
|
package usecase
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
authdomain "gateway/internal/model/auth/domain"
|
||
|
|
domrepo "gateway/internal/model/auth/domain/repository"
|
||
|
|
domusecase "gateway/internal/model/auth/domain/usecase"
|
||
|
|
|
||
|
|
"github.com/google/uuid"
|
||
|
|
)
|
||
|
|
|
||
|
|
type loginMFAChallengeUseCase struct {
|
||
|
|
store domrepo.LoginMFAChallengeStore
|
||
|
|
}
|
||
|
|
|
||
|
|
// LoginMFAChallengeUseCaseParam wires LoginMFAChallengeUseCase.
|
||
|
|
type LoginMFAChallengeUseCaseParam struct {
|
||
|
|
Store domrepo.LoginMFAChallengeStore
|
||
|
|
}
|
||
|
|
|
||
|
|
// MustLoginMFAChallengeUseCase constructs LoginMFAChallengeUseCase.
|
||
|
|
func MustLoginMFAChallengeUseCase(param LoginMFAChallengeUseCaseParam) domusecase.LoginMFAChallengeUseCase {
|
||
|
|
if param.Store == nil {
|
||
|
|
panic("auth: login mfa challenge store is required")
|
||
|
|
}
|
||
|
|
return &loginMFAChallengeUseCase{store: param.Store}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (uc *loginMFAChallengeUseCase) Create(ctx context.Context, req *domusecase.CreateLoginMFAChallengeRequest) (*domusecase.LoginMFAChallengeView, error) {
|
||
|
|
if req == nil || req.TenantID == "" || req.TenantSlug == "" || req.UID == "" {
|
||
|
|
return nil, errb.InputMissingRequired("tenant_id, tenant_slug and uid are required")
|
||
|
|
}
|
||
|
|
ttl := req.TTL
|
||
|
|
if ttl <= 0 {
|
||
|
|
ttl = 5 * time.Minute
|
||
|
|
}
|
||
|
|
challengeID := uuid.NewString()
|
||
|
|
challenge := &domrepo.LoginMFAChallenge{
|
||
|
|
ChallengeID: challengeID,
|
||
|
|
TenantID: req.TenantID,
|
||
|
|
TenantSlug: req.TenantSlug,
|
||
|
|
UID: req.UID,
|
||
|
|
}
|
||
|
|
if err := uc.store.Save(ctx, challenge, ttl); err != nil {
|
||
|
|
return nil, wrapRepoErr(err, "save login mfa challenge failed")
|
||
|
|
}
|
||
|
|
return &domusecase.LoginMFAChallengeView{
|
||
|
|
ChallengeID: challengeID,
|
||
|
|
ExpiresIn: int(ttl.Seconds()),
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (uc *loginMFAChallengeUseCase) Get(ctx context.Context, challengeID string) (*domusecase.CreateLoginMFAChallengeRequest, error) {
|
||
|
|
if challengeID == "" {
|
||
|
|
return nil, errb.InputMissingRequired("challenge_id is required")
|
||
|
|
}
|
||
|
|
challenge, err := uc.store.Get(ctx, challengeID)
|
||
|
|
if err != nil {
|
||
|
|
if errors.Is(err, authdomain.ErrLoginMFAChallengeNotFound) {
|
||
|
|
return nil, errb.ResNotFound("login mfa challenge", challengeID).WithCause(err)
|
||
|
|
}
|
||
|
|
return nil, wrapRepoErr(err, "read login mfa challenge failed")
|
||
|
|
}
|
||
|
|
return &domusecase.CreateLoginMFAChallengeRequest{
|
||
|
|
TenantID: challenge.TenantID,
|
||
|
|
TenantSlug: challenge.TenantSlug,
|
||
|
|
UID: challenge.UID,
|
||
|
|
}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (uc *loginMFAChallengeUseCase) Delete(ctx context.Context, challengeID string) error {
|
||
|
|
if challengeID == "" {
|
||
|
|
return errb.InputMissingRequired("challenge_id is required")
|
||
|
|
}
|
||
|
|
if err := uc.store.Delete(ctx, challengeID); err != nil {
|
||
|
|
return wrapRepoErr(err, "delete login mfa challenge failed")
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
var _ domusecase.LoginMFAChallengeUseCase = (*loginMFAChallengeUseCase)(nil)
|