diff --git a/.env.test b/.env.test index 8bde4b4..50124dc 100644 --- a/.env.test +++ b/.env.test @@ -10,5 +10,4 @@ SMTP_HOST=smtp.mailtrap.io SMTP_PORT=2525 SMTP_USERNAME=test SMTP_PASSWORD=test -SENDER_EMAIL="info@authorizer.dev" -AWS_REGION=ap-south-1 \ No newline at end of file +SENDER_EMAIL="info@authorizer.dev" \ No newline at end of file diff --git a/couchbase.env b/couchbase.env new file mode 100644 index 0000000..d28bc0b --- /dev/null +++ b/couchbase.env @@ -0,0 +1,14 @@ + +ENV=test +DATABASE_TYPE=couchbase +COUCHBASE_SCOPE=_default +DATABASE_USERNAME=admin +DATABASE_PASSWORD=123456 +COUCHBASE_BUCKET=auth +DATABASE_URL=couchbase://127.0.0.1 +CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}" +SMTP_HOST=smtp.mailtrap.io +SMTP_PORT=2525 +SMTP_USERNAME=test +SMTP_PASSWORD=test +SENDER_EMAIL="info@authorizer.dev" \ No newline at end of file diff --git a/server/db/db.go b/server/db/db.go index 3a1c018..f83fe2f 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -1,6 +1,8 @@ package db import ( + "fmt" + log "github.com/sirupsen/logrus" "github.com/authorizerdev/authorizer/server/constants" @@ -19,6 +21,7 @@ var Provider providers.Provider func InitDB() error { var err error + fmt.Println("isCouchbaseDB::: InitDB") envs := memorystore.RequiredEnvStoreObj.GetRequiredEnv() @@ -77,11 +80,13 @@ func InitDB() error { if isCouchbaseDB { log.Info("Initializing CouchbaseDB Driver for: ", envs.DatabaseType) Provider, err = couchbase.NewProvider() + fmt.Println("isCouchbaseDB", Provider) if err != nil { log.Fatal("Failed to initialize Couchbase driver: ", err) return err } } + fmt.Println("isCouchbaseDB:::", Provider) return nil } diff --git a/server/db/providers/couchbase/otp.go b/server/db/providers/couchbase/otp.go index dac3766..013239a 100644 --- a/server/db/providers/couchbase/otp.go +++ b/server/db/providers/couchbase/otp.go @@ -63,7 +63,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models return otp, err } } else { - query := fmt.Sprintf(`UPDATE auth._default.%s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID) + query := fmt.Sprintf(`UPDATE auth._default.%s SET otp="%s", expires_at=%d, updated_at=%d WHERE _id="%s"`, models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID) scope := p.db.Scope("_default") _, err := scope.Query(query, &gocb.QueryOptions{}) if err != nil { diff --git a/server/db/providers/couchbase/provider.go b/server/db/providers/couchbase/provider.go index 97a83d4..f8710c0 100644 --- a/server/db/providers/couchbase/provider.go +++ b/server/db/providers/couchbase/provider.go @@ -1,12 +1,10 @@ package couchbase import ( - "context" + "fmt" "os" - "reflect" "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/couchbase/gocb/v2" ) @@ -19,12 +17,12 @@ type provider struct { // NewProvider returns a new SQL provider // TODO change following provider to new db provider func NewProvider() (*provider, error) { - scopeName := os.Getenv(constants.EnvCouchbaseScope) + // scopeName := os.Getenv(constants.EnvCouchbaseScope) bucketName := os.Getenv(constants.EnvCouchbaseBucket) dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL userName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseUsername password := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePassword - + fmt.Println("dbURL", dbURL, userName, password) opts := gocb.ClusterOptions{ Username: userName, Password: password, @@ -35,20 +33,28 @@ func NewProvider() (*provider, error) { return nil, err } bucket := cluster.Bucket(bucketName) + // fmt.Println("1 called in oprovuider") - v := reflect.ValueOf(models.Collections) - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - user := gocb.CollectionSpec{ - Name: field.String(), - ScopeName: scopeName, - } - collectionOpts := gocb.CreateCollectionOptions{ - Context: context.TODO(), - } - _ = bucket.Collections().CreateCollection(user, &collectionOpts) - } + // v := reflect.ValueOf(models.Collections) + // fmt.Println("called in v", v) + // for i := 0; i < v.NumField(); i++ { + + // field := v.Field(i) + // fmt.Println("called in v", field) + + // user := gocb.CollectionSpec{ + // Name: field.String(), + // ScopeName: scopeName, + // } + // collectionOpts := gocb.CreateCollectionOptions{ + // Context: context.TODO(), + // } + // err = bucket.Collections().CreateCollection(user, &collectionOpts) + // fmt.Println("2 called in oprovuider", err) + + // } + // fmt.Println("called in oprovuider") return &provider{ db: bucket, }, nil diff --git a/server/db/providers/couchbase/user.go b/server/db/providers/couchbase/user.go index a5b356e..78544ac 100644 --- a/server/db/providers/couchbase/user.go +++ b/server/db/providers/couchbase/user.go @@ -80,9 +80,12 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) ( paginationClone := pagination inventoryScope := p.db.Scope("_default") - userQuery := fmt.Sprintf("SELECT * FROM auth._default.%s ORDER BY id OFFSET %d LIMIT %d", models.Collections.User, paginationClone.Offset, paginationClone.Limit) + userQuery := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM auth._default.%s ORDER BY id OFFSET %d LIMIT %d", models.Collections.User, paginationClone.Offset, paginationClone.Limit) - queryResult, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{}) + queryResult, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + Context: ctx, + }) if err != nil { return nil, err @@ -113,7 +116,10 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use user := models.User{} scope := p.db.Scope("_default") query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM auth._default.%s WHERE email = '%s' LIMIT 1", models.Collections.User, email) - q, err := scope.Query(query, &gocb.QueryOptions{}) + q, err := scope.Query(query, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + Context: ctx, + }) if err != nil { return user, err @@ -131,7 +137,10 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err user := models.User{} scope := p.db.Scope("_default") query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM auth._default.%s WHERE _id = '%s' LIMIT 1", models.Collections.User, id) - q, err := scope.Query(query, &gocb.QueryOptions{}) + q, err := scope.Query(query, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + Context: ctx, + }) if err != nil { return user, err } @@ -150,7 +159,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, data["updated_at"] = time.Now().Unix() inventoryScope := p.db.Scope("_default") - updateFields := "" + upf := "" for key, value := range data { if key == "_id" { continue @@ -161,30 +170,37 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, } if value == nil { - updateFields += fmt.Sprintf("%s = null,", key) + upf += fmt.Sprintf("%s = null,", key) continue } valueType := reflect.TypeOf(value) if valueType.Name() == "string" { - updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string)) + upf += fmt.Sprintf("%s = '%s', ", key, value.(string)) } else { - updateFields += fmt.Sprintf("%s = %v, ", key, value) + upf += fmt.Sprintf("%s = %v, ", key, value) } } + updateFields := removeLastRune(upf) if ids != nil && len(ids) > 0 { for _, v := range ids { - userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE id = '%s'", models.Collections.User, updateFields, v) + userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE _id = '%s'", models.Collections.User, updateFields, v) - _, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{}) + _, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + Context: ctx, + }) if err != nil { return err } } } else { - userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE id IS NOT NULL", models.Collections.User, updateFields) - _, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{}) + userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE _id IS NOT NULL", models.Collections.User, updateFields) + _, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{ + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + Context: ctx, + }) if err != nil { return err } @@ -192,3 +208,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, return nil } + +func removeLastRune(s string) string { + return s[:len(s)-2] +} diff --git a/server/db/providers/couchbase/verification_requests.go b/server/db/providers/couchbase/verification_requests.go index 7456e3c..53373bf 100644 --- a/server/db/providers/couchbase/verification_requests.go +++ b/server/db/providers/couchbase/verification_requests.go @@ -43,6 +43,7 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri queryResult, err := scope.Query(query, &gocb.QueryOptions{ Context: ctx, PositionalParameters: []interface{}{token}, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, }) if err != nil { @@ -66,6 +67,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri queryResult, err := scope.Query(query, &gocb.QueryOptions{ Context: ctx, PositionalParameters: []interface{}{email, identifier}, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, }) verificationRequest := models.VerificationRequest{} @@ -88,7 +90,10 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode paginationClone := pagination query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.VerificationRequest, paginationClone.Offset, paginationClone.Limit) - queryResult, err := scope.Query(query, &gocb.QueryOptions{}) + queryResult, err := scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err diff --git a/server/db/providers/couchbase/webhook.go b/server/db/providers/couchbase/webhook.go index 7414995..02e47c1 100644 --- a/server/db/providers/couchbase/webhook.go +++ b/server/db/providers/couchbase/webhook.go @@ -79,7 +79,10 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (* updateFields = strings.TrimSuffix(updateFields, ",") query := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE _id = '%s'", models.Collections.Webhook, updateFields, webhook.ID) - _, err = scope.Query(query, &gocb.QueryOptions{}) + _, err = scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err @@ -95,7 +98,10 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) paginationClone := pagination query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.Webhook, paginationClone.Offset, paginationClone.Limit) - queryResult, err := scope.Query(query, &gocb.QueryOptions{}) + queryResult, err := scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err @@ -124,7 +130,10 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model var webhook models.Webhook scope := p.db.Scope("_default") query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM auth._default.%s WHERE _id = '%s' LIMIT 1`, models.Collections.Webhook, webhookID) - q, err := scope.Query(query, &gocb.QueryOptions{}) + q, err := scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err } @@ -142,7 +151,10 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) var webhook models.Webhook scope := p.db.Scope("_default") query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM auth._default.%s WHERE event_name = '%s' LIMIT 1`, models.Collections.Webhook, eventName) - q, err := scope.Query(query, &gocb.QueryOptions{}) + q, err := scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err @@ -158,12 +170,26 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) // DeleteWebhook to delete webhook func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error { + fmt.Println("trying to dlete webhooks logs", webhook.EventName) + scope := p.db.Scope("_default") removeOpt := gocb.RemoveOptions{ Context: ctx, } _, err := p.db.Collection(models.Collections.Webhook).Remove(webhook.ID, &removeOpt) + if err != nil { return err } + + query := fmt.Sprintf(`DELETE FROM auth._default.%s WHERE webhook_id=%s`, models.Collections.WebhookLog, webhook.ID) + fmt.Println("") + _, err = scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) + if err != nil { + return err + } + return nil } diff --git a/server/db/providers/couchbase/webhook_log.go b/server/db/providers/couchbase/webhook_log.go index b7d046f..a576367 100644 --- a/server/db/providers/couchbase/webhook_log.go +++ b/server/db/providers/couchbase/webhook_log.go @@ -39,7 +39,10 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat scope := p.db.Scope("_default") paginationClone := pagination query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.Env, paginationClone.Offset, paginationClone.Limit) - queryResult, err := scope.Query(query, &gocb.QueryOptions{}) + queryResult, err := scope.Query(query, &gocb.QueryOptions{ + Context: ctx, + ScanConsistency: gocb.QueryScanConsistencyRequestPlus, + }) if err != nil { return nil, err diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index d5cd071..d5edda1 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -74,6 +74,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR log := log.WithFields(log.Fields{ "email": params.Email, }) + time.Sleep(500 * time.Millisecond) // find user with email existingUser, err := db.Provider.GetUserByEmail(ctx, params.Email) if err != nil { diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go index b792adb..04503ba 100644 --- a/server/resolvers/verify_otp.go +++ b/server/resolvers/verify_otp.go @@ -31,7 +31,6 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod log.Debug("Failed to get otp request by email: ", err) return res, fmt.Errorf(`invalid email: %s`, err.Error()) } - if params.Otp != otp.Otp { log.Debug("Failed to verify otp request: Incorrect value") return res, fmt.Errorf(`invalid otp`) diff --git a/server/test/forgot_password_test.go b/server/test/forgot_password_test.go index cd09a0a..60c41bc 100644 --- a/server/test/forgot_password_test.go +++ b/server/test/forgot_password_test.go @@ -2,6 +2,7 @@ package test import ( "testing" + "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" @@ -21,6 +22,7 @@ func forgotPasswordTest(t *testing.T, s TestSetup) { ConfirmPassword: s.TestInfo.Password, }) + time.Sleep(500 * time.Millisecond) _, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{ Email: email, }) diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index a35b754..60eb9b4 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -5,7 +5,6 @@ import ( "os" "strings" "testing" - "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" @@ -37,7 +36,7 @@ func TestResolvers(t *testing.T) { } else { t.Log("waiting for docker containers to start...") // wait for docker containers to spun up - time.Sleep(30 * time.Second) + // time.Sleep(30 * time.Second) } testDb := "authorizer_test" diff --git a/server/test/signup_test.go b/server/test/signup_test.go index a66906c..6c67a25 100644 --- a/server/test/signup_test.go +++ b/server/test/signup_test.go @@ -1,6 +1,7 @@ package test import ( + "fmt" "testing" "github.com/authorizerdev/authorizer/server/constants" @@ -55,6 +56,9 @@ func signupTests(t *testing.T, s TestSetup) { ConfirmPassword: s.TestInfo.Password, }) + fmt.Println("err", err) + fmt.Println("res", res) + assert.NotNil(t, err, "should throw duplicate email error") verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup) diff --git a/server/test/test.go b/server/test/test.go index 1fb6492..c9b510f 100644 --- a/server/test/test.go +++ b/server/test/test.go @@ -108,8 +108,10 @@ func testSetup() TestSetup { memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpPassword, "test") memorystore.Provider.UpdateEnvVariable(constants.EnvKeySenderEmail, "info@yopmail.com") memorystore.Provider.UpdateEnvVariable(constants.EnvKeyProtectedRoles, "admin") + fmt.Println("called test suite before") err = db.InitDB() + fmt.Println("called test suite") if err != nil { log.Fatal("Error loading db: ", err) } diff --git a/server/test/update_all_users_tests.go b/server/test/update_all_users_tests.go index 6473908..b7f61d4 100644 --- a/server/test/update_all_users_tests.go +++ b/server/test/update_all_users_tests.go @@ -3,6 +3,7 @@ package test import ( "fmt" "testing" + "time" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db" @@ -41,9 +42,12 @@ func updateAllUsersTest(t *testing.T, s TestSetup) { Offset: 0, }) assert.NoError(t, err) + time.Sleep(500 * time.Millisecond) + for _, u := range listUsers.Users { assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled)) } + time.Sleep(1 * time.Second) // // update few users updateIds := []string{listUsers.Users[0].ID, listUsers.Users[1].ID} diff --git a/server/test/webhook_logs_test.go b/server/test/webhook_logs_test.go index 8b9a04a..d34f9ce 100644 --- a/server/test/webhook_logs_test.go +++ b/server/test/webhook_logs_test.go @@ -25,7 +25,12 @@ func webhookLogsTest(t *testing.T, s TestSetup) { assert.NoError(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h)) + time.Sleep(1 * time.Second) webhookLogs, err := resolvers.WebhookLogsResolver(ctx, nil) + fmt.Printf("webhookLogs=========== %+v \n", webhookLogs.WebhookLogs) + time.Sleep(20 * time.Second) + fmt.Println("total documents found", len(webhookLogs.WebhookLogs)) + assert.NoError(t, err) assert.Greater(t, len(webhookLogs.WebhookLogs), 1)