From 39c2c364d9a3db8f02b5ca42c6705c469e8c5ae8 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Fri, 22 Apr 2022 21:24:39 +0530 Subject: [PATCH] feat: add support for db username, password, host, port --- server/constants/env.go | 8 + server/db/providers/cassandradb/provider.go | 15 +- server/env/env.go | 10 +- server/go.mod | 2 +- server/go.sum | 3 +- server/graph/generated/generated.go | 196 ++++++++++++++++++++ server/graph/model/models_gen.go | 4 + server/graph/schema.graphqls | 4 + server/resolvers/env.go | 8 + server/test/resolvers_test.go | 4 +- server/test/test.go | 42 ++--- 11 files changed, 269 insertions(+), 27 deletions(-) diff --git a/server/constants/env.go b/server/constants/env.go index 66b466a..4f391a9 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -30,6 +30,14 @@ const ( EnvKeyDatabaseURL = "DATABASE_URL" // EnvKeyDatabaseName key for env variable DATABASE_NAME EnvKeyDatabaseName = "DATABASE_NAME" + // EnvKeyDatabaseUsername key for env variable DATABASE_USERNAME + EnvKeyDatabaseUsername = "DATABASE_USERNAME" + // EnvKeyDatabasePassword key for env variable DATABASE_PASSWORD + EnvKeyDatabasePassword = "DATABASE_PASSWORD" + // EnvKeyDatabasePort key for env variable DATABASE_PORT + EnvKeyDatabasePort = "DATABASE_PORT" + // EnvKeyDatabaseHost key for env variable DATABASE_HOST + EnvKeyDatabaseHost = "DATABASE_HOST" // EnvKeySmtpHost key for env variable SMTP_HOST EnvKeySmtpHost = "SMTP_HOST" // EnvKeySmtpPort key for env variable SMTP_PORT diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go index 8e12c40..4c41870 100644 --- a/server/db/providers/cassandradb/provider.go +++ b/server/db/providers/cassandradb/provider.go @@ -3,6 +3,7 @@ package cassandradb import ( "fmt" "log" + "strings" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/db/models" @@ -21,7 +22,19 @@ var KeySpace string func NewProvider() (*provider, error) { dbURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL) KeySpace = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName) - cassandraClient := cansandraDriver.NewCluster(dbURL) + clusterURL := []string{} + if strings.Contains(dbURL, ",") { + clusterURL = strings.Split(dbURL, ",") + } else { + clusterURL = append(clusterURL, dbURL) + } + cassandraClient := cansandraDriver.NewCluster(clusterURL...) + if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseUsername) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePassword) != "" { + cassandraClient.Authenticator = &cansandraDriver.PasswordAuthenticator{ + Username: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseUsername), + Password: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePassword), + } + } cassandraClient.RetryPolicy = &cansandraDriver.SimpleRetryPolicy{ NumRetries: 3, diff --git a/server/env/env.go b/server/env/env.go index 7202d9b..aeb5c27 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -38,6 +38,10 @@ func InitRequiredEnv() error { dbURL := os.Getenv(constants.EnvKeyDatabaseURL) dbType := os.Getenv(constants.EnvKeyDatabaseType) dbName := os.Getenv(constants.EnvKeyDatabaseName) + dbPort := os.Getenv(constants.EnvKeyDatabasePort) + dbHost := os.Getenv(constants.EnvKeyDatabaseHost) + dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername) + dbPassword := os.Getenv(constants.EnvKeyDatabasePassword) if strings.TrimSpace(dbType) == "" { if envstore.ARG_DB_TYPE != nil && *envstore.ARG_DB_TYPE != "" { @@ -54,7 +58,7 @@ func InitRequiredEnv() error { dbURL = strings.TrimSpace(*envstore.ARG_DB_URL) } - if dbURL == "" { + if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" { return errors.New("invalid database url. DATABASE_URL is required") } } @@ -69,6 +73,10 @@ func InitRequiredEnv() error { envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseURL, dbURL) envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseType, dbType) envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseName, dbName) + envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseHost, dbHost) + envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePort, dbPort) + envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseUsername, dbUsername) + envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePassword, dbPassword) return nil } diff --git a/server/go.mod b/server/go.mod index d72588a..7c341f5 100644 --- a/server/go.mod +++ b/server/go.mod @@ -9,7 +9,7 @@ require ( github.com/gin-gonic/gin v1.7.2 github.com/go-playground/validator/v10 v10.8.0 // indirect github.com/go-redis/redis/v8 v8.11.0 - github.com/gocql/gocql v1.0.0 // indirect + github.com/gocql/gocql v1.0.0 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 diff --git a/server/go.sum b/server/go.sum index 983aa42..e386cbd 100644 --- a/server/go.sum +++ b/server/go.sum @@ -48,7 +48,9 @@ github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2 github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= @@ -144,7 +146,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index e33e660..c8cb538 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -61,9 +61,13 @@ type ComplexityRoot struct { ClientSecret func(childComplexity int) int CookieName func(childComplexity int) int CustomAccessTokenScript func(childComplexity int) int + DatabaseHost func(childComplexity int) int DatabaseName func(childComplexity int) int + DatabasePassword func(childComplexity int) int + DatabasePort func(childComplexity int) int DatabaseType func(childComplexity int) int DatabaseURL func(childComplexity int) int + DatabaseUsername func(childComplexity int) int DefaultRoles func(childComplexity int) int DisableBasicAuthentication func(childComplexity int) int DisableEmailVerification func(childComplexity int) int @@ -356,6 +360,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Env.CustomAccessTokenScript(childComplexity), true + case "Env.DATABASE_HOST": + if e.complexity.Env.DatabaseHost == nil { + break + } + + return e.complexity.Env.DatabaseHost(childComplexity), true + case "Env.DATABASE_NAME": if e.complexity.Env.DatabaseName == nil { break @@ -363,6 +374,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Env.DatabaseName(childComplexity), true + case "Env.DATABASE_PASSWORD": + if e.complexity.Env.DatabasePassword == nil { + break + } + + return e.complexity.Env.DatabasePassword(childComplexity), true + + case "Env.DATABASE_PORT": + if e.complexity.Env.DatabasePort == nil { + break + } + + return e.complexity.Env.DatabasePort(childComplexity), true + case "Env.DATABASE_TYPE": if e.complexity.Env.DatabaseType == nil { break @@ -377,6 +402,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Env.DatabaseURL(childComplexity), true + case "Env.DATABASE_USERNAME": + if e.complexity.Env.DatabaseUsername == nil { + break + } + + return e.complexity.Env.DatabaseUsername(childComplexity), true + case "Env.DEFAULT_ROLES": if e.complexity.Env.DefaultRoles == nil { break @@ -1394,6 +1426,10 @@ type Env { DATABASE_NAME: String! DATABASE_URL: String! DATABASE_TYPE: String! + DATABASE_USERNAME: String! + DATABASE_PASSWORD: String! + DATABASE_HOST: String! + DATABASE_PORT: String! CLIENT_ID: String! CLIENT_SECRET: String! CUSTOM_ACCESS_TOKEN_SCRIPT: String @@ -2400,6 +2436,146 @@ func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Env", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DatabaseUsername, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Env", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DatabasePassword, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Env", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DatabaseHost, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Env", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DatabasePort, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -8780,6 +8956,26 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj if out.Values[i] == graphql.Null { invalids++ } + case "DATABASE_USERNAME": + out.Values[i] = ec._Env_DATABASE_USERNAME(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "DATABASE_PASSWORD": + out.Values[i] = ec._Env_DATABASE_PASSWORD(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "DATABASE_HOST": + out.Values[i] = ec._Env_DATABASE_HOST(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "DATABASE_PORT": + out.Values[i] = ec._Env_DATABASE_PORT(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } case "CLIENT_ID": out.Values[i] = ec._Env_CLIENT_ID(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 09468b4..1660c9c 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -29,6 +29,10 @@ type Env struct { DatabaseName string `json:"DATABASE_NAME"` DatabaseURL string `json:"DATABASE_URL"` DatabaseType string `json:"DATABASE_TYPE"` + DatabaseUsername string `json:"DATABASE_USERNAME"` + DatabasePassword string `json:"DATABASE_PASSWORD"` + DatabaseHost string `json:"DATABASE_HOST"` + DatabasePort string `json:"DATABASE_PORT"` ClientID string `json:"CLIENT_ID"` ClientSecret string `json:"CLIENT_SECRET"` CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"` diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 841ad8c..d3673cd 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -92,6 +92,10 @@ type Env { DATABASE_NAME: String! DATABASE_URL: String! DATABASE_TYPE: String! + DATABASE_USERNAME: String! + DATABASE_PASSWORD: String! + DATABASE_HOST: String! + DATABASE_PORT: String! CLIENT_ID: String! CLIENT_SECRET: String! CUSTOM_ACCESS_TOKEN_SCRIPT: String diff --git a/server/resolvers/env.go b/server/resolvers/env.go index dc7db8d..b8c2d3d 100644 --- a/server/resolvers/env.go +++ b/server/resolvers/env.go @@ -34,6 +34,10 @@ func EnvResolver(ctx context.Context) (*model.Env, error) { databaseURL := store.StringEnv[constants.EnvKeyDatabaseURL] databaseName := store.StringEnv[constants.EnvKeyDatabaseName] databaseType := store.StringEnv[constants.EnvKeyDatabaseType] + databaseUsername := store.StringEnv[constants.EnvKeyDatabaseUsername] + databasePassword := store.StringEnv[constants.EnvKeyDatabasePassword] + databaseHost := store.StringEnv[constants.EnvKeyDatabaseHost] + databasePort := store.StringEnv[constants.EnvKeyDatabasePort] customAccessTokenScript := store.StringEnv[constants.EnvKeyCustomAccessTokenScript] smtpHost := store.StringEnv[constants.EnvKeySmtpHost] smtpPort := store.StringEnv[constants.EnvKeySmtpPort] @@ -77,6 +81,10 @@ func EnvResolver(ctx context.Context) (*model.Env, error) { DatabaseName: databaseName, DatabaseURL: databaseURL, DatabaseType: databaseType, + DatabaseUsername: databaseUsername, + DatabasePassword: databasePassword, + DatabaseHost: databaseHost, + DatabasePort: databasePort, ClientID: clientID, ClientSecret: clientSecret, CustomAccessTokenScript: &customAccessTokenScript, diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index 513c1b0..84a5c76 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -11,10 +11,10 @@ import ( func TestResolvers(t *testing.T) { databases := map[string]string{ - constants.DbTypeSqlite: "../../data.db", + // constants.DbTypeSqlite: "../../data.db", // constants.DbTypeArangodb: "http://localhost:8529", // constants.DbTypeMongodb: "mongodb://localhost:27017", - // constants.DbTypeCassandraDB: "127.0.0.1:9042", + constants.DbTypeCassandraDB: "127.0.0.1:9042", } for dbType, dbURL := range databases { diff --git a/server/test/test.go b/server/test/test.go index c4cb14f..2c673b6 100644 --- a/server/test/test.go +++ b/server/test/test.go @@ -31,31 +31,31 @@ type TestSetup struct { } func cleanData(email string) { - verificationRequest, err := db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeBasicAuthSignup) - if err == nil { - err = db.Provider.DeleteVerificationRequest(verificationRequest) - } + // verificationRequest, err := db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeBasicAuthSignup) + // if err == nil { + // err = db.Provider.DeleteVerificationRequest(verificationRequest) + // } - verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeForgotPassword) - if err == nil { - err = db.Provider.DeleteVerificationRequest(verificationRequest) - } + // verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeForgotPassword) + // if err == nil { + // err = db.Provider.DeleteVerificationRequest(verificationRequest) + // } - verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeUpdateEmail) - if err == nil { - err = db.Provider.DeleteVerificationRequest(verificationRequest) - } + // verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeUpdateEmail) + // if err == nil { + // err = db.Provider.DeleteVerificationRequest(verificationRequest) + // } - verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeMagicLinkLogin) - if err == nil { - err = db.Provider.DeleteVerificationRequest(verificationRequest) - } + // verificationRequest, err = db.Provider.GetVerificationRequestByEmail(email, constants.VerificationTypeMagicLinkLogin) + // if err == nil { + // err = db.Provider.DeleteVerificationRequest(verificationRequest) + // } - dbUser, err := db.Provider.GetUserByEmail(email) - if err == nil { - db.Provider.DeleteUser(dbUser) - db.Provider.DeleteSession(dbUser.ID) - } + // dbUser, err := db.Provider.GetUserByEmail(email) + // if err == nil { + // db.Provider.DeleteUser(dbUser) + // db.Provider.DeleteSession(dbUser.ID) + // } } func createContext(s TestSetup) (*http.Request, context.Context) {