Compare commits
3 Commits
add-projec
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
34d44cf1de
|
|||
|
08087d453f
|
|||
|
a9784c3436
|
@@ -2,15 +2,9 @@ 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"
|
||||
)
|
||||
|
||||
@@ -24,64 +18,25 @@ func NewAccountServer(
|
||||
}
|
||||
}
|
||||
|
||||
//var _ accounts.AccountsServiceServer = (*AccountsServer)(nil)
|
||||
|
||||
type AccountsServer struct {
|
||||
accounts.UnimplementedAccountsServiceServer
|
||||
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
|
||||
// IsEmailVerified implements [v1.AccountsServiceServer].
|
||||
func (a *AccountsServer) IsEmailVerified(context.Context, *accounts.IsEmailVerifiedRequest) (*accounts.IsEmailVerifiedResponse, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// RemoveSession implements [v1.AccountsServiceServer].
|
||||
func (a *AccountsServer) RemoveSession(context.Context, *accounts.RemoveSessionRequest) (*emptypb.Empty, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// TokenAuthorization implements [v1.AccountsServiceServer].
|
||||
func (a *AccountsServer) TokenAuthorization(context.Context, *emptypb.Empty) (*emptypb.Empty, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
@@ -5,12 +5,8 @@ import (
|
||||
|
||||
"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 NewPublicAccountServer(
|
||||
@@ -29,7 +25,7 @@ type PublicAccountService struct {
|
||||
authorizationCtrl *controllers.AuthController
|
||||
}
|
||||
|
||||
func (a *PublicAccountService) SignIn(ctx context.Context, in *accounts.SignInRequest) (*empty.Empty, error) {
|
||||
func (a *PublicAccountService) SignIn(ctx context.Context, in *accounts.SignInRequest) (*accounts.SignInResponse, error) {
|
||||
id, err := a.accountsCtrl.Login(ctx, in.GetEmail(), in.GetPassword())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Couldn't create a user")
|
||||
@@ -57,18 +53,16 @@ func (a *PublicAccountService) SignIn(ctx context.Context, in *accounts.SignInRe
|
||||
if err := a.authorizationCtrl.SaveSession(ctx, tokenID, session); 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
|
||||
return &accounts.SignInResponse{
|
||||
TokenPair: &accounts.TokenPair{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create a new account in Softplayer
|
||||
func (a *PublicAccountService) SignUp(ctx context.Context, in *accounts.SignUpRequest) (*empty.Empty, error) {
|
||||
func (a *PublicAccountService) SignUp(ctx context.Context, in *accounts.SignUpRequest) (*accounts.SignUpResponse, error) {
|
||||
data := &controllers.AccountData{
|
||||
Password: in.GetPassword(),
|
||||
Email: in.GetEmail(),
|
||||
@@ -102,12 +96,10 @@ func (a *PublicAccountService) SignUp(ctx context.Context, in *accounts.SignUpRe
|
||||
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
|
||||
return &accounts.SignUpResponse{
|
||||
TokenPair: &accounts.TokenPair{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
78
api/v1/refresh_session.go
Normal file
78
api/v1/refresh_session.go
Normal file
@@ -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
|
||||
}
|
||||
@@ -38,7 +38,7 @@ type Server struct {
|
||||
DBConnectionString string `env:"SOFTPLAYER_DB_CONNECTION_STRING"`
|
||||
RedisHost string `env:"SOFTPLAYER_REDIS_HOST"`
|
||||
// JWT parameters
|
||||
RefrestTokenTTL time.Duration `default:"8h"`
|
||||
RefreshTokenTTL time.Duration `default:"8h"`
|
||||
AccessTokenTTL time.Duration `default:"15m"`
|
||||
JWTSecret string `default:"qwertyu9"`
|
||||
// Dev and logging
|
||||
@@ -71,7 +71,7 @@ func (cmd *Server) Run(ctx context.Context) error {
|
||||
authController := controllers.NewAuthController(
|
||||
[]byte(cmd.JWTSecret),
|
||||
cmd.AccessTokenTTL,
|
||||
cmd.RefrestTokenTTL,
|
||||
cmd.RefreshTokenTTL,
|
||||
rdb,
|
||||
)
|
||||
|
||||
@@ -106,7 +106,7 @@ func (cmd *Server) Run(ctx context.Context) error {
|
||||
HashCost: cmd.HashCost,
|
||||
DB: db,
|
||||
DevMode: cmd.DevMode,
|
||||
RefreshTokenTTL: cmd.RefrestTokenTTL,
|
||||
RefreshTokenTTL: cmd.RefreshTokenTTL,
|
||||
AccessTokenTTL: cmd.AccessTokenTTL,
|
||||
JWTSecret: []byte(cmd.JWTSecret),
|
||||
Redis: rdb,
|
||||
@@ -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
|
||||
}
|
||||
|
||||
4
go.mod
4
go.mod
@@ -43,8 +43,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260517200845-22f1b32dfad9
|
||||
github.com/golang/protobuf v1.5.4
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260528090010-7bf4ddafe7f0
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
golang.org/x/net v0.51.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
|
||||
4
go.sum
4
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-20260528090010-7bf4ddafe7f0 h1:CI6EwQndn8cr6ofpc1HbDsphCwK3NOZrdl2PS0BnX+Q=
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260528090010-7bf4ddafe7f0/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=
|
||||
|
||||
@@ -72,6 +72,9 @@ spec:
|
||||
- server
|
||||
- --dev-mode
|
||||
- --reflection
|
||||
{{- with .Values.args }}
|
||||
{{ . | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: grpc
|
||||
containerPort: {{ .Values.service.port }}
|
||||
|
||||
@@ -15,6 +15,8 @@ podAnnotations: {}
|
||||
podLabels: {}
|
||||
podSecurityContext: {}
|
||||
securityContext: {}
|
||||
|
||||
args: []
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
|
||||
Reference in New Issue
Block a user