diff --git a/server/cookie/cookie.go b/server/cookie/cookie.go index ad9fca8..f90dd21 100644 --- a/server/cookie/cookie.go +++ b/server/cookie/cookie.go @@ -10,6 +10,30 @@ import ( "github.com/gin-gonic/gin" ) +// SetSessionCookie sets the session cookie in the response +func SetSessionCookie(gc *gin.Context, sessionID string) { + secure := true + httpOnly := true + hostname := utils.GetHost(gc) + host, _ := utils.GetHostParts(hostname) + domain := utils.GetDomainName(hostname) + if domain != "localhost" { + domain = "." + domain + } + + // TODO allow configuring from dashboard + year := 60 * 60 * 24 * 365 + + gc.SetSameSite(http.SameSiteNoneMode) + gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session", sessionID, year, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session.domain", sessionID, year, "/", domain, secure, httpOnly) + + // Fallback cookie for anomaly getection on browsers that don’t support the sameSite=None attribute. + gc.SetSameSite(http.SameSiteDefaultMode) + gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session_compat", sessionID, year, "/", host, secure, httpOnly) + gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session.domain_compat", sessionID, year, "/", domain, secure, httpOnly) +} + // SetCookie sets the cookie in the response. It sets 4 cookies // 1 COOKIE_NAME.access_token jwt token for the host (temp.abc.com) // 2 COOKIE_NAME.access_token.domain jwt token for the domain (abc.com). diff --git a/server/utils/crypto.go b/server/crypto/aes.go similarity index 60% rename from server/utils/crypto.go rename to server/crypto/aes.go index cd84d33..5d0bed4 100644 --- a/server/utils/crypto.go +++ b/server/crypto/aes.go @@ -1,32 +1,15 @@ -package utils +package crypto import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "encoding/base64" - "encoding/json" "io" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/envstore" - "golang.org/x/crypto/bcrypt" ) -// EncryptB64 encrypts data into base64 string -func EncryptB64(text string) string { - return base64.StdEncoding.EncodeToString([]byte(text)) -} - -// DecryptB64 decrypts from base64 string to readable string -func DecryptB64(s string) (string, error) { - data, err := base64.StdEncoding.DecodeString(s) - if err != nil { - return "", err - } - return string(data), nil -} - // EncryptAES encrypts data using AES algorithm func EncryptAES(text []byte) ([]byte, error) { key := []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)) @@ -88,39 +71,3 @@ func DecryptAES(ciphertext []byte) ([]byte, error) { return plaintext, nil } - -// EncryptEnvData is used to encrypt the env data -func EncryptEnvData(data envstore.Store) (string, error) { - jsonBytes, err := json.Marshal(data) - if err != nil { - return "", err - } - - storeData := envstore.EnvStoreObj.GetEnvStoreClone() - - err = json.Unmarshal(jsonBytes, &storeData) - if err != nil { - return "", err - } - - configData, err := json.Marshal(storeData) - if err != nil { - return "", err - } - encryptedConfig, err := EncryptAES(configData) - if err != nil { - return "", err - } - - return EncryptB64(string(encryptedConfig)), nil -} - -// EncryptPassword is used for encrypting password -func EncryptPassword(password string) (string, error) { - pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) - if err != nil { - return "", err - } - - return string(pw), nil -} diff --git a/server/crypto/b64.go b/server/crypto/b64.go new file mode 100644 index 0000000..3453422 --- /dev/null +++ b/server/crypto/b64.go @@ -0,0 +1,17 @@ +package crypto + +import "encoding/base64" + +// EncryptB64 encrypts data into base64 string +func EncryptB64(text string) string { + return base64.StdEncoding.EncodeToString([]byte(text)) +} + +// DecryptB64 decrypts from base64 string to readable string +func DecryptB64(s string) (string, error) { + data, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return "", err + } + return string(data), nil +} diff --git a/server/crypto/common.go b/server/crypto/common.go index 698917a..45f8917 100644 --- a/server/crypto/common.go +++ b/server/crypto/common.go @@ -2,9 +2,11 @@ package crypto import ( "crypto/x509" + "encoding/json" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/envstore" + "golang.org/x/crypto/bcrypt" "gopkg.in/square/go-jose.v2" ) @@ -73,3 +75,39 @@ func GenerateJWKBasedOnEnv() (string, error) { return jwk, nil } + +// EncryptEnvData is used to encrypt the env data +func EncryptEnvData(data envstore.Store) (string, error) { + jsonBytes, err := json.Marshal(data) + if err != nil { + return "", err + } + + storeData := envstore.EnvStoreObj.GetEnvStoreClone() + + err = json.Unmarshal(jsonBytes, &storeData) + if err != nil { + return "", err + } + + configData, err := json.Marshal(storeData) + if err != nil { + return "", err + } + encryptedConfig, err := EncryptAES(configData) + if err != nil { + return "", err + } + + return EncryptB64(string(encryptedConfig)), nil +} + +// EncryptPassword is used for encrypting password +func EncryptPassword(password string) (string, error) { + pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return "", err + } + + return string(pw), nil +} diff --git a/server/env/persist_env.go b/server/env/persist_env.go index 30e93d3..a7fba71 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -27,18 +27,18 @@ func GetEnvData() (envstore.Store, error) { } encryptionKey := env.Hash - decryptedEncryptionKey, err := utils.DecryptB64(encryptionKey) + decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey) if err != nil { return result, err } envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey) - b64DecryptedConfig, err := utils.DecryptB64(env.EnvData) + b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData) if err != nil { return result, err } - decryptedConfigs, err := utils.DecryptAES([]byte(b64DecryptedConfig)) + decryptedConfigs, err := crypto.DecryptAES([]byte(b64DecryptedConfig)) if err != nil { return result, err } @@ -59,9 +59,9 @@ func PersistEnv() error { // 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.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, hash) - encodedHash := utils.EncryptB64(hash) + encodedHash := crypto.EncryptB64(hash) - encryptedConfig, err := utils.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone()) + encryptedConfig, err := crypto.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone()) if err != nil { return err } @@ -79,18 +79,18 @@ func PersistEnv() error { // decrypt the config data from db // decryption can be done using the hash stored in db encryptionKey := env.Hash - decryptedEncryptionKey, err := utils.DecryptB64(encryptionKey) + decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey) if err != nil { return err } envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey) - b64DecryptedConfig, err := utils.DecryptB64(env.EnvData) + b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData) if err != nil { return err } - decryptedConfigs, err := utils.DecryptAES([]byte(b64DecryptedConfig)) + decryptedConfigs, err := crypto.DecryptAES([]byte(b64DecryptedConfig)) if err != nil { return err } @@ -172,7 +172,7 @@ func PersistEnv() error { envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk) if hasChanged { - encryptedConfig, err := utils.EncryptEnvData(storeData) + encryptedConfig, err := crypto.EncryptEnvData(storeData) if err != nil { return err } diff --git a/server/handlers/app.go b/server/handlers/app.go index 61325a9..483b8e1 100644 --- a/server/handlers/app.go +++ b/server/handlers/app.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/utils" "github.com/gin-gonic/gin" @@ -36,7 +37,7 @@ func AppHandler() gin.HandlerFunc { stateObj.AuthorizerURL = hostname stateObj.RedirectURL = hostname + "/app" } else { - decodedState, err := utils.DecryptB64(state) + decodedState, err := crypto.DecryptB64(state) if err != nil { c.JSON(400, gin.H{"error": "[unable to decode state] invalid state"}) return diff --git a/server/handlers/authorize.go b/server/handlers/authorize.go new file mode 100644 index 0000000..67123cd --- /dev/null +++ b/server/handlers/authorize.go @@ -0,0 +1,72 @@ +package handlers + +import ( + "fmt" + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +// AuthorizeHandler is the handler for the /authorize route +// required params +// ?redirect_uri = redirect url +// state[recommended] = to prevent CSRF attack (for authorizer its compulsory) +// code_challenge = to prevent CSRF attack +// code_challenge_method = to prevent CSRF attack [only sh256 is supported] +func AuthorizeHandler() gin.HandlerFunc { + return func(c *gin.Context) { + redirectURI := strings.TrimSpace(c.Query("redirect_uri")) + responseType := strings.TrimSpace(c.Query("response_type")) + state := strings.TrimSpace(c.Query("state")) + codeChallenge := strings.TrimSpace(c.Query("code_challenge")) + codeChallengeMethod := strings.TrimSpace(c.Query("code_challenge_method")) + fmt.Println(codeChallengeMethod) + template := "authorize.tmpl" + + if redirectURI == "" { + c.HTML(http.StatusBadRequest, template, gin.H{ + "targetOrigin": nil, + "authorizationResponse": nil, + "error": "redirect_uri is required", + }) + return + } + + if state == "" { + c.HTML(http.StatusBadRequest, template, gin.H{ + "targetOrigin": nil, + "authorizationResponse": nil, + "error": "state is required", + }) + return + } + + if responseType == "" { + responseType = "code" + } + + isCode := responseType == "code" + isToken := responseType == "token" + + if !isCode && !isToken { + c.HTML(http.StatusBadRequest, template, gin.H{ + "targetOrigin": nil, + "authorizationResponse": nil, + "error": "response_type is invalid", + }) + return + } + + if isCode { + if codeChallenge == "" { + c.HTML(http.StatusBadRequest, template, gin.H{ + "targetOrigin": nil, + "authorizationResponse": nil, + "error": "code_challenge is required", + }) + return + } + } + } +} diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index 5ba684a..3232c47 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -30,11 +30,11 @@ func OAuthCallbackHandler() gin.HandlerFunc { provider := c.Param("oauth_provider") state := c.Request.FormValue("state") - sessionState := sessionstore.GetSocailLoginState(state) + sessionState := sessionstore.GetState(state) if sessionState == "" { c.JSON(400, gin.H{"error": "invalid oauth state"}) } - sessionstore.RemoveSocialLoginState(state) + sessionstore.GetState(state) // contains random token, redirect url, role sessionSplit := strings.Split(state, "___") diff --git a/server/handlers/oauth_login.go b/server/handlers/oauth_login.go index a01a300..9ef000e 100644 --- a/server/handlers/oauth_login.go +++ b/server/handlers/oauth_login.go @@ -54,7 +54,7 @@ func OAuthLoginHandler() gin.HandlerFunc { isProviderConfigured = false break } - sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGoogle) + sessionstore.SetState(oauthStateString, constants.SignupMethodGoogle) // during the init of OAuthProvider authorizer url might be empty oauth.OAuthProviders.GoogleConfig.RedirectURL = hostname + "/oauth_callback/google" url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString) @@ -64,7 +64,7 @@ func OAuthLoginHandler() gin.HandlerFunc { isProviderConfigured = false break } - sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGithub) + sessionstore.SetState(oauthStateString, constants.SignupMethodGithub) oauth.OAuthProviders.GithubConfig.RedirectURL = hostname + "/oauth_callback/github" url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString) c.Redirect(http.StatusTemporaryRedirect, url) @@ -73,7 +73,7 @@ func OAuthLoginHandler() gin.HandlerFunc { isProviderConfigured = false break } - sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodFacebook) + sessionstore.SetState(oauthStateString, constants.SignupMethodFacebook) oauth.OAuthProviders.FacebookConfig.RedirectURL = hostname + "/oauth_callback/facebook" url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString) c.Redirect(http.StatusTemporaryRedirect, url) diff --git a/server/resolvers/admin_login.go b/server/resolvers/admin_login.go index 306a214..3e28b3f 100644 --- a/server/resolvers/admin_login.go +++ b/server/resolvers/admin_login.go @@ -6,6 +6,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/utils" @@ -25,7 +26,7 @@ func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*mod return res, fmt.Errorf(`invalid admin secret`) } - hashedKey, err := utils.EncryptPassword(adminSecret) + hashedKey, err := crypto.EncryptPassword(adminSecret) if err != nil { return res, err } diff --git a/server/resolvers/admin_session.go b/server/resolvers/admin_session.go index f464aee..9809835 100644 --- a/server/resolvers/admin_session.go +++ b/server/resolvers/admin_session.go @@ -6,6 +6,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/token" @@ -25,7 +26,7 @@ func AdminSessionResolver(ctx context.Context) (*model.Response, error) { return res, fmt.Errorf("unauthorized") } - hashedKey, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) if err != nil { return res, err } diff --git a/server/resolvers/admin_signup.go b/server/resolvers/admin_signup.go index 8fa00d7..bb2f1eb 100644 --- a/server/resolvers/admin_signup.go +++ b/server/resolvers/admin_signup.go @@ -8,6 +8,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" @@ -58,7 +59,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m return res, err } - envData, err := utils.EncryptEnvData(storeData) + envData, err := crypto.EncryptEnvData(storeData) if err != nil { return res, err } @@ -68,7 +69,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m return res, err } - hashedKey, err := utils.EncryptPassword(params.AdminSecret) + hashedKey, err := crypto.EncryptPassword(params.AdminSecret) if err != nil { return res, err } diff --git a/server/resolvers/logout.go b/server/resolvers/logout.go index 4653896..a6626e7 100644 --- a/server/resolvers/logout.go +++ b/server/resolvers/logout.go @@ -4,6 +4,7 @@ import ( "context" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/sessionstore" "github.com/authorizerdev/authorizer/server/token" @@ -30,7 +31,7 @@ func LogoutResolver(ctx context.Context) (*model.Response, error) { return res, err } - decryptedFingerPrint, err := utils.DecryptAES([]byte(fingerprintHash)) + decryptedFingerPrint, err := crypto.DecryptAES([]byte(fingerprintHash)) if err != nil { return res, err } diff --git a/server/resolvers/reset_password.go b/server/resolvers/reset_password.go index 843370f..2eceb79 100644 --- a/server/resolvers/reset_password.go +++ b/server/resolvers/reset_password.go @@ -7,11 +7,11 @@ import ( "time" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/token" - "github.com/authorizerdev/authorizer/server/utils" ) // ResetPasswordResolver is a resolver for reset password mutation @@ -41,7 +41,7 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) return res, err } - password, _ := utils.EncryptPassword(params.Password) + password, _ := crypto.EncryptPassword(params.Password) user.Password = &password signupMethod := user.SignupMethods diff --git a/server/resolvers/session.go b/server/resolvers/session.go index e390b5a..acd72c4 100644 --- a/server/resolvers/session.go +++ b/server/resolvers/session.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/sessionstore" @@ -33,7 +34,7 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod return res, err } - decryptedFingerPrint, err := utils.DecryptAES([]byte(fingerprintHash)) + decryptedFingerPrint, err := crypto.DecryptAES([]byte(fingerprintHash)) if err != nil { return res, err } diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index b227797..0ce3953 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -9,6 +9,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/email" @@ -72,7 +73,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR user.Roles = strings.Join(inputRoles, ",") - password, _ := utils.EncryptPassword(params.Password) + password, _ := crypto.EncryptPassword(params.Password) user.Password = &password if params.GivenName != nil { diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index 317bd88..0f428bb 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -199,14 +199,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model } if params.AdminSecret != nil { - hashedKey, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) if err != nil { return res, err } cookie.SetAdminCookie(gc, hashedKey) } - encryptedConfig, err := utils.EncryptEnvData(updatedData) + encryptedConfig, err := crypto.EncryptEnvData(updatedData) if err != nil { return res, err } diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go index 1f19adb..2fef3e3 100644 --- a/server/resolvers/update_profile.go +++ b/server/resolvers/update_profile.go @@ -9,6 +9,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/email" @@ -92,7 +93,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) return res, fmt.Errorf(`password and confirm password does not match`) } - password, _ := utils.EncryptPassword(*params.NewPassword) + password, _ := crypto.EncryptPassword(*params.NewPassword) user.Password = &password } diff --git a/server/sessionstore/in_memory_session.go b/server/sessionstore/in_memory_session.go index 9e52928..567c881 100644 --- a/server/sessionstore/in_memory_session.go +++ b/server/sessionstore/in_memory_session.go @@ -6,9 +6,9 @@ import ( // InMemoryStore is a simple in-memory store for sessions. type InMemoryStore struct { - mutex sync.Mutex - store map[string]map[string]string - socialLoginState map[string]string + mutex sync.Mutex + sessionStore map[string]map[string]string + stateStore map[string]string } // AddUserSession adds a user session to the in-memory store. @@ -16,20 +16,20 @@ func (c *InMemoryStore) AddUserSession(userId, accessToken, refreshToken string) c.mutex.Lock() defer c.mutex.Unlock() // delete sessions > 500 // not recommended for production - if len(c.store) >= 500 { - c.store = map[string]map[string]string{} + if len(c.sessionStore) >= 500 { + c.sessionStore = map[string]map[string]string{} } // check if entry exists in map - _, exists := c.store[userId] + _, exists := c.sessionStore[userId] if exists { - tempMap := c.store[userId] + tempMap := c.sessionStore[userId] tempMap[accessToken] = refreshToken - c.store[userId] = tempMap + c.sessionStore[userId] = tempMap } else { tempMap := map[string]string{ accessToken: refreshToken, } - c.store[userId] = tempMap + c.sessionStore[userId] = tempMap } } @@ -37,21 +37,21 @@ func (c *InMemoryStore) AddUserSession(userId, accessToken, refreshToken string) func (c *InMemoryStore) DeleteAllUserSession(userId string) { c.mutex.Lock() defer c.mutex.Unlock() - delete(c.store, userId) + delete(c.sessionStore, userId) } // DeleteUserSession deletes the particular user session from in-memory store. func (c *InMemoryStore) DeleteUserSession(userId, accessToken string) { c.mutex.Lock() defer c.mutex.Unlock() - delete(c.store[userId], accessToken) + delete(c.sessionStore[userId], accessToken) } // ClearStore clears the in-memory store. func (c *InMemoryStore) ClearStore() { c.mutex.Lock() defer c.mutex.Unlock() - c.store = map[string]map[string]string{} + c.sessionStore = map[string]map[string]string{} } // GetUserSession returns the user session token from the in-memory store. @@ -60,7 +60,7 @@ func (c *InMemoryStore) GetUserSession(userId, accessToken string) string { // defer c.mutex.Unlock() token := "" - if sessionMap, ok := c.store[userId]; ok { + if sessionMap, ok := c.sessionStore[userId]; ok { if val, ok := sessionMap[accessToken]; ok { token = val } @@ -74,7 +74,7 @@ func (c *InMemoryStore) GetUserSessions(userId string) map[string]string { // c.mutex.Lock() // defer c.mutex.Unlock() - sessionMap, ok := c.store[userId] + sessionMap, ok := c.sessionStore[userId] if !ok { return nil } @@ -82,31 +82,31 @@ func (c *InMemoryStore) GetUserSessions(userId string) map[string]string { return sessionMap } -// SetSocialLoginState sets the social login state in the in-memory store. -func (c *InMemoryStore) SetSocialLoginState(key, state string) { +// SetState sets the state in the in-memory store. +func (c *InMemoryStore) SetState(key, state string) { c.mutex.Lock() defer c.mutex.Unlock() - c.socialLoginState[key] = state + c.stateStore[key] = state } -// GetSocialLoginState gets the social login state from the in-memory store. -func (c *InMemoryStore) GetSocialLoginState(key string) string { +// GetState gets the state from the in-memory store. +func (c *InMemoryStore) GetState(key string) string { c.mutex.Lock() defer c.mutex.Unlock() state := "" - if stateVal, ok := c.socialLoginState[key]; ok { + if stateVal, ok := c.stateStore[key]; ok { state = stateVal } return state } -// RemoveSocialLoginState removes the social login state from the in-memory store. -func (c *InMemoryStore) RemoveSocialLoginState(key string) { +// RemoveState removes the state from the in-memory store. +func (c *InMemoryStore) RemoveState(key string) { c.mutex.Lock() defer c.mutex.Unlock() - delete(c.socialLoginState, key) + delete(c.stateStore, key) } diff --git a/server/sessionstore/redis_store.go b/server/sessionstore/redis_store.go index 4531e0f..98a1711 100644 --- a/server/sessionstore/redis_store.go +++ b/server/sessionstore/redis_store.go @@ -68,16 +68,16 @@ func (c *RedisStore) GetUserSessions(userID string) map[string]string { return res } -// SetSocialLoginState sets the social login state in redis store. -func (c *RedisStore) SetSocialLoginState(key, state string) { +// SetState sets the state in redis store. +func (c *RedisStore) SetState(key, state string) { err := c.store.Set(c.ctx, key, state, 0).Err() if err != nil { log.Fatalln("Error saving redis token:", err) } } -// GetSocialLoginState gets the social login state from redis store. -func (c *RedisStore) GetSocialLoginState(key string) string { +// GetState gets the state from redis store. +func (c *RedisStore) GetState(key string) string { state := "" state, err := c.store.Get(c.ctx, key).Result() if err != nil { @@ -87,8 +87,8 @@ func (c *RedisStore) GetSocialLoginState(key string) string { return state } -// RemoveSocialLoginState removes the social login state from redis store. -func (c *RedisStore) RemoveSocialLoginState(key string) { +// RemoveState removes the state from redis store. +func (c *RedisStore) RemoveState(key string) { err := c.store.Del(c.ctx, key).Err() if err != nil { log.Fatalln("Error deleting redis token:", err) diff --git a/server/sessionstore/session.go b/server/sessionstore/session.go index f3fdf39..f33638c 100644 --- a/server/sessionstore/session.go +++ b/server/sessionstore/session.go @@ -86,35 +86,35 @@ func ClearStore() { } } -// SetSocialLoginState sets the social login state in the session store -func SetSocailLoginState(key, state string) { +// SetState sets the login state (key, value form) in the session store +func SetState(key, state string) { if SessionStoreObj.RedisMemoryStoreObj != nil { - SessionStoreObj.RedisMemoryStoreObj.SetSocialLoginState(key, state) + SessionStoreObj.RedisMemoryStoreObj.SetState(key, state) } if SessionStoreObj.InMemoryStoreObj != nil { - SessionStoreObj.InMemoryStoreObj.SetSocialLoginState(key, state) + SessionStoreObj.InMemoryStoreObj.SetState(key, state) } } -// GetSocialLoginState returns the social login state from the session store -func GetSocailLoginState(key string) string { +// GetState returns the state from the session store +func GetState(key string) string { if SessionStoreObj.RedisMemoryStoreObj != nil { - return SessionStoreObj.RedisMemoryStoreObj.GetSocialLoginState(key) + return SessionStoreObj.RedisMemoryStoreObj.GetState(key) } if SessionStoreObj.InMemoryStoreObj != nil { - return SessionStoreObj.InMemoryStoreObj.GetSocialLoginState(key) + return SessionStoreObj.InMemoryStoreObj.GetState(key) } return "" } -// RemoveSocialLoginState removes the social login state from the session store -func RemoveSocialLoginState(key string) { +// RemoveState removes the social login state from the session store +func RemoveState(key string) { if SessionStoreObj.RedisMemoryStoreObj != nil { - SessionStoreObj.RedisMemoryStoreObj.RemoveSocialLoginState(key) + SessionStoreObj.RedisMemoryStoreObj.RemoveState(key) } if SessionStoreObj.InMemoryStoreObj != nil { - SessionStoreObj.InMemoryStoreObj.RemoveSocialLoginState(key) + SessionStoreObj.InMemoryStoreObj.RemoveState(key) } } @@ -174,8 +174,8 @@ func InitSession() error { // if redis url is not set use in memory store SessionStoreObj.InMemoryStoreObj = &InMemoryStore{ - store: map[string]map[string]string{}, - socialLoginState: map[string]string{}, + sessionStore: map[string]map[string]string{}, + stateStore: map[string]string{}, } return nil diff --git a/server/test/admin_logout_test.go b/server/test/admin_logout_test.go index d322578..94f65c0 100644 --- a/server/test/admin_logout_test.go +++ b/server/test/admin_logout_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/authorizerdev/authorizer/server/utils" "github.com/stretchr/testify/assert" ) @@ -18,7 +18,7 @@ func adminLogoutTests(t *testing.T, s TestSetup) { _, err := resolvers.AdminLogoutResolver(ctx) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.AdminLogoutResolver(ctx) diff --git a/server/test/admin_session_test.go b/server/test/admin_session_test.go index 8954f08..96f5bfc 100644 --- a/server/test/admin_session_test.go +++ b/server/test/admin_session_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/authorizerdev/authorizer/server/utils" "github.com/stretchr/testify/assert" ) @@ -18,7 +18,7 @@ func adminSessionTests(t *testing.T, s TestSetup) { _, err := resolvers.AdminSessionResolver(ctx) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.AdminSessionResolver(ctx) diff --git a/server/test/delete_user_test.go b/server/test/delete_user_test.go index 4c385a3..2ecbe35 100644 --- a/server/test/delete_user_test.go +++ b/server/test/delete_user_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "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" ) @@ -28,7 +28,7 @@ func deleteUserTest(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) diff --git a/server/test/env_test.go b/server/test/env_test.go index 19707a3..f825a50 100644 --- a/server/test/env_test.go +++ b/server/test/env_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/resolvers" - "github.com/authorizerdev/authorizer/server/utils" "github.com/stretchr/testify/assert" ) @@ -18,7 +18,7 @@ func envTests(t *testing.T, s TestSetup) { _, err := resolvers.EnvResolver(ctx) assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) res, err := resolvers.EnvResolver(ctx) diff --git a/server/test/logout_test.go b/server/test/logout_test.go index 3fbab1e..db5688a 100644 --- a/server/test/logout_test.go +++ b/server/test/logout_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/sessionstore" - "github.com/authorizerdev/authorizer/server/utils" "github.com/stretchr/testify/assert" ) @@ -38,7 +38,7 @@ func logoutTests(t *testing.T, s TestSetup) { refreshToken = val } - fingerPrintHash, _ := utils.EncryptAES([]byte(fingerPrint)) + fingerPrintHash, _ := crypto.EncryptAES([]byte(fingerPrint)) token := *verifyRes.AccessToken cookie := fmt.Sprintf("%s=%s;%s=%s;%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".fingerprint", url.QueryEscape(string(fingerPrintHash)), envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".refresh_token", refreshToken, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".access_token", token) diff --git a/server/test/session_test.go b/server/test/session_test.go index e42c99b..99b1295 100644 --- a/server/test/session_test.go +++ b/server/test/session_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/sessionstore" - "github.com/authorizerdev/authorizer/server/utils" "github.com/stretchr/testify/assert" ) @@ -43,7 +43,7 @@ func sessionTests(t *testing.T, s TestSetup) { refreshToken = val } - fingerPrintHash, _ := utils.EncryptAES([]byte(fingerPrint)) + fingerPrintHash, _ := crypto.EncryptAES([]byte(fingerPrint)) token := *verifyRes.AccessToken cookie := fmt.Sprintf("%s=%s;%s=%s;%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".fingerprint", url.QueryEscape(string(fingerPrintHash)), envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".refresh_token", refreshToken, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+".access_token", token) diff --git a/server/test/update_env_test.go b/server/test/update_env_test.go index 8b687e4..527becc 100644 --- a/server/test/update_env_test.go +++ b/server/test/update_env_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "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" ) @@ -23,7 +23,7 @@ func updateEnvTests(t *testing.T, s TestSetup) { assert.NotNil(t, err) - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) newURL := "https://test.com" diff --git a/server/test/update_user_test.go b/server/test/update_user_test.go index cc2333c..d072a27 100644 --- a/server/test/update_user_test.go +++ b/server/test/update_user_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "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" ) @@ -33,7 +33,7 @@ func updateUserTest(t *testing.T, s TestSetup) { }) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) _, err = resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{ diff --git a/server/test/users_test.go b/server/test/users_test.go index 223cb61..f390ed0 100644 --- a/server/test/users_test.go +++ b/server/test/users_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "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" ) @@ -35,7 +35,7 @@ func usersTest(t *testing.T, s TestSetup) { usersRes, err := resolvers.UsersResolver(ctx, pagination) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) diff --git a/server/test/verification_requests_test.go b/server/test/verification_requests_test.go index 1e40c22..58891a0 100644 --- a/server/test/verification_requests_test.go +++ b/server/test/verification_requests_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/crypto" "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" ) @@ -37,7 +37,7 @@ func verificationRequestsTest(t *testing.T, s TestSetup) { requests, err := resolvers.VerificationRequestsResolver(ctx, pagination) assert.NotNil(t, err, "unauthorized") - h, err := utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) assert.Nil(t, err) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) requests, err = resolvers.VerificationRequestsResolver(ctx, pagination) diff --git a/server/token/admin_token.go b/server/token/admin_token.go index 46ce97a..1cdfe50 100644 --- a/server/token/admin_token.go +++ b/server/token/admin_token.go @@ -5,15 +5,15 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/envstore" - "github.com/authorizerdev/authorizer/server/utils" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" ) // CreateAdminAuthToken creates the admin token based on secret key func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) { - return utils.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) + return crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) } // GetAdminAuthToken helps in getting the admin token from the request cookie diff --git a/server/token/auth_token.go b/server/token/auth_token.go index 8f2c7a4..b9eb25d 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -11,10 +11,10 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/sessionstore" - "github.com/authorizerdev/authorizer/server/utils" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "github.com/google/uuid" @@ -38,7 +38,7 @@ type Token struct { // CreateAuthToken creates a new auth token when userlogs in func CreateAuthToken(user models.User, roles []string) (*Token, error) { fingerprint := uuid.NewString() - fingerPrintHashBytes, err := utils.EncryptAES([]byte(fingerprint)) + fingerPrintHashBytes, err := crypto.EncryptAES([]byte(fingerprint)) if err != nil { return nil, err } diff --git a/templates/authorize.tmpl b/templates/authorize.tmpl new file mode 100644 index 0000000..a42c15b --- /dev/null +++ b/templates/authorize.tmpl @@ -0,0 +1,16 @@ + + +
+