From 68cb2c79e938d744403a729388e6ce0abde29cdc Mon Sep 17 00:00:00 2001 From: Piyush Kumar Date: Tue, 1 Oct 2024 12:33:21 +0530 Subject: [PATCH 1/3] validate recaptcha only when environment will be available --- apps/auth/internal/domain/impl.go | 30 ++++++++++++++++++------------ apps/auth/internal/env/env.go | 6 +++--- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/apps/auth/internal/domain/impl.go b/apps/auth/internal/domain/impl.go index 0ab0380ec..ca7468934 100644 --- a/apps/auth/internal/domain/impl.go +++ b/apps/auth/internal/domain/impl.go @@ -203,13 +203,16 @@ func (d *domainI) verifyCaptcha(ctx context.Context, token string) (bool, error) } func (d *domainI) SignUp(ctx context.Context, name string, email string, password string, captchaToken string) (*common.AuthSession, error) { - isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) - if err != nil { - return nil, errors.Newf("failed to verify CAPTCHA: %v", err) - } - if !isValidCaptcha { - return nil, errors.New("CAPTCHA verification failed") + if d.envVars.GoogleCloudProjectId != "" && d.envVars.RecaptchaSiteKey != "" && d.envVars.GoogleApplicationCredentials != "" { + isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) + if err != nil { + return nil, errors.Newf("failed to verify CAPTCHA: %v", err) + } + + if !isValidCaptcha { + return nil, errors.New("CAPTCHA verification failed") + } } matched, err := d.userRepo.FindOne(ctx, repos.Filter{"email": email}) @@ -342,13 +345,16 @@ func (d *domainI) ResetPassword(ctx context.Context, token string, password stri } func (d *domainI) RequestResetPassword(ctx context.Context, email string, captchaToken string) (bool, error) { - isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) - if err != nil { - return false, errors.Newf("failed to verify CAPTCHA: %v", err) - } - if !isValidCaptcha { - return false, errors.New("CAPTCHA verification failed") + if d.envVars.GoogleCloudProjectId != "" && d.envVars.RecaptchaSiteKey != "" && d.envVars.GoogleApplicationCredentials != "" { + isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) + if err != nil { + return false, errors.Newf("failed to verify CAPTCHA: %v", err) + } + + if !isValidCaptcha { + return false, errors.New("CAPTCHA verification failed") + } } resetToken := generateId("reset") diff --git a/apps/auth/internal/env/env.go b/apps/auth/internal/env/env.go index 7aa0a3c5e..8339bd19a 100644 --- a/apps/auth/internal/env/env.go +++ b/apps/auth/internal/env/env.go @@ -46,9 +46,9 @@ type Env struct { VerifyTokenKVBucket string `env:"VERIFY_TOKEN_KV_BUCKET" required:"true"` ResetPasswordTokenKVBucket string `env:"RESET_PASSWORD_TOKEN_KV_BUCKET" required:"true"` - GoogleCloudProjectId string `env:"GOOGLE_CLOUD_PROJECT_ID" required:"true"` - RecaptchaSiteKey string `env:"RECAPTCHA_SITE_KEY" required:"true"` - GoogleApplicationCredentials string `env:"GOOGLE_APPLICATION_CREDENTIALS" required:"true"` + GoogleCloudProjectId string `env:"GOOGLE_CLOUD_PROJECT_ID" required:"false"` + RecaptchaSiteKey string `env:"RECAPTCHA_SITE_KEY" required:"false"` + GoogleApplicationCredentials string `env:"GOOGLE_APPLICATION_CREDENTIALS" required:"false"` IsDev bool } From 1ba1e25038475180e03384b9c7830db1f0c6c5c3 Mon Sep 17 00:00:00 2001 From: nxtcoder17 Date: Tue, 1 Oct 2024 13:13:21 +0530 Subject: [PATCH 2/3] fix: updates auth env parsing --- apps/auth/internal/env/env.go | 126 +++++++++++++++++----------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/apps/auth/internal/env/env.go b/apps/auth/internal/env/env.go index 8339bd19a..86e5e1f20 100644 --- a/apps/auth/internal/env/env.go +++ b/apps/auth/internal/env/env.go @@ -5,7 +5,7 @@ import ( "github.com/kloudlite/api/pkg/errors" ) -type Env struct { +type authEnv struct { MongoUri string `env:"MONGO_URI" required:"true"` MongoDbName string `env:"MONGO_DB_NAME" required:"true"` Port uint16 `env:"PORT" required:"true"` @@ -18,27 +18,9 @@ type Env struct { OAuth2Enabled bool `env:"OAUTH2_ENABLED" required:"true"` - OAuth2GithubEnabled bool `env:"OAUTH2_GITHUB_ENABLED" required:"false"` - GithubClientId string `env:"GITHUB_CLIENT_ID" required:"false"` - GithubClientSecret string `env:"GITHUB_CLIENT_SECRET" required:"false"` - GithubCallbackUrl string `env:"GITHUB_CALLBACK_URL" required:"false"` - GithubAppId string `env:"GITHUB_APP_ID" required:"false"` - GithubAppPKFile string `env:"GITHUB_APP_PK_FILE" required:"false"` - GithubScopes string `env:"GITHUB_SCOPES" required:"false"` - GithubWebhookUrl string `env:"GITHUB_WEBHOOK_URL" required:"false"` - - OAuth2GitlabEnabled bool `env:"OAUTH2_GITLAB_ENABLED" required:"false"` - GitlabClientId string `env:"GITLAB_CLIENT_ID" required:"false"` - GitlabClientSecret string `env:"GITLAB_CLIENT_SECRET" required:"false"` - GitlabCallbackUrl string `env:"GITLAB_CALLBACK_URL" required:"false"` - GitlabScopes string `env:"GITLAB_SCOPES" required:"false"` - GitlabWebhookUrl string `env:"GITLAB_WEBHOOK_URL" required:"false"` - - OAuth2GoogleEnabled bool `env:"OAUTH2_GOOGLE_ENABLED" required:"false"` - GoogleClientId string `env:"GOOGLE_CLIENT_ID" required:"false"` - GoogleClientSecret string `env:"GOOGLE_CLIENT_SECRET" required:"false"` - GoogleCallbackUrl string `env:"GOOGLE_CALLBACK_URL" required:"false"` - GoogleScopes string `env:"GOOGLE_SCOPES" required:"false"` + OAuth2GithubEnabled bool `env:"OAUTH2_GITHUB_ENABLED" default:"false"` + OAuth2GitlabEnabled bool `env:"OAUTH2_GITLAB_ENABLED" default:"false"` + OAuth2GoogleEnabled bool `env:"OAUTH2_GOOGLE_ENABLED" default:"false"` CommsService string `env:"COMMS_SERVICE" required:"true"` NatsURL string `env:"NATS_URL" required:"true"` @@ -46,60 +28,80 @@ type Env struct { VerifyTokenKVBucket string `env:"VERIFY_TOKEN_KV_BUCKET" required:"true"` ResetPasswordTokenKVBucket string `env:"RESET_PASSWORD_TOKEN_KV_BUCKET" required:"true"` - GoogleCloudProjectId string `env:"GOOGLE_CLOUD_PROJECT_ID" required:"false"` - RecaptchaSiteKey string `env:"RECAPTCHA_SITE_KEY" required:"false"` - GoogleApplicationCredentials string `env:"GOOGLE_APPLICATION_CREDENTIALS" required:"false"` + GoogleRecaptchaEnabled bool `env:"GOOGLE_RECAPTCHA_ENABLED" default:"false"` IsDev bool } -func (ev *Env) validateEnv() error { - if ev.OAuth2Enabled { - if ev.OAuth2GithubEnabled { - err := errors.Newf("when github oauth2 is enabled, secrets `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET`, `GITHUB_CALLBACK_URL`, `GITHUB_APP_ID`, `GITHUB_APP_PK_FILE`, `GITHUB_SCOPES` are required") - - if ev.GithubClientId == "" || - ev.GithubClientSecret == "" || - ev.GithubCallbackUrl == "" || - ev.GithubAppId == "" || - ev.GithubAppPKFile == "" || - ev.GithubScopes == "" { - return err - } - } +type githubOAuthEnv struct { + GithubClientId string `env:"GITHUB_CLIENT_ID" required:"true"` + GithubClientSecret string `env:"GITHUB_CLIENT_SECRET" required:"true"` + GithubCallbackUrl string `env:"GITHUB_CALLBACK_URL" required:"true"` + GithubAppId string `env:"GITHUB_APP_ID" required:"true"` + GithubAppPKFile string `env:"GITHUB_APP_PK_FILE" required:"true"` + GithubScopes string `env:"GITHUB_SCOPES" required:"true"` + GithubWebhookUrl string `env:"GITHUB_WEBHOOK_URL" required:"true"` +} - if ev.OAuth2GitlabEnabled { - err := errors.Newf("when gitlab oauth2 is enabled, secrets `GITLAB_CLIENT_ID`, `GITLAB_CLIENT_SECRET`, `GITLAB_CALLBACK_URL`, `GITLAB_SCOPES` are required") +type gitlabOAuthEnv struct { + GitlabClientId string `env:"GITLAB_CLIENT_ID" required:"true"` + GitlabClientSecret string `env:"GITLAB_CLIENT_SECRET" required:"true"` + GitlabCallbackUrl string `env:"GITLAB_CALLBACK_URL" required:"true"` + GitlabScopes string `env:"GITLAB_SCOPES" required:"true"` + GitlabWebhookUrl string `env:"GITLAB_WEBHOOK_URL" required:"true"` +} - if ev.GitlabClientId == "" || - ev.GitlabClientSecret == "" || - ev.GitlabCallbackUrl == "" || - ev.GitlabScopes == "" { - return errors.NewE(err) - } - } +type googleOAuthEnv struct { + GoogleClientId string `env:"GOOGLE_CLIENT_ID" required:"true"` + GoogleClientSecret string `env:"GOOGLE_CLIENT_SECRET" required:"true"` + GoogleCallbackUrl string `env:"GOOGLE_CALLBACK_URL" required:"true"` + GoogleScopes string `env:"GOOGLE_SCOPES" required:"true"` +} - if ev.OAuth2GoogleEnabled { - err := errors.Newf("when google oauth2 is enabled, secrets `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `GOOGLE_CALLBACK_URL`, `GOOGLE_SCOPES` are required") +type googleRecaptchaEnv struct { + GoogleCloudProjectId string `env:"GOOGLE_CLOUD_PROJECT_ID" required:"true"` + RecaptchaSiteKey string `env:"RECAPTCHA_SITE_KEY" required:"true"` + GoogleApplicationCredentials string `env:"GOOGLE_APPLICATION_CREDENTIALS" required:"true"` +} - if ev.GoogleClientId == "" || - ev.GoogleClientSecret == "" || - ev.GoogleCallbackUrl == "" || - ev.GoogleScopes == "" { - return errors.NewE(err) - } - } - } - return nil +type Env struct { + authEnv + githubOAuthEnv + gitlabOAuthEnv + googleOAuthEnv + googleRecaptchaEnv } func LoadEnv() (*Env, error) { var ev Env - if err := env.Set(&ev); err != nil { + + if err := env.Set(&ev.authEnv); err != nil { return nil, errors.NewE(err) } - if err := ev.validateEnv(); err != nil { - return nil, errors.NewE(err) + + if ev.OAuth2GithubEnabled { + if err := env.Set(&ev.githubOAuthEnv); err != nil { + return nil, errors.NewE(err) + } + } + + if ev.OAuth2GitlabEnabled { + if err := env.Set(&ev.gitlabOAuthEnv); err != nil { + return nil, errors.NewE(err) + } + } + + if ev.OAuth2GoogleEnabled { + if err := env.Set(&ev.googleOAuthEnv); err != nil { + return nil, errors.NewE(err) + } + } + + if ev.GoogleRecaptchaEnabled { + if err := env.Set(&ev.googleRecaptchaEnv); err != nil { + return nil, errors.NewE(err) + } } + return &ev, nil } From f1a33a104dec9a33be0984b870c93dc0fa749c59 Mon Sep 17 00:00:00 2001 From: Piyush Kumar Date: Tue, 1 Oct 2024 13:39:07 +0530 Subject: [PATCH 3/3] minor refactoring --- apps/auth/internal/app/app.go | 11 +++++++---- apps/auth/internal/domain/impl.go | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/auth/internal/app/app.go b/apps/auth/internal/app/app.go index 806d4f595..5b3894794 100644 --- a/apps/auth/internal/app/app.go +++ b/apps/auth/internal/app/app.go @@ -52,11 +52,14 @@ var Module = fx.Module( fx.Provide( func(ev *env.Env) (*recaptchaenterprise.Client, error) { - client, err := recaptchaenterprise.NewClient(context.TODO()) - if err != nil { - return nil, err + if ev.GoogleRecaptchaEnabled { + client, err := recaptchaenterprise.NewClient(context.TODO()) + if err != nil { + return nil, err + } + return client, nil } - return client, nil + return nil, nil }, ), diff --git a/apps/auth/internal/domain/impl.go b/apps/auth/internal/domain/impl.go index ca7468934..f1a492792 100644 --- a/apps/auth/internal/domain/impl.go +++ b/apps/auth/internal/domain/impl.go @@ -204,7 +204,7 @@ func (d *domainI) verifyCaptcha(ctx context.Context, token string) (bool, error) func (d *domainI) SignUp(ctx context.Context, name string, email string, password string, captchaToken string) (*common.AuthSession, error) { - if d.envVars.GoogleCloudProjectId != "" && d.envVars.RecaptchaSiteKey != "" && d.envVars.GoogleApplicationCredentials != "" { + if d.envVars.GoogleRecaptchaEnabled { isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) if err != nil { return nil, errors.Newf("failed to verify CAPTCHA: %v", err) @@ -346,7 +346,7 @@ func (d *domainI) ResetPassword(ctx context.Context, token string, password stri func (d *domainI) RequestResetPassword(ctx context.Context, email string, captchaToken string) (bool, error) { - if d.envVars.GoogleCloudProjectId != "" && d.envVars.RecaptchaSiteKey != "" && d.envVars.GoogleApplicationCredentials != "" { + if d.envVars.GoogleRecaptchaEnabled { isValidCaptcha, err := d.verifyCaptcha(ctx, captchaToken) if err != nil { return false, errors.Newf("failed to verify CAPTCHA: %v", err)