From c52c3d1046aeaa8258f6cc72e9abfd37f7922ae4 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Tue, 5 May 2026 22:56:56 +0200 Subject: [PATCH] WIP: Start implementing the internal auth Signed-off-by: Nikolai Rodionov --- Taskfile.yml | 13 ++++ api/v1/accounts_no_auth.go | 62 +++++-------------- go.mod | 2 +- go.sum | 12 +--- .../templates/deployment.yaml | 13 ++++ internal/controllers/accounts.go | 8 ++- migrations/20260425183515_init.up.sql | 4 +- 7 files changed, 51 insertions(+), 63 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index a1adc41..7740a72 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -38,3 +38,16 @@ tasks: helmfile-deploy: desc: Deploy the helmfile for the local dev cmd: helmfile apply + + get-proto-from-branch: + desc: Get the latest version of generated protobuf code from the branch + silent: true + vars: + WORKDIR: + sh: mktemp -d + cmds: + - git clone git@gitea.badhouseplants.net:softplayer/softplayer-go-proto.git '{{ .WORKDIR }}' + - git -C '{{ .WORKDIR }}' checkout '{{ .CLI_ARGS }}' + - go get gitea.badhouseplants.net/softplayer/softplayer-go-proto@$(git -C '{{ .WORKDIR }}' rev-parse HEAD) + - rm -rf '{{ .WORKDIR }}' + - go mod tidy diff --git a/api/v1/accounts_no_auth.go b/api/v1/accounts_no_auth.go index d6aad9f..ea2eca8 100644 --- a/api/v1/accounts_no_auth.go +++ b/api/v1/accounts_no_auth.go @@ -4,10 +4,9 @@ import ( "context" "gitea.badhouseplants.net/softplayer/softplayer-backend/internal/controllers" + "gitea.badhouseplants.net/softplayer/softplayer-backend/internal/tools/logger" accounts "gitea.badhouseplants.net/softplayer/softplayer-go-proto/pkg/accounts/v1" - "github.com/coreos/go-oidc/v3/oidc" "github.com/golang/protobuf/ptypes/empty" - "golang.org/x/oauth2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -25,49 +24,20 @@ type AccountsNoAuthServer struct { } func (a *AccountsNoAuthServer) SignIn(ctx context.Context, in *accounts.SignInRequest) (*empty.Empty, error) { - provider, err := oidc.NewProvider(ctx, "https://authentik.badhouseplants.net") - if err != nil { - return nil, err - } - - // Configure an OpenID Connect aware OAuth2 client. - oauth2Config := oauth2.Config{ - ClientID: "softplayer-localhost", - ClientSecret: "pRpe3scGUE2jNH6t5rqI9R4OROeQHs4eO6ku957mYjDumKhQGX8QJcO0BMJ2FG4sUpvFrqccEqWgc3wKMp94tC8LyvTnkPF0Tg0CaldAEHuoQQdNKAzXVxwrHE6kNyBC", - RedirectURL: "http://localhost:8080/#/auth/callback", - - // Discovery returns the OAuth2 endpoints. - Endpoint: provider.Endpoint(), - - // "openid" is a required scope for OpenID Connect flows. - Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, - } - verifier := provider.Verifier(&oidc.Config{ClientID: "softplayer-localhost"}) - - oauth2Token, err := oauth2Config.Exchange(ctx, in.Code) - if err != nil { - return nil, err - } - - // Extract the ID Token from OAuth2 token. - rawIDToken, ok := oauth2Token.Extra("id_token").(string) - if !ok { - return nil, status.Error(codes.Unauthenticated, "Couldn't parse oauth token") - } - - // Parse and verify ID Token payload. - idToken, err := verifier.Verify(ctx, rawIDToken) - if err != nil { - return nil, status.Error(codes.Unauthenticated, "Couldn't verify oauth token") - } - - // Extract custom claims - var claims struct { - Email string `json:"email"` - Verified bool `json:"email_verified"` - } - if err := idToken.Claims(&claims); err != nil { - // handle error - } + return &emptypb.Empty{}, nil +} + +func (a *AccountsNoAuthServer) SignUp(ctx context.Context, in *accounts.SignUpRequest) (*empty.Empty, error) { + log := logger.FromContext(ctx) + data := &controllers.AccountData{ + Password: in.GetPassword(), + Email: in.GetEmail(), + } + id, err := a.ctrl.Create(ctx, data) + if err != nil { + return nil, status.Error(codes.Aborted, "Couldn't create a user") + } + + log.Info(id) return &emptypb.Empty{}, nil } diff --git a/go.mod b/go.mod index 4cb682a..412383d 100644 --- a/go.mod +++ b/go.mod @@ -140,7 +140,7 @@ require ( ) require ( - gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260430152421-88c087f0cea0 + gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260505200910-6680dffa2e8b github.com/golang/protobuf v1.5.4 golang.org/x/net v0.49.0 // indirect golang.org/x/sys v0.40.0 // indirect diff --git a/go.sum b/go.sum index 1257e52..7e27f78 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260430152421-88c087f0cea0 h1:2UggBAWgOJ1MYgkk+RTaWhfTGtzAZ0B9MriZMoHqnq4= -gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260430152421-88c087f0cea0/go.mod h1:AgOh1lkPHyRgBf3/s1btKcAqke/33LbKYarTD13qeAg= +gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260505200910-6680dffa2e8b h1:/mhdJ1VEhIWmLd6Wrs6xIs+USjhHcAn8MsK7wZqzi3Y= +gitea.badhouseplants.net/softplayer/softplayer-go-proto v0.0.0-20260505200910-6680dffa2e8b/go.mod h1:AgOh1lkPHyRgBf3/s1btKcAqke/33LbKYarTD13qeAg= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= @@ -189,8 +189,6 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= @@ -243,15 +241,10 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= @@ -464,7 +457,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/helm/softplayer-backend/templates/deployment.yaml b/helm/softplayer-backend/templates/deployment.yaml index 712595b..04761f2 100644 --- a/helm/softplayer-backend/templates/deployment.yaml +++ b/helm/softplayer-backend/templates/deployment.yaml @@ -32,6 +32,19 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} + initContainers: + - name: {{ .Chart.Name }}-migrations + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - migrate + resources: + {{- toYaml . | nindent 12 }} + {{- end }} containers: - name: {{ .Chart.Name }} {{- with .Values.securityContext }} diff --git a/internal/controllers/accounts.go b/internal/controllers/accounts.go index df3e21d..743c314 100644 --- a/internal/controllers/accounts.go +++ b/internal/controllers/accounts.go @@ -32,22 +32,24 @@ type JWT struct { type AccountParams struct{} type AccountData struct { - Username string Password string Email string UUID string } func (c *AccountController) Create(ctx context.Context, data *AccountData) (string, error) { + log := logger.FromContext(ctx) data.UUID = uuid.New().String() passwordHash, err := hash.HashPassword(data.Password, int(c.HashCost)) if err != nil { + log.Error(err, "Couldn't crate the password hash") return "", nil } - query := "INSERT INTO users (uuid, username, email, password_hash) VALUES ($1, $2, $3, $4)" - if _, err := c.DB.Query(query, data.UUID, data.Username, data.Email, passwordHash); err != nil { + query := "INSERT INTO users (uuid, email, password_hash) VALUES ($1, $2, $3)" + if _, err := c.DB.Query(query, data.UUID, data.Email, passwordHash); err != nil { + log.Error(err, "Couldn't create a user in the database") return "", err } diff --git a/migrations/20260425183515_init.up.sql b/migrations/20260425183515_init.up.sql index 83b5410..a0e8f9a 100644 --- a/migrations/20260425183515_init.up.sql +++ b/migrations/20260425183515_init.up.sql @@ -1,9 +1,7 @@ CREATE TABLE IF NOT EXISTS users ( uuid UUID PRIMARY KEY, - username VARCHAR(10) NOT NULL - CHECK (username ~ '^[a-z0-9]{1,10}$') UNIQUE, email VARCHAR(255) NOT NULL - CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'), + CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$') UNIQUE, password_hash TEXT NOT NULL, email_verified BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP