sso/internal/grpc/auth/server.go

104 lines
2.7 KiB
Go

package auth
import (
"context"
"errors"
"sso/internal/services/auth"
ssov1 "gitea.computernetthings.ru/yash/protos/gen/sso"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type Auth interface {
Login(ctx context.Context, email string, password string, appID int) (token string, err error)
RegisterNewUser(ctx context.Context, email string, password string) (userID int64, err error)
IsAdmin(ctx context.Context, userID int64) (bool, error)
}
type serverAPI struct {
ssov1.UnimplementedAuthServer
auth Auth
}
func Register(gRPC *grpc.Server, auth Auth) {
ssov1.RegisterAuthServer(gRPC, &serverAPI{auth: auth})
}
const (
emptyValue = 0
)
func (s *serverAPI) Login(ctx context.Context, req *ssov1.LoginRequest) (*ssov1.LoginResponse, error) {
// validate recieved data
if req.GetEmail() == "" {
return nil, status.Error(codes.InvalidArgument, "email is required")
}
if req.GetPassword() == "" {
return nil, status.Error(codes.InvalidArgument, "password is required")
}
if req.GetAppId() == emptyValue {
return nil, status.Error(codes.InvalidArgument, "app_id is required")
}
// login via auth service
token, err := s.auth.Login(ctx, req.GetEmail(), req.GetPassword(), int(req.GetAppId()))
if err != nil {
if errors.Is(err, auth.ErrInvalidCredentials) {
return nil, status.Error(codes.InvalidArgument, "invalid credentials")
}
return nil, status.Error(codes.Internal, "internal error")
}
return &ssov1.LoginResponse{
Token: token,
}, nil
}
func (s *serverAPI) Register(ctx context.Context, req *ssov1.RegisterRequest) (*ssov1.RegisterResponse, error) {
// validate fields
if req.GetEmail() == "" {
return nil, status.Error(codes.InvalidArgument, "email is required")
}
if req.GetPassword() == "" {
return nil, status.Error(codes.InvalidArgument, "password is required")
}
userID, err := s.auth.RegisterNewUser(ctx, req.GetEmail(), req.GetPassword())
if err != nil {
if errors.Is(err, auth.ErrUserExists) {
return nil, status.Error(codes.AlreadyExists, "user already exists")
}
return nil, status.Error(codes.Internal, "internal error")
}
return &ssov1.RegisterResponse{
UserId: userID,
}, nil
}
func (s *serverAPI) IsAdmin(ctx context.Context, req *ssov1.IsAdminRequest) (*ssov1.IsAdminResponse, error) {
if req.GetUserId() == emptyValue {
return nil, status.Error(codes.InvalidArgument, "user_id is required")
}
isAdmin, err := s.auth.IsAdmin(ctx, req.GetUserId())
if err != nil {
if errors.Is(err, auth.ErrUserNotFound) {
return nil, status.Error(codes.NotFound, "user not found")
}
return nil, status.Error(codes.Internal, "internal error")
}
return &ssov1.IsAdminResponse{
IsAdmin: isAdmin,
}, nil
}