From 38419a4ef4116654540d7c9ddff9ec454236a345 Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Thu, 20 Jan 2022 16:52:37 +0530 Subject: [PATCH] fix: rename config -> env and handle env interface better --- server/constants/env.go | 8 + server/db/arangodb.go | 18 +-- server/db/config.go | 161 ------------------- server/db/db.go | 30 ++-- server/db/env.go | 161 +++++++++++++++++++ server/db/mongodb.go | 6 +- server/db/user.go | 2 +- server/email/email.go | 8 +- server/email/forgot_password_email.go | 8 +- server/email/verification_email.go | 6 +- server/env/env.go | 181 +++++++++++----------- server/env/persist_env.go | 105 ++++++------- server/envstore/store.go | 87 ++++++++--- server/handlers/app.go | 8 +- server/handlers/dashboard.go | 2 +- server/handlers/oauth_callback.go | 4 +- server/handlers/oauth_login.go | 10 +- server/main.go | 4 +- server/middlewares/context.go | 4 +- server/oauth/oauth.go | 24 +-- server/resolvers/admin_login.go | 2 +- server/resolvers/admin_session.go | 2 +- server/resolvers/admin_signup.go | 18 +-- server/resolvers/env.go | 66 ++++---- server/resolvers/forgot_password.go | 2 +- server/resolvers/login.go | 4 +- server/resolvers/magic_link_login.go | 10 +- server/resolvers/reset_password.go | 2 +- server/resolvers/session.go | 2 +- server/resolvers/signup.go | 11 +- server/resolvers/update_env.go | 36 +++-- server/resolvers/update_user.go | 2 +- server/routes/routes.go | 2 +- server/session/session.go | 4 +- server/test/admin_login_test.go | 2 +- server/test/admin_logout_test.go | 4 +- server/test/admin_session_test.go | 4 +- server/test/admin_signup_test.go | 2 +- server/test/delete_user_test.go | 4 +- server/test/env_file_test.go | 26 ++-- server/test/env_test.go | 10 +- server/test/logout_test.go | 2 +- server/test/magic_link_login_test.go | 2 +- server/test/profile_test.go | 2 +- server/test/resolvers_test.go | 16 +- server/test/session_test.go | 2 +- server/test/test.go | 4 +- server/test/update_config_test.go | 44 ------ server/test/update_env_test.go | 54 +++++++ server/test/update_profile_test.go | 2 +- server/test/update_user_test.go | 4 +- server/test/users_test.go | 4 +- server/test/validator_test.go | 4 +- server/test/verification_requests_test.go | 4 +- server/utils/auth_token.go | 12 +- server/utils/cookie.go | 30 ++-- server/utils/crypto.go | 6 +- server/utils/meta.go | 14 +- server/utils/validator.go | 12 +- server/utils/verification_token.go | 8 +- 60 files changed, 668 insertions(+), 610 deletions(-) delete mode 100644 server/db/config.go create mode 100644 server/db/env.go delete mode 100644 server/test/update_config_test.go create mode 100644 server/test/update_env_test.go diff --git a/server/constants/env.go b/server/constants/env.go index ddff7b4..8c71105 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -1,6 +1,14 @@ package constants const ( + // Envstore identifier + // StringStore string store identifier + StringStoreIdentifier = "stringStore" + // BoolStore bool store identifier + BoolStoreIdentifier = "boolStore" + // SliceStore slice store identifier + SliceStoreIdentifier = "sliceStore" + // EnvKeyEnv key for env variable ENV EnvKeyEnv = "ENV" // EnvKeyEnvPath key for cli arg variable ENV_PATH diff --git a/server/db/arangodb.go b/server/db/arangodb.go index d7cfd64..85b33b0 100644 --- a/server/db/arangodb.go +++ b/server/db/arangodb.go @@ -18,7 +18,7 @@ import ( func initArangodb() (arangoDriver.Database, error) { ctx := context.Background() conn, err := http.NewConnection(http.ConnectionConfig{ - Endpoints: []string{envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)}, + Endpoints: []string{envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)}, }) if err != nil { return nil, err @@ -33,16 +33,16 @@ func initArangodb() (arangoDriver.Database, error) { var arangodb driver.Database - arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string)) + arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)) if arangodb_exists { - log.Println(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string) + " db exists already") - arangodb, err = arangoClient.Database(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string)) + log.Println(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName) + " db exists already") + arangodb, err = arangoClient.Database(nil, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)) if err != nil { return nil, err } } else { - arangodb, err = arangoClient.CreateDatabase(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string), nil) + arangodb, err = arangoClient.CreateDatabase(nil, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName), nil) if err != nil { return nil, err } @@ -101,13 +101,13 @@ func initArangodb() (arangoDriver.Database, error) { Sparse: true, }) - configCollectionExists, err := arangodb.CollectionExists(ctx, Collections.Config) + configCollectionExists, err := arangodb.CollectionExists(ctx, Collections.Env) if configCollectionExists { - log.Println(Collections.Config + " collection exists already") + log.Println(Collections.Env + " collection exists already") } else { - _, err = arangodb.CreateCollection(ctx, Collections.Config, nil) + _, err = arangodb.CreateCollection(ctx, Collections.Env, nil) if err != nil { - log.Println("error creating collection("+Collections.Config+"):", err) + log.Println("error creating collection("+Collections.Env+"):", err) } } diff --git a/server/db/config.go b/server/db/config.go deleted file mode 100644 index d4f724a..0000000 --- a/server/db/config.go +++ /dev/null @@ -1,161 +0,0 @@ -package db - -import ( - "fmt" - "log" - "time" - - arangoDriver "github.com/arangodb/go-driver" - "github.com/google/uuid" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo/options" -) - -type Config struct { - Key string `json:"_key,omitempty" bson:"_key"` // for arangodb - ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id"` - Config []byte `gorm:"type:text" json:"config" bson:"config"` - Hash string `gorm:"type:hash" json:"hash" bson:"hash"` - UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"` - CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"` -} - -// AddConfig function to add config -func (mgr *manager) AddConfig(config Config) (Config, error) { - if config.ID == "" { - config.ID = uuid.New().String() - } - - if IsORMSupported { - // copy id as value for fields required for mongodb & arangodb - config.Key = config.ID - result := mgr.sqlDB.Create(&config) - - if result.Error != nil { - log.Println("error adding config:", result.Error) - return config, result.Error - } - } - - if IsArangoDB { - config.CreatedAt = time.Now().Unix() - config.UpdatedAt = time.Now().Unix() - configCollection, _ := mgr.arangodb.Collection(nil, Collections.Config) - meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(nil), config) - if err != nil { - log.Println("error adding config:", err) - return config, err - } - config.Key = meta.Key - config.ID = meta.ID.String() - } - - if IsMongoDB { - config.CreatedAt = time.Now().Unix() - config.UpdatedAt = time.Now().Unix() - config.Key = config.ID - configCollection := mgr.mongodb.Collection(Collections.Config, options.Collection()) - _, err := configCollection.InsertOne(nil, config) - if err != nil { - log.Println("error adding config:", err) - return config, err - } - } - - return config, nil -} - -// UpdateConfig function to update config -func (mgr *manager) UpdateConfig(config Config) (Config, error) { - config.UpdatedAt = time.Now().Unix() - - if IsORMSupported { - result := mgr.sqlDB.Save(&config) - - if result.Error != nil { - log.Println("error updating config:", result.Error) - return config, result.Error - } - } - - if IsArangoDB { - collection, _ := mgr.arangodb.Collection(nil, Collections.Config) - meta, err := collection.UpdateDocument(nil, config.Key, config) - if err != nil { - log.Println("error updating config:", err) - return config, err - } - - config.Key = meta.Key - config.ID = meta.ID.String() - } - - if IsMongoDB { - configCollection := mgr.mongodb.Collection(Collections.Config, options.Collection()) - _, err := configCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": config.ID}}, bson.M{"$set": config}, options.MergeUpdateOptions()) - if err != nil { - log.Println("error updating config:", err) - return config, err - } - } - - return config, nil -} - -// GetConfig function to get config -func (mgr *manager) GetConfig() (Config, error) { - var config Config - - if IsORMSupported { - result := mgr.sqlDB.First(&config) - - if result.Error != nil { - return config, result.Error - } - } - - if IsArangoDB { - query := fmt.Sprintf("FOR d in %s RETURN d", Collections.Config) - - cursor, err := mgr.arangodb.Query(nil, query, nil) - if err != nil { - return config, err - } - defer cursor.Close() - - for { - if !cursor.HasMore() { - if config.Key == "" { - return config, fmt.Errorf("config not found") - } - break - } - _, err := cursor.ReadDocument(nil, &config) - if err != nil { - return config, err - } - } - } - - if IsMongoDB { - configCollection := mgr.mongodb.Collection(Collections.Config, options.Collection()) - cursor, err := configCollection.Find(nil, bson.M{}, options.Find()) - if err != nil { - return config, err - } - defer cursor.Close(nil) - - for cursor.Next(nil) { - err := cursor.Decode(&config) - if err != nil { - return config, err - } - } - - if config.ID == "" { - return config, fmt.Errorf("config not found") - } - } - - return config, nil -} diff --git a/server/db/db.go b/server/db/db.go index 5ba6da2..25d1ddc 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -29,9 +29,9 @@ type Manager interface { GetVerificationByEmail(email string, identifier string) (VerificationRequest, error) AddSession(session Session) error DeleteUserSession(userId string) error - AddConfig(config Config) (Config, error) - UpdateConfig(config Config) (Config, error) - GetConfig() (Config, error) + AddEnv(env Env) (Env, error) + UpdateEnv(env Env) (Env, error) + GetEnv() (Env, error) } type manager struct { @@ -45,7 +45,7 @@ type CollectionList struct { User string VerificationRequest string Session string - Config string + Env string } var ( @@ -58,7 +58,7 @@ var ( User: Prefix + "users", VerificationRequest: Prefix + "verification_requests", Session: Prefix + "sessions", - Config: Prefix + "config", + Env: Prefix + "env", } ) @@ -66,9 +66,9 @@ func InitDB() { var sqlDB *gorm.DB var err error - IsORMSupported = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) != constants.DbTypeArangodb && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) != constants.DbTypeMongodb - IsArangoDB = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) == constants.DbTypeArangodb - IsMongoDB = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) == constants.DbTypeMongodb + IsORMSupported = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) != constants.DbTypeArangodb && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) != constants.DbTypeMongodb + IsArangoDB = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeArangodb + IsMongoDB = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeMongodb // sql db orm config ormConfig := &gorm.Config{ @@ -77,20 +77,20 @@ func InitDB() { }, } - log.Println("db type:", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string)) + log.Println("db type:", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType)) - switch envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) { + switch envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) { case constants.DbTypePostgres: - sqlDB, err = gorm.Open(postgres.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig) + sqlDB, err = gorm.Open(postgres.Open(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) break case constants.DbTypeSqlite: - sqlDB, err = gorm.Open(sqlite.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig) + sqlDB, err = gorm.Open(sqlite.Open(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) break case constants.DbTypeMysql: - sqlDB, err = gorm.Open(mysql.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig) + sqlDB, err = gorm.Open(mysql.Open(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) break case constants.DbTypeSqlserver: - sqlDB, err = gorm.Open(sqlserver.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig) + sqlDB, err = gorm.Open(sqlserver.Open(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) break case constants.DbTypeArangodb: arangodb, err := initArangodb() @@ -123,7 +123,7 @@ func InitDB() { if err != nil { log.Fatal("Failed to init sqlDB:", err) } else { - sqlDB.AutoMigrate(&User{}, &VerificationRequest{}, &Session{}, &Config{}) + sqlDB.AutoMigrate(&User{}, &VerificationRequest{}, &Session{}, &Env{}) } Mgr = &manager{ sqlDB: sqlDB, diff --git a/server/db/env.go b/server/db/env.go new file mode 100644 index 0000000..5d51371 --- /dev/null +++ b/server/db/env.go @@ -0,0 +1,161 @@ +package db + +import ( + "fmt" + "log" + "time" + + arangoDriver "github.com/arangodb/go-driver" + "github.com/google/uuid" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type Env struct { + Key string `json:"_key,omitempty" bson:"_key"` // for arangodb + ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id"` + EnvData []byte `gorm:"type:text" json:"env" bson:"env"` + Hash string `gorm:"type:hash" json:"hash" bson:"hash"` + UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"` + CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"` +} + +// AddEnv function to add env to db +func (mgr *manager) AddEnv(env Env) (Env, error) { + if env.ID == "" { + env.ID = uuid.New().String() + } + + if IsORMSupported { + // copy id as value for fields required for mongodb & arangodb + env.Key = env.ID + result := mgr.sqlDB.Create(&env) + + if result.Error != nil { + log.Println("error adding config:", result.Error) + return env, result.Error + } + } + + if IsArangoDB { + env.CreatedAt = time.Now().Unix() + env.UpdatedAt = time.Now().Unix() + configCollection, _ := mgr.arangodb.Collection(nil, Collections.Env) + meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(nil), env) + if err != nil { + log.Println("error adding config:", err) + return env, err + } + env.Key = meta.Key + env.ID = meta.ID.String() + } + + if IsMongoDB { + env.CreatedAt = time.Now().Unix() + env.UpdatedAt = time.Now().Unix() + env.Key = env.ID + configCollection := mgr.mongodb.Collection(Collections.Env, options.Collection()) + _, err := configCollection.InsertOne(nil, env) + if err != nil { + log.Println("error adding config:", err) + return env, err + } + } + + return env, nil +} + +// UpdateEnv function to update env in db +func (mgr *manager) UpdateEnv(env Env) (Env, error) { + env.UpdatedAt = time.Now().Unix() + + if IsORMSupported { + result := mgr.sqlDB.Save(&env) + + if result.Error != nil { + log.Println("error updating config:", result.Error) + return env, result.Error + } + } + + if IsArangoDB { + collection, _ := mgr.arangodb.Collection(nil, Collections.Env) + meta, err := collection.UpdateDocument(nil, env.Key, env) + if err != nil { + log.Println("error updating config:", err) + return env, err + } + + env.Key = meta.Key + env.ID = meta.ID.String() + } + + if IsMongoDB { + configCollection := mgr.mongodb.Collection(Collections.Env, options.Collection()) + _, err := configCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions()) + if err != nil { + log.Println("error updating config:", err) + return env, err + } + } + + return env, nil +} + +// GetConfig function to get config +func (mgr *manager) GetEnv() (Env, error) { + var env Env + + if IsORMSupported { + result := mgr.sqlDB.First(&env) + + if result.Error != nil { + return env, result.Error + } + } + + if IsArangoDB { + query := fmt.Sprintf("FOR d in %s RETURN d", Collections.Env) + + cursor, err := mgr.arangodb.Query(nil, query, nil) + if err != nil { + return env, err + } + defer cursor.Close() + + for { + if !cursor.HasMore() { + if env.Key == "" { + return env, fmt.Errorf("config not found") + } + break + } + _, err := cursor.ReadDocument(nil, &env) + if err != nil { + return env, err + } + } + } + + if IsMongoDB { + configCollection := mgr.mongodb.Collection(Collections.Env, options.Collection()) + cursor, err := configCollection.Find(nil, bson.M{}, options.Find()) + if err != nil { + return env, err + } + defer cursor.Close(nil) + + for cursor.Next(nil) { + err := cursor.Decode(&env) + if err != nil { + return env, err + } + } + + if env.ID == "" { + return env, fmt.Errorf("config not found") + } + } + + return env, nil +} diff --git a/server/db/mongodb.go b/server/db/mongodb.go index 971b5ec..1480bd6 100644 --- a/server/db/mongodb.go +++ b/server/db/mongodb.go @@ -13,7 +13,7 @@ import ( ) func initMongodb() (*mongo.Database, error) { - mongodbOptions := options.Client().ApplyURI(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)) + mongodbOptions := options.Client().ApplyURI(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)) maxWait := time.Duration(5 * time.Second) mongodbOptions.ConnectTimeout = &maxWait mongoClient, err := mongo.NewClient(mongodbOptions) @@ -31,7 +31,7 @@ func initMongodb() (*mongo.Database, error) { return nil, err } - mongodb := mongoClient.Database(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string), options.Database()) + mongodb := mongoClient.Database(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName), options.Database()) mongodb.CreateCollection(ctx, Collections.User, options.CreateCollection()) userCollection := mongodb.Collection(Collections.User, options.Collection()) @@ -74,7 +74,7 @@ func initMongodb() (*mongo.Database, error) { }, }, options.CreateIndexes()) - mongodb.CreateCollection(ctx, Collections.Config, options.CreateCollection()) + mongodb.CreateCollection(ctx, Collections.Env, options.CreateCollection()) return mongodb, nil } diff --git a/server/db/user.go b/server/db/user.go index 48c0015..3ab2def 100644 --- a/server/db/user.go +++ b/server/db/user.go @@ -45,7 +45,7 @@ func (mgr *manager) AddUser(user User) (User, error) { } if user.Roles == "" { - user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string), ",") + user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") } if IsORMSupported { diff --git a/server/email/email.go b/server/email/email.go index adf1ac5..5a76a43 100644 --- a/server/email/email.go +++ b/server/email/email.go @@ -32,13 +32,13 @@ func addEmailTemplate(a string, b map[string]interface{}, templateName string) s // SendMail function to send mail func SendMail(to []string, Subject, bodyMessage string) error { m := gomail.NewMessage() - m.SetHeader("From", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySenderEmail).(string)) + m.SetHeader("From", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeySenderEmail)) m.SetHeader("To", to...) m.SetHeader("Subject", Subject) m.SetBody("text/html", bodyMessage) - port, _ := strconv.Atoi(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpPort).(string)) - d := gomail.NewDialer(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpHost).(string), port, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpUsername).(string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpPassword).(string)) - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyEnv).(string) == "development" { + port, _ := strconv.Atoi(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)) + d := gomail.NewDialer(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpHost), port, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpUsername), envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpPassword)) + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEnv) == "development" { d.TLSConfig = &tls.Config{InsecureSkipVerify: true} } if err := d.DialAndSend(m); err != nil { diff --git a/server/email/forgot_password_email.go b/server/email/forgot_password_email.go index 3320315..4c00feb 100644 --- a/server/email/forgot_password_email.go +++ b/server/email/forgot_password_email.go @@ -7,9 +7,9 @@ import ( // SendForgotPasswordMail to send forgot password email func SendForgotPasswordMail(toEmail, token, host string) error { - resetPasswordUrl := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyResetPasswordURL).(string) + resetPasswordUrl := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL) if resetPasswordUrl == "" { - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyResetPasswordURL, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)+"/app/reset-password") + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyResetPasswordURL, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)+"/app/reset-password") } // The receiver needs to be in slice as the receive supports multiple receiver @@ -103,8 +103,8 @@ func SendForgotPasswordMail(toEmail, token, host string) error { ` data := make(map[string]interface{}, 3) - data["org_logo"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string) - data["org_name"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string) + data["org_logo"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo) + data["org_name"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName) data["verification_url"] = resetPasswordUrl + "?token=" + token message = addEmailTemplate(message, data, "reset_password_email.tmpl") diff --git a/server/email/verification_email.go b/server/email/verification_email.go index 1c4fd23..54cfa11 100644 --- a/server/email/verification_email.go +++ b/server/email/verification_email.go @@ -97,9 +97,9 @@ func SendVerificationMail(toEmail, token string) error { ` data := make(map[string]interface{}, 3) - data["org_logo"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string) - data["org_name"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string) - data["verification_url"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/verify_email?token=" + token + data["org_logo"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo) + data["org_name"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName) + data["verification_url"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/verify_email?token=" + token message = addEmailTemplate(message, data, "verify_email.tmpl") // bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message) diff --git a/server/env/env.go b/server/env/env.go index cd9ba0a..23656e4 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -27,176 +27,175 @@ func InitEnv() { // get clone of current store envData := envstore.EnvInMemoryStoreObj.GetEnvStoreClone() - if envData[constants.EnvKeyEnv] == nil || envData[constants.EnvKeyEnv] == "" { - envData[constants.EnvKeyEnv] = os.Getenv("ENV") - if envData[constants.EnvKeyEnv] == "" { - envData[constants.EnvKeyEnv] = "production" + if envData.StringEnv[constants.EnvKeyEnv] == "" { + envData.StringEnv[constants.EnvKeyEnv] = os.Getenv("ENV") + if envData.StringEnv[constants.EnvKeyEnv] == "" { + envData.StringEnv[constants.EnvKeyEnv] = "production" } - if envData[constants.EnvKeyEnv] == "production" { - envData[constants.EnvKeyIsProd] = true + if envData.StringEnv[constants.EnvKeyEnv] == "production" { + envData.BoolEnv[constants.EnvKeyIsProd] = true os.Setenv("GIN_MODE", "release") } else { - envData[constants.EnvKeyIsProd] = false + envData.BoolEnv[constants.EnvKeyIsProd] = false } } // set authorizer url to empty string so that fresh url is obtained with every server start - envData[constants.EnvKeyAuthorizerURL] = "" - if envData[constants.EnvKeyAppURL] == nil || envData[constants.EnvKeyAppURL] == "" { - envData[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL) + envData.StringEnv[constants.EnvKeyAuthorizerURL] = "" + if envData.StringEnv[constants.EnvKeyAppURL] == "" { + envData.StringEnv[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL) } - if envData[constants.EnvKeyEnvPath] == nil || envData[constants.EnvKeyEnvPath].(string) == "" { - envData[constants.EnvKeyEnvPath] = `.env` + if envData.StringEnv[constants.EnvKeyEnvPath] == "" { + envData.StringEnv[constants.EnvKeyEnvPath] = `.env` } if ARG_ENV_FILE != nil && *ARG_ENV_FILE != "" { - envData[constants.EnvKeyEnvPath] = *ARG_ENV_FILE + envData.StringEnv[constants.EnvKeyEnvPath] = *ARG_ENV_FILE } - err := godotenv.Load(envData[constants.EnvKeyEnvPath].(string)) + err := godotenv.Load(envData.StringEnv[constants.EnvKeyEnvPath]) if err != nil { - log.Printf("error loading %s file", envData[constants.EnvKeyEnvPath]) + log.Printf("error loading %s file", envData.StringEnv[constants.EnvKeyEnvPath]) } - if envData[constants.EnvKeyPort] == nil || envData[constants.EnvKeyPort].(string) == "" { - envData[constants.EnvKeyPort] = os.Getenv("PORT") - if envData[constants.EnvKeyPort].(string) == "" { - envData[constants.EnvKeyPort] = "8080" + if envData.StringEnv[constants.EnvKeyPort] == "" { + envData.StringEnv[constants.EnvKeyPort] = os.Getenv("PORT") + if envData.StringEnv[constants.EnvKeyPort] == "" { + envData.StringEnv[constants.EnvKeyPort] = "8080" } } - if envData[constants.EnvKeyAdminSecret] == nil || envData[constants.EnvKeyAdminSecret].(string) == "" { - envData[constants.EnvKeyAdminSecret] = os.Getenv("ADMIN_SECRET") + if envData.StringEnv[constants.EnvKeyAdminSecret] == "" { + envData.StringEnv[constants.EnvKeyAdminSecret] = os.Getenv("ADMIN_SECRET") } - if envData[constants.EnvKeyDatabaseType] == nil || envData[constants.EnvKeyDatabaseType].(string) == "" { - envData[constants.EnvKeyDatabaseType] = os.Getenv("DATABASE_TYPE") - log.Println(envData[constants.EnvKeyDatabaseType].(string)) + if envData.StringEnv[constants.EnvKeyDatabaseType] == "" { + envData.StringEnv[constants.EnvKeyDatabaseType] = os.Getenv("DATABASE_TYPE") if ARG_DB_TYPE != nil && *ARG_DB_TYPE != "" { - envData[constants.EnvKeyDatabaseType] = *ARG_DB_TYPE + envData.StringEnv[constants.EnvKeyDatabaseType] = *ARG_DB_TYPE } - if envData[constants.EnvKeyDatabaseType].(string) == "" { + if envData.StringEnv[constants.EnvKeyDatabaseType] == "" { panic("DATABASE_TYPE is required") } } - if envData[constants.EnvKeyDatabaseURL] == nil || envData[constants.EnvKeyDatabaseURL].(string) == "" { - envData[constants.EnvKeyDatabaseURL] = os.Getenv("DATABASE_URL") + if envData.StringEnv[constants.EnvKeyDatabaseURL] == "" { + envData.StringEnv[constants.EnvKeyDatabaseURL] = os.Getenv("DATABASE_URL") if ARG_DB_URL != nil && *ARG_DB_URL != "" { - envData[constants.EnvKeyDatabaseURL] = *ARG_DB_URL + envData.StringEnv[constants.EnvKeyDatabaseURL] = *ARG_DB_URL } - if envData[constants.EnvKeyDatabaseURL] == "" { + if envData.StringEnv[constants.EnvKeyDatabaseURL] == "" { panic("DATABASE_URL is required") } } - if envData[constants.EnvKeyDatabaseName] == nil || envData[constants.EnvKeyDatabaseName].(string) == "" { - envData[constants.EnvKeyDatabaseName] = os.Getenv("DATABASE_NAME") - if envData[constants.EnvKeyDatabaseName].(string) == "" { - envData[constants.EnvKeyDatabaseName] = "authorizer" + if envData.StringEnv[constants.EnvKeyDatabaseName] == "" { + envData.StringEnv[constants.EnvKeyDatabaseName] = os.Getenv("DATABASE_NAME") + if envData.StringEnv[constants.EnvKeyDatabaseName] == "" { + envData.StringEnv[constants.EnvKeyDatabaseName] = "authorizer" } } - if envData[constants.EnvKeySmtpHost] == nil || envData[constants.EnvKeySmtpHost].(string) == "" { - envData[constants.EnvKeySmtpHost] = os.Getenv("SMTP_HOST") + if envData.StringEnv[constants.EnvKeySmtpHost] == "" { + envData.StringEnv[constants.EnvKeySmtpHost] = os.Getenv("SMTP_HOST") } - if envData[constants.EnvKeySmtpPort] == nil || envData[constants.EnvKeySmtpPort].(string) == "" { - envData[constants.EnvKeySmtpPort] = os.Getenv("SMTP_PORT") + if envData.StringEnv[constants.EnvKeySmtpPort] == "" { + envData.StringEnv[constants.EnvKeySmtpPort] = os.Getenv("SMTP_PORT") } - if envData[constants.EnvKeySmtpUsername] == nil || envData[constants.EnvKeySmtpUsername].(string) == "" { - envData[constants.EnvKeySmtpUsername] = os.Getenv("SMTP_USERNAME") + if envData.StringEnv[constants.EnvKeySmtpUsername] == "" { + envData.StringEnv[constants.EnvKeySmtpUsername] = os.Getenv("SMTP_USERNAME") } - if envData[constants.EnvKeySmtpPassword] == nil || envData[constants.EnvKeySmtpPassword].(string) == "" { - envData[constants.EnvKeySmtpPassword] = os.Getenv("SMTP_PASSWORD") + if envData.StringEnv[constants.EnvKeySmtpPassword] == "" { + envData.StringEnv[constants.EnvKeySmtpPassword] = os.Getenv("SMTP_PASSWORD") } - if envData[constants.EnvKeySenderEmail] == nil || envData[constants.EnvKeySenderEmail].(string) == "" { - envData[constants.EnvKeySenderEmail] = os.Getenv("SENDER_EMAIL") + if envData.StringEnv[constants.EnvKeySenderEmail] == "" { + envData.StringEnv[constants.EnvKeySenderEmail] = os.Getenv("SENDER_EMAIL") } - if envData[constants.EnvKeyJwtSecret] == nil || envData[constants.EnvKeyJwtSecret].(string) == "" { - envData[constants.EnvKeyJwtSecret] = os.Getenv("JWT_SECRET") - if envData[constants.EnvKeyJwtSecret].(string) == "" { - envData[constants.EnvKeyJwtSecret] = uuid.New().String() + if envData.StringEnv[constants.EnvKeyJwtSecret] == "" { + envData.StringEnv[constants.EnvKeyJwtSecret] = os.Getenv("JWT_SECRET") + if envData.StringEnv[constants.EnvKeyJwtSecret] == "" { + envData.StringEnv[constants.EnvKeyJwtSecret] = uuid.New().String() } } - if envData[constants.EnvKeyJwtType] == nil || envData[constants.EnvKeyJwtType].(string) == "" { - envData[constants.EnvKeyJwtType] = os.Getenv("JWT_TYPE") - if envData[constants.EnvKeyJwtType].(string) == "" { - envData[constants.EnvKeyJwtType] = "HS256" + if envData.StringEnv[constants.EnvKeyJwtType] == "" { + envData.StringEnv[constants.EnvKeyJwtType] = os.Getenv("JWT_TYPE") + if envData.StringEnv[constants.EnvKeyJwtType] == "" { + envData.StringEnv[constants.EnvKeyJwtType] = "HS256" } } - if envData[constants.EnvKeyJwtRoleClaim] == nil || envData[constants.EnvKeyJwtRoleClaim].(string) == "" { - envData[constants.EnvKeyJwtRoleClaim] = os.Getenv("JWT_ROLE_CLAIM") + if envData.StringEnv[constants.EnvKeyJwtRoleClaim] == "" { + envData.StringEnv[constants.EnvKeyJwtRoleClaim] = os.Getenv("JWT_ROLE_CLAIM") - if envData[constants.EnvKeyJwtRoleClaim].(string) == "" { - envData[constants.EnvKeyJwtRoleClaim] = "role" + if envData.StringEnv[constants.EnvKeyJwtRoleClaim] == "" { + envData.StringEnv[constants.EnvKeyJwtRoleClaim] = "role" } } - if envData[constants.EnvKeyRedisURL] == nil || envData[constants.EnvKeyRedisURL].(string) == "" { - envData[constants.EnvKeyRedisURL] = os.Getenv("REDIS_URL") + if envData.StringEnv[constants.EnvKeyRedisURL] == "" { + envData.StringEnv[constants.EnvKeyRedisURL] = os.Getenv("REDIS_URL") } - if envData[constants.EnvKeyCookieName] == nil || envData[constants.EnvKeyCookieName].(string) == "" { - envData[constants.EnvKeyCookieName] = os.Getenv("COOKIE_NAME") - if envData[constants.EnvKeyCookieName].(string) == "" { - envData[constants.EnvKeyCookieName] = "authorizer" + if envData.StringEnv[constants.EnvKeyCookieName] == "" { + envData.StringEnv[constants.EnvKeyCookieName] = os.Getenv("COOKIE_NAME") + if envData.StringEnv[constants.EnvKeyCookieName] == "" { + envData.StringEnv[constants.EnvKeyCookieName] = "authorizer" } } - if envData[constants.EnvKeyGoogleClientID] == nil || envData[constants.EnvKeyGoogleClientID].(string) == "" { - envData[constants.EnvKeyGoogleClientID] = os.Getenv("GOOGLE_CLIENT_ID") + if envData.StringEnv[constants.EnvKeyGoogleClientID] == "" { + envData.StringEnv[constants.EnvKeyGoogleClientID] = os.Getenv("GOOGLE_CLIENT_ID") } - if envData[constants.EnvKeyGoogleClientSecret] == nil || envData[constants.EnvKeyGoogleClientSecret].(string) == "" { - envData[constants.EnvKeyGoogleClientSecret] = os.Getenv("GOOGLE_CLIENT_SECRET") + if envData.StringEnv[constants.EnvKeyGoogleClientSecret] == "" { + envData.StringEnv[constants.EnvKeyGoogleClientSecret] = os.Getenv("GOOGLE_CLIENT_SECRET") } - if envData[constants.EnvKeyGithubClientID] == nil || envData[constants.EnvKeyGithubClientID].(string) == "" { - envData[constants.EnvKeyGithubClientID] = os.Getenv("GITHUB_CLIENT_ID") + if envData.StringEnv[constants.EnvKeyGithubClientID] == "" { + envData.StringEnv[constants.EnvKeyGithubClientID] = os.Getenv("GITHUB_CLIENT_ID") } - if envData[constants.EnvKeyGithubClientSecret] == nil || envData[constants.EnvKeyGithubClientSecret].(string) == "" { - envData[constants.EnvKeyGithubClientSecret] = os.Getenv("GITHUB_CLIENT_SECRET") + if envData.StringEnv[constants.EnvKeyGithubClientSecret] == "" { + envData.StringEnv[constants.EnvKeyGithubClientSecret] = os.Getenv("GITHUB_CLIENT_SECRET") } - if envData[constants.EnvKeyFacebookClientID] == nil || envData[constants.EnvKeyFacebookClientID].(string) == "" { - envData[constants.EnvKeyFacebookClientID] = os.Getenv("FACEBOOK_CLIENT_ID") + if envData.StringEnv[constants.EnvKeyFacebookClientID] == "" { + envData.StringEnv[constants.EnvKeyFacebookClientID] = os.Getenv("FACEBOOK_CLIENT_ID") } - if envData[constants.EnvKeyFacebookClientSecret] == nil || envData[constants.EnvKeyFacebookClientSecret].(string) == "" { - envData[constants.EnvKeyFacebookClientSecret] = os.Getenv("FACEBOOK_CLIENT_SECRET") + if envData.StringEnv[constants.EnvKeyFacebookClientSecret] == "" { + envData.StringEnv[constants.EnvKeyFacebookClientSecret] = os.Getenv("FACEBOOK_CLIENT_SECRET") } - if envData[constants.EnvKeyResetPasswordURL] == nil || envData[constants.EnvKeyResetPasswordURL].(string) == "" { - envData[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(os.Getenv("RESET_PASSWORD_URL"), "/") + if envData.StringEnv[constants.EnvKeyResetPasswordURL] == "" { + envData.StringEnv[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(os.Getenv("RESET_PASSWORD_URL"), "/") } - envData[constants.EnvKeyDisableBasicAuthentication] = os.Getenv("DISABLE_BASIC_AUTHENTICATION") == "true" - envData[constants.EnvKeyDisableEmailVerification] = os.Getenv("DISABLE_EMAIL_VERIFICATION") == "true" - envData[constants.EnvKeyDisableMagicLinkLogin] = os.Getenv("DISABLE_MAGIC_LINK_LOGIN") == "true" - envData[constants.EnvKeyDisableLoginPage] = os.Getenv("DISABLE_LOGIN_PAGE") == "true" + envData.BoolEnv[constants.EnvKeyDisableBasicAuthentication] = os.Getenv("DISABLE_BASIC_AUTHENTICATION") == "true" + envData.BoolEnv[constants.EnvKeyDisableEmailVerification] = os.Getenv("DISABLE_EMAIL_VERIFICATION") == "true" + envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = os.Getenv("DISABLE_MAGIC_LINK_LOGIN") == "true" + envData.BoolEnv[constants.EnvKeyDisableLoginPage] = os.Getenv("DISABLE_LOGIN_PAGE") == "true" // no need to add nil check as its already done above - if envData[constants.EnvKeySmtpHost].(string) == "" || envData[constants.EnvKeySmtpUsername].(string) == "" || envData[constants.EnvKeySmtpPassword].(string) == "" || envData[constants.EnvKeySenderEmail].(string) == "" { - envData[constants.EnvKeyDisableEmailVerification] = true - envData[constants.EnvKeyDisableMagicLinkLogin] = true + if envData.StringEnv[constants.EnvKeySmtpHost] == "" || envData.StringEnv[constants.EnvKeySmtpUsername] == "" || envData.StringEnv[constants.EnvKeySmtpPassword] == "" || envData.StringEnv[constants.EnvKeySenderEmail] == "" && envData.StringEnv[constants.EnvKeySmtpPort] == "" { + envData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true + envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true } - if envData[constants.EnvKeyDisableEmailVerification].(bool) { - envData[constants.EnvKeyDisableMagicLinkLogin] = true + if envData.BoolEnv[constants.EnvKeyDisableEmailVerification] { + envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true } allowedOriginsSplit := strings.Split(os.Getenv("ALLOWED_ORIGINS"), ",") @@ -225,7 +224,7 @@ func InitEnv() { allowedOrigins = []string{"*"} } - envData[constants.EnvKeyAllowedOrigins] = allowedOrigins + envData.SliceEnv[constants.EnvKeyAllowedOrigins] = allowedOrigins rolesEnv := strings.TrimSpace(os.Getenv("ROLES")) rolesSplit := strings.Split(rolesEnv, ",") @@ -268,16 +267,16 @@ func InitEnv() { panic(`Invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`) } - envData[constants.EnvKeyRoles] = roles - envData[constants.EnvKeyDefaultRoles] = defaultRoles - envData[constants.EnvKeyProtectedRoles] = protectedRoles + envData.SliceEnv[constants.EnvKeyRoles] = roles + envData.SliceEnv[constants.EnvKeyDefaultRoles] = defaultRoles + envData.SliceEnv[constants.EnvKeyProtectedRoles] = protectedRoles if os.Getenv("ORGANIZATION_NAME") != "" { - envData[constants.EnvKeyOrganizationName] = os.Getenv("ORGANIZATION_NAME") + envData.StringEnv[constants.EnvKeyOrganizationName] = os.Getenv("ORGANIZATION_NAME") } if os.Getenv("ORGANIZATION_LOGO") != "" { - envData[constants.EnvKeyOrganizationLogo] = os.Getenv("ORGANIZATION_LOGO") + envData.StringEnv[constants.EnvKeyOrganizationLogo] = os.Getenv("ORGANIZATION_LOGO") } envstore.EnvInMemoryStoreObj.UpdateEnvStore(envData) diff --git a/server/env/persist_env.go b/server/env/persist_env.go index 291e1f3..6e04c43 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -4,7 +4,7 @@ import ( "encoding/json" "log" "os" - "reflect" + "strconv" "strings" "github.com/authorizerdev/authorizer/server/constants" @@ -16,12 +16,12 @@ import ( // PersistEnv persists the environment variables to the database func PersistEnv() error { - config, err := db.Mgr.GetConfig() + env, err := db.Mgr.GetEnv() // config not found in db if err != nil { // AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid hash := uuid.New().String()[:36-4] - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, hash) encodedHash := utils.EncryptB64(hash) configData, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone()) @@ -34,31 +34,31 @@ func PersistEnv() error { return err } - config = db.Config{ - Hash: encodedHash, - Config: encryptedConfig, + env = db.Env{ + Hash: encodedHash, + EnvData: encryptedConfig, } - db.Mgr.AddConfig(config) + db.Mgr.AddEnv(env) } else { // decrypt the config data from db // decryption can be done using the hash stored in db - encryptionKey := config.Hash + encryptionKey := env.Hash decryptedEncryptionKey, err := utils.DecryptB64(encryptionKey) if err != nil { return err } - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey) - decryptedConfigs, err := utils.DecryptAES(config.Config) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey) + decryptedConfigs, err := utils.DecryptAES(env.EnvData) if err != nil { return err } - // temp json to validate with env - var jsonData map[string]interface{} + // temp store variable + var storeData envstore.Store - err = json.Unmarshal(decryptedConfigs, &jsonData) + err = json.Unmarshal(decryptedConfigs, &storeData) if err != nil { return err } @@ -68,69 +68,70 @@ func PersistEnv() error { hasChanged := false - for key, value := range jsonData { - fieldType := reflect.TypeOf(value).String() + for key, value := range storeData.StringEnv { + if key != constants.EnvKeyEncryptionKey { + // check only for derivative keys + // No need to check for ENCRYPTION_KEY which special key we use for encrypting config data + // as we have removed it from json + envValue := strings.TrimSpace(os.Getenv(key)) - // check only for derivative keys - // No need to check for ENCRYPTION_KEY which special key we use for encrypting config data - // as we have removed it from json + // env is not empty + if envValue != "" { + if value != envValue { + storeData.StringEnv[key] = envValue + hasChanged = true + } + } + } + } + + for key, value := range storeData.BoolEnv { envValue := strings.TrimSpace(os.Getenv(key)) - // env is not empty if envValue != "" { - // check the type - // currently we have 3 types of env vars: string, bool, []string{} - if fieldType == "string" { - if value != envValue { - jsonData[key] = envValue - hasChanged = true - } + envValueBool, _ := strconv.ParseBool(envValue) + if value != envValueBool { + storeData.BoolEnv[key] = envValueBool + hasChanged = true } + } + } - if fieldType == "bool" { - newValue := envValue == "true" - if value != newValue { - jsonData[key] = newValue - hasChanged = true - } - } - - if fieldType == "[]interface {}" { - stringArr := []string{} - envStringArr := strings.Split(envValue, ",") - for _, v := range value.([]interface{}) { - stringArr = append(stringArr, v.(string)) - } - if !utils.IsStringArrayEqual(stringArr, envStringArr) { - jsonData[key] = envStringArr - } + for key, value := range storeData.SliceEnv { + envValue := strings.TrimSpace(os.Getenv(key)) + // env is not empty + if envValue != "" { + envStringArr := strings.Split(envValue, ",") + if !utils.IsStringArrayEqual(value, envStringArr) { + storeData.SliceEnv[key] = envStringArr + hasChanged = true } } } // handle derivative cases like disabling email verification & magic login // in case SMTP is off but env is set to true - if jsonData["SMTP_HOST"] == "" || jsonData["SENDER_EMAIL"] == "" || jsonData["SENDER_PASSWORD"] == "" { - if !jsonData["DISABLE_EMAIL_VERIFICATION"].(bool) { - jsonData["DISABLE_EMAIL_VERIFICATION"] = true + if storeData.StringEnv[constants.EnvKeySmtpHost] == "" || storeData.StringEnv[constants.EnvKeySmtpUsername] == "" || storeData.StringEnv[constants.EnvKeySmtpPassword] == "" || storeData.StringEnv[constants.EnvKeySenderEmail] == "" && storeData.StringEnv[constants.EnvKeySmtpPort] == "" { + if !storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] { + storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true hasChanged = true } - if !jsonData["DISABLE_MAGIC_LINK_LOGIN"].(bool) { - jsonData["DISABLE_MAGIC_LINK_LOGIN"] = true + if !storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] { + storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true hasChanged = true } } - envstore.EnvInMemoryStoreObj.UpdateEnvStore(jsonData) + envstore.EnvInMemoryStoreObj.UpdateEnvStore(storeData) if hasChanged { - encryptedConfig, err := utils.EncryptEnvData(jsonData) + encryptedConfig, err := utils.EncryptEnvData(storeData) if err != nil { return err } - config.Config = encryptedConfig - _, err = db.Mgr.UpdateConfig(config) + env.EnvData = encryptedConfig + _, err = db.Mgr.UpdateEnv(env) if err != nil { log.Println("error updating config:", err) return err diff --git a/server/envstore/store.go b/server/envstore/store.go index c676c2b..3fec232 100644 --- a/server/envstore/store.go +++ b/server/envstore/store.go @@ -6,60 +6,97 @@ import ( "github.com/authorizerdev/authorizer/server/constants" ) +// Store data structure +type Store struct { + StringEnv map[string]string `json:"string_env"` + BoolEnv map[string]bool `json:"bool_env"` + SliceEnv map[string][]string `json:"slice_env"` +} + // EnvInMemoryStore struct type EnvInMemoryStore struct { mutex sync.Mutex - store map[string]interface{} + store *Store } // EnvInMemoryStoreObj global variable for EnvInMemoryStore var EnvInMemoryStoreObj = &EnvInMemoryStore{ - store: map[string]interface{}{ - constants.EnvKeyAdminCookieName: "authorizer-admin", - constants.EnvKeyJwtRoleClaim: "role", - constants.EnvKeyOrganizationName: "Authorizer", - constants.EnvKeyOrganizationLogo: "https://www.authorizer.io/images/logo.png", - constants.EnvKeyDisableBasicAuthentication: false, - constants.EnvKeyDisableMagicLinkLogin: false, - constants.EnvKeyDisableEmailVerification: false, - constants.EnvKeyDisableLoginPage: false, + store: &Store{ + StringEnv: map[string]string{ + constants.EnvKeyAdminCookieName: "authorizer-admin", + constants.EnvKeyJwtRoleClaim: "role", + constants.EnvKeyOrganizationName: "Authorizer", + constants.EnvKeyOrganizationLogo: "https://www.authorizer.io/images/logo.png", + }, + BoolEnv: map[string]bool{ + constants.EnvKeyDisableBasicAuthentication: false, + constants.EnvKeyDisableMagicLinkLogin: false, + constants.EnvKeyDisableEmailVerification: false, + constants.EnvKeyDisableLoginPage: false, + }, + SliceEnv: map[string][]string{}, }, } // UpdateEnvStore to update the whole env store object -func (e *EnvInMemoryStore) UpdateEnvStore(data map[string]interface{}) { +func (e *EnvInMemoryStore) UpdateEnvStore(store Store) { e.mutex.Lock() defer e.mutex.Unlock() // just override the keys + new keys - for key, value := range data { - e.store[key] = value + + for key, value := range store.StringEnv { + e.store.StringEnv[key] = value + } + + for key, value := range store.BoolEnv { + e.store.BoolEnv[key] = value + } + + for key, value := range store.SliceEnv { + e.store.SliceEnv[key] = value } } // UpdateEnvVariable to update the particular env variable -func (e *EnvInMemoryStore) UpdateEnvVariable(key string, value interface{}) map[string]interface{} { +func (e *EnvInMemoryStore) UpdateEnvVariable(storeIdentifier, key string, value interface{}) { e.mutex.Lock() defer e.mutex.Unlock() - e.store[key] = value - return e.store + switch storeIdentifier { + case constants.StringStoreIdentifier: + e.store.StringEnv[key] = value.(string) + case constants.BoolStoreIdentifier: + e.store.BoolEnv[key] = value.(bool) + case constants.SliceStoreIdentifier: + e.store.SliceEnv[key] = value.([]string) + } } -// GetEnvStore to get the env variable from env store object -func (e *EnvInMemoryStore) GetEnvVariable(key string) interface{} { +// GetStringStoreEnvVariable to get the env variable from string store object +func (e *EnvInMemoryStore) GetStringStoreEnvVariable(key string) string { // e.mutex.Lock() // defer e.mutex.Unlock() - return e.store[key] + return e.store.StringEnv[key] +} + +// GetBoolStoreEnvVariable to get the env variable from bool store object +func (e *EnvInMemoryStore) GetBoolStoreEnvVariable(key string) bool { + // e.mutex.Lock() + // defer e.mutex.Unlock() + return e.store.BoolEnv[key] +} + +// GetSliceStoreEnvVariable to get the env variable from slice store object +func (e *EnvInMemoryStore) GetSliceStoreEnvVariable(key string) []string { + // e.mutex.Lock() + // defer e.mutex.Unlock() + return e.store.SliceEnv[key] } // GetEnvStoreClone to get clone of current env store object -func (e *EnvInMemoryStore) GetEnvStoreClone() map[string]interface{} { +func (e *EnvInMemoryStore) GetEnvStoreClone() Store { e.mutex.Lock() defer e.mutex.Unlock() - result := make(map[string]interface{}) - for key, value := range e.store { - result[key] = value - } - + result := *e.store return result } diff --git a/server/handlers/app.go b/server/handlers/app.go index 4ad5a49..d6deb68 100644 --- a/server/handlers/app.go +++ b/server/handlers/app.go @@ -27,7 +27,7 @@ func AppHandler() gin.HandlerFunc { var stateObj State if state == "" { - stateObj.AuthorizerURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + stateObj.AuthorizerURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) stateObj.RedirectURL = stateObj.AuthorizerURL + "/app" } else { @@ -57,7 +57,7 @@ func AppHandler() gin.HandlerFunc { } // validate host and domain of authorizer url - if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) { + if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) { c.JSON(400, gin.H{"error": "invalid host url"}) return } @@ -74,8 +74,8 @@ func AppHandler() gin.HandlerFunc { "data": map[string]string{ "authorizerURL": stateObj.AuthorizerURL, "redirectURL": stateObj.RedirectURL, - "organizationName": envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string), - "organizationLogo": envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string), + "organizationName": envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName), + "organizationLogo": envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo), }, }) } diff --git a/server/handlers/dashboard.go b/server/handlers/dashboard.go index 002b30d..5e54513 100644 --- a/server/handlers/dashboard.go +++ b/server/handlers/dashboard.go @@ -13,7 +13,7 @@ func DashboardHandler() gin.HandlerFunc { return func(c *gin.Context) { isOnboardingCompleted := false - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret) != nil && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string) != "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) != "" { isOnboardingCompleted = true } diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index aac9d25..36c7a80 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -71,7 +71,7 @@ func OAuthCallbackHandler() gin.HandlerFunc { // make sure inputRoles don't include protected roles hasProtectedRole := false for _, ir := range inputRoles { - if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ir) { + if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ir) { hasProtectedRole = true } } @@ -114,7 +114,7 @@ func OAuthCallbackHandler() gin.HandlerFunc { // check if it contains protected unassigned role hasProtectedRole := false for _, ur := range unasignedRoles { - if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ur) { + if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ur) { hasProtectedRole = true } } diff --git a/server/handlers/oauth_login.go b/server/handlers/oauth_login.go index 733a60b..3922f5b 100644 --- a/server/handlers/oauth_login.go +++ b/server/handlers/oauth_login.go @@ -33,14 +33,14 @@ func OAuthLoginHandler() gin.HandlerFunc { // use protected roles verification for admin login only. // though if not associated with user, it will be rejected from oauth_callback - if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string)...)...), rolesSplit) { + if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...), rolesSplit) { c.JSON(400, gin.H{ "error": "invalid role", }) return } } else { - roles = strings.Join(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string), ",") + roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") } uuid := uuid.New() @@ -56,7 +56,7 @@ func OAuthLoginHandler() gin.HandlerFunc { } session.SetSocailLoginState(oauthStateString, constants.SignupMethodGoogle) // during the init of OAuthProvider authorizer url might be empty - oauth.OAuthProviders.GoogleConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/google" + oauth.OAuthProviders.GoogleConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/google" url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString) c.Redirect(http.StatusTemporaryRedirect, url) case constants.SignupMethodGithub: @@ -65,7 +65,7 @@ func OAuthLoginHandler() gin.HandlerFunc { break } session.SetSocailLoginState(oauthStateString, constants.SignupMethodGithub) - oauth.OAuthProviders.GithubConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/github" + oauth.OAuthProviders.GithubConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/github" url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString) c.Redirect(http.StatusTemporaryRedirect, url) case constants.SignupMethodFacebook: @@ -74,7 +74,7 @@ func OAuthLoginHandler() gin.HandlerFunc { break } session.SetSocailLoginState(oauthStateString, constants.SignupMethodFacebook) - oauth.OAuthProviders.FacebookConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/facebook" + oauth.OAuthProviders.FacebookConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/facebook" url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString) c.Redirect(http.StatusTemporaryRedirect, url) default: diff --git a/server/main.go b/server/main.go index 6b4c1bd..a2a94b7 100644 --- a/server/main.go +++ b/server/main.go @@ -20,7 +20,7 @@ func main() { env.ARG_ENV_FILE = flag.String("env_file", "", "Env file path") flag.Parse() - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyVersion, VERSION) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyVersion, VERSION) env.InitEnv() db.InitDB() @@ -31,5 +31,5 @@ func main() { router := routes.InitRouter() - router.Run(":" + envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyPort).(string)) + router.Run(":" + envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyPort)) } diff --git a/server/middlewares/context.go b/server/middlewares/context.go index 86bf34a..6dce92d 100644 --- a/server/middlewares/context.go +++ b/server/middlewares/context.go @@ -12,9 +12,9 @@ import ( // GinContextToContextMiddleware is a middleware to add gin context in context func GinContextToContextMiddleware() gin.HandlerFunc { return func(c *gin.Context) { - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) == "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) == "" { url := location.Get(c) - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAuthorizerURL, url.Scheme+"://"+c.Request.Host) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAuthorizerURL, url.Scheme+"://"+c.Request.Host) } ctx := context.WithValue(c.Request.Context(), "GinContextKey", c) c.Request = c.Request.WithContext(ctx) diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go index d5ac082..317be78 100644 --- a/server/oauth/oauth.go +++ b/server/oauth/oauth.go @@ -34,33 +34,33 @@ var ( // InitOAuth initializes the OAuth providers based on EnvData func InitOAuth() { ctx := context.Background() - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientSecret).(string) != "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret) != "" { p, err := oidc.NewProvider(ctx, "https://accounts.google.com") if err != nil { log.Fatalln("error creating oidc provider for google:", err) } OIDCProviders.GoogleOIDC = p OAuthProviders.GoogleConfig = &oauth2.Config{ - ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string), - ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientSecret).(string), - RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/google", + ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID), + ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret), + RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/google", Endpoint: OIDCProviders.GoogleOIDC.Endpoint(), Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } } - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientSecret).(string) != "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret) != "" { OAuthProviders.GithubConfig = &oauth2.Config{ - ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientID).(string), - ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientSecret).(string), - RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/github", + ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID), + ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret), + RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/github", Endpoint: githubOAuth2.Endpoint, } } - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string) != "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" { OAuthProviders.FacebookConfig = &oauth2.Config{ - ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientID).(string), - ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientSecret).(string), - RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/facebook", + ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID), + ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret), + RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/facebook", Endpoint: facebookOAuth2.Endpoint, Scopes: []string{"public_profile", "email"}, } diff --git a/server/resolvers/admin_login.go b/server/resolvers/admin_login.go index df66226..6459291 100644 --- a/server/resolvers/admin_login.go +++ b/server/resolvers/admin_login.go @@ -19,7 +19,7 @@ func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*mod return res, err } - adminSecret := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string) + adminSecret := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) if params.AdminSecret != adminSecret { return res, fmt.Errorf(`invalid admin secret`) } diff --git a/server/resolvers/admin_session.go b/server/resolvers/admin_session.go index 25a7c28..e7d7a9e 100644 --- a/server/resolvers/admin_session.go +++ b/server/resolvers/admin_session.go @@ -23,7 +23,7 @@ func AdminSessionResolver(ctx context.Context) (*model.Response, error) { return res, fmt.Errorf("unauthorized") } - hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) if err != nil { return res, err } diff --git a/server/resolvers/admin_signup.go b/server/resolvers/admin_signup.go index 6a14839..f553ac2 100644 --- a/server/resolvers/admin_signup.go +++ b/server/resolvers/admin_signup.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "log" "strings" "github.com/authorizerdev/authorizer/server/constants" @@ -33,39 +32,38 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m return res, err } - adminSecret := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string) + adminSecret := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) if adminSecret != "" { err = fmt.Errorf("admin sign up already completed") return res, err } - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, params.AdminSecret) // consvert EnvData to JSON - var jsonData map[string]interface{} + var storeData envstore.Store jsonBytes, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone()) if err != nil { return res, err } - if err := json.Unmarshal(jsonBytes, &jsonData); err != nil { + if err := json.Unmarshal(jsonBytes, &storeData); err != nil { return res, err } - config, err := db.Mgr.GetConfig() + env, err := db.Mgr.GetEnv() if err != nil { return res, err } - configData, err := utils.EncryptEnvData(jsonData) - log.Println("=> config data from signup:", configData) + envData, err := utils.EncryptEnvData(storeData) if err != nil { return res, err } - config.Config = configData - if _, err := db.Mgr.UpdateConfig(config); err != nil { + env.EnvData = envData + if _, err := db.Mgr.UpdateEnv(env); err != nil { return res, err } diff --git a/server/resolvers/env.go b/server/resolvers/env.go index 01faca4..e573661 100644 --- a/server/resolvers/env.go +++ b/server/resolvers/env.go @@ -26,39 +26,39 @@ func EnvResolver(ctx context.Context) (*model.Env, error) { // get clone of store store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone() - adminSecret := store[constants.EnvKeyAdminSecret].(string) - databaseType := store[constants.EnvKeyDatabaseType].(string) - databaseURL := store[constants.EnvKeyDatabaseURL].(string) - databaseName := store[constants.EnvKeyDatabaseName].(string) - smtpHost := store[constants.EnvKeySmtpHost].(string) - smtpPort := store[constants.EnvKeySmtpPort].(string) - smtpUsername := store[constants.EnvKeySmtpUsername].(string) - smtpPassword := store[constants.EnvKeySmtpPassword].(string) - senderEmail := store[constants.EnvKeySenderEmail].(string) - jwtType := store[constants.EnvKeyJwtType].(string) - jwtSecret := store[constants.EnvKeyJwtSecret].(string) - jwtRoleClaim := store[constants.EnvKeyJwtRoleClaim].(string) - allowedOrigins := store[constants.EnvKeyAllowedOrigins].([]string) - authorizerURL := store[constants.EnvKeyAuthorizerURL].(string) - appURL := store[constants.EnvKeyAppURL].(string) - redisURL := store[constants.EnvKeyRedisURL].(string) - cookieName := store[constants.EnvKeyCookieName].(string) - resetPasswordURL := store[constants.EnvKeyResetPasswordURL].(string) - disableEmailVerification := store[constants.EnvKeyDisableEmailVerification].(bool) - disableBasicAuthentication := store[constants.EnvKeyDisableBasicAuthentication].(bool) - disableMagicLinkLogin := store[constants.EnvKeyDisableMagicLinkLogin].(bool) - disableLoginPage := store[constants.EnvKeyDisableLoginPage].(bool) - roles := store[constants.EnvKeyRoles].([]string) - defaultRoles := store[constants.EnvKeyDefaultRoles].([]string) - protectedRoles := store[constants.EnvKeyProtectedRoles].([]string) - googleClientID := store[constants.EnvKeyGoogleClientID].(string) - googleClientSecret := store[constants.EnvKeyGoogleClientSecret].(string) - facebookClientID := store[constants.EnvKeyFacebookClientID].(string) - facebookClientSecret := store[constants.EnvKeyFacebookClientSecret].(string) - githubClientID := store[constants.EnvKeyGithubClientID].(string) - githubClientSecret := store[constants.EnvKeyGithubClientSecret].(string) - organizationName := store[constants.EnvKeyOrganizationName].(string) - organizationLogo := store[constants.EnvKeyOrganizationLogo].(string) + adminSecret := store.StringEnv[constants.EnvKeyAdminSecret] + databaseType := store.StringEnv[constants.EnvKeyDatabaseType] + databaseURL := store.StringEnv[constants.EnvKeyDatabaseURL] + databaseName := store.StringEnv[constants.EnvKeyDatabaseName] + smtpHost := store.StringEnv[constants.EnvKeySmtpHost] + smtpPort := store.StringEnv[constants.EnvKeySmtpPort] + smtpUsername := store.StringEnv[constants.EnvKeySmtpUsername] + smtpPassword := store.StringEnv[constants.EnvKeySmtpPassword] + senderEmail := store.StringEnv[constants.EnvKeySenderEmail] + jwtType := store.StringEnv[constants.EnvKeyJwtType] + jwtSecret := store.StringEnv[constants.EnvKeyJwtSecret] + jwtRoleClaim := store.StringEnv[constants.EnvKeyJwtRoleClaim] + allowedOrigins := store.SliceEnv[constants.EnvKeyAllowedOrigins] + authorizerURL := store.StringEnv[constants.EnvKeyAuthorizerURL] + appURL := store.StringEnv[constants.EnvKeyAppURL] + redisURL := store.StringEnv[constants.EnvKeyRedisURL] + cookieName := store.StringEnv[constants.EnvKeyCookieName] + resetPasswordURL := store.StringEnv[constants.EnvKeyResetPasswordURL] + disableEmailVerification := store.BoolEnv[constants.EnvKeyDisableEmailVerification] + disableBasicAuthentication := store.BoolEnv[constants.EnvKeyDisableBasicAuthentication] + disableMagicLinkLogin := store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] + disableLoginPage := store.BoolEnv[constants.EnvKeyDisableLoginPage] + roles := store.SliceEnv[constants.EnvKeyRoles] + defaultRoles := store.SliceEnv[constants.EnvKeyDefaultRoles] + protectedRoles := store.SliceEnv[constants.EnvKeyProtectedRoles] + googleClientID := store.StringEnv[constants.EnvKeyGoogleClientID] + googleClientSecret := store.StringEnv[constants.EnvKeyGoogleClientSecret] + facebookClientID := store.StringEnv[constants.EnvKeyFacebookClientID] + facebookClientSecret := store.StringEnv[constants.EnvKeyFacebookClientSecret] + githubClientID := store.StringEnv[constants.EnvKeyGithubClientID] + githubClientSecret := store.StringEnv[constants.EnvKeyGithubClientSecret] + organizationName := store.StringEnv[constants.EnvKeyOrganizationName] + organizationLogo := store.StringEnv[constants.EnvKeyOrganizationLogo] res = &model.Env{ AdminSecret: &adminSecret, diff --git a/server/resolvers/forgot_password.go b/server/resolvers/forgot_password.go index 5fdf3c4..7bd5338 100644 --- a/server/resolvers/forgot_password.go +++ b/server/resolvers/forgot_password.go @@ -22,7 +22,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu if err != nil { return res, err } - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { return res, fmt.Errorf(`basic authentication is disabled for this instance`) } host := gc.Request.Host diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 80d4c4e..9af7f95 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -23,7 +23,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes return res, err } - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { return res, fmt.Errorf(`basic authentication is disabled for this instance`) } @@ -47,7 +47,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes log.Println("compare password error:", err) return res, fmt.Errorf(`invalid password`) } - roles := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string) + roles := envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) currentRoles := strings.Split(user.Roles, ",") if len(params.Roles) > 0 { if !utils.IsValidRoles(currentRoles, params.Roles) { diff --git a/server/resolvers/magic_link_login.go b/server/resolvers/magic_link_login.go index 6aaa81b..b9a2318 100644 --- a/server/resolvers/magic_link_login.go +++ b/server/resolvers/magic_link_login.go @@ -19,7 +19,7 @@ import ( func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) { var res *model.Response - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableMagicLinkLogin).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) { return res, fmt.Errorf(`magic link login is disabled for this instance`) } @@ -43,13 +43,13 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu // define roles for new user if len(params.Roles) > 0 { // check if roles exists - if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), params.Roles) { + if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) { return res, fmt.Errorf(`invalid roles`) } else { inputRoles = params.Roles } } else { - inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string) + inputRoles = envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) } user.Roles = strings.Join(inputRoles, ",") @@ -74,7 +74,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu // check if it contains protected unassigned role hasProtectedRole := false for _, ur := range unasignedRoles { - if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ur) { + if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ur) { hasProtectedRole = true } } @@ -100,7 +100,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu } } - if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) { + if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { // insert verification request verificationType := constants.VerificationTypeMagicLinkLogin token, err := utils.CreateVerificationToken(params.Email, verificationType) diff --git a/server/resolvers/reset_password.go b/server/resolvers/reset_password.go index f933ca4..fd20b85 100644 --- a/server/resolvers/reset_password.go +++ b/server/resolvers/reset_password.go @@ -16,7 +16,7 @@ import ( // ResetPasswordResolver is a resolver for reset password mutation func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) { var res *model.Response - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { return res, fmt.Errorf(`basic authentication is disabled for this instance`) } diff --git a/server/resolvers/session.go b/server/resolvers/session.go index eb02ae6..896d63a 100644 --- a/server/resolvers/session.go +++ b/server/resolvers/session.go @@ -46,7 +46,7 @@ func SessionResolver(ctx context.Context, roles []string) (*model.AuthResponse, expiresTimeObj := time.Unix(expiresAt, 0) currentTimeObj := time.Now() - claimRoleInterface := claim[envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtRoleClaim).(string)].([]interface{}) + claimRoleInterface := claim[envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim)].([]interface{}) claimRoles := make([]string, len(claimRoleInterface)) for i, v := range claimRoleInterface { claimRoles[i] = v.(string) diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 0459fcc..5dee56c 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -18,14 +18,13 @@ import ( // SignupResolver is a resolver for signup mutation func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) { - log.Println(envstore.EnvInMemoryStoreObj.GetEnvStoreClone()) gc, err := utils.GinContextFromContext(ctx) var res *model.AuthResponse if err != nil { return res, err } - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { return res, fmt.Errorf(`basic authentication is disabled for this instance`) } if params.ConfirmPassword != params.Password { @@ -55,13 +54,13 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR if len(params.Roles) > 0 { // check if roles exists - if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), params.Roles) { + if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) { return res, fmt.Errorf(`invalid roles`) } else { inputRoles = params.Roles } } else { - inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string) + inputRoles = envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) } user := db.User{ @@ -106,7 +105,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR } user.SignupMethods = constants.SignupMethodBasicAuth - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) { + if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { now := time.Now().Unix() user.EmailVerifiedAt = &now } @@ -118,7 +117,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR roles := strings.Split(user.Roles, ",") userToReturn := utils.GetResponseUserData(user) - if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) { + if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { // insert verification request verificationType := constants.VerificationTypeBasicAuthSignup token, err := utils.CreateVerificationToken(params.Email, verificationType) diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index 5113fd3..c933dcf 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -41,44 +41,48 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model return res, fmt.Errorf("error un-marshalling params: %t", err) } - updatedData := make(map[string]interface{}) + updatedData := envstore.EnvInMemoryStoreObj.GetEnvStoreClone() for key, value := range data { if value != nil { fieldType := reflect.TypeOf(value).String() - if fieldType == "string" || fieldType == "bool" { - updatedData[key] = value + if fieldType == "string" { + updatedData.StringEnv[key] = value.(string) } + if fieldType == "bool" { + updatedData.BoolEnv[key] = value.(bool) + } if fieldType == "[]interface {}" { stringArr := []string{} for _, v := range value.([]interface{}) { stringArr = append(stringArr, v.(string)) } - updatedData[key] = stringArr + updatedData.SliceEnv[key] = stringArr } } } // handle derivative cases like disabling email verification & magic login // in case SMTP is off but env is set to true - if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySenderEmail] == "" || updatedData[constants.EnvKeySmtpPort] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" { - if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) { - updatedData[constants.EnvKeyDisableEmailVerification] = true + if updatedData.StringEnv[constants.EnvKeySmtpHost] == "" || updatedData.StringEnv[constants.EnvKeySmtpUsername] == "" || updatedData.StringEnv[constants.EnvKeySmtpPassword] == "" || updatedData.StringEnv[constants.EnvKeySenderEmail] == "" && updatedData.StringEnv[constants.EnvKeySmtpPort] == "" { + if !updatedData.BoolEnv[constants.EnvKeyDisableEmailVerification] { + updatedData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true } - if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) { - updatedData[constants.EnvKeyDisableMagicLinkLogin] = true + if !updatedData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] { + updatedData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true } } + // Update local store + envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData) - config, err := db.Mgr.GetConfig() + // Fetch the current db store and update it + env, err := db.Mgr.GetEnv() if err != nil { return res, err } - envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData) - encryptedConfig, err := utils.EncryptEnvData(updatedData) if err != nil { return res, err @@ -95,20 +99,20 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model return res, errors.New("admin secret and old admin secret are required for secret change") } - err := bcrypt.CompareHashAndPassword([]byte(*params.OldAdminSecret), []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))) + err := bcrypt.CompareHashAndPassword([]byte(*params.OldAdminSecret), []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))) if err != nil { return res, errors.New("old admin secret is not correct") } - hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) if err != nil { return res, err } utils.SetAdminCookie(gc, hashedKey) } - config.Config = encryptedConfig - _, err = db.Mgr.UpdateConfig(config) + env.EnvData = encryptedConfig + _, err = db.Mgr.UpdateEnv(env) if err != nil { log.Println("error updating config:", err) return res, err diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go index 6c84fe7..ae7e97b 100644 --- a/server/resolvers/update_user.go +++ b/server/resolvers/update_user.go @@ -124,7 +124,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod inputRoles = append(inputRoles, *item) } - if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string)...)...), inputRoles) { + if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...), inputRoles) { return res, fmt.Errorf("invalid list of roles") } diff --git a/server/routes/routes.go b/server/routes/routes.go index 0a8f938..1e92d62 100644 --- a/server/routes/routes.go +++ b/server/routes/routes.go @@ -25,7 +25,7 @@ func InitRouter() *gin.Engine { router.LoadHTMLGlob("templates/*") // login page app related routes. - if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableLoginPage).(bool) { + if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) { app := router.Group("/app") { app.Static("/build", "app/build") diff --git a/server/session/session.go b/server/session/session.go index 62331d7..aca4555 100644 --- a/server/session/session.go +++ b/server/session/session.go @@ -107,9 +107,9 @@ func RemoveSocialLoginState(key string) { // InitializeSessionStore initializes the SessionStoreObj based on environment variables func InitSession() { - if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRedisURL).(string) != "" { + if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" { log.Println("using redis store to save sessions") - opt, err := redis.ParseURL(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRedisURL).(string)) + opt, err := redis.ParseURL(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)) if err != nil { log.Fatalln("Error parsing redis url:", err) } diff --git a/server/test/admin_login_test.go b/server/test/admin_login_test.go index 4bdb8e8..63307c1 100644 --- a/server/test/admin_login_test.go +++ b/server/test/admin_login_test.go @@ -21,7 +21,7 @@ func adminLoginTests(t *testing.T, s TestSetup) { assert.NotNil(t, err) _, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{ - AdminSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string), + AdminSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret), }) assert.Nil(t, err) diff --git a/server/test/admin_logout_test.go b/server/test/admin_logout_test.go index 26b3011..3a885c1 100644 --- a/server/test/admin_logout_test.go +++ b/server/test/admin_logout_test.go @@ -18,9 +18,9 @@ func adminLogoutTests(t *testing.T, s TestSetup) { _, err := resolvers.AdminLogoutResolver(ctx) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.AdminLogoutResolver(ctx) assert.Nil(t, err) diff --git a/server/test/admin_session_test.go b/server/test/admin_session_test.go index 259f088..d859e98 100644 --- a/server/test/admin_session_test.go +++ b/server/test/admin_session_test.go @@ -20,9 +20,9 @@ func adminSessionTests(t *testing.T, s TestSetup) { log.Println("error:", err) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.AdminSessionResolver(ctx) assert.Nil(t, err) diff --git a/server/test/admin_signup_test.go b/server/test/admin_signup_test.go index 1fbd750..e48822a 100644 --- a/server/test/admin_signup_test.go +++ b/server/test/admin_signup_test.go @@ -21,7 +21,7 @@ func adminSignupTests(t *testing.T, s TestSetup) { assert.NotNil(t, err) // reset env for test to pass - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAdminSecret, "") + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, "") _, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{ AdminSecret: uuid.New().String(), diff --git a/server/test/delete_user_test.go b/server/test/delete_user_test.go index 45faf58..398e33e 100644 --- a/server/test/delete_user_test.go +++ b/server/test/delete_user_test.go @@ -28,9 +28,9 @@ func deleteUserTest(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{ Email: email, diff --git a/server/test/env_file_test.go b/server/test/env_file_test.go index 0452239..496e79f 100644 --- a/server/test/env_file_test.go +++ b/server/test/env_file_test.go @@ -10,20 +10,20 @@ import ( ) func TestEnvs(t *testing.T) { - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEnvPath, "../../.env.sample") + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, "../../.env.sample") env.InitEnv() store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone() - assert.Equal(t, store[constants.EnvKeyAdminSecret].(string), "admin") - assert.Equal(t, store[constants.EnvKeyEnv].(string), "production") - assert.False(t, store[constants.EnvKeyDisableEmailVerification].(bool)) - assert.False(t, store[constants.EnvKeyDisableMagicLinkLogin].(bool)) - assert.False(t, store[constants.EnvKeyDisableBasicAuthentication].(bool)) - assert.Equal(t, store[constants.EnvKeyJwtType].(string), "HS256") - assert.Equal(t, store[constants.EnvKeyJwtSecret].(string), "random_string") - assert.Equal(t, store[constants.EnvKeyJwtRoleClaim].(string), "role") - assert.EqualValues(t, store[constants.EnvKeyRoles].([]string), []string{"user"}) - assert.EqualValues(t, store[constants.EnvKeyDefaultRoles].([]string), []string{"user"}) - assert.EqualValues(t, store[constants.EnvKeyProtectedRoles].([]string), []string{"admin"}) - assert.EqualValues(t, store[constants.EnvKeyAllowedOrigins].([]string), []string{"*"}) + assert.Equal(t, store.StringEnv[constants.EnvKeyAdminSecret], "admin") + assert.Equal(t, store.StringEnv[constants.EnvKeyEnv], "production") + assert.False(t, store.BoolEnv[constants.EnvKeyDisableEmailVerification]) + assert.False(t, store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin]) + assert.False(t, store.BoolEnv[constants.EnvKeyDisableBasicAuthentication]) + assert.Equal(t, store.StringEnv[constants.EnvKeyJwtType], "HS256") + assert.Equal(t, store.StringEnv[constants.EnvKeyJwtSecret], "random_string") + assert.Equal(t, store.StringEnv[constants.EnvKeyJwtRoleClaim], "role") + assert.EqualValues(t, store.SliceEnv[constants.EnvKeyRoles], []string{"user"}) + assert.EqualValues(t, store.SliceEnv[constants.EnvKeyDefaultRoles], []string{"user"}) + assert.EqualValues(t, store.SliceEnv[constants.EnvKeyProtectedRoles], []string{"admin"}) + assert.EqualValues(t, store.SliceEnv[constants.EnvKeyAllowedOrigins], []string{"*"}) } diff --git a/server/test/env_test.go b/server/test/env_test.go index 8f53aa0..3160e67 100644 --- a/server/test/env_test.go +++ b/server/test/env_test.go @@ -12,20 +12,20 @@ import ( "github.com/stretchr/testify/assert" ) -func configTests(t *testing.T, s TestSetup) { +func envTests(t *testing.T, s TestSetup) { t.Helper() - t.Run(`should get config`, func(t *testing.T) { + t.Run(`should get envs`, func(t *testing.T) { req, ctx := createContext(s) _, err := resolvers.EnvResolver(ctx) log.Println("error:", err) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) res, err := resolvers.EnvResolver(ctx) assert.Nil(t, err) - assert.Equal(t, *res.AdminSecret, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + assert.Equal(t, *res.AdminSecret, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) }) } diff --git a/server/test/logout_test.go b/server/test/logout_test.go index 9c7def5..da390bd 100644 --- a/server/test/logout_test.go +++ b/server/test/logout_test.go @@ -28,7 +28,7 @@ func logoutTests(t *testing.T, s TestSetup) { }) token := *verifyRes.AccessToken - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token)) _, err = resolvers.LogoutResolver(ctx) assert.Nil(t, err) _, err = resolvers.ProfileResolver(ctx) diff --git a/server/test/magic_link_login_test.go b/server/test/magic_link_login_test.go index 9841ad7..9615194 100644 --- a/server/test/magic_link_login_test.go +++ b/server/test/magic_link_login_test.go @@ -29,7 +29,7 @@ func magicLinkLoginTests(t *testing.T, s TestSetup) { }) token := *verifyRes.AccessToken - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token)) _, err = resolvers.ProfileResolver(ctx) assert.Nil(t, err) diff --git a/server/test/profile_test.go b/server/test/profile_test.go index 45d07fd..6450b37 100644 --- a/server/test/profile_test.go +++ b/server/test/profile_test.go @@ -33,7 +33,7 @@ func profileTests(t *testing.T, s TestSetup) { }) token := *verifyRes.AccessToken - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token)) profileRes, err := resolvers.ProfileResolver(ctx) assert.Nil(t, err) diff --git a/server/test/resolvers_test.go b/server/test/resolvers_test.go index 9651a1c..0d6a3db 100644 --- a/server/test/resolvers_test.go +++ b/server/test/resolvers_test.go @@ -15,19 +15,19 @@ func TestResolvers(t *testing.T) { // constants.DbTypeArangodb: "http://localhost:8529", // constants.DbTypeMongodb: "mongodb://localhost:27017", } - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyVersion, "test") + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyVersion, "test") for dbType, dbURL := range databases { - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL) - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyDatabaseType, dbType) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseURL, dbURL) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseType, dbType) env.InitEnv() db.InitDB() // clean the persisted config for test to use fresh config - config, err := db.Mgr.GetConfig() + envData, err := db.Mgr.GetEnv() if err == nil { - config.Config = []byte{} - db.Mgr.UpdateConfig(config) + envData.EnvData = []byte{} + db.Mgr.UpdateEnv(envData) } env.PersistEnv() @@ -44,8 +44,8 @@ func TestResolvers(t *testing.T) { adminLoginTests(t, s) adminLogoutTests(t, s) adminSessionTests(t, s) - updateConfigTests(t, s) - configTests(t, s) + updateEnvTests(t, s) + envTests(t, s) // user tests loginTests(t, s) diff --git a/server/test/session_test.go b/server/test/session_test.go index 1b4e7eb..40a6510 100644 --- a/server/test/session_test.go +++ b/server/test/session_test.go @@ -33,7 +33,7 @@ func sessionTests(t *testing.T, s TestSetup) { }) token := *verifyRes.AccessToken - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token)) sessionRes, err := resolvers.SessionResolver(ctx, []string{}) assert.Nil(t, err) diff --git a/server/test/test.go b/server/test/test.go index 898d14e..42f4406 100644 --- a/server/test/test.go +++ b/server/test/test.go @@ -3,6 +3,7 @@ package test import ( "context" "fmt" + "log" "net/http" "net/http/httptest" "time" @@ -72,7 +73,8 @@ func testSetup() TestSetup { Password: "test", } - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEnvPath, "../../.env.sample") + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, "../../.env.sample") + log.Println("envstore", envstore.EnvInMemoryStoreObj.GetEnvStoreClone()) env.InitEnv() session.InitSession() diff --git a/server/test/update_config_test.go b/server/test/update_config_test.go deleted file mode 100644 index 7dfcfd2..0000000 --- a/server/test/update_config_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package test - -import ( - "fmt" - "log" - "testing" - - "github.com/authorizerdev/authorizer/server/constants" - "github.com/authorizerdev/authorizer/server/envstore" - "github.com/authorizerdev/authorizer/server/graph/model" - "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/authorizerdev/authorizer/server/utils" - "github.com/stretchr/testify/assert" -) - -func updateConfigTests(t *testing.T, s TestSetup) { - t.Helper() - t.Run(`should update configs`, func(t *testing.T) { - req, ctx := createContext(s) - originalAppURL := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAppURL).(string) - - data := model.UpdateEnvInput{} - _, err := resolvers.UpdateEnvResolver(ctx, data) - log.Println("error:", err) - assert.NotNil(t, err) - - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) - assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) - newURL := "https://test.com" - data = model.UpdateEnvInput{ - AppURL: &newURL, - } - _, err = resolvers.UpdateEnvResolver(ctx, data) - log.Println("error:", err) - assert.Nil(t, err) - assert.Equal(t, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAppURL).(string), newURL) - data = model.UpdateEnvInput{ - AppURL: &originalAppURL, - } - _, err = resolvers.UpdateEnvResolver(ctx, data) - assert.Nil(t, err) - }) -} diff --git a/server/test/update_env_test.go b/server/test/update_env_test.go new file mode 100644 index 0000000..7a7b65d --- /dev/null +++ b/server/test/update_env_test.go @@ -0,0 +1,54 @@ +package test + +import ( + "fmt" + "log" + "testing" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/envstore" + "github.com/authorizerdev/authorizer/server/graph/model" + "github.com/authorizerdev/authorizer/server/resolvers" + "github.com/authorizerdev/authorizer/server/utils" + "github.com/stretchr/testify/assert" +) + +func updateEnvTests(t *testing.T, s TestSetup) { + t.Helper() + t.Run(`should update envs`, func(t *testing.T) { + req, ctx := createContext(s) + originalAppURL := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL) + + data := model.UpdateEnvInput{} + _, err := resolvers.UpdateEnvResolver(ctx, data) + log.Println("error:", err) + assert.NotNil(t, err) + + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + assert.Nil(t, err) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) + newURL := "https://test.com" + disableLoginPage := true + allowedOrigins := []string{"http://localhost:8080"} + data = model.UpdateEnvInput{ + AppURL: &newURL, + DisableLoginPage: &disableLoginPage, + AllowedOrigins: allowedOrigins, + } + _, err = resolvers.UpdateEnvResolver(ctx, data) + + assert.Nil(t, err) + assert.Equal(t, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL), newURL) + assert.True(t, envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage)) + assert.Equal(t, envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyAllowedOrigins), allowedOrigins) + + disableLoginPage = false + data = model.UpdateEnvInput{ + AppURL: &originalAppURL, + DisableLoginPage: &disableLoginPage, + AllowedOrigins: []string{"*"}, + } + _, err = resolvers.UpdateEnvResolver(ctx, data) + assert.Nil(t, err) + }) +} diff --git a/server/test/update_profile_test.go b/server/test/update_profile_test.go index 58a23a8..c7de158 100644 --- a/server/test/update_profile_test.go +++ b/server/test/update_profile_test.go @@ -36,7 +36,7 @@ func updateProfileTests(t *testing.T, s TestSetup) { }) token := *verifyRes.AccessToken - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token)) _, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{ FamilyName: &fName, }) diff --git a/server/test/update_user_test.go b/server/test/update_user_test.go index 429df00..58e06d3 100644 --- a/server/test/update_user_test.go +++ b/server/test/update_user_test.go @@ -33,9 +33,9 @@ func updateUserTest(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{ ID: user.ID, Roles: newRoles, diff --git a/server/test/users_test.go b/server/test/users_test.go index 8c4d62a..437effb 100644 --- a/server/test/users_test.go +++ b/server/test/users_test.go @@ -26,9 +26,9 @@ func usersTest(t *testing.T, s TestSetup) { users, err := resolvers.UsersResolver(ctx) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) users, err = resolvers.UsersResolver(ctx) assert.Nil(t, err) rLen := len(users) diff --git a/server/test/validator_test.go b/server/test/validator_test.go index 646be5b..798bba3 100644 --- a/server/test/validator_test.go +++ b/server/test/validator_test.go @@ -22,7 +22,7 @@ func TestIsValidEmail(t *testing.T) { func TestIsValidOrigin(t *testing.T) { // don't use portocal(http/https) for ALLOWED_ORIGINS while testing, // as we trim them off while running the main function - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAllowedOrigins, []string{"localhost:8080", "*.google.com", "*.google.in", "*abc.*"}) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyAllowedOrigins, []string{"localhost:8080", "*.google.com", "*.google.in", "*abc.*"}) assert.False(t, utils.IsValidOrigin("http://myapp.com"), "it should be invalid origin") assert.False(t, utils.IsValidOrigin("http://appgoogle.com"), "it should be invalid origin") assert.True(t, utils.IsValidOrigin("http://app.google.com"), "it should be valid origin") @@ -32,7 +32,7 @@ func TestIsValidOrigin(t *testing.T) { assert.True(t, utils.IsValidOrigin("http://xyx.abc.in"), "it should be valid origin") assert.True(t, utils.IsValidOrigin("http://xyxabc.in"), "it should be valid origin") assert.True(t, utils.IsValidOrigin("http://localhost:8080"), "it should be valid origin") - envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAllowedOrigins, []string{"*"}) + envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyAllowedOrigins, []string{"*"}) } func TestIsValidIdentifier(t *testing.T) { diff --git a/server/test/verification_requests_test.go b/server/test/verification_requests_test.go index 2c7de87..f434539 100644 --- a/server/test/verification_requests_test.go +++ b/server/test/verification_requests_test.go @@ -28,9 +28,9 @@ func verificationRequestsTest(t *testing.T, s TestSetup) { requests, err := resolvers.VerificationRequestsResolver(ctx) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) - req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h)) + req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) requests, err = resolvers.VerificationRequestsResolver(ctx) assert.Nil(t, err) diff --git a/server/utils/auth_token.go b/server/utils/auth_token.go index 984ab9f..c907bfe 100644 --- a/server/utils/auth_token.go +++ b/server/utils/auth_token.go @@ -21,7 +21,7 @@ import ( // CreateAuthToken util to create JWT token, based on // user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT func CreateAuthToken(user db.User, tokenType string, roles []string) (string, int64, error) { - t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtType).(string))) + t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType))) expiryBound := time.Hour if tokenType == constants.TokenTypeRefreshToken { // expires in 1 year @@ -35,7 +35,7 @@ func CreateAuthToken(user db.User, tokenType string, roles []string) (string, in var userMap map[string]interface{} json.Unmarshal(userBytes, &userMap) - claimKey := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtRoleClaim).(string) + claimKey := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim) customClaims := jwt.MapClaims{ "exp": expiresAt, "iat": time.Now().Unix(), @@ -82,7 +82,7 @@ func CreateAuthToken(user db.User, tokenType string, roles []string) (string, in t.Claims = customClaims - token, err := t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtSecret).(string))) + token, err := t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret))) if err != nil { return "", 0, err } @@ -112,7 +112,7 @@ func VerifyAuthToken(token string) (map[string]interface{}, error) { claims := jwt.MapClaims{} _, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) { - return []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtSecret).(string)), nil + return []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)), nil }) if err != nil { return res, err @@ -134,7 +134,7 @@ func VerifyAuthToken(token string) (map[string]interface{}, error) { // CreateAdminAuthToken creates the admin token based on secret key func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) { - return EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)) + return EncryptPassword(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) } // GetAdminAuthToken helps in getting the admin token from the request cookie @@ -151,7 +151,7 @@ func GetAdminAuthToken(gc *gin.Context) (string, error) { return "", err } - err = bcrypt.CompareHashAndPassword([]byte(decodedValue), []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))) + err = bcrypt.CompareHashAndPassword([]byte(decodedValue), []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))) log.Println("error comparing hash:", err) if err != nil { return "", fmt.Errorf(`unauthorized`) diff --git a/server/utils/cookie.go b/server/utils/cookie.go index c64e233..a30b350 100644 --- a/server/utils/cookie.go +++ b/server/utils/cookie.go @@ -15,22 +15,22 @@ import ( func SetCookie(gc *gin.Context, token string) { secure := true httpOnly := true - host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) - domain := GetDomainName(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) + host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) + domain := GetDomainName(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) if domain != "localhost" { domain = "." + domain } gc.SetSameSite(http.SameSiteNoneMode) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token, 3600, "/", host, secure, httpOnly) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string)+"-client", token, 3600, "/", domain, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), token, 3600, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"-client", token, 3600, "/", domain, secure, httpOnly) } // GetCookie gets the cookie from the request func GetCookie(gc *gin.Context) (string, error) { - cookie, err := gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string)) + cookie, err := gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)) if err != nil { - cookie, err = gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string) + "-client") + cookie, err = gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName) + "-client") if err != nil { return "", err } @@ -44,28 +44,28 @@ func DeleteCookie(gc *gin.Context) { secure := true httpOnly := true - host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) - domain := GetDomainName(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) + host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) + domain := GetDomainName(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) if domain != "localhost" { domain = "." + domain } gc.SetSameSite(http.SameSiteNoneMode) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), "", -1, "/", host, secure, httpOnly) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string)+"-client", "", -1, "/", domain, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName), "", -1, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"-client", "", -1, "/", domain, secure, httpOnly) } // SetAdminCookie sets the admin cookie in the response func SetAdminCookie(gc *gin.Context, token string) { secure := true httpOnly := true - host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) + host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), token, 3600, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), token, 3600, "/", host, secure, httpOnly) } func GetAdminCookie(gc *gin.Context) (string, error) { - cookie, err := gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string)) + cookie, err := gc.Request.Cookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName)) if err != nil { return "", err } @@ -75,7 +75,7 @@ func GetAdminCookie(gc *gin.Context) (string, error) { func DeleteAdminCookie(gc *gin.Context) { secure := true httpOnly := true - host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)) + host, _ := GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)) - gc.SetCookie(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), "", -1, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), "", -1, "/", host, secure, httpOnly) } diff --git a/server/utils/crypto.go b/server/utils/crypto.go index 5a872d9..b965a64 100644 --- a/server/utils/crypto.go +++ b/server/utils/crypto.go @@ -29,7 +29,7 @@ func DecryptB64(s string) (string, error) { // EncryptAES encrypts data using AES algorithm func EncryptAES(text []byte) ([]byte, error) { - key := []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyEncryptionKey).(string)) + key := []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)) c, err := aes.NewCipher(key) var res []byte if err != nil { @@ -63,7 +63,7 @@ func EncryptAES(text []byte) ([]byte, error) { // DecryptAES decrypts data using AES algorithm func DecryptAES(ciphertext []byte) ([]byte, error) { - key := []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyEncryptionKey).(string)) + key := []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)) c, err := aes.NewCipher(key) var res []byte if err != nil { @@ -90,7 +90,7 @@ func DecryptAES(ciphertext []byte) ([]byte, error) { } // EncryptEnvData is used to encrypt the env data -func EncryptEnvData(data map[string]interface{}) ([]byte, error) { +func EncryptEnvData(data envstore.Store) ([]byte, error) { jsonBytes, err := json.Marshal(data) if err != nil { return []byte{}, err diff --git a/server/utils/meta.go b/server/utils/meta.go index 888aca3..c94f0ff 100644 --- a/server/utils/meta.go +++ b/server/utils/meta.go @@ -9,12 +9,12 @@ import ( // GetMeta helps in getting the meta data about the deployment from EnvData func GetMetaInfo() model.Meta { return model.Meta{ - Version: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyVersion).(string), - IsGoogleLoginEnabled: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientSecret).(string) != "", - IsGithubLoginEnabled: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientSecret).(string) != "", - IsFacebookLoginEnabled: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientSecret).(string) != "", - IsBasicAuthenticationEnabled: !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool), - IsEmailVerificationEnabled: !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool), - IsMagicLinkLoginEnabled: !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableMagicLinkLogin).(bool), + Version: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyVersion), + IsGoogleLoginEnabled: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret) != "", + IsGithubLoginEnabled: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret) != "", + IsFacebookLoginEnabled: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID) != "" && envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret) != "", + IsBasicAuthenticationEnabled: !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication), + IsEmailVerificationEnabled: !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification), + IsMagicLinkLoginEnabled: !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin), } } diff --git a/server/utils/validator.go b/server/utils/validator.go index be708f1..1c85ee8 100644 --- a/server/utils/validator.go +++ b/server/utils/validator.go @@ -18,8 +18,8 @@ func IsValidEmail(email string) bool { // IsValidOrigin validates origin based on ALLOWED_ORIGINS func IsValidOrigin(url string) bool { - allowedOrigins := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAllowedOrigins).([]interface{}) - if len(allowedOrigins) == 1 && allowedOrigins[0].(string) == "*" { + allowedOrigins := envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyAllowedOrigins) + if len(allowedOrigins) == 1 && allowedOrigins[0] == "*" { return true } @@ -28,10 +28,10 @@ func IsValidOrigin(url string) bool { currentOrigin := hostName + ":" + port for _, origin := range allowedOrigins { - replacedString := origin.(string) + replacedString := origin // if has regex whitelisted domains - if strings.Contains(origin.(string), "*") { - replacedString = strings.Replace(origin.(string), ".", "\\.", -1) + if strings.Contains(origin, "*") { + replacedString = strings.Replace(origin, ".", "\\.", -1) replacedString = strings.Replace(replacedString, "*", ".*", -1) if strings.HasPrefix(replacedString, ".*") { @@ -61,7 +61,7 @@ func IsSuperAdmin(gc *gin.Context) bool { return false } - return secret == envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string) + return secret == envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) } return token != "" diff --git a/server/utils/verification_token.go b/server/utils/verification_token.go index 73a1c7b..bea1ca4 100644 --- a/server/utils/verification_token.go +++ b/server/utils/verification_token.go @@ -26,24 +26,24 @@ type CustomClaim struct { // CreateVerificationToken creates a verification JWT token func CreateVerificationToken(email string, tokenType string) (string, error) { - t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtType).(string))) + t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType))) t.Claims = &CustomClaim{ &jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), }, tokenType, - UserInfo{Email: email, Host: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string), RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAppURL).(string)}, + UserInfo{Email: email, Host: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL), RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)}, } - return t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtSecret).(string))) + return t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret))) } // VerifyVerificationToken verifies the verification JWT token func VerifyVerificationToken(token string) (*CustomClaim, error) { claims := &CustomClaim{} _, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) { - return []byte(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtSecret).(string)), nil + return []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)), nil }) if err != nil { return claims, err