Files
softplayer-backend/cmd/server.go
Nikolai Rodionov 99f9bb462f
All checks were successful
ci/woodpecker/push/build Pipeline was successful
A bit of refactoring and updates
Signed-off-by: Nikolai Rodionov <iam@allanger.xyz>
2026-05-11 11:57:17 +02:00

124 lines
3.9 KiB
Go

package cmd
import (
"context"
"database/sql"
"fmt"
"net"
"strings"
"time"
v1 "gitea.badhouseplants.net/softplayer/softplayer-backend/api/v1"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers"
"gitea.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/logger"
accounts "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/accounts/v1"
test "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/test/v1"
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/selector"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
type Server struct {
// Service related
Port int64 `short:"p" env:"SOFTPLAYER_PORT" default:"4020"`
Host string `env:"SOFTPLAYER_HOST" default:"0.0.0.0"`
HashCost int16 `env:"SOFTPLAYER_HASH_COST" default:"1"`
// SMTP Config
SMTPHost string `env:"SOFTPLAYER_SMTP_HOST"`
SMTPPort string `env:"SOFTPLAYER_SMTP_PORT" default:"587"`
SMTPFrom string `env:"SOFTPLAYER_SMTP_FROM" default:"overlord@badhouseplants.net"`
SMTPPassword string `env:"SOFTPLAYER_SMTP_PASSWORD"`
// Database and redis
DBConnectionString string `env:"SOFTPLAYER_DB_CONNECTION_STRING"`
RedisHost string `env:"SOFTPLAYER_REDIS_HOST"`
// JWT parameters
RefrestTokenTTL time.Duration `default:"8h"`
AccessTokenTTL time.Duration `default:"15m"`
JWTSecret string `default:"qwertyu9"`
// Dev and logging
Reflection bool `env:"SOFTPLAYER_REFLECTION" default:"false"`
DevMode bool `env:"SOFTPLAYER_DEV_MODE" default:"false"`
}
// Run the grpc backend server
func (cmd *Server) Run(ctx context.Context) error {
// Make sure the download dir exists
log := logger.FromContext(ctx)
log.Info("Opening a database connection")
db, err := sql.Open("postgres", cmd.DBConnectionString)
if err != nil {
log.Error(err, "Couldn't start a database driver")
return err
}
address := fmt.Sprintf("%s:%d", cmd.Host, cmd.Port)
lis, err := net.Listen("tcp", address)
if err != nil {
return err
}
rdb := redis.NewClient(&redis.Options{
Addr: cmd.RedisHost,
})
authInterceptor := controllers.NewAuthController(
[]byte(cmd.JWTSecret),
cmd.AccessTokenTTL,
cmd.RefrestTokenTTL,
rdb,
)
grpcServer := grpc.NewServer(
grpc.ChainUnaryInterceptor(
grpc_zap.UnaryServerInterceptor(logger.SetupLogger("info")),
// jwtVerifier.JWTAuthInterceptor,
selector.UnaryServerInterceptor(
auth.UnaryServerInterceptor(authInterceptor.AuthInterceptorFN),
selector.MatchFunc(selectorRequireAuth),
),
),
grpc.StreamInterceptor(grpc_zap.StreamServerInterceptor(logger.SetupLogger("info"))),
)
if cmd.Reflection {
reflection.Register(grpcServer)
}
accountCtrl := &controllers.AccountController{
HashCost: cmd.HashCost,
DB: db,
DevMode: cmd.DevMode,
RefreshTokenTTL: cmd.RefrestTokenTTL,
AccessTokenTTL: cmd.AccessTokenTTL,
JWTSecret: []byte(cmd.JWTSecret),
Redis: rdb,
}
accounts.RegisterPublicAccountsServiceServer(grpcServer, v1.NewPublicAccountServer(accountCtrl, authInterceptor))
accounts.RegisterAccountsServiceServer(grpcServer, v1.NewAccountServer(accountCtrl, authInterceptor))
test.RegisterTestServiceServer(grpcServer, v1.NewTestServer())
test.RegisterPublicTestServiceServer(grpcServer, v1.NewPublicTestServer())
if err := grpcServer.Serve(lis); err != nil {
return err
}
return nil
}
// Parse the service name and check whether it's public or not
func selectorRequireAuth(ctx context.Context, callMeta interceptors.CallMeta) bool {
serviceParts := strings.Split(callMeta.Service, ".")
if len(serviceParts) == 0 {
return false
}
serviceName := serviceParts[len(serviceParts)-1]
fmt.Println(serviceName)
return !strings.HasPrefix(serviceName, "Public")
}