Files
enkly-ai/services/iam/internal/interfaces/grpc/server.go
enkly 79ce8dc4c0
Some checks failed
Go CI Pipeline / build_and_test (push) Failing after 22m0s
Init Project
2026-10-30 18:06:55 +01:00

129 lines
4.2 KiB
Go

// Package grpc adapts application.Service onto the generated
// iamv1.IAMServiceServer interface — the only layer in this service
// that imports google.golang.org/grpc or the generated gen/iam/v1
// package. Keeping that import confined to this one file is what lets
// internal/application stay transport-agnostic and unit-testable
// without spinning up a gRPC server.
package grpc
import (
"context"
"errors"
"google.golang.org/protobuf/types/known/timestamppb"
iamv1 "enkly/gen/iam/v1"
"enkly/pkg/grpcerr"
"enkly/services/iam/internal/application"
"enkly/services/iam/internal/domain"
)
type Server struct {
iamv1.UnimplementedIAMServiceServer
Svc *application.Service
}
func New(svc *application.Service) *Server { return &Server{Svc: svc} }
func toProtoUser(u *domain.User) *iamv1.User {
if u == nil {
return nil
}
return &iamv1.User{
Id: u.ID,
Email: u.Email,
EmailVerified: u.EmailVerified,
CreatedAt: timestamppb.New(u.CreatedAt),
}
}
func (s *Server) SignUp(ctx context.Context, req *iamv1.SignUpRequest) (*iamv1.SignUpResponse, error) {
res, err := s.Svc.SignUp(ctx, req.GetEmail(), req.GetPassword(), req.GetClientIp())
if err != nil {
return nil, err
}
return &iamv1.SignUpResponse{
CheckInbox: res.CheckInbox,
Email: res.Email,
MailConfigured: res.MailConfigured,
}, nil
}
func (s *Server) ResendVerification(ctx context.Context, req *iamv1.ResendVerificationRequest) (*iamv1.ResendVerificationResponse, error) {
if err := s.Svc.ResendVerification(ctx, req.GetEmail(), req.GetClientIp()); err != nil {
return nil, err
}
return &iamv1.ResendVerificationResponse{MailConfigured: s.Svc.MailConfigured}, nil
}
func (s *Server) VerifyEmail(ctx context.Context, req *iamv1.VerifyEmailRequest) (*iamv1.VerifyEmailResponse, error) {
ok, err := s.Svc.VerifyEmail(ctx, req.GetEmail(), req.GetCode(), req.GetClientIp())
if err != nil {
return nil, err
}
return &iamv1.VerifyEmailResponse{Verified: ok}, nil
}
func (s *Server) Login(ctx context.Context, req *iamv1.LoginRequest) (*iamv1.LoginResponse, error) {
res, err := s.Svc.Login(ctx, req.GetEmail(), req.GetPassword(), req.GetClientIp())
if err != nil {
return nil, err
}
resp := &iamv1.LoginResponse{Ok: res.OK, NeedsVerification: res.NeedsVerification}
if res.OK {
resp.SessionToken = res.SessionToken
resp.SessionExpiresAt = timestamppb.New(res.SessionExpiresAt)
resp.User = toProtoUser(res.User)
}
return resp, nil
}
func (s *Server) Logout(ctx context.Context, req *iamv1.LogoutRequest) (*iamv1.LogoutResponse, error) {
if err := s.Svc.Logout(ctx, req.GetSessionToken()); err != nil {
return nil, err
}
return &iamv1.LogoutResponse{}, nil
}
func (s *Server) ValidateSession(ctx context.Context, req *iamv1.ValidateSessionRequest) (*iamv1.ValidateSessionResponse, error) {
u, ok := s.Svc.ValidateSession(ctx, req.GetSessionToken())
if !ok {
return &iamv1.ValidateSessionResponse{Valid: false}, nil
}
return &iamv1.ValidateSessionResponse{Valid: true, User: toProtoUser(u)}, nil
}
func (s *Server) ForgotPassword(ctx context.Context, req *iamv1.ForgotPasswordRequest) (*iamv1.ForgotPasswordResponse, error) {
if err := s.Svc.ForgotPassword(ctx, req.GetEmail(), req.GetClientIp()); err != nil {
return nil, err
}
return &iamv1.ForgotPasswordResponse{}, nil
}
func (s *Server) CheckPasswordResetToken(ctx context.Context, req *iamv1.CheckPasswordResetTokenRequest) (*iamv1.CheckPasswordResetTokenResponse, error) {
ok, err := s.Svc.CheckPasswordResetToken(ctx, req.GetToken())
if err != nil {
return nil, err
}
return &iamv1.CheckPasswordResetTokenResponse{Valid: ok}, nil
}
func (s *Server) ResetPassword(ctx context.Context, req *iamv1.ResetPasswordRequest) (*iamv1.ResetPasswordResponse, error) {
ok, err := s.Svc.ResetPassword(ctx, req.GetToken(), req.GetPassword())
if err != nil {
return nil, err
}
return &iamv1.ResetPasswordResponse{Ok: ok}, nil
}
func (s *Server) GetUser(ctx context.Context, req *iamv1.GetUserRequest) (*iamv1.User, error) {
u, err := s.Svc.GetUser(ctx, req.GetUserId())
if err != nil {
if errors.Is(err, domain.ErrNotFound) {
return nil, grpcerr.NotFound("user")
}
return nil, err
}
return toProtoUser(u), nil
}