diff --git a/api/v1/accounts.go b/api/v1/accounts.go index 0d7a603..73ebc5e 100644 --- a/api/v1/accounts.go +++ b/api/v1/accounts.go @@ -1,17 +1,8 @@ package v1 import ( - "context" - "errors" - "gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers" accounts "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/accounts/v1" - "github.com/golang/protobuf/ptypes/empty" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" ) func NewAccountServer( @@ -29,59 +20,3 @@ type AccountsServer struct { accountsCtrl *controllers.AccountController authorizationCtrl *controllers.AuthController } - -func (srv *AccountsServer) RefreshToken(ctx context.Context, in *empty.Empty) (*empty.Empty, error) { - claims, err := controllers.ClaimsFromContext(ctx) - if err != nil { - return nil, status.Error(codes.Aborted, "Context is invalid") - } - - if claims.TokenType != controllers.TokenTypeRefresh { - return nil, status.Error(codes.Unauthenticated, "Invalid token") - } - - session, err := srv.authorizationCtrl.GetSession(ctx, claims.TokenID) - if err != nil { - if errors.Is(err, controllers.ErrSessionNotFound) { - return nil, status.Error(codes.Unauthenticated, "Session doesn't exists") - } - return nil, status.Error(codes.Internal, "Somethings is broken on our side") - } - - if session.UserID != claims.UserID { - return nil, status.Error(codes.Unauthenticated, "Invalid session") - } - - accessToken, _, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{ - UserID: claims.UserID, - TokenType: controllers.TokenTypeAccess, - TokenAud: controllers.TokenAudWeb, - }) - if err != nil { - return nil, status.Error(codes.Aborted, "Couldn't generate an access token") - } - - refreshToken, tokenID, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{ - UserID: claims.UserID, - TokenType: controllers.TokenTypeRefresh, - TokenAud: controllers.TokenAudWeb, - }) - if err != nil { - return nil, status.Error(codes.Aborted, "Couldn't generate an access token") - } - newSession := &controllers.Session{UserID: session.UserID} - - if err := srv.authorizationCtrl.SaveSession(ctx, tokenID, newSession); err != nil { - return nil, status.Error(codes.Aborted, "Couldn't store session") - } - - header := metadata.New(map[string]string{ - "X-Access-Token": accessToken, - "X-Refresh-Token": refreshToken, - }) - if err := grpc.SetHeader(ctx, header); err != nil { - return nil, status.Error(codes.Aborted, "Couldn't set metadata") - } - - return &emptypb.Empty{}, nil -} diff --git a/api/v1/refresh_session.go b/api/v1/refresh_session.go new file mode 100644 index 0000000..c0b53b8 --- /dev/null +++ b/api/v1/refresh_session.go @@ -0,0 +1,78 @@ +package v1 + +import ( + "context" + "errors" + "fmt" + + "gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers" + accounts "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/accounts/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func NewRefreshSessionServer( + authorizationCtrl *controllers.AuthController, +) *RefreshSessionService { + return &RefreshSessionService{ + authorizationCtrl: authorizationCtrl, + } +} + +type RefreshSessionService struct { + accounts.UnimplementedRefreshSessionServiceServer + authorizationCtrl *controllers.AuthController +} + +func (srv *RefreshSessionService) RefreshSession(ctx context.Context, in *accounts.RefreshSessionRequest) (*accounts.RefreshSessionResponse, error) { + fmt.Println(in.GetRefreshToken()) + claims, err := srv.authorizationCtrl.ParseToken(in.GetRefreshToken()) + if err != nil { + fmt.Println(err) + return nil, status.Error(codes.Aborted, "Invalid token is sent") + } + + if claims.TokenType != controllers.TokenTypeRefresh { + return nil, status.Error(codes.Unauthenticated, "Invalid token") + } + + session, err := srv.authorizationCtrl.GetSession(ctx, claims.TokenID) + if err != nil { + if errors.Is(err, controllers.ErrSessionNotFound) { + return nil, status.Error(codes.Unauthenticated, "Session doesn't exists") + } + return nil, status.Error(codes.Internal, "Somethings is broken on our side") + } + + if session.UserID != claims.UserID { + return nil, status.Error(codes.Unauthenticated, "Invalid session") + } + + accessToken, _, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{ + UserID: claims.UserID, + TokenType: controllers.TokenTypeAccess, + TokenAud: controllers.TokenAudWeb, + }) + if err != nil { + return nil, status.Error(codes.Aborted, "Couldn't generate an access token") + } + + refreshToken, tokenID, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{ + UserID: claims.UserID, + TokenType: controllers.TokenTypeRefresh, + TokenAud: controllers.TokenAudWeb, + }) + if err != nil { + return nil, status.Error(codes.Aborted, "Couldn't generate an access token") + } + newSession := &controllers.Session{UserID: session.UserID} + + if err := srv.authorizationCtrl.SaveSession(ctx, tokenID, newSession); err != nil { + return nil, status.Error(codes.Aborted, "Couldn't store session") + } + + return &accounts.RefreshSessionResponse{TokenPair: &accounts.TokenPair{ + AccessToken: accessToken, + RefreshToken: refreshToken, + }}, nil +} diff --git a/cmd/server.go b/cmd/server.go index afda1e7..3986a05 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -114,11 +114,12 @@ func (cmd *Server) Run(ctx context.Context) error { // Services that should be accessible for tokens should go here accounts.RegisterAccountsServiceServer(grpcServer, v1.NewAccountServer(accountCtrl, authController)) + accounts.RegisterPublicAccountsServiceServer(grpcServer, v1.NewPublicAccountServer(accountCtrl, authController)) + accounts.RegisterRefreshSessionServiceServer(grpcServer, v1.NewRefreshSessionServer(authController)) test.RegisterTestServiceServer(grpcServer, v1.NewTestServer()) test.RegisterPublicTestServiceServer(grpcServer, v1.NewPublicTestServer()) tokens.RegisterTokensServiceServer(grpcServer, v1.NewTokensServer(tokenCtrl, authController)) tokens.RegisterPublicTokensServiceServer(grpcServer, v1.NewPublicTokensServer(tokenCtrl, authController)) - accounts.RegisterPublicAccountsServiceServer(grpcServer, v1.NewPublicAccountServer(accountCtrl, authController)) info := grpcServer.GetServiceInfo() tokenCtrl.SetGRPCInfo(info) @@ -144,6 +145,10 @@ func selectorRequireAuth(ctx context.Context, callMeta interceptors.CallMeta) bo return false } + if strings.HasPrefix(serviceName, "RefreshSession") { + return false + } + if strings.Contains(serviceName, "ServerReflection") { return false } diff --git a/go.mod b/go.mod index d9ad547..4c18644 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( ) require ( - gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260517200845-22f1b32dfad9 + gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260527105637-8480adc36c56 github.com/golang/protobuf v1.5.4 golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.42.0 // indirect diff --git a/go.sum b/go.sum index 6e15f29..3bb2f9a 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260517200845-22f1b32dfad9 h1:RP73i+SOZYmc61F+gZjO/rvUlpPP0Za4MLJKAgS+1YI= -gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260517200845-22f1b32dfad9/go.mod h1:EcQEZ3NN06b3UmKxiRnQnXDDjQ9kmJgoQQBAS+fpRQw= +gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260527105637-8480adc36c56 h1:BCY0WiluIdOjYjisjxGvt06xlWeknkfQjqZPVlJg/VQ= +gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260527105637-8480adc36c56/go.mod h1:EcQEZ3NN06b3UmKxiRnQnXDDjQ9kmJgoQQBAS+fpRQw= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=