fix: import cycle issues

This commit is contained in:
Lakhan Samani 2022-05-30 11:54:16 +05:30
parent 1146468a03
commit 7e3bd6a721
37 changed files with 349 additions and 239 deletions

View File

@ -1,4 +1,4 @@
package utils package cli
var ( var (
// ARG_DB_URL is the cli arg variable for the database url // ARG_DB_URL is the cli arg variable for the database url

View File

@ -4,7 +4,7 @@ import (
"net/url" "net/url"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -12,8 +12,8 @@ import (
func SetAdminCookie(gc *gin.Context, token string) { func SetAdminCookie(gc *gin.Context, token string) {
secure := true secure := true
httpOnly := true httpOnly := true
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
host, _ := utils.GetHostParts(hostname) host, _ := parsers.GetHostParts(hostname)
gc.SetCookie(constants.AdminCookieName, token, 3600, "/", host, secure, httpOnly) gc.SetCookie(constants.AdminCookieName, token, 3600, "/", host, secure, httpOnly)
} }
@ -37,7 +37,7 @@ func GetAdminCookie(gc *gin.Context) (string, error) {
func DeleteAdminCookie(gc *gin.Context) { func DeleteAdminCookie(gc *gin.Context) {
secure := true secure := true
httpOnly := true httpOnly := true
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
host, _ := utils.GetHostParts(hostname) host, _ := parsers.GetHostParts(hostname)
gc.SetCookie(constants.AdminCookieName, "", -1, "/", host, secure, httpOnly) gc.SetCookie(constants.AdminCookieName, "", -1, "/", host, secure, httpOnly)
} }

View File

@ -5,7 +5,7 @@ import (
"net/url" "net/url"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -13,9 +13,9 @@ import (
func SetSession(gc *gin.Context, sessionID string) { func SetSession(gc *gin.Context, sessionID string) {
secure := true secure := true
httpOnly := true httpOnly := true
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
host, _ := utils.GetHostParts(hostname) host, _ := parsers.GetHostParts(hostname)
domain := utils.GetDomainName(hostname) domain := parsers.GetDomainName(hostname)
if domain != "localhost" { if domain != "localhost" {
domain = "." + domain domain = "." + domain
} }
@ -32,9 +32,9 @@ func SetSession(gc *gin.Context, sessionID string) {
func DeleteSession(gc *gin.Context) { func DeleteSession(gc *gin.Context) {
secure := true secure := true
httpOnly := true httpOnly := true
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
host, _ := utils.GetHostParts(hostname) host, _ := parsers.GetHostParts(hostname)
domain := utils.GetDomainName(hostname) domain := parsers.GetDomainName(hostname)
if domain != "localhost" { if domain != "localhost" {
domain = "." + domain domain = "." + domain
} }

3
server/env/env.go vendored
View File

@ -11,6 +11,7 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -251,7 +252,7 @@ func InitAllEnv() error {
trimVal := strings.TrimSpace(val) trimVal := strings.TrimSpace(val)
if trimVal != "" { if trimVal != "" {
if trimVal != "*" { if trimVal != "*" {
host, port := utils.GetHostParts(trimVal) host, port := parsers.GetHostParts(trimVal)
allowedOrigins = append(allowedOrigins, host+":"+port) allowedOrigins = append(allowedOrigins, host+":"+port)
} else { } else {
hasWildCard = true hasWildCard = true

View File

@ -15,6 +15,7 @@ import (
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// GetEnvData returns the env data from database // GetEnvData returns the env data from database
@ -138,7 +139,7 @@ func PersistEnv() error {
case constants.EnvKeyRoles, constants.EnvKeyDefaultRoles, constants.EnvKeyProtectedRoles: case constants.EnvKeyRoles, constants.EnvKeyDefaultRoles, constants.EnvKeyProtectedRoles:
envStringArr := strings.Split(envValue, ",") envStringArr := strings.Split(envValue, ",")
originalValue := utils.ConvertInterfaceToStringSlice(value) originalValue := utils.ConvertInterfaceToStringSlice(value)
if !utils.IsStringArrayEqual(originalValue, envStringArr) { if !validators.IsStringArrayEqual(originalValue, envStringArr) {
storeData[key] = envStringArr storeData[key] = envStringArr
hasChanged = true hasChanged = true
} }

View File

@ -9,7 +9,8 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/validators"
) )
// State is the struct that holds authorizer url and redirect url // State is the struct that holds authorizer url and redirect url
@ -22,7 +23,7 @@ type State struct {
// AppHandler is the handler for the /app route // AppHandler is the handler for the /app route
func AppHandler() gin.HandlerFunc { func AppHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
hostname := utils.GetHost(c) hostname := parsers.GetHost(c)
if isLoginPageDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage); err != nil || isLoginPageDisabled { if isLoginPageDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage); err != nil || isLoginPageDisabled {
log.Debug("Login page is disabled") log.Debug("Login page is disabled")
c.JSON(400, gin.H{"error": "login page is not enabled"}) c.JSON(400, gin.H{"error": "login page is not enabled"})
@ -44,7 +45,7 @@ func AppHandler() gin.HandlerFunc {
redirect_uri = hostname + "/app" redirect_uri = hostname + "/app"
} else { } else {
// validate redirect url with allowed origins // validate redirect url with allowed origins
if !utils.IsValidOrigin(redirect_uri) { if !validators.IsValidOrigin(redirect_uri) {
log.Debug("Invalid redirect_uri") log.Debug("Invalid redirect_uri")
c.JSON(400, gin.H{"error": "invalid redirect url"}) c.JSON(400, gin.H{"error": "invalid redirect url"})
return return

View File

@ -10,13 +10,14 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/oauth" "github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/validators"
) )
// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback // OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
func OAuthLoginHandler() gin.HandlerFunc { func OAuthLoginHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
hostname := utils.GetHost(c) hostname := parsers.GetHost(c)
// deprecating redirectURL instead use redirect_uri // deprecating redirectURL instead use redirect_uri
redirectURI := strings.TrimSpace(c.Query("redirectURL")) redirectURI := strings.TrimSpace(c.Query("redirectURL"))
if redirectURI == "" { if redirectURI == "" {
@ -64,7 +65,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
log.Debug("Error getting protected roles: ", err) log.Debug("Error getting protected roles: ", err)
} }
if !utils.IsValidRoles(rolesSplit, append([]string{}, append(roles, protectedRoles...)...)) { if !validators.IsValidRoles(rolesSplit, append([]string{}, append(roles, protectedRoles...)...)) {
log.Debug("Invalid roles: ", roles) log.Debug("Invalid roles: ", roles)
c.JSON(400, gin.H{ c.JSON(400, gin.H{
"error": "invalid role", "error": "invalid role",

View File

@ -5,13 +5,13 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/parsers"
) )
// OpenIDConfigurationHandler handler for open-id configurations // OpenIDConfigurationHandler handler for open-id configurations
func OpenIDConfigurationHandler() gin.HandlerFunc { func OpenIDConfigurationHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
issuer := utils.GetHost(c) issuer := parsers.GetHost(c)
jwtType, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType) jwtType, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
c.JSON(200, gin.H{ c.JSON(200, gin.H{

View File

@ -13,6 +13,7 @@ import (
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -40,7 +41,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
} }
// verify if token exists in db // verify if token exists in db
hostname := utils.GetHost(c) hostname := parsers.GetHost(c)
claim, err := token.ParseJWTToken(tokenInQuery, hostname, verificationRequest.Nonce, verificationRequest.Email) claim, err := token.ParseJWTToken(tokenInQuery, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil { if err != nil {
log.Debug("Error parsing token: ", err) log.Debug("Error parsing token: ", err)

View File

@ -6,13 +6,13 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cli"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/env" "github.com/authorizerdev/authorizer/server/env"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/oauth" "github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/routes" "github.com/authorizerdev/authorizer/server/routes"
"github.com/authorizerdev/authorizer/server/utils"
) )
var VERSION string var VERSION string
@ -27,10 +27,10 @@ func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
} }
func main() { func main() {
utils.ARG_DB_URL = flag.String("database_url", "", "Database connection string") cli.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
utils.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite") cli.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
utils.ARG_ENV_FILE = flag.String("env_file", "", "Env file path") cli.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
utils.ARG_LOG_LEVEL = flag.String("log_level", "info", "Log level, possible values are debug,info,warn,error,fatal,panic") cli.ARG_LOG_LEVEL = flag.String("log_level", "info", "Log level, possible values are debug,info,warn,error,fatal,panic")
flag.Parse() flag.Parse()
// global log level // global log level
@ -41,7 +41,7 @@ func main() {
log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}}) log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
var logLevel logrus.Level var logLevel logrus.Level
switch *utils.ARG_LOG_LEVEL { switch *cli.ARG_LOG_LEVEL {
case "debug": case "debug":
logLevel = logrus.DebugLevel logLevel = logrus.DebugLevel
case "info": case "info":
@ -107,5 +107,11 @@ func main() {
router := routes.InitRouter(log) router := routes.InitRouter(log)
log.Info("Starting Authorizer: ", VERSION) log.Info("Starting Authorizer: ", VERSION)
router.Run(":" + memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyPort)) port, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyPort)
if err != nil {
log.Info("Error while getting port from env using default port 8080: ", err)
port = "8080"
}
router.Run(":" + port)
} }

View File

@ -2,8 +2,6 @@ package inmemory
import ( import (
"strings" "strings"
"github.com/authorizerdev/authorizer/server/utils"
) )
// ClearStore clears the in-memory store. // ClearStore clears the in-memory store.
@ -105,6 +103,12 @@ func (c *provider) GetBoolStoreEnvVariable(key string) (bool, error) {
// GetSliceStoreEnvVariable to get the env variable from slice store object // GetSliceStoreEnvVariable to get the env variable from slice store object
func (c *provider) GetSliceStoreEnvVariable(key string) ([]string, error) { func (c *provider) GetSliceStoreEnvVariable(key string) ([]string, error) {
res := c.envStore.Get(key) res := c.envStore.Get(key)
resSlice := utils.ConvertInterfaceToStringSlice(res) data := res.([]interface{})
var resSlice []string
for _, v := range data {
resSlice = append(resSlice, v.(string))
}
return resSlice, nil return resSlice, nil
} }

View File

@ -9,8 +9,8 @@ import (
"github.com/joho/godotenv" "github.com/joho/godotenv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cli"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/utils"
) )
// RequiredEnv holds information about required envs // RequiredEnv holds information about required envs
@ -62,8 +62,8 @@ func InitRequiredEnv() error {
} }
} }
if utils.ARG_ENV_FILE != nil && *utils.ARG_ENV_FILE != "" { if cli.ARG_ENV_FILE != nil && *cli.ARG_ENV_FILE != "" {
envPath = *utils.ARG_ENV_FILE envPath = *cli.ARG_ENV_FILE
} }
log.Info("env path: ", envPath) log.Info("env path: ", envPath)
@ -85,8 +85,8 @@ func InitRequiredEnv() error {
redisURL := os.Getenv(constants.EnvKeyRedisURL) redisURL := os.Getenv(constants.EnvKeyRedisURL)
if strings.TrimSpace(dbType) == "" { if strings.TrimSpace(dbType) == "" {
if utils.ARG_DB_TYPE != nil && *utils.ARG_DB_TYPE != "" { if cli.ARG_DB_TYPE != nil && *cli.ARG_DB_TYPE != "" {
dbType = strings.TrimSpace(*utils.ARG_DB_TYPE) dbType = strings.TrimSpace(*cli.ARG_DB_TYPE)
} }
if dbType == "" { if dbType == "" {
@ -96,8 +96,8 @@ func InitRequiredEnv() error {
} }
if strings.TrimSpace(dbURL) == "" { if strings.TrimSpace(dbURL) == "" {
if utils.ARG_DB_URL != nil && *utils.ARG_DB_URL != "" { if cli.ARG_DB_URL != nil && *cli.ARG_DB_URL != "" {
dbURL = strings.TrimSpace(*utils.ARG_DB_URL) dbURL = strings.TrimSpace(*cli.ARG_DB_URL)
} }
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" { if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {

View File

@ -1,7 +1,7 @@
package middlewares package middlewares
import ( import (
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/validators"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -10,7 +10,7 @@ func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
origin := c.Request.Header.Get("Origin") origin := c.Request.Header.Get("Origin")
if utils.IsValidOrigin(origin) { if validators.IsValidOrigin(origin) {
c.Writer.Header().Set("Access-Control-Allow-Origin", origin) c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
} }

View File

@ -1,4 +1,4 @@
package utils package parsers
import ( import (
"net/url" "net/url"
@ -19,7 +19,10 @@ func GetHost(c *gin.Context) string {
return authorizerURL return authorizerURL
} }
authorizerURL = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) authorizerURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)
if err == nil {
authorizerURL = ""
}
if authorizerURL != "" { if authorizerURL != "" {
return authorizerURL return authorizerURL
} }
@ -89,8 +92,8 @@ func GetDomainName(uri string) string {
// GetAppURL to get /app/ url if not configured by user // GetAppURL to get /app/ url if not configured by user
func GetAppURL(gc *gin.Context) string { func GetAppURL(gc *gin.Context) string {
envAppURL := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppURL) envAppURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
if envAppURL == "" { if envAppURL == "" || err != nil {
envAppURL = GetHost(gc) + "/app" envAppURL = GetHost(gc) + "/app"
} }
return envAppURL return envAppURL

View File

@ -14,8 +14,10 @@ import (
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// ForgotPasswordResolver is a resolver for forgot password mutation // ForgotPasswordResolver is a resolver for forgot password mutation
@ -39,7 +41,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
} }
params.Email = strings.ToLower(params.Email) params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) { if !validators.IsValidEmail(params.Email) {
log.Debug("Invalid email address: ", params.Email) log.Debug("Invalid email address: ", params.Email)
return res, fmt.Errorf("invalid email") return res, fmt.Errorf("invalid email")
} }
@ -53,13 +55,13 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
return res, fmt.Errorf(`user with this email not found`) return res, fmt.Errorf(`user with this email not found`)
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
_, nonceHash, err := utils.GenerateNonce() _, nonceHash, err := utils.GenerateNonce()
if err != nil { if err != nil {
log.Debug("Failed to generate nonce: ", err) log.Debug("Failed to generate nonce: ", err)
return res, err return res, err
} }
redirectURL := utils.GetAppURL(gc) + "/reset-password" redirectURL := parsers.GetAppURL(gc) + "/reset-password"
if params.RedirectURI != nil { if params.RedirectURI != nil {
redirectURL = *params.RedirectURI redirectURL = *params.RedirectURI
} }

View File

@ -15,8 +15,10 @@ import (
emailservice "github.com/authorizerdev/authorizer/server/email" emailservice "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// InviteMembersResolver resolver to invite members // InviteMembersResolver resolver to invite members
@ -54,7 +56,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
// filter valid emails // filter valid emails
emails := []string{} emails := []string{}
for _, email := range params.Emails { for _, email := range params.Emails {
if utils.IsValidEmail(email) { if validators.IsValidEmail(email) {
emails = append(emails, email) emails = append(emails, email)
} }
} }
@ -93,9 +95,9 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
Email: email, Email: email,
Roles: strings.Join(defaultRoles, ","), Roles: strings.Join(defaultRoles, ","),
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
verifyEmailURL := hostname + "/verify_email" verifyEmailURL := hostname + "/verify_email"
appURL := utils.GetAppURL(gc) appURL := parsers.GetAppURL(gc)
redirectURL := appURL redirectURL := appURL
if params.RedirectURI != nil { if params.RedirectURI != nil {

View File

@ -17,6 +17,7 @@ import (
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// LoginResolver is a resolver for login mutation // LoginResolver is a resolver for login mutation
@ -78,7 +79,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
} }
currentRoles := strings.Split(user.Roles, ",") currentRoles := strings.Split(user.Roles, ",")
if len(params.Roles) > 0 { if len(params.Roles) > 0 {
if !utils.IsValidRoles(params.Roles, currentRoles) { if !validators.IsValidRoles(params.Roles, currentRoles) {
log.Debug("Invalid roles: ", params.Roles) log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf(`invalid roles`) return res, fmt.Errorf(`invalid roles`)
} }

View File

@ -14,8 +14,10 @@ import (
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// MagicLinkLoginResolver is a resolver for magic link login mutation // MagicLinkLoginResolver is a resolver for magic link login mutation
@ -41,7 +43,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
params.Email = strings.ToLower(params.Email) params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) { if !validators.IsValidEmail(params.Email) {
log.Debug("Invalid email") log.Debug("Invalid email")
return res, fmt.Errorf(`invalid email address`) return res, fmt.Errorf(`invalid email address`)
} }
@ -77,7 +79,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
log.Debug("Error getting roles: ", err) log.Debug("Error getting roles: ", err)
return res, err return res, err
} }
if !utils.IsValidRoles(params.Roles, roles) { if !validators.IsValidRoles(params.Roles, roles) {
log.Debug("Invalid roles: ", params.Roles) log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf(`invalid roles`) return res, fmt.Errorf(`invalid roles`)
} else { } else {
@ -158,7 +160,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
} }
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil { if err != nil {
log.Debug("Error getting email verification disabled: ", err) log.Debug("Error getting email verification disabled: ", err)
@ -178,7 +180,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
if params.Scope != nil && len(params.Scope) > 0 { if params.Scope != nil && len(params.Scope) > 0 {
redirectURLParams = redirectURLParams + "&scope=" + strings.Join(params.Scope, " ") redirectURLParams = redirectURLParams + "&scope=" + strings.Join(params.Scope, " ")
} }
redirectURL := utils.GetAppURL(gc) redirectURL := parsers.GetAppURL(gc)
if params.RedirectURI != nil { if params.RedirectURI != nil {
redirectURL = *params.RedirectURI redirectURL = *params.RedirectURI
} }

View File

@ -3,12 +3,90 @@ package resolvers
import ( import (
"context" "context"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// MetaResolver is a resolver for meta query // MetaResolver is a resolver for meta query
func MetaResolver(ctx context.Context) (*model.Meta, error) { func MetaResolver(ctx context.Context) (*model.Meta, error) {
metaInfo := utils.GetMetaInfo() clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if err != nil {
return nil, err
}
googleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID)
if err != nil {
log.Debug("Failed to get Google Client ID from environment variable", err)
googleClientID = ""
}
googleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret)
if err != nil {
log.Debug("Failed to get Google Client Secret from environment variable", err)
googleClientSecret = ""
}
facebookClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID)
if err != nil {
log.Debug("Failed to get Facebook Client ID from environment variable", err)
facebookClientID = ""
}
facebookClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret)
if err != nil {
log.Debug("Failed to get Facebook Client Secret from environment variable", err)
facebookClientSecret = ""
}
githubClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID)
if err != nil {
log.Debug("Failed to get Github Client ID from environment variable", err)
githubClientID = ""
}
githubClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret)
if err != nil {
log.Debug("Failed to get Github Client Secret from environment variable", err)
githubClientSecret = ""
}
isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil {
log.Debug("Failed to get Disable Basic Authentication from environment variable", err)
isBasicAuthDisabled = true
}
isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil {
log.Debug("Failed to get Disable Email Verification from environment variable", err)
isEmailVerificationDisabled = true
}
isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
if err != nil {
log.Debug("Failed to get Disable Magic Link Login from environment variable", err)
isMagicLinkLoginDisabled = true
}
isSignUpDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
if err != nil {
log.Debug("Failed to get Disable Signup from environment variable", err)
isSignUpDisabled = true
}
metaInfo := model.Meta{
Version: constants.VERSION,
ClientID: clientID,
IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "",
IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "",
IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "",
IsBasicAuthenticationEnabled: !isBasicAuthDisabled,
IsEmailVerificationEnabled: !isEmailVerificationDisabled,
IsMagicLinkLoginEnabled: !isMagicLinkLoginDisabled,
IsSignUpEnabled: !isSignUpDisabled,
}
return &metaInfo, nil return &metaInfo, nil
} }

View File

@ -12,8 +12,10 @@ import (
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// ResendVerifyEmailResolver is a resolver for resend verify email mutation // ResendVerifyEmailResolver is a resolver for resend verify email mutation
@ -27,12 +29,12 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
} }
params.Email = strings.ToLower(params.Email) params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) { if !validators.IsValidEmail(params.Email) {
log.Debug("Invalid email: ", params.Email) log.Debug("Invalid email: ", params.Email)
return res, fmt.Errorf("invalid email") return res, fmt.Errorf("invalid email")
} }
if !utils.IsValidVerificationIdentifier(params.Identifier) { if !validators.IsValidVerificationIdentifier(params.Identifier) {
log.Debug("Invalid verification identifier: ", params.Identifier) log.Debug("Invalid verification identifier: ", params.Identifier)
return res, fmt.Errorf("invalid identifier") return res, fmt.Errorf("invalid identifier")
} }
@ -49,7 +51,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
log.Debug("Failed to delete verification request: ", err) log.Debug("Failed to delete verification request: ", err)
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
_, nonceHash, err := utils.GenerateNonce() _, nonceHash, err := utils.GenerateNonce()
if err != nil { if err != nil {
log.Debug("Failed to generate nonce: ", err) log.Debug("Failed to generate nonce: ", err)

View File

@ -13,8 +13,10 @@ import (
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// ResetPasswordResolver is a resolver for reset password mutation // ResetPasswordResolver is a resolver for reset password mutation
@ -48,13 +50,13 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
return res, fmt.Errorf(`passwords don't match`) return res, fmt.Errorf(`passwords don't match`)
} }
if !utils.IsValidPassword(params.Password) { if !validators.IsValidPassword(params.Password) {
log.Debug("Invalid password") log.Debug("Invalid password")
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`) return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
} }
// verify if token exists in db // verify if token exists in db
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email) claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil { if err != nil {
log.Debug("Failed to parse token: ", err) log.Debug("Failed to parse token: ", err)

View File

@ -16,8 +16,10 @@ import (
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// SignupResolver is a resolver for signup mutation // SignupResolver is a resolver for signup mutation
@ -56,14 +58,14 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, fmt.Errorf(`password and confirm password does not match`) return res, fmt.Errorf(`password and confirm password does not match`)
} }
if !utils.IsValidPassword(params.Password) { if !validators.IsValidPassword(params.Password) {
log.Debug("Invalid password") log.Debug("Invalid password")
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`) return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
} }
params.Email = strings.ToLower(params.Email) params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) { if !validators.IsValidEmail(params.Email) {
log.Debug("Invalid email: ", params.Email) log.Debug("Invalid email: ", params.Email)
return res, fmt.Errorf(`invalid email address`) return res, fmt.Errorf(`invalid email address`)
} }
@ -95,7 +97,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
log.Debug("Error getting roles: ", err) log.Debug("Error getting roles: ", err)
return res, err return res, err
} }
if !utils.IsValidRoles(roles, params.Roles) { if !validators.IsValidRoles(roles, params.Roles) {
log.Debug("Invalid roles: ", params.Roles) log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf(`invalid roles`) return res, fmt.Errorf(`invalid roles`)
} else { } else {
@ -168,7 +170,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
roles := strings.Split(user.Roles, ",") roles := strings.Split(user.Roles, ",")
userToReturn := user.AsAPIUser() userToReturn := user.AsAPIUser()
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
if !isEmailVerificationDisabled { if !isEmailVerificationDisabled {
// insert verification request // insert verification request
_, nonceHash, err := utils.GenerateNonce() _, nonceHash, err := utils.GenerateNonce()
@ -177,7 +179,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, err return res, err
} }
verificationType := constants.VerificationTypeBasicAuthSignup verificationType := constants.VerificationTypeBasicAuthSignup
redirectURL := utils.GetAppURL(gc) redirectURL := parsers.GetAppURL(gc)
if params.RedirectURI != nil { if params.RedirectURI != nil {
redirectURL = *params.RedirectURI redirectURL = *params.RedirectURI
} }

View File

@ -16,8 +16,10 @@ import (
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@ -121,14 +123,14 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.Email != nil && user.Email != *params.Email { if params.Email != nil && user.Email != *params.Email {
// check if valid email // check if valid email
if !utils.IsValidEmail(*params.Email) { if !validators.IsValidEmail(*params.Email) {
log.Debug("Failed to validate email: ", *params.Email) log.Debug("Failed to validate email: ", *params.Email)
return res, fmt.Errorf("invalid email address") return res, fmt.Errorf("invalid email address")
} }
newEmail := strings.ToLower(*params.Email) newEmail := strings.ToLower(*params.Email)
// check if valid email // check if valid email
if !utils.IsValidEmail(newEmail) { if !validators.IsValidEmail(newEmail) {
log.Debug("Failed to validate new email: ", newEmail) log.Debug("Failed to validate new email: ", newEmail)
return res, fmt.Errorf("invalid new email address") return res, fmt.Errorf("invalid new email address")
} }
@ -150,7 +152,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
return res, err return res, err
} }
if !isEmailVerificationDisabled { if !isEmailVerificationDisabled {
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
user.EmailVerifiedAt = nil user.EmailVerifiedAt = nil
hasEmailChanged = true hasEmailChanged = true
// insert verification request // insert verification request
@ -160,7 +162,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
return res, err return res, err
} }
verificationType := constants.VerificationTypeUpdateEmail verificationType := constants.VerificationTypeUpdateEmail
redirectURL := utils.GetAppURL(gc) redirectURL := parsers.GetAppURL(gc)
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL) verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
if err != nil { if err != nil {
log.Debug("Failed to create verification token: ", err) log.Debug("Failed to create verification token: ", err)

View File

@ -14,8 +14,10 @@ import (
"github.com/authorizerdev/authorizer/server/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
) )
// UpdateUserResolver is a resolver for update user mutation // UpdateUserResolver is a resolver for update user mutation
@ -97,7 +99,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
if params.Email != nil && user.Email != *params.Email { if params.Email != nil && user.Email != *params.Email {
// check if valid email // check if valid email
if !utils.IsValidEmail(*params.Email) { if !validators.IsValidEmail(*params.Email) {
log.Debug("Invalid email: ", *params.Email) log.Debug("Invalid email: ", *params.Email)
return res, fmt.Errorf("invalid email address") return res, fmt.Errorf("invalid email address")
} }
@ -113,7 +115,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
// TODO figure out how to do this // TODO figure out how to do this
go memorystore.Provider.DeleteAllUserSession(user.ID) go memorystore.Provider.DeleteAllUserSession(user.ID)
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
user.Email = newEmail user.Email = newEmail
user.EmailVerifiedAt = nil user.EmailVerifiedAt = nil
// insert verification request // insert verification request
@ -123,7 +125,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
return res, err return res, err
} }
verificationType := constants.VerificationTypeUpdateEmail verificationType := constants.VerificationTypeUpdateEmail
redirectURL := utils.GetAppURL(gc) redirectURL := parsers.GetAppURL(gc)
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL) verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
if err != nil { if err != nil {
log.Debug("Failed to create verification token: ", err) log.Debug("Failed to create verification token: ", err)
@ -163,12 +165,12 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
log.Debug("Error getting protected roles: ", err) log.Debug("Error getting protected roles: ", err)
} }
if !utils.IsValidRoles(inputRoles, append([]string{}, append(roles, protectedRoles...)...)) { if !validators.IsValidRoles(inputRoles, append([]string{}, append(roles, protectedRoles...)...)) {
log.Debug("Invalid roles: ", params.Roles) log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf("invalid list of roles") return res, fmt.Errorf("invalid list of roles")
} }
if !utils.IsStringArrayEqual(inputRoles, currentRoles) { if !validators.IsStringArrayEqual(inputRoles, currentRoles) {
rolesToSave = strings.Join(inputRoles, ",") rolesToSave = strings.Join(inputRoles, ",")
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -49,7 +50,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
userID = savedSessionSplit[1] userID = savedSessionSplit[1]
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
var claimRoles []string var claimRoles []string
var claims jwt.MapClaims var claims jwt.MapClaims

View File

@ -13,6 +13,7 @@ import (
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -34,7 +35,7 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
} }
// verify if token exists in db // verify if token exists in db
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email) claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil { if err != nil {
log.Debug("Failed to parse token: ", err) log.Debug("Failed to parse token: ", err)

View File

@ -3,6 +3,7 @@ package test
import ( import (
"testing" "testing"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -10,7 +11,7 @@ import (
func TestGetHostName(t *testing.T) { func TestGetHostName(t *testing.T) {
url := "http://test.herokuapp.com:80" url := "http://test.herokuapp.com:80"
host, port := utils.GetHostParts(url) host, port := parsers.GetHostParts(url)
expectedHost := "test.herokuapp.com" expectedHost := "test.herokuapp.com"
assert.Equal(t, host, expectedHost, "hostname should be equal") assert.Equal(t, host, expectedHost, "hostname should be equal")

View File

@ -6,6 +6,7 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -14,24 +15,24 @@ func TestIsValidEmail(t *testing.T) {
invalidEmail1 := "lakhan" invalidEmail1 := "lakhan"
invalidEmail2 := "lakhan.me" invalidEmail2 := "lakhan.me"
assert.True(t, utils.IsValidEmail(validEmail), "it should be valid email") assert.True(t, validators.IsValidEmail(validEmail), "it should be valid email")
assert.False(t, utils.IsValidEmail(invalidEmail1), "it should be invalid email") assert.False(t, validators.IsValidEmail(invalidEmail1), "it should be invalid email")
assert.False(t, utils.IsValidEmail(invalidEmail2), "it should be invalid email") assert.False(t, validators.IsValidEmail(invalidEmail2), "it should be invalid email")
} }
func TestIsValidOrigin(t *testing.T) { func TestIsValidOrigin(t *testing.T) {
// don't use portocal(http/https) for ALLOWED_ORIGINS while testing, // don't use portocal(http/https) for ALLOWED_ORIGINS while testing,
// as we trim them off while running the main function // as we trim them off while running the main function
memorystore.Provider.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyAllowedOrigins, []string{"localhost:8080", "*.google.com", "*.google.in", "*abc.*"}) memorystore.Provider.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, validators.IsValidOrigin("http://myapp.com"), "it should be invalid origin")
assert.False(t, utils.IsValidOrigin("http://appgoogle.com"), "it should be invalid origin") assert.False(t, validators.IsValidOrigin("http://appgoogle.com"), "it should be invalid origin")
assert.True(t, utils.IsValidOrigin("http://app.google.com"), "it should be valid origin") assert.True(t, validators.IsValidOrigin("http://app.google.com"), "it should be valid origin")
assert.False(t, utils.IsValidOrigin("http://app.google.ind"), "it should be invalid origin") assert.False(t, validators.IsValidOrigin("http://app.google.ind"), "it should be invalid origin")
assert.True(t, utils.IsValidOrigin("http://app.google.in"), "it should be valid origin") assert.True(t, validators.IsValidOrigin("http://app.google.in"), "it should be valid origin")
assert.True(t, utils.IsValidOrigin("http://xyx.abc.com"), "it should be valid origin") assert.True(t, validators.IsValidOrigin("http://xyx.abc.com"), "it should be valid origin")
assert.True(t, utils.IsValidOrigin("http://xyx.abc.in"), "it should be valid origin") assert.True(t, validators.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, validators.IsValidOrigin("http://xyxabc.in"), "it should be valid origin")
assert.True(t, utils.IsValidOrigin("http://localhost:8080"), "it should be valid origin") assert.True(t, validators.IsValidOrigin("http://localhost:8080"), "it should be valid origin")
memorystore.Provider.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyAllowedOrigins, []string{"*"}) memorystore.Provider.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyAllowedOrigins, []string{"*"})
} }

View File

@ -17,6 +17,7 @@ import (
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -66,7 +67,7 @@ func CreateSessionToken(user models.User, nonce string, roles, scope []string) (
// CreateAuthToken creates a new auth token when userlogs in // CreateAuthToken creates a new auth token when userlogs in
func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string) (*Token, error) { func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string) (*Token, error) {
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
nonce := uuid.New().String() nonce := uuid.New().String()
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope) _, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope)
if err != nil { if err != nil {
@ -206,7 +207,7 @@ func ValidateAccessToken(gc *gin.Context, accessToken string) (map[string]interf
nonce := savedSessionSplit[0] nonce := savedSessionSplit[0]
userID := savedSessionSplit[1] userID := savedSessionSplit[1]
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
res, err = ParseJWTToken(accessToken, hostname, nonce, userID) res, err = ParseJWTToken(accessToken, hostname, nonce, userID)
if err != nil { if err != nil {
return res, err return res, err
@ -236,7 +237,7 @@ func ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]inte
nonce := savedSessionSplit[0] nonce := savedSessionSplit[0]
userID := savedSessionSplit[1] userID := savedSessionSplit[1]
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
res, err = ParseJWTToken(refreshToken, hostname, nonce, userID) res, err = ParseJWTToken(refreshToken, hostname, nonce, userID)
if err != nil { if err != nil {
return res, err return res, err

View File

@ -1,22 +0,0 @@
package utils
import (
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
)
// GetMeta helps in getting the meta data about the deployment from EnvData
func GetMetaInfo() model.Meta {
return model.Meta{
Version: constants.VERSION,
ClientID: memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID),
IsGoogleLoginEnabled: memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" && memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret) != "",
IsGithubLoginEnabled: memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID) != "" && memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret) != "",
IsFacebookLoginEnabled: memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID) != "" && memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret) != "",
IsBasicAuthenticationEnabled: !memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication),
IsEmailVerificationEnabled: !memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification),
IsMagicLinkLoginEnabled: !memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin),
IsSignUpEnabled: !memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp),
}
}

View File

@ -1,120 +0,0 @@
package utils
import (
"net/mail"
"regexp"
"strings"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore"
)
// IsValidEmail validates email
func IsValidEmail(email string) bool {
_, err := mail.ParseAddress(email)
return err == nil
}
// IsValidOrigin validates origin based on ALLOWED_ORIGINS
func IsValidOrigin(url string) bool {
allowedOrigins := memorystore.Provider.GetSliceStoreEnvVariable(constants.EnvKeyAllowedOrigins)
if len(allowedOrigins) == 1 && allowedOrigins[0] == "*" {
return true
}
hasValidURL := false
hostName, port := GetHostParts(url)
currentOrigin := hostName + ":" + port
for _, origin := range allowedOrigins {
replacedString := origin
// if has regex whitelisted domains
if strings.Contains(origin, "*") {
replacedString = strings.Replace(origin, ".", "\\.", -1)
replacedString = strings.Replace(replacedString, "*", ".*", -1)
if strings.HasPrefix(replacedString, ".*") {
replacedString += "\\b"
}
if strings.HasSuffix(replacedString, ".*") {
replacedString = "\\b" + replacedString
}
}
if matched, _ := regexp.MatchString(replacedString, currentOrigin); matched {
hasValidURL = true
break
}
}
return hasValidURL
}
// IsValidRoles validates roles
func IsValidRoles(userRoles []string, roles []string) bool {
valid := true
for _, userRole := range userRoles {
if !StringSliceContains(roles, userRole) {
valid = false
break
}
}
return valid
}
// IsValidVerificationIdentifier validates verification identifier that is used to identify
// the type of verification request
func IsValidVerificationIdentifier(identifier string) bool {
if identifier != constants.VerificationTypeBasicAuthSignup && identifier != constants.VerificationTypeForgotPassword && identifier != constants.VerificationTypeUpdateEmail {
return false
}
return true
}
// IsStringArrayEqual validates if string array are equal.
// This does check if the order is same
func IsStringArrayEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
// ValidatePassword to validate the password against the following policy
// min char length: 6
// max char length: 36
// at least one upper case letter
// at least one lower case letter
// at least one digit
// at least one special character
func IsValidPassword(password string) bool {
if len(password) < 6 || len(password) > 36 {
return false
}
hasUpperCase := false
hasLowerCase := false
hasDigit := false
hasSpecialChar := false
for _, char := range password {
if char >= 'A' && char <= 'Z' {
hasUpperCase = true
} else if char >= 'a' && char <= 'z' {
hasLowerCase = true
} else if char >= '0' && char <= '9' {
hasDigit = true
} else {
hasSpecialChar = true
}
}
return hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar
}

View File

@ -0,0 +1,15 @@
package validators
// IsStringArrayEqual validates if string array are equal.
// This does check if the order is same
func IsStringArrayEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}

View File

@ -0,0 +1,9 @@
package validators
import "net/mail"
// IsValidEmail validates email
func IsValidEmail(email string) bool {
_, err := mail.ParseAddress(email)
return err == nil
}

View File

@ -0,0 +1,33 @@
package validators
// ValidatePassword to validate the password against the following policy
// min char length: 6
// max char length: 36
// at least one upper case letter
// at least one lower case letter
// at least one digit
// at least one special character
func IsValidPassword(password string) bool {
if len(password) < 6 || len(password) > 36 {
return false
}
hasUpperCase := false
hasLowerCase := false
hasDigit := false
hasSpecialChar := false
for _, char := range password {
if char >= 'A' && char <= 'Z' {
hasUpperCase = true
} else if char >= 'a' && char <= 'z' {
hasLowerCase = true
} else if char >= '0' && char <= '9' {
hasDigit = true
} else {
hasSpecialChar = true
}
}
return hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar
}

View File

@ -0,0 +1,16 @@
package validators
import "github.com/authorizerdev/authorizer/server/utils"
// IsValidRoles validates roles
func IsValidRoles(userRoles []string, roles []string) bool {
valid := true
for _, userRole := range userRoles {
if !utils.StringSliceContains(roles, userRole) {
valid = false
break
}
}
return valid
}

49
server/validators/url.go Normal file
View File

@ -0,0 +1,49 @@
package validators
import (
"regexp"
"strings"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
)
// IsValidOrigin validates origin based on ALLOWED_ORIGINS
func IsValidOrigin(url string) bool {
allowedOrigins, err := memorystore.Provider.GetSliceStoreEnvVariable(constants.EnvKeyAllowedOrigins)
if err != nil {
allowedOrigins = []string{"*"}
}
if len(allowedOrigins) == 1 && allowedOrigins[0] == "*" {
return true
}
hasValidURL := false
hostName, port := parsers.GetHostParts(url)
currentOrigin := hostName + ":" + port
for _, origin := range allowedOrigins {
replacedString := origin
// if has regex whitelisted domains
if strings.Contains(origin, "*") {
replacedString = strings.Replace(origin, ".", "\\.", -1)
replacedString = strings.Replace(replacedString, "*", ".*", -1)
if strings.HasPrefix(replacedString, ".*") {
replacedString += "\\b"
}
if strings.HasSuffix(replacedString, ".*") {
replacedString = "\\b" + replacedString
}
}
if matched, _ := regexp.MatchString(replacedString, currentOrigin); matched {
hasValidURL = true
break
}
}
return hasValidURL
}

View File

@ -0,0 +1,12 @@
package validators
import "github.com/authorizerdev/authorizer/server/constants"
// IsValidVerificationIdentifier validates verification identifier that is used to identify
// the type of verification request
func IsValidVerificationIdentifier(identifier string) bool {
if identifier != constants.VerificationTypeBasicAuthSignup && identifier != constants.VerificationTypeForgotPassword && identifier != constants.VerificationTypeUpdateEmail {
return false
}
return true
}