Implement a couple of rpcs
All checks were successful
ci/woodpecker/push/build Pipeline was successful
All checks were successful
ci/woodpecker/push/build Pipeline was successful
Signed-off-by: Nikolai Rodionov <iam@allanger.xyz>
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/postgres"
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/services"
|
||||
accounts "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/accounts/v1"
|
||||
projects "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/projects/v1"
|
||||
test "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/test/v1"
|
||||
tokens "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/tokens/v1"
|
||||
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/health"
|
||||
healthgrpc "google.golang.org/grpc/health/grpc_health_v1"
|
||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
@@ -118,6 +118,10 @@ func (cmd *Server) Run(ctx context.Context) error {
|
||||
Redis: rdb,
|
||||
}
|
||||
|
||||
projectsCtrl := &services.ProjectsController{
|
||||
DB: db,
|
||||
}
|
||||
|
||||
// Services that should be accessible for tokens should go here
|
||||
accounts.RegisterAccountsServiceServer(grpcServer, v1.NewAccountServer(accountCtrl, authController))
|
||||
accounts.RegisterPublicAccountsServiceServer(grpcServer, v1.NewPublicAccountServer(accountCtrl, authController))
|
||||
@@ -126,7 +130,7 @@ func (cmd *Server) Run(ctx context.Context) error {
|
||||
test.RegisterPublicTestServiceServer(grpcServer, v1.NewPublicTestServer())
|
||||
tokens.RegisterTokensServiceServer(grpcServer, v1.NewTokensServer(tokenCtrl, authController))
|
||||
tokens.RegisterPublicTokensServiceServer(grpcServer, v1.NewPublicTokensServer(tokenCtrl, authController))
|
||||
|
||||
projects.RegisterProjectsServiceServer(grpcServer, v1.NewProjectsServer(projectsCtrl))
|
||||
healthcheck := health.NewServer()
|
||||
healthgrpc.RegisterHealthServer(grpcServer, healthcheck)
|
||||
|
||||
@@ -140,10 +144,10 @@ func (cmd *Server) Run(ctx context.Context) error {
|
||||
dbOK := checkDatabase(db)
|
||||
redisOK := checkRedis(rdb)
|
||||
|
||||
status := healthpb.HealthCheckResponse_SERVING
|
||||
status := healthgrpc.HealthCheckResponse_SERVING
|
||||
|
||||
if !dbOK || !redisOK {
|
||||
status = healthpb.HealthCheckResponse_NOT_SERVING
|
||||
status = healthgrpc.HealthCheckResponse_NOT_SERVING
|
||||
}
|
||||
|
||||
healthcheck.SetServingStatus(
|
||||
|
||||
4
go.mod
4
go.mod
@@ -43,8 +43,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260528090010-7bf4ddafe7f0
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260609122010-15a8c9529644
|
||||
github.com/golang/protobuf v1.5.4
|
||||
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-20260528090010-7bf4ddafe7f0 h1:CI6EwQndn8cr6ofpc1HbDsphCwK3NOZrdl2PS0BnX+Q=
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260528090010-7bf4ddafe7f0/go.mod h1:EcQEZ3NN06b3UmKxiRnQnXDDjQ9kmJgoQQBAS+fpRQw=
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260609122010-15a8c9529644 h1:PSLGU8NVSfAi7EZwIbrLZO0AYrx5N8aMAAW3B7kkhRc=
|
||||
gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260609122010-15a8c9529644/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=
|
||||
|
||||
@@ -3,23 +3,44 @@ package v1
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/services"
|
||||
projects "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/projects/v1"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func NewProjectsServer() *ProjectsServer {
|
||||
return &ProjectsServer{}
|
||||
func NewProjectsServer(projectCtrl *services.ProjectsController) *ProjectsServer {
|
||||
return &ProjectsServer{
|
||||
projectCtrl: projectCtrl,
|
||||
}
|
||||
}
|
||||
|
||||
// var _ projects.ProjectsServiceServer = (*ProjectsServer)(nil)
|
||||
|
||||
type ProjectsServer struct {
|
||||
projects.UnimplementedProjectsServiceServer
|
||||
projectCtrl *services.ProjectsController
|
||||
}
|
||||
|
||||
// CreateProject implements [v1.ProjectsServiceServer].
|
||||
func (p *ProjectsServer) CreateProject(context.Context, *projects.CreateProjectRequest) (*projects.CreateProjectResponse, error) {
|
||||
panic("unimplemented")
|
||||
func (p *ProjectsServer) CreateProject(ctx context.Context, in *projects.CreateProjectRequest) (*projects.CreateProjectResponse, error) {
|
||||
claims, err := services.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Context is invalid")
|
||||
}
|
||||
|
||||
projectData := &services.ProjectData{
|
||||
Name: in.Name,
|
||||
Slug: in.Slug,
|
||||
Description: in.Description,
|
||||
}
|
||||
|
||||
id, err := p.projectCtrl.Create(ctx, projectData, claims.UserID)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Couldn't create a project")
|
||||
}
|
||||
return &projects.CreateProjectResponse{Id: id}, nil
|
||||
}
|
||||
|
||||
// GetProject implements [v1.ProjectsServiceServer].
|
||||
@@ -28,8 +49,27 @@ func (p *ProjectsServer) GetProject(context.Context, *projects.GetProjectRequest
|
||||
}
|
||||
|
||||
// ListProjects implements [v1.ProjectsServiceServer].
|
||||
func (p *ProjectsServer) ListProjects(*projects.ListProjectsRequest, grpc.ServerStreamingServer[projects.ListProjectsResponse]) error {
|
||||
panic("unimplemented")
|
||||
func (p *ProjectsServer) ListProjects(_in *projects.ListProjectsRequest, stream grpc.ServerStreamingServer[projects.ListProjectsResponse]) error {
|
||||
claims, err := services.ClaimsFromContext(stream.Context())
|
||||
if err != nil {
|
||||
return status.Error(codes.Aborted, "Context is invalid")
|
||||
}
|
||||
|
||||
res, err := p.projectCtrl.List(stream.Context(), claims.UserID)
|
||||
if err != nil {
|
||||
return status.Error(codes.Aborted, "Couldn't list projects")
|
||||
}
|
||||
for _, project := range res {
|
||||
payload := &projects.ListProjectsResponse{
|
||||
Id: project.UUID,
|
||||
Slug: "dummy",
|
||||
Name: project.Name,
|
||||
}
|
||||
if err := stream.Send(payload); err != nil {
|
||||
return status.Error(codes.Aborted, "Couldn't send data")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProject implements [v1.ProjectsServiceServer].
|
||||
|
||||
@@ -5,14 +5,14 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers"
|
||||
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/services"
|
||||
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,
|
||||
authorizationCtrl *services.AuthController,
|
||||
) *RefreshSessionService {
|
||||
return &RefreshSessionService{
|
||||
authorizationCtrl: authorizationCtrl,
|
||||
@@ -21,7 +21,7 @@ func NewRefreshSessionServer(
|
||||
|
||||
type RefreshSessionService struct {
|
||||
accounts.UnimplementedRefreshSessionServiceServer
|
||||
authorizationCtrl *controllers.AuthController
|
||||
authorizationCtrl *services.AuthController
|
||||
}
|
||||
|
||||
func (srv *RefreshSessionService) RefreshSession(ctx context.Context, in *accounts.RefreshSessionRequest) (*accounts.RefreshSessionResponse, error) {
|
||||
@@ -32,13 +32,13 @@ func (srv *RefreshSessionService) RefreshSession(ctx context.Context, in *accoun
|
||||
return nil, status.Error(codes.Aborted, "Invalid token is sent")
|
||||
}
|
||||
|
||||
if claims.TokenType != controllers.TokenTypeRefresh {
|
||||
if claims.TokenType != services.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) {
|
||||
if errors.Is(err, services.ErrSessionNotFound) {
|
||||
return nil, status.Error(codes.Unauthenticated, "Session doesn't exists")
|
||||
}
|
||||
return nil, status.Error(codes.Internal, "Somethings is broken on our side")
|
||||
@@ -48,24 +48,24 @@ func (srv *RefreshSessionService) RefreshSession(ctx context.Context, in *accoun
|
||||
return nil, status.Error(codes.Unauthenticated, "Invalid session")
|
||||
}
|
||||
|
||||
accessToken, _, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{
|
||||
accessToken, _, err := srv.authorizationCtrl.GenerateToken(&services.JWTData{
|
||||
UserID: claims.UserID,
|
||||
TokenType: controllers.TokenTypeAccess,
|
||||
TokenAud: controllers.TokenAudWeb,
|
||||
TokenType: services.TokenTypeAccess,
|
||||
TokenAud: services.TokenAudWeb,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Couldn't generate an access token")
|
||||
}
|
||||
|
||||
refreshToken, tokenID, err := srv.authorizationCtrl.GenerateToken(&controllers.JWTData{
|
||||
refreshToken, tokenID, err := srv.authorizationCtrl.GenerateToken(&services.JWTData{
|
||||
UserID: claims.UserID,
|
||||
TokenType: controllers.TokenTypeRefresh,
|
||||
TokenAud: controllers.TokenAudWeb,
|
||||
TokenType: services.TokenTypeRefresh,
|
||||
TokenAud: services.TokenAudWeb,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Couldn't generate an access token")
|
||||
}
|
||||
newSession := &controllers.Session{UserID: session.UserID}
|
||||
newSession := &services.Session{UserID: session.UserID}
|
||||
|
||||
if err := srv.authorizationCtrl.SaveSession(ctx, tokenID, newSession); err != nil {
|
||||
return nil, status.Error(codes.Aborted, "Couldn't store session")
|
||||
|
||||
@@ -60,7 +60,8 @@ func CreateProject(ctx context.Context, db *sql.DB, data *ProjectData) error {
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6);
|
||||
`
|
||||
if _, err := tx.ExecContext(ctx, queryMembership,
|
||||
if _, err := tx.ExecContext(
|
||||
ctx, queryMembership,
|
||||
data.UUID, data.CreatedBy, "owner", "active", data.CreatedBy, data.CreatedAt,
|
||||
); err != nil {
|
||||
var pgErr *pgconn.PgError
|
||||
|
||||
@@ -23,8 +23,9 @@ type ProjectData struct {
|
||||
}
|
||||
|
||||
var (
|
||||
ErrProjectExists = errors.New("project exists")
|
||||
ErrInvalidProject = errors.New("invalid project data")
|
||||
ErrProjectExists = errors.New("project exists")
|
||||
ErrInvalidProject = errors.New("invalid project data")
|
||||
ErrProjectNotFound = errors.New("project not found")
|
||||
)
|
||||
|
||||
// Create a new project
|
||||
@@ -66,6 +67,24 @@ func (ctrl *ProjectsController) Get(ctx context.Context, projectID string) (data
|
||||
}
|
||||
|
||||
// List projects available for a user
|
||||
func (ctrl *ProjectsController) List(ctx context.Context) (data []*ProjectData, err error) {
|
||||
return nil, nil
|
||||
func (ctrl *ProjectsController) List(ctx context.Context, userID string) (data []*ProjectData, err error) {
|
||||
log := logger.FromContext(ctx)
|
||||
log.V(2).Info("Listing projects")
|
||||
data = []*ProjectData{}
|
||||
res, err := repository.ListProjects(ctx, ctrl.DB, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, repository.ErrNotFound) {
|
||||
return nil, ErrProjectNotFound
|
||||
}
|
||||
log.Error(err, "Couldn't list projects")
|
||||
return nil, ErrServerError
|
||||
}
|
||||
for _, val := range res {
|
||||
data = append(data, &ProjectData{
|
||||
UUID: val.UUID,
|
||||
Name: val.Name,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user