package gapi import ( "context" "errors" "strings" db "github.com/FernandoJVideira/api_tmpl/internal/db/sqlc" "github.com/FernandoJVideira/api_tmpl/internal/service" "github.com/FernandoJVideira/api_tmpl/internal/val" "github.com/FernandoJVideira/api_tmpl/pb" "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *Server) LoginUser(ctx context.Context, req *pb.LoginUserRequest) (*pb.LoginUserResponse, error) { violations := validateLoginUserRequest(req) if violations != nil { return nil, invalidArgumentError(violations) } mtdt := s.extractMetadata(ctx) result, err := s.authService.Login(ctx, service.LoginCredentials{ Username: req.GetUsername(), Password: req.GetPassword(), UserAgent: mtdt.UserAgent, ClientIP: mtdt.ClientIP, }) if err != nil { errMsg := err.Error() if errors.Is(err, db.ErrRecordNotFound) || strings.Contains(errMsg, "user not found") { return nil, status.Errorf(codes.NotFound, "user not found") } if strings.Contains(errMsg, "incorrect password") { return nil, status.Errorf(codes.Unauthenticated, "incorrect password") } return nil, status.Errorf(codes.Internal, "failed to login: %v", err) } resp := convertLoginUserResponse( result.User, result.SessionID, result.AccessToken, result.RefreshToken, result.AccessTokenExpiresAt, result.RefreshTokenExpiresAt, ) return resp, nil } // TODO: Change to throw "username or password is incorrect" instead of specifying which one is wrong func validateLoginUserRequest(req *pb.LoginUserRequest) (violations []*errdetails.BadRequest_FieldViolation) { if err := val.ValidateUsername(req.GetUsername()); err != nil { violations = append(violations, fieldViolation("username", err)) } if err := val.ValidatePassword(req.GetPassword()); err != nil { violations = append(violations, fieldViolation("password", err)) } return violations }