Merge pull request #174 from authorizerdev/fix/memory-store

fix: replica cache consistency
This commit is contained in:
Lakhan Samani 2022-06-01 23:47:55 +05:30 committed by GitHub
commit d1e1e287db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
131 changed files with 3083 additions and 1923 deletions

View File

@ -1,3 +1,4 @@
ENV=production
DATABASE_URL=data.db DATABASE_URL=data.db
DATABASE_TYPE=sqlite DATABASE_TYPE=sqlite
CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}" CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}"

9
.env.test Normal file
View File

@ -0,0 +1,9 @@
ENV=test
DATABASE_URL=test.db
DATABASE_TYPE=sqlite
CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}"
SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=2525
SMTP_USERNAME=test
SMTP_PASSWORD=test
SENDER_EMAIL="info@authorizer.dev"

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ dashboard/build
build build
.env .env
data.db data.db
test.db
.DS_Store .DS_Store
.env.local .env.local
*.tar.gz *.tar.gz

View File

@ -10,7 +10,7 @@ build-dashboard:
clean: clean:
rm -rf build rm -rf build
test: test:
cd server && go clean --testcache && go test -v ./test rm -rf server/test/test.db && rm -rf test.db && cd server && go clean --testcache && go test -p 1 -v ./test
generate: generate:
cd server && go get github.com/99designs/gqlgen/cmd@v0.14.0 && go run github.com/99designs/gqlgen generate cd server && go get github.com/99designs/gqlgen/cmd@v0.14.0 && go run github.com/99designs/gqlgen generate

View File

@ -1,88 +1,89 @@
import React from "react"; import React from 'react';
import { Flex, Stack, Center, Text, useMediaQuery } from "@chakra-ui/react"; import { Flex, Stack, Center, Text, useMediaQuery } from '@chakra-ui/react';
import InputField from "../../components/InputField"; import InputField from '../../components/InputField';
import { TextInputType } from "../../constants"; import { TextInputType } from '../../constants';
const DatabaseCredentials = ({ variables, setVariables }: any) => { const DatabaseCredentials = ({ variables, setVariables }: any) => {
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)"); const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
return ( return (
<div> <div>
{" "} {' '}
<Text fontSize="md" paddingTop="2%" fontWeight="bold"> <Text fontSize="md" paddingTop="2%" fontWeight="bold">
Database Credentials Database Credentials
</Text> </Text>
<Stack spacing={6} padding="3% 0"> <Stack spacing={6} padding="3% 0">
<Text fontStyle="italic" fontSize="sm" color="blackAlpha.500" mt={3}> <Text fontStyle="italic" fontSize="sm" color="blackAlpha.500" mt={3}>
Note: Database related environment variables cannot be updated from Note: Database related environment variables cannot be updated from
dashboard :( dashboard. Please use .env file or OS environment variables to update
</Text> it.
<Flex direction={isNotSmallerScreen ? "row" : "column"}> </Text>
<Flex <Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
w={isNotSmallerScreen ? "30%" : "40%"} <Flex
justifyContent="start" w={isNotSmallerScreen ? '30%' : '40%'}
alignItems="center" justifyContent="start"
> alignItems="center"
<Text fontSize="sm">DataBase Name:</Text> >
</Flex> <Text fontSize="sm">DataBase Name:</Text>
<Center </Flex>
w={isNotSmallerScreen ? "70%" : "100%"} <Center
mt={isNotSmallerScreen ? "0" : "3"} w={isNotSmallerScreen ? '70%' : '100%'}
> mt={isNotSmallerScreen ? '0' : '3'}
<InputField >
borderRadius={5} <InputField
variables={variables} borderRadius={5}
setVariables={setVariables} variables={variables}
inputType={TextInputType.DATABASE_NAME} setVariables={setVariables}
isDisabled={true} inputType={TextInputType.DATABASE_NAME}
/> isDisabled={true}
</Center> />
</Flex> </Center>
<Flex direction={isNotSmallerScreen ? "row" : "column"}> </Flex>
<Flex <Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
w={isNotSmallerScreen ? "30%" : "40%"} <Flex
justifyContent="start" w={isNotSmallerScreen ? '30%' : '40%'}
alignItems="center" justifyContent="start"
> alignItems="center"
<Text fontSize="sm">DataBase Type:</Text> >
</Flex> <Text fontSize="sm">DataBase Type:</Text>
<Center </Flex>
w={isNotSmallerScreen ? "70%" : "100%"} <Center
mt={isNotSmallerScreen ? "0" : "3"} w={isNotSmallerScreen ? '70%' : '100%'}
> mt={isNotSmallerScreen ? '0' : '3'}
<InputField >
borderRadius={5} <InputField
variables={variables} borderRadius={5}
setVariables={setVariables} variables={variables}
inputType={TextInputType.DATABASE_TYPE} setVariables={setVariables}
isDisabled={true} inputType={TextInputType.DATABASE_TYPE}
/> isDisabled={true}
</Center> />
</Flex> </Center>
<Flex direction={isNotSmallerScreen ? "row" : "column"}> </Flex>
<Flex <Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
w={isNotSmallerScreen ? "30%" : "40%"} <Flex
justifyContent="start" w={isNotSmallerScreen ? '30%' : '40%'}
alignItems="center" justifyContent="start"
> alignItems="center"
<Text fontSize="sm">DataBase URL:</Text> >
</Flex> <Text fontSize="sm">DataBase URL:</Text>
<Center </Flex>
w={isNotSmallerScreen ? "70%" : "100%"} <Center
mt={isNotSmallerScreen ? "0" : "3"} w={isNotSmallerScreen ? '70%' : '100%'}
> mt={isNotSmallerScreen ? '0' : '3'}
<InputField >
borderRadius={5} <InputField
variables={variables} borderRadius={5}
setVariables={setVariables} variables={variables}
inputType={TextInputType.DATABASE_URL} setVariables={setVariables}
isDisabled={true} inputType={TextInputType.DATABASE_URL}
/> isDisabled={true}
</Center> />
</Flex> </Center>
</Stack> </Flex>
</div> </Stack>
); </div>
);
}; };
export default DatabaseCredentials; export default DatabaseCredentials;

View File

@ -3,7 +3,7 @@ import { Flex, Stack, Text } from '@chakra-ui/react';
import InputField from '../InputField'; import InputField from '../InputField';
import { SwitchInputType } from '../../constants'; import { SwitchInputType } from '../../constants';
const UICustomization = ({ variables, setVariables }: any) => { const Features = ({ variables, setVariables }: any) => {
return ( return (
<div> <div>
{' '} {' '}
@ -76,4 +76,4 @@ const UICustomization = ({ variables, setVariables }: any) => {
); );
}; };
export default UICustomization; export default Features;

View File

@ -1,36 +1,42 @@
import React from "react"; import React from 'react';
import { Flex, Stack, Center, Text, useMediaQuery } from "@chakra-ui/react"; import { Flex, Stack, Center, Text, useMediaQuery } from '@chakra-ui/react';
import InputField from "../InputField"; import InputField from '../InputField';
const SessionStorage = ({ variables, setVariables, RedisURL }: any) => { const SessionStorage = ({ variables, setVariables, RedisURL }: any) => {
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)"); const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
return ( return (
<div> <div>
{" "} {' '}
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}> <Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
Session Storage Session Storage
</Text> </Text>
<Stack spacing={6} padding="2% 0%"> <Text fontStyle="italic" fontSize="sm" color="blackAlpha.500" mt={3}>
<Flex direction={isNotSmallerScreen ? "row" : "column"}> Note: Redis related environment variables cannot be updated from
<Flex w="30%" justifyContent="start" alignItems="center"> dashboard. Please use .env file or OS environment variables to update
<Text fontSize="sm">Redis URL:</Text> it.
</Flex> </Text>
<Center <Stack spacing={6} padding="2% 0%">
w={isNotSmallerScreen ? "70%" : "100%"} <Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
mt={isNotSmallerScreen ? "0" : "3"} <Flex w="30%" justifyContent="start" alignItems="center">
> <Text fontSize="sm">Redis URL:</Text>
<InputField </Flex>
borderRadius={5} <Center
variables={variables} w={isNotSmallerScreen ? '70%' : '100%'}
setVariables={setVariables} mt={isNotSmallerScreen ? '0' : '3'}
inputType={RedisURL} >
placeholder="Redis URL" <InputField
/> disabled
</Center> borderRadius={5}
</Flex> variables={variables}
</Stack> setVariables={setVariables}
</div> inputType={RedisURL}
); placeholder="Redis URL"
/>
</Center>
</Flex>
</Stack>
</div>
);
}; };
export default SessionStorage; export default SessionStorage;

View File

@ -22,7 +22,7 @@ import {
InputRightElement, InputRightElement,
Text, Text,
Link, Link,
Tooltip Tooltip,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { useClient } from 'urql'; import { useClient } from 'urql';
import { FaUserPlus, FaMinusCircle, FaPlus, FaUpload } from 'react-icons/fa'; import { FaUserPlus, FaMinusCircle, FaPlus, FaUpload } from 'react-icons/fa';
@ -187,22 +187,22 @@ const InviteMembersModal = ({
isDisabled={disabled} isDisabled={disabled}
size="sm" size="sm"
> >
<Center h="100%"> <Center h="100%">
{disabled ? ( {disabled ? (
<Tooltip <Tooltip
mr={8} mr={8}
mt={1} mt={1}
hasArrow hasArrow
bg="gray.300" bg="gray.300"
color="black" color="black"
label="Email verification is disabled, refer to 'UI Customization' tab within 'Environment' to enable it." label="Email verification is disabled, refer to 'Features' tab within 'Environment' to enable it."
> >
Invite Members Invite Members
</Tooltip> </Tooltip>
) : ( ) : (
"Invite Members" 'Invite Members'
)} )}
</Center>{" "} </Center>{' '}
</Button> </Button>
<Modal isOpen={isOpen} onClose={closeModalHandler} size="xl"> <Modal isOpen={isOpen} onClose={closeModalHandler} size="xl">
<ModalOverlay /> <ModalOverlay />

View File

@ -98,9 +98,9 @@ const LinkItems: Array<LinkItemProps> = [
}, },
{ name: 'Access Token', icon: SiOpenaccess, route: '/access-token' }, { name: 'Access Token', icon: SiOpenaccess, route: '/access-token' },
{ {
name: 'UI Customization', name: 'Features',
icon: BiCustomize, icon: BiCustomize,
route: '/ui-customization', route: '/features',
}, },
{ name: 'Database', icon: RiDatabase2Line, route: '/db-cred' }, { name: 'Database', icon: RiDatabase2Line, route: '/db-cred' },
{ {

View File

@ -62,6 +62,7 @@ export const SwitchInputType = {
DISABLE_EMAIL_VERIFICATION: 'DISABLE_EMAIL_VERIFICATION', DISABLE_EMAIL_VERIFICATION: 'DISABLE_EMAIL_VERIFICATION',
DISABLE_BASIC_AUTHENTICATION: 'DISABLE_BASIC_AUTHENTICATION', DISABLE_BASIC_AUTHENTICATION: 'DISABLE_BASIC_AUTHENTICATION',
DISABLE_SIGN_UP: 'DISABLE_SIGN_UP', DISABLE_SIGN_UP: 'DISABLE_SIGN_UP',
DISABLE_REDIS_FOR_ENV: 'DISABLE_REDIS_FOR_ENV',
}; };
export const DateInputType = { export const DateInputType = {
@ -138,7 +139,7 @@ export const envSubViews = {
WHITELIST_VARIABLES: 'whitelist-variables', WHITELIST_VARIABLES: 'whitelist-variables',
ORGANIZATION_INFO: 'organization-info', ORGANIZATION_INFO: 'organization-info',
ACCESS_TOKEN: 'access-token', ACCESS_TOKEN: 'access-token',
UI_CUSTOMIZATION: 'ui-customization', FEATURES: 'features',
ADMIN_SECRET: 'admin-secret', ADMIN_SECRET: 'admin-secret',
DB_CRED: 'db-cred', DB_CRED: 'db-cred',
}; };

View File

@ -49,6 +49,7 @@ export const EnvVariablesQuery = `
DISABLE_EMAIL_VERIFICATION, DISABLE_EMAIL_VERIFICATION,
DISABLE_BASIC_AUTHENTICATION, DISABLE_BASIC_AUTHENTICATION,
DISABLE_SIGN_UP, DISABLE_SIGN_UP,
DISABLE_REDIS_FOR_ENV,
CUSTOM_ACCESS_TOKEN_SCRIPT, CUSTOM_ACCESS_TOKEN_SCRIPT,
DATABASE_NAME, DATABASE_NAME,
DATABASE_TYPE, DATABASE_TYPE,

View File

@ -25,7 +25,7 @@ import EmailConfigurations from '../components/EnvComponents/EmailConfiguration'
import DomainWhiteListing from '../components/EnvComponents/DomainWhitelisting'; import DomainWhiteListing from '../components/EnvComponents/DomainWhitelisting';
import OrganizationInfo from '../components/EnvComponents/OrganizationInfo'; import OrganizationInfo from '../components/EnvComponents/OrganizationInfo';
import AccessToken from '../components/EnvComponents/AccessToken'; import AccessToken from '../components/EnvComponents/AccessToken';
import UICustomization from '../components/EnvComponents/UICustomization'; import Features from '../components/EnvComponents/Features';
import SecurityAdminSecret from '../components/EnvComponents/SecurityAdminSecret'; import SecurityAdminSecret from '../components/EnvComponents/SecurityAdminSecret';
import DatabaseCredentials from '../components/EnvComponents/DatabaseCredentials'; import DatabaseCredentials from '../components/EnvComponents/DatabaseCredentials';
@ -259,12 +259,9 @@ const Environment = () => {
setVariables={setEnvVariables} setVariables={setEnvVariables}
/> />
); );
case envSubViews.UI_CUSTOMIZATION: case envSubViews.FEATURES:
return ( return (
<UICustomization <Features variables={envVariables} setVariables={setEnvVariables} />
variables={envVariables}
setVariables={setEnvVariables}
/>
); );
case envSubViews.ADMIN_SECRET: case envSubViews.ADMIN_SECRET:
return ( return (

14
server/cli/cli.go Normal file
View File

@ -0,0 +1,14 @@
package cli
var (
// ARG_DB_URL is the cli arg variable for the database url
ARG_DB_URL *string
// ARG_DB_TYPE is the cli arg variable for the database type
ARG_DB_TYPE *string
// ARG_ENV_FILE is the cli arg variable for the env file
ARG_ENV_FILE *string
// ARG_LOG_LEVEL is the cli arg variable for the log level
ARG_LOG_LEVEL *string
// ARG_REDIS_URL is the cli arg variable for the redis url
ARG_REDIS_URL *string
)

View File

@ -0,0 +1,8 @@
package constants
const (
// AppCookieName is the name of the cookie that is used to store the application token
AppCookieName = "cookie"
// AdminCookieName is the name of the cookie that is used to store the admin token
AdminCookieName = "authorizer-admin"
)

View File

@ -5,11 +5,11 @@ var VERSION = "0.0.1"
const ( const (
// Envstore identifier // Envstore identifier
// StringStore string store identifier // StringStore string store identifier
StringStoreIdentifier = "stringStore" // StringStoreIdentifier = "stringStore"
// BoolStore bool store identifier // // BoolStore bool store identifier
BoolStoreIdentifier = "boolStore" // BoolStoreIdentifier = "boolStore"
// SliceStore slice store identifier // // SliceStore slice store identifier
SliceStoreIdentifier = "sliceStore" // SliceStoreIdentifier = "sliceStore"
// EnvKeyEnv key for env variable ENV // EnvKeyEnv key for env variable ENV
EnvKeyEnv = "ENV" EnvKeyEnv = "ENV"
@ -19,7 +19,6 @@ const (
EnvKeyAuthorizerURL = "AUTHORIZER_URL" EnvKeyAuthorizerURL = "AUTHORIZER_URL"
// EnvKeyPort key for env variable PORT // EnvKeyPort key for env variable PORT
EnvKeyPort = "PORT" EnvKeyPort = "PORT"
// EnvKeyAccessTokenExpiryTime key for env variable ACCESS_TOKEN_EXPIRY_TIME // EnvKeyAccessTokenExpiryTime key for env variable ACCESS_TOKEN_EXPIRY_TIME
EnvKeyAccessTokenExpiryTime = "ACCESS_TOKEN_EXPIRY_TIME" EnvKeyAccessTokenExpiryTime = "ACCESS_TOKEN_EXPIRY_TIME"
// EnvKeyAdminSecret key for env variable ADMIN_SECRET // EnvKeyAdminSecret key for env variable ADMIN_SECRET
@ -62,34 +61,12 @@ const (
EnvKeyJwtPrivateKey = "JWT_PRIVATE_KEY" EnvKeyJwtPrivateKey = "JWT_PRIVATE_KEY"
// EnvKeyJwtPublicKey key for env variable JWT_PUBLIC_KEY // EnvKeyJwtPublicKey key for env variable JWT_PUBLIC_KEY
EnvKeyJwtPublicKey = "JWT_PUBLIC_KEY" EnvKeyJwtPublicKey = "JWT_PUBLIC_KEY"
// EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
// EnvKeyAppURL key for env variable APP_URL // EnvKeyAppURL key for env variable APP_URL
EnvKeyAppURL = "APP_URL" EnvKeyAppURL = "APP_URL"
// EnvKeyRedisURL key for env variable REDIS_URL // EnvKeyRedisURL key for env variable REDIS_URL
EnvKeyRedisURL = "REDIS_URL" EnvKeyRedisURL = "REDIS_URL"
// EnvKeyCookieName key for env variable COOKIE_NAME
EnvKeyCookieName = "COOKIE_NAME"
// EnvKeyAdminCookieName key for env variable ADMIN_COOKIE_NAME
EnvKeyAdminCookieName = "ADMIN_COOKIE_NAME"
// EnvKeyResetPasswordURL key for env variable RESET_PASSWORD_URL // EnvKeyResetPasswordURL key for env variable RESET_PASSWORD_URL
EnvKeyResetPasswordURL = "RESET_PASSWORD_URL" EnvKeyResetPasswordURL = "RESET_PASSWORD_URL"
// EnvKeyDisableEmailVerification key for env variable DISABLE_EMAIL_VERIFICATION
EnvKeyDisableEmailVerification = "DISABLE_EMAIL_VERIFICATION"
// EnvKeyDisableBasicAuthentication key for env variable DISABLE_BASIC_AUTH
EnvKeyDisableBasicAuthentication = "DISABLE_BASIC_AUTHENTICATION"
// EnvKeyDisableMagicLinkLogin key for env variable DISABLE_MAGIC_LINK_LOGIN
EnvKeyDisableMagicLinkLogin = "DISABLE_MAGIC_LINK_LOGIN"
// EnvKeyDisableLoginPage key for env variable DISABLE_LOGIN_PAGE
EnvKeyDisableLoginPage = "DISABLE_LOGIN_PAGE"
// EnvKeyDisableSignUp key for env variable DISABLE_SIGN_UP
EnvKeyDisableSignUp = "DISABLE_SIGN_UP"
// EnvKeyRoles key for env variable ROLES
EnvKeyRoles = "ROLES"
// EnvKeyProtectedRoles key for env variable PROTECTED_ROLES
EnvKeyProtectedRoles = "PROTECTED_ROLES"
// EnvKeyDefaultRoles key for env variable DEFAULT_ROLES
EnvKeyDefaultRoles = "DEFAULT_ROLES"
// EnvKeyJwtRoleClaim key for env variable JWT_ROLE_CLAIM // EnvKeyJwtRoleClaim key for env variable JWT_ROLE_CLAIM
EnvKeyJwtRoleClaim = "JWT_ROLE_CLAIM" EnvKeyJwtRoleClaim = "JWT_ROLE_CLAIM"
// EnvKeyGoogleClientID key for env variable GOOGLE_CLIENT_ID // EnvKeyGoogleClientID key for env variable GOOGLE_CLIENT_ID
@ -120,6 +97,30 @@ const (
EnvKeyEncryptionKey = "ENCRYPTION_KEY" EnvKeyEncryptionKey = "ENCRYPTION_KEY"
// EnvKeyJWK key for env variable JWK // EnvKeyJWK key for env variable JWK
EnvKeyJWK = "JWK" EnvKeyJWK = "JWK"
// Boolean variables
// EnvKeyIsProd key for env variable IS_PROD // EnvKeyIsProd key for env variable IS_PROD
EnvKeyIsProd = "IS_PROD" EnvKeyIsProd = "IS_PROD"
// EnvKeyDisableEmailVerification key for env variable DISABLE_EMAIL_VERIFICATION
EnvKeyDisableEmailVerification = "DISABLE_EMAIL_VERIFICATION"
// EnvKeyDisableBasicAuthentication key for env variable DISABLE_BASIC_AUTH
EnvKeyDisableBasicAuthentication = "DISABLE_BASIC_AUTHENTICATION"
// EnvKeyDisableMagicLinkLogin key for env variable DISABLE_MAGIC_LINK_LOGIN
EnvKeyDisableMagicLinkLogin = "DISABLE_MAGIC_LINK_LOGIN"
// EnvKeyDisableLoginPage key for env variable DISABLE_LOGIN_PAGE
EnvKeyDisableLoginPage = "DISABLE_LOGIN_PAGE"
// EnvKeyDisableSignUp key for env variable DISABLE_SIGN_UP
EnvKeyDisableSignUp = "DISABLE_SIGN_UP"
// EnvKeyDisableRedisForEnv key for env variable DISABLE_REDIS_FOR_ENV
EnvKeyDisableRedisForEnv = "DISABLE_REDIS_FOR_ENV"
// Slice variables
// EnvKeyRoles key for env variable ROLES
EnvKeyRoles = "ROLES"
// EnvKeyProtectedRoles key for env variable PROTECTED_ROLES
EnvKeyProtectedRoles = "PROTECTED_ROLES"
// EnvKeyDefaultRoles key for env variable DEFAULT_ROLES
EnvKeyDefaultRoles = "DEFAULT_ROLES"
// EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
) )

View File

@ -4,8 +4,7 @@ import (
"net/url" "net/url"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -13,15 +12,14 @@ 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(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), token, 3600, "/", host, secure, httpOnly)
} }
// GetAdminCookie gets the admin cookie from the request // GetAdminCookie gets the admin cookie from the request
func GetAdminCookie(gc *gin.Context) (string, error) { func GetAdminCookie(gc *gin.Context) (string, error) {
cookie, err := gc.Request.Cookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName)) cookie, err := gc.Request.Cookie(constants.AdminCookieName)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -39,8 +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(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), "", -1, "/", host, secure, httpOnly)
} }

View File

@ -5,8 +5,7 @@ import (
"net/url" "net/url"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -14,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
} }
@ -25,33 +24,33 @@ func SetSession(gc *gin.Context, sessionID string) {
year := 60 * 60 * 24 * 365 year := 60 * 60 * 24 * 365
gc.SetSameSite(http.SameSiteNoneMode) gc.SetSameSite(http.SameSiteNoneMode)
gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session", sessionID, year, "/", host, secure, httpOnly) gc.SetCookie(constants.AppCookieName+"_session", sessionID, year, "/", host, secure, httpOnly)
gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session_domain", sessionID, year, "/", domain, secure, httpOnly) gc.SetCookie(constants.AppCookieName+"_session_domain", sessionID, year, "/", domain, secure, httpOnly)
} }
// DeleteSession sets session cookies to expire // DeleteSession sets session cookies to expire
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
} }
gc.SetSameSite(http.SameSiteNoneMode) gc.SetSameSite(http.SameSiteNoneMode)
gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session", "", -1, "/", host, secure, httpOnly) gc.SetCookie(constants.AppCookieName+"_session", "", -1, "/", host, secure, httpOnly)
gc.SetCookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName)+"_session_domain", "", -1, "/", domain, secure, httpOnly) gc.SetCookie(constants.AppCookieName+"_session_domain", "", -1, "/", domain, secure, httpOnly)
} }
// GetSession gets the session cookie from context // GetSession gets the session cookie from context
func GetSession(gc *gin.Context) (string, error) { func GetSession(gc *gin.Context) (string, error) {
var cookie *http.Cookie var cookie *http.Cookie
var err error var err error
cookie, err = gc.Request.Cookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName) + "_session") cookie, err = gc.Request.Cookie(constants.AppCookieName + "_session")
if err != nil { if err != nil {
cookie, err = gc.Request.Cookie(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyCookieName) + "_session_domain") cookie, err = gc.Request.Cookie(constants.AppCookieName + "_session_domain")
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -7,14 +7,18 @@ import (
"io" "io"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
var bytes = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 0o5} var bytes = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 0o5}
// EncryptAES method is to encrypt or hide any classified text // EncryptAES method is to encrypt or hide any classified text
func EncryptAES(text string) (string, error) { func EncryptAES(text string) (string, error) {
key := []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)) k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
if err != nil {
return "", err
}
key := []byte(k)
block, err := aes.NewCipher(key) block, err := aes.NewCipher(key)
if err != nil { if err != nil {
return "", err return "", err
@ -28,7 +32,11 @@ func EncryptAES(text string) (string, error) {
// DecryptAES method is to extract back the encrypted text // DecryptAES method is to extract back the encrypted text
func DecryptAES(text string) (string, error) { func DecryptAES(text string) (string, error) {
key := []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)) k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
if err != nil {
return "", err
}
key := []byte(k)
block, err := aes.NewCipher(key) block, err := aes.NewCipher(key)
if err != nil { if err != nil {
return "", err return "", err
@ -46,9 +54,13 @@ func DecryptAES(text string) (string, error) {
// EncryptAESEnv encrypts data using AES algorithm // EncryptAESEnv encrypts data using AES algorithm
// kept for the backward compatibility of env data encryption // kept for the backward compatibility of env data encryption
func EncryptAESEnv(text []byte) ([]byte, error) { func EncryptAESEnv(text []byte) ([]byte, error) {
key := []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey))
c, err := aes.NewCipher(key)
var res []byte var res []byte
k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
if err != nil {
return res, err
}
key := []byte(k)
c, err := aes.NewCipher(key)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -81,9 +93,13 @@ func EncryptAESEnv(text []byte) ([]byte, error) {
// DecryptAES decrypts data using AES algorithm // DecryptAES decrypts data using AES algorithm
// Kept for the backward compatibility of env data decryption // Kept for the backward compatibility of env data decryption
func DecryptAESEnv(ciphertext []byte) ([]byte, error) { func DecryptAESEnv(ciphertext []byte) ([]byte, error) {
key := []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey))
c, err := aes.NewCipher(key)
var res []byte var res []byte
k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
if err != nil {
return res, err
}
key := []byte(k)
c, err := aes.NewCipher(key)
if err != nil { if err != nil {
return res, err return res, err
} }

View File

@ -5,7 +5,7 @@ import (
"encoding/json" "encoding/json"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"gopkg.in/square/go-jose.v2" "gopkg.in/square/go-jose.v2"
) )
@ -37,20 +37,35 @@ func GetPubJWK(algo, keyID string, publicKey interface{}) (string, error) {
// this is called while initializing app / when env is updated // this is called while initializing app / when env is updated
func GenerateJWKBasedOnEnv() (string, error) { func GenerateJWKBasedOnEnv() (string, error) {
jwk := "" jwk := ""
algo := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType) algo, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
clientID := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) if err != nil {
return jwk, err
}
clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if err != nil {
return jwk, err
}
jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)
if err != nil {
return jwk, err
}
var err error
// check if jwt secret is provided // check if jwt secret is provided
if IsHMACA(algo) { if IsHMACA(algo) {
jwk, err = GetPubJWK(algo, clientID, []byte(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret))) jwk, err = GetPubJWK(algo, clientID, []byte(jwtSecret))
if err != nil { if err != nil {
return "", err return "", err
} }
} }
jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
if err != nil {
return jwk, err
}
if IsRSA(algo) { if IsRSA(algo) {
publicKeyInstance, err := ParseRsaPublicKeyFromPemStr(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) publicKeyInstance, err := ParseRsaPublicKeyFromPemStr(jwtPublicKey)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -62,7 +77,11 @@ func GenerateJWKBasedOnEnv() (string, error) {
} }
if IsECDSA(algo) { if IsECDSA(algo) {
publicKeyInstance, err := ParseEcdsaPublicKeyFromPemStr(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)) jwtPublicKey, err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
if err != nil {
return jwk, err
}
publicKeyInstance, err := ParseEcdsaPublicKeyFromPemStr(jwtPublicKey)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -77,13 +96,16 @@ func GenerateJWKBasedOnEnv() (string, error) {
} }
// EncryptEnvData is used to encrypt the env data // EncryptEnvData is used to encrypt the env data
func EncryptEnvData(data envstore.Store) (string, error) { func EncryptEnvData(data map[string]interface{}) (string, error) {
jsonBytes, err := json.Marshal(data) jsonBytes, err := json.Marshal(data)
if err != nil { if err != nil {
return "", err return "", err
} }
storeData := envstore.EnvStoreObj.GetEnvStoreClone() storeData, err := memorystore.Provider.GetEnvStore()
if err != nil {
return "", err
}
err = json.Unmarshal(jsonBytes, &storeData) err = json.Unmarshal(jsonBytes, &storeData)
if err != nil { if err != nil {

View File

@ -9,7 +9,7 @@ import (
"github.com/authorizerdev/authorizer/server/db/providers/cassandradb" "github.com/authorizerdev/authorizer/server/db/providers/cassandradb"
"github.com/authorizerdev/authorizer/server/db/providers/mongodb" "github.com/authorizerdev/authorizer/server/db/providers/mongodb"
"github.com/authorizerdev/authorizer/server/db/providers/sql" "github.com/authorizerdev/authorizer/server/db/providers/sql"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// Provider returns the current database provider // Provider returns the current database provider
@ -18,13 +18,15 @@ var Provider providers.Provider
func InitDB() error { func InitDB() error {
var err error var err error
isSQL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) != constants.DbTypeArangodb && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) != constants.DbTypeMongodb && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) != constants.DbTypeCassandraDB envs := memorystore.RequiredEnvStoreObj.GetRequiredEnv()
isArangoDB := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeArangodb
isMongoDB := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeMongodb isSQL := envs.DatabaseType != constants.DbTypeArangodb && envs.DatabaseType != constants.DbTypeMongodb && envs.DatabaseType != constants.DbTypeCassandraDB
isCassandra := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeCassandraDB isArangoDB := envs.DatabaseType == constants.DbTypeArangodb
isMongoDB := envs.DatabaseType == constants.DbTypeMongodb
isCassandra := envs.DatabaseType == constants.DbTypeCassandraDB
if isSQL { if isSQL {
log.Info("Initializing SQL Driver for: ", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType)) log.Info("Initializing SQL Driver for: ", envs.DatabaseType)
Provider, err = sql.NewProvider() Provider, err = sql.NewProvider()
if err != nil { if err != nil {
log.Fatal("Failed to initialize SQL driver: ", err) log.Fatal("Failed to initialize SQL driver: ", err)

View File

@ -6,9 +6,8 @@ import (
"github.com/arangodb/go-driver" "github.com/arangodb/go-driver"
arangoDriver "github.com/arangodb/go-driver" arangoDriver "github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/http" "github.com/arangodb/go-driver/http"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
type provider struct { type provider struct {
@ -22,8 +21,9 @@ type provider struct {
// NewProvider to initialize arangodb connection // NewProvider to initialize arangodb connection
func NewProvider() (*provider, error) { func NewProvider() (*provider, error) {
ctx := context.Background() ctx := context.Background()
dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
conn, err := http.NewConnection(http.ConnectionConfig{ conn, err := http.NewConnection(http.ConnectionConfig{
Endpoints: []string{envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)}, Endpoints: []string{dbURL},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -37,16 +37,16 @@ func NewProvider() (*provider, error) {
} }
var arangodb driver.Database var arangodb driver.Database
dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)) arangodb_exists, err := arangoClient.DatabaseExists(nil, dbName)
if arangodb_exists { if arangodb_exists {
arangodb, err = arangoClient.Database(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)) arangodb, err = arangoClient.Database(nil, dbName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { } else {
arangodb, err = arangoClient.CreateDatabase(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName), nil) arangodb, err = arangoClient.CreateDatabase(nil, dbName, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,15 +3,14 @@ package arangodb
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/arangodb/go-driver" "github.com/arangodb/go-driver"
arangoDriver "github.com/arangodb/go-driver" arangoDriver "github.com/arangodb/go-driver"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/google/uuid" "github.com/google/uuid"
) )
@ -22,7 +21,11 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
} }
if user.Roles == "" { if user.Roles == "" {
user.Roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
return user, err
}
user.Roles = defaultRoles
} }
user.CreatedAt = time.Now().Unix() user.CreatedAt = time.Now().Unix()

View File

@ -9,7 +9,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/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/gocql/gocql" "github.com/gocql/gocql"
cansandraDriver "github.com/gocql/gocql" cansandraDriver "github.com/gocql/gocql"
) )
@ -23,15 +23,19 @@ var KeySpace string
// NewProvider to initialize arangodb connection // NewProvider to initialize arangodb connection
func NewProvider() (*provider, error) { func NewProvider() (*provider, error) {
dbURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL) dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
if dbURL == "" { if dbURL == "" {
dbURL = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseHost) dbHost := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseHost
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePort) != "" { dbPort := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePort
dbURL = fmt.Sprintf("%s:%s", dbURL, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePort)) if dbPort != "" && dbHost != "" {
dbURL = fmt.Sprintf("%s:%s", dbHost, dbPort)
} }
} }
KeySpace = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName) KeySpace = memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
if KeySpace == "" {
KeySpace = constants.EnvKeyDatabaseName
}
clusterURL := []string{} clusterURL := []string{}
if strings.Contains(dbURL, ",") { if strings.Contains(dbURL, ",") {
clusterURL = strings.Split(dbURL, ",") clusterURL = strings.Split(dbURL, ",")
@ -39,25 +43,31 @@ func NewProvider() (*provider, error) {
clusterURL = append(clusterURL, dbURL) clusterURL = append(clusterURL, dbURL)
} }
cassandraClient := cansandraDriver.NewCluster(clusterURL...) cassandraClient := cansandraDriver.NewCluster(clusterURL...)
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseUsername) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePassword) != "" { dbUsername := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseUsername
dbPassword := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePassword
if dbUsername != "" && dbPassword != "" {
cassandraClient.Authenticator = &cansandraDriver.PasswordAuthenticator{ cassandraClient.Authenticator = &cansandraDriver.PasswordAuthenticator{
Username: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseUsername), Username: dbUsername,
Password: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePassword), Password: dbPassword,
} }
} }
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCert) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCACert) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCertKey) != "" { dbCert := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCert
certString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCert)) dbCACert := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCACert
dbCertKey := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCertKey
if dbCert != "" && dbCACert != "" && dbCertKey != "" {
certString, err := crypto.DecryptB64(dbCert)
if err != nil { if err != nil {
return nil, err return nil, err
} }
keyString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCertKey)) keyString, err := crypto.DecryptB64(dbCertKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
caString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCACert)) caString, err := crypto.DecryptB64(dbCACert)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -9,8 +9,8 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/gocql/gocql" "github.com/gocql/gocql"
"github.com/google/uuid" "github.com/google/uuid"
) )
@ -22,7 +22,11 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
} }
if user.Roles == "" { if user.Roles == "" {
user.Roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
return user, err
}
user.Roles = defaultRoles
} }
user.CreatedAt = time.Now().Unix() user.CreatedAt = time.Now().Unix()

View File

@ -4,9 +4,8 @@ import (
"context" "context"
"time" "time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
@ -19,7 +18,8 @@ type provider struct {
// NewProvider to initialize mongodb connection // NewProvider to initialize mongodb connection
func NewProvider() (*provider, error) { func NewProvider() (*provider, error) {
mongodbOptions := options.Client().ApplyURI(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)) dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
mongodbOptions := options.Client().ApplyURI(dbURL)
maxWait := time.Duration(5 * time.Second) maxWait := time.Duration(5 * time.Second)
mongodbOptions.ConnectTimeout = &maxWait mongodbOptions.ConnectTimeout = &maxWait
mongoClient, err := mongo.NewClient(mongodbOptions) mongoClient, err := mongo.NewClient(mongodbOptions)
@ -37,18 +37,19 @@ func NewProvider() (*provider, error) {
return nil, err return nil, err
} }
mongodb := mongoClient.Database(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName), options.Database()) dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
mongodb := mongoClient.Database(dbName, options.Database())
mongodb.CreateCollection(ctx, models.Collections.User, options.CreateCollection()) mongodb.CreateCollection(ctx, models.Collections.User, options.CreateCollection())
userCollection := mongodb.Collection(models.Collections.User, options.Collection()) userCollection := mongodb.Collection(models.Collections.User, options.Collection())
userCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ userCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongo.IndexModel{ {
Keys: bson.M{"email": 1}, Keys: bson.M{"email": 1},
Options: options.Index().SetUnique(true).SetSparse(true), Options: options.Index().SetUnique(true).SetSparse(true),
}, },
}, options.CreateIndexes()) }, options.CreateIndexes())
userCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ userCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongo.IndexModel{ {
Keys: bson.M{"phone_number": 1}, Keys: bson.M{"phone_number": 1},
Options: options.Index().SetUnique(true).SetSparse(true).SetPartialFilterExpression(map[string]interface{}{ Options: options.Index().SetUnique(true).SetSparse(true).SetPartialFilterExpression(map[string]interface{}{
"phone_number": map[string]string{"$type": "string"}, "phone_number": map[string]string{"$type": "string"},
@ -59,13 +60,13 @@ func NewProvider() (*provider, error) {
mongodb.CreateCollection(ctx, models.Collections.VerificationRequest, options.CreateCollection()) mongodb.CreateCollection(ctx, models.Collections.VerificationRequest, options.CreateCollection())
verificationRequestCollection := mongodb.Collection(models.Collections.VerificationRequest, options.Collection()) verificationRequestCollection := mongodb.Collection(models.Collections.VerificationRequest, options.Collection())
verificationRequestCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ verificationRequestCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongo.IndexModel{ {
Keys: bson.M{"email": 1, "identifier": 1}, Keys: bson.M{"email": 1, "identifier": 1},
Options: options.Index().SetUnique(true).SetSparse(true), Options: options.Index().SetUnique(true).SetSparse(true),
}, },
}, options.CreateIndexes()) }, options.CreateIndexes())
verificationRequestCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ verificationRequestCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongo.IndexModel{ {
Keys: bson.M{"token": 1}, Keys: bson.M{"token": 1},
Options: options.Index().SetSparse(true), Options: options.Index().SetSparse(true),
}, },
@ -74,7 +75,7 @@ func NewProvider() (*provider, error) {
mongodb.CreateCollection(ctx, models.Collections.Session, options.CreateCollection()) mongodb.CreateCollection(ctx, models.Collections.Session, options.CreateCollection())
sessionCollection := mongodb.Collection(models.Collections.Session, options.Collection()) sessionCollection := mongodb.Collection(models.Collections.Session, options.Collection())
sessionCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{ sessionCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongo.IndexModel{ {
Keys: bson.M{"user_id": 1}, Keys: bson.M{"user_id": 1},
Options: options.Index().SetSparse(true), Options: options.Index().SetSparse(true),
}, },

View File

@ -1,13 +1,12 @@
package mongodb package mongodb
import ( import (
"strings"
"time" "time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/google/uuid" "github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
@ -20,7 +19,11 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
} }
if user.Roles == "" { if user.Roles == "" {
user.Roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
return user, err
}
user.Roles = defaultRoles
} }
user.CreatedAt = time.Now().Unix() user.CreatedAt = time.Now().Unix()
user.UpdatedAt = time.Now().Unix() user.UpdatedAt = time.Now().Unix()

View File

@ -1,13 +1,12 @@
package provider_template package provider_template
import ( import (
"strings"
"time" "time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/google/uuid" "github.com/google/uuid"
) )
@ -18,7 +17,11 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
} }
if user.Roles == "" { if user.Roles == "" {
user.Roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
return user, err
}
user.Roles = defaultRoles
} }
user.CreatedAt = time.Now().Unix() user.CreatedAt = time.Now().Unix()

View File

@ -7,7 +7,7 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
@ -41,15 +41,19 @@ func NewProvider() (*provider, error) {
TablePrefix: models.Prefix, TablePrefix: models.Prefix,
}, },
} }
switch envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) {
dbType := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseType
dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
switch dbType {
case constants.DbTypePostgres, constants.DbTypeYugabyte: case constants.DbTypePostgres, constants.DbTypeYugabyte:
sqlDB, err = gorm.Open(postgres.Open(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) sqlDB, err = gorm.Open(postgres.Open(dbURL), ormConfig)
case constants.DbTypeSqlite: case constants.DbTypeSqlite:
sqlDB, err = gorm.Open(sqlite.Open(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) sqlDB, err = gorm.Open(sqlite.Open(dbURL), ormConfig)
case constants.DbTypeMysql, constants.DbTypeMariaDB: case constants.DbTypeMysql, constants.DbTypeMariaDB:
sqlDB, err = gorm.Open(mysql.Open(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) sqlDB, err = gorm.Open(mysql.Open(dbURL), ormConfig)
case constants.DbTypeSqlserver: case constants.DbTypeSqlserver:
sqlDB, err = gorm.Open(sqlserver.Open(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)), ormConfig) sqlDB, err = gorm.Open(sqlserver.Open(dbURL), ormConfig)
} }
if err != nil { if err != nil {

View File

@ -1,13 +1,12 @@
package sql package sql
import ( import (
"strings"
"time" "time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
@ -19,7 +18,11 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
} }
if user.Roles == "" { if user.Roles == "" {
user.Roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
return user, err
}
user.Roles = defaultRoles
} }
user.CreatedAt = time.Now().Unix() user.CreatedAt = time.Now().Unix()

View File

@ -11,7 +11,7 @@ import (
gomail "gopkg.in/mail.v2" gomail "gopkg.in/mail.v2"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// addEmailTemplate is used to add html template in email body // addEmailTemplate is used to add html template in email body
@ -33,17 +33,57 @@ func addEmailTemplate(a string, b map[string]interface{}, templateName string) s
// SendMail function to send mail // SendMail function to send mail
func SendMail(to []string, Subject, bodyMessage string) error { func SendMail(to []string, Subject, bodyMessage string) error {
// dont trigger email sending in case of test // dont trigger email sending in case of test
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEnv) == "test" { envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
if err != nil {
return err
}
if envKey == "test" {
return nil return nil
} }
m := gomail.NewMessage() m := gomail.NewMessage()
m.SetHeader("From", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeySenderEmail)) senderEmail, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySenderEmail)
if err != nil {
log.Errorf("Error while getting sender email from env variable: %v", err)
return err
}
smtpPort, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)
if err != nil {
log.Errorf("Error while getting smtp port from env variable: %v", err)
return err
}
smtpHost, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpHost)
if err != nil {
log.Errorf("Error while getting smtp host from env variable: %v", err)
return err
}
smtpUsername, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpUsername)
if err != nil {
log.Errorf("Error while getting smtp username from env variable: %v", err)
return err
}
smtpPassword, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPassword)
if err != nil {
log.Errorf("Error while getting smtp password from env variable: %v", err)
return err
}
isProd, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsProd)
if err != nil {
log.Errorf("Error while getting env variable: %v", err)
return err
}
m.SetHeader("From", senderEmail)
m.SetHeader("To", to...) m.SetHeader("To", to...)
m.SetHeader("Subject", Subject) m.SetHeader("Subject", Subject)
m.SetBody("text/html", bodyMessage) m.SetBody("text/html", bodyMessage)
port, _ := strconv.Atoi(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)) port, _ := strconv.Atoi(smtpPort)
d := gomail.NewDialer(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpHost), port, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpUsername), envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeySmtpPassword)) d := gomail.NewDialer(smtpHost, port, smtpUsername, smtpPassword)
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEnv) == "development" { if !isProd {
d.TLSConfig = &tls.Config{InsecureSkipVerify: true} d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
} }
if err := d.DialAndSend(m); err != nil { if err := d.DialAndSend(m); err != nil {

View File

@ -2,14 +2,19 @@ package email
import ( import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// SendForgotPasswordMail to send forgot password email // SendForgotPasswordMail to send forgot password email
func SendForgotPasswordMail(toEmail, token, hostname string) error { func SendForgotPasswordMail(toEmail, token, hostname string) error {
resetPasswordUrl := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL) resetPasswordUrl, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL)
if err != nil {
return err
}
if resetPasswordUrl == "" { if resetPasswordUrl == "" {
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyResetPasswordURL, hostname+"/app/reset-password") if err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyResetPasswordURL, hostname+"/app/reset-password"); err != nil {
return err
}
} }
// The receiver needs to be in slice as the receive supports multiple receiver // The receiver needs to be in slice as the receive supports multiple receiver
@ -103,8 +108,14 @@ func SendForgotPasswordMail(toEmail, token, hostname string) error {
` `
data := make(map[string]interface{}, 3) data := make(map[string]interface{}, 3)
data["org_logo"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo) data["org_logo"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
data["org_name"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName) if err != nil {
return err
}
data["org_name"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
if err != nil {
return err
}
data["verification_url"] = resetPasswordUrl + "?token=" + token data["verification_url"] = resetPasswordUrl + "?token=" + token
message = addEmailTemplate(message, data, "reset_password_email.tmpl") message = addEmailTemplate(message, data, "reset_password_email.tmpl")

View File

@ -4,7 +4,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// InviteEmail to send invite email // InviteEmail to send invite email
@ -99,13 +99,20 @@ func InviteEmail(toEmail, token, verificationURL, redirectURI string) error {
</html> </html>
` `
data := make(map[string]interface{}, 3) data := make(map[string]interface{}, 3)
data["org_logo"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo) var err error
data["org_name"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName) data["org_logo"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
if err != nil {
return err
}
data["org_name"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
if err != nil {
return err
}
data["verification_url"] = verificationURL + "?token=" + token + "&redirect_uri=" + redirectURI data["verification_url"] = verificationURL + "?token=" + token + "&redirect_uri=" + redirectURI
message = addEmailTemplate(message, data, "invite_email.tmpl") message = addEmailTemplate(message, data, "invite_email.tmpl")
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message) // bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
err := SendMail(Receiver, Subject, message) err = SendMail(Receiver, Subject, message)
if err != nil { if err != nil {
log.Warn("error sending email: ", err) log.Warn("error sending email: ", err)
} }

View File

@ -4,7 +4,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// SendVerificationMail to send verification email // SendVerificationMail to send verification email
@ -99,13 +99,20 @@ func SendVerificationMail(toEmail, token, hostname string) error {
</html> </html>
` `
data := make(map[string]interface{}, 3) data := make(map[string]interface{}, 3)
data["org_logo"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo) var err error
data["org_name"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName) data["org_logo"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
if err != nil {
return err
}
data["org_name"], err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
if err != nil {
return err
}
data["verification_url"] = hostname + "/verify_email?token=" + token data["verification_url"] = hostname + "/verify_email?token=" + token
message = addEmailTemplate(message, data, "verify_email.tmpl") message = addEmailTemplate(message, data, "verify_email.tmpl")
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message) // bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
err := SendMail(Receiver, Subject, message) err = SendMail(Receiver, Subject, message)
if err != nil { if err != nil {
log.Warn("error sending email: ", err) log.Warn("error sending email: ", err)
} }

665
server/env/env.go vendored
View File

@ -2,212 +2,242 @@ package env
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"strconv"
"strings" "strings"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/joho/godotenv"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
// InitRequiredEnv to initialize EnvData and through error if required env are not present
func InitRequiredEnv() error {
envPath := os.Getenv(constants.EnvKeyEnvPath)
if envPath == "" {
envPath = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyEnvPath)
if envPath == "" {
envPath = `.env`
}
}
if envstore.ARG_ENV_FILE != nil && *envstore.ARG_ENV_FILE != "" {
envPath = *envstore.ARG_ENV_FILE
}
log.Info("env path: ", envPath)
err := godotenv.Load(envPath)
if err != nil {
log.Info("using OS env instead of %s file", envPath)
}
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
dbType := os.Getenv(constants.EnvKeyDatabaseType)
dbName := os.Getenv(constants.EnvKeyDatabaseName)
dbPort := os.Getenv(constants.EnvKeyDatabasePort)
dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
dbCert := os.Getenv(constants.EnvKeyDatabaseCert)
dbCertKey := os.Getenv(constants.EnvKeyDatabaseCertKey)
dbCACert := os.Getenv(constants.EnvKeyDatabaseCACert)
if strings.TrimSpace(dbType) == "" {
if envstore.ARG_DB_TYPE != nil && *envstore.ARG_DB_TYPE != "" {
dbType = strings.TrimSpace(*envstore.ARG_DB_TYPE)
}
if dbType == "" {
log.Debug("DATABASE_TYPE is not set")
return errors.New("invalid database type. DATABASE_TYPE is empty")
}
}
if strings.TrimSpace(dbURL) == "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL) == "" {
if envstore.ARG_DB_URL != nil && *envstore.ARG_DB_URL != "" {
dbURL = strings.TrimSpace(*envstore.ARG_DB_URL)
}
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
log.Debug("DATABASE_URL is not set")
return errors.New("invalid database url. DATABASE_URL is required")
}
}
if dbName == "" {
if dbName == "" {
dbName = "authorizer"
}
}
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, envPath)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseURL, dbURL)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseType, dbType)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseName, dbName)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseHost, dbHost)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePort, dbPort)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseUsername, dbUsername)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePassword, dbPassword)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCert, dbCert)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCertKey, dbCertKey)
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCACert, dbCACert)
return nil
}
// InitEnv to initialize EnvData and through error if required env are not present // InitEnv to initialize EnvData and through error if required env are not present
func InitAllEnv() error { func InitAllEnv() error {
envData, err := GetEnvData() envData, err := GetEnvData()
if err != nil { if err != nil {
log.Info("No env data found in db, using local clone of env data") log.Info("No env data found in db, using local clone of env data")
// get clone of current store // get clone of current store
envData = envstore.EnvStoreObj.GetEnvStoreClone() envData, err = memorystore.Provider.GetEnvStore()
if err != nil {
log.Debug("Error while getting env data from memorystore: ", err)
return err
}
} }
clientID := envData.StringEnv[constants.EnvKeyClientID]
// unique client id for each instance // unique client id for each instance
if clientID == "" { cid, ok := envData[constants.EnvKeyClientID]
clientID := ""
if !ok || cid == "" {
clientID = uuid.New().String() clientID = uuid.New().String()
envData.StringEnv[constants.EnvKeyClientID] = clientID envData[constants.EnvKeyClientID] = clientID
} else {
clientID = cid.(string)
} }
clientSecret := envData.StringEnv[constants.EnvKeyClientSecret] // unique client secret for each instance
// unique client id for each instance if val, ok := envData[constants.EnvKeyClientSecret]; !ok || val != "" {
if clientSecret == "" { envData[constants.EnvKeyClientSecret] = uuid.New().String()
clientSecret = uuid.New().String()
envData.StringEnv[constants.EnvKeyClientSecret] = clientSecret
} }
if envData.StringEnv[constants.EnvKeyEnv] == "" { // os string envs
envData.StringEnv[constants.EnvKeyEnv] = os.Getenv(constants.EnvKeyEnv) osEnv := os.Getenv(constants.EnvKeyEnv)
if envData.StringEnv[constants.EnvKeyEnv] == "" { osAppURL := os.Getenv(constants.EnvKeyAppURL)
envData.StringEnv[constants.EnvKeyEnv] = "production" osAuthorizerURL := os.Getenv(constants.EnvKeyAuthorizerURL)
osPort := os.Getenv(constants.EnvKeyPort)
osAccessTokenExpiryTime := os.Getenv(constants.EnvKeyAccessTokenExpiryTime)
osAdminSecret := os.Getenv(constants.EnvKeyAdminSecret)
osSmtpHost := os.Getenv(constants.EnvKeySmtpHost)
osSmtpPort := os.Getenv(constants.EnvKeySmtpPort)
osSmtpUsername := os.Getenv(constants.EnvKeySmtpUsername)
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
osJwtType := os.Getenv(constants.EnvKeyJwtType)
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
osJwtPublicKey := os.Getenv(constants.EnvKeyJwtPublicKey)
osJwtRoleClaim := os.Getenv(constants.EnvKeyJwtRoleClaim)
osCustomAccessTokenScript := os.Getenv(constants.EnvKeyCustomAccessTokenScript)
osGoogleClientID := os.Getenv(constants.EnvKeyGoogleClientID)
osGoogleClientSecret := os.Getenv(constants.EnvKeyGoogleClientSecret)
osGithubClientID := os.Getenv(constants.EnvKeyGithubClientID)
osGithubClientSecret := os.Getenv(constants.EnvKeyGithubClientSecret)
osFacebookClientID := os.Getenv(constants.EnvKeyFacebookClientID)
osFacebookClientSecret := os.Getenv(constants.EnvKeyFacebookClientSecret)
osResetPasswordURL := os.Getenv(constants.EnvKeyResetPasswordURL)
osOrganizationName := os.Getenv(constants.EnvKeyOrganizationName)
osOrganizationLogo := os.Getenv(constants.EnvKeyOrganizationLogo)
// os bool vars
osDisableBasicAuthentication := os.Getenv(constants.EnvKeyDisableBasicAuthentication)
osDisableEmailVerification := os.Getenv(constants.EnvKeyDisableEmailVerification)
osDisableMagicLinkLogin := os.Getenv(constants.EnvKeyDisableMagicLinkLogin)
osDisableLoginPage := os.Getenv(constants.EnvKeyDisableLoginPage)
osDisableSignUp := os.Getenv(constants.EnvKeyDisableSignUp)
osDisableRedisForEnv := os.Getenv(constants.EnvKeyDisableRedisForEnv)
// os slice vars
osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins)
osRoles := os.Getenv(constants.EnvKeyRoles)
osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles)
osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles)
ienv, ok := envData[constants.EnvKeyEnv]
if !ok || ienv == "" {
envData[constants.EnvKeyEnv] = osEnv
if envData[constants.EnvKeyEnv] == "" {
envData[constants.EnvKeyEnv] = "production"
} }
if envData.StringEnv[constants.EnvKeyEnv] == "production" { if envData[constants.EnvKeyEnv] == "production" {
envData.BoolEnv[constants.EnvKeyIsProd] = true envData[constants.EnvKeyIsProd] = true
} else { } else {
envData.BoolEnv[constants.EnvKeyIsProd] = false envData[constants.EnvKeyIsProd] = false
} }
} }
if osEnv != "" && osEnv != envData[constants.EnvKeyEnv] {
if envData.StringEnv[constants.EnvKeyAppURL] == "" { envData[constants.EnvKeyEnv] = osEnv
envData.StringEnv[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL) if envData[constants.EnvKeyEnv] == "production" {
} envData[constants.EnvKeyIsProd] = true
if envData.StringEnv[constants.EnvKeyAuthorizerURL] == "" {
envData.StringEnv[constants.EnvKeyAuthorizerURL] = os.Getenv(constants.EnvKeyAuthorizerURL)
}
if envData.StringEnv[constants.EnvKeyPort] == "" {
envData.StringEnv[constants.EnvKeyPort] = os.Getenv(constants.EnvKeyPort)
if envData.StringEnv[constants.EnvKeyPort] == "" {
envData.StringEnv[constants.EnvKeyPort] = "8080"
}
}
if envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] == "" {
envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] = os.Getenv(constants.EnvKeyAccessTokenExpiryTime)
if envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] == "" {
envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] = "30m"
}
}
if envData.StringEnv[constants.EnvKeyAdminSecret] == "" {
envData.StringEnv[constants.EnvKeyAdminSecret] = os.Getenv(constants.EnvKeyAdminSecret)
}
if envData.StringEnv[constants.EnvKeySmtpHost] == "" {
envData.StringEnv[constants.EnvKeySmtpHost] = os.Getenv(constants.EnvKeySmtpHost)
}
if envData.StringEnv[constants.EnvKeySmtpPort] == "" {
envData.StringEnv[constants.EnvKeySmtpPort] = os.Getenv(constants.EnvKeySmtpPort)
}
if envData.StringEnv[constants.EnvKeySmtpUsername] == "" {
envData.StringEnv[constants.EnvKeySmtpUsername] = os.Getenv(constants.EnvKeySmtpUsername)
}
if envData.StringEnv[constants.EnvKeySmtpPassword] == "" {
envData.StringEnv[constants.EnvKeySmtpPassword] = os.Getenv(constants.EnvKeySmtpPassword)
}
if envData.StringEnv[constants.EnvKeySenderEmail] == "" {
envData.StringEnv[constants.EnvKeySenderEmail] = os.Getenv(constants.EnvKeySenderEmail)
}
algo := envData.StringEnv[constants.EnvKeyJwtType]
if algo == "" {
envData.StringEnv[constants.EnvKeyJwtType] = os.Getenv(constants.EnvKeyJwtType)
if envData.StringEnv[constants.EnvKeyJwtType] == "" {
envData.StringEnv[constants.EnvKeyJwtType] = "RS256"
algo = envData.StringEnv[constants.EnvKeyJwtType]
} else { } else {
algo = envData.StringEnv[constants.EnvKeyJwtType] envData[constants.EnvKeyIsProd] = false
if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
log.Debug("Invalid JWT Algorithm")
return errors.New("invalid JWT_TYPE")
}
} }
} }
if val, ok := envData[constants.EnvKeyAppURL]; !ok || val == "" {
envData[constants.EnvKeyAppURL] = osAppURL
}
if osAppURL != "" && envData[constants.EnvKeyAppURL] != osAppURL {
envData[constants.EnvKeyAppURL] = osAppURL
}
if val, ok := envData[constants.EnvKeyAuthorizerURL]; !ok || val == "" {
envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
}
if osAuthorizerURL != "" && envData[constants.EnvKeyAuthorizerURL] != osAuthorizerURL {
envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
}
if val, ok := envData[constants.EnvKeyPort]; !ok || val == "" {
envData[constants.EnvKeyPort] = osPort
if envData[constants.EnvKeyPort] == "" {
envData[constants.EnvKeyPort] = "8080"
}
}
if osPort != "" && envData[constants.EnvKeyPort] != osPort {
envData[constants.EnvKeyPort] = osPort
}
if val, ok := envData[constants.EnvKeyAccessTokenExpiryTime]; !ok || val == "" {
envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
if envData[constants.EnvKeyAccessTokenExpiryTime] == "" {
envData[constants.EnvKeyAccessTokenExpiryTime] = "30m"
}
}
if osAccessTokenExpiryTime != "" && envData[constants.EnvKeyAccessTokenExpiryTime] != osAccessTokenExpiryTime {
envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
}
if val, ok := envData[constants.EnvKeyAdminSecret]; !ok || val == "" {
envData[constants.EnvKeyAdminSecret] = osAdminSecret
}
if osAdminSecret != "" && envData[constants.EnvKeyAdminSecret] != osAdminSecret {
envData[constants.EnvKeyAdminSecret] = osAdminSecret
}
if val, ok := envData[constants.EnvKeySmtpHost]; !ok || val == "" {
envData[constants.EnvKeySmtpHost] = osSmtpHost
}
if osSmtpHost != "" && envData[constants.EnvKeySmtpHost] != osSmtpHost {
envData[constants.EnvKeySmtpHost] = osSmtpHost
}
if val, ok := envData[constants.EnvKeySmtpPort]; !ok || val == "" {
envData[constants.EnvKeySmtpPort] = osSmtpPort
}
if osSmtpPort != "" && envData[constants.EnvKeySmtpPort] != osSmtpPort {
envData[constants.EnvKeySmtpPort] = osSmtpPort
}
if val, ok := envData[constants.EnvKeySmtpUsername]; !ok || val == "" {
envData[constants.EnvKeySmtpUsername] = osSmtpUsername
}
if osSmtpUsername != "" && envData[constants.EnvKeySmtpUsername] != osSmtpUsername {
envData[constants.EnvKeySmtpUsername] = osSmtpUsername
}
if val, ok := envData[constants.EnvKeySmtpPassword]; !ok || val == "" {
envData[constants.EnvKeySmtpPassword] = osSmtpPassword
}
if osSmtpPassword != "" && envData[constants.EnvKeySmtpPassword] != osSmtpPassword {
envData[constants.EnvKeySmtpPassword] = osSmtpPassword
}
if val, ok := envData[constants.EnvKeySenderEmail]; !ok || val == "" {
envData[constants.EnvKeySenderEmail] = osSenderEmail
}
if osSenderEmail != "" && envData[constants.EnvKeySenderEmail] != osSenderEmail {
envData[constants.EnvKeySenderEmail] = osSenderEmail
}
algoVal, ok := envData[constants.EnvKeyJwtType]
algo := ""
if !ok || algoVal == "" {
envData[constants.EnvKeyJwtType] = osJwtType
if envData[constants.EnvKeyJwtType] == "" {
envData[constants.EnvKeyJwtType] = "RS256"
algo = envData[constants.EnvKeyJwtType].(string)
}
} else {
algo = algoVal.(string)
if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
log.Debug("Invalid JWT Algorithm")
return errors.New("invalid JWT_TYPE")
}
}
if osJwtType != "" && osJwtType != algo {
if !crypto.IsHMACA(osJwtType) && !crypto.IsRSA(osJwtType) && !crypto.IsECDSA(osJwtType) {
log.Debug("Invalid JWT Algorithm")
return errors.New("invalid JWT_TYPE")
}
algo = osJwtType
envData[constants.EnvKeyJwtType] = osJwtType
}
if crypto.IsHMACA(algo) { if crypto.IsHMACA(algo) {
if envData.StringEnv[constants.EnvKeyJwtSecret] == "" { if val, ok := envData[constants.EnvKeyJwtSecret]; !ok || val == "" {
envData.StringEnv[constants.EnvKeyJwtSecret] = os.Getenv(constants.EnvKeyJwtSecret) envData[constants.EnvKeyJwtSecret] = osJwtSecret
if envData.StringEnv[constants.EnvKeyJwtSecret] == "" { if envData[constants.EnvKeyJwtSecret] == "" {
envData.StringEnv[constants.EnvKeyJwtSecret], _, err = crypto.NewHMACKey(algo, clientID) envData[constants.EnvKeyJwtSecret], _, err = crypto.NewHMACKey(algo, clientID)
if err != nil { if err != nil {
return err return err
} }
} }
} }
if osJwtSecret != "" && envData[constants.EnvKeyJwtSecret] != osJwtSecret {
envData[constants.EnvKeyJwtSecret] = osJwtSecret
}
} }
if crypto.IsRSA(algo) || crypto.IsECDSA(algo) { if crypto.IsRSA(algo) || crypto.IsECDSA(algo) {
privateKey, publicKey := "", "" privateKey, publicKey := "", ""
if envData.StringEnv[constants.EnvKeyJwtPrivateKey] == "" { if val, ok := envData[constants.EnvKeyJwtPrivateKey]; !ok || val == "" {
privateKey = os.Getenv(constants.EnvKeyJwtPrivateKey) privateKey = osJwtPrivateKey
}
if osJwtPrivateKey != "" && privateKey != osJwtPrivateKey {
privateKey = osJwtPrivateKey
} }
if envData.StringEnv[constants.EnvKeyJwtPublicKey] == "" { if val, ok := envData[constants.EnvKeyJwtPublicKey]; !ok || val == "" {
publicKey = os.Getenv(constants.EnvKeyJwtPublicKey) publicKey = osJwtPublicKey
}
if osJwtPublicKey != "" && publicKey != osJwtPublicKey {
publicKey = osJwtPublicKey
} }
// if algo is RSA / ECDSA, then we need to have both private and public key // if algo is RSA / ECDSA, then we need to have both private and public key
@ -250,159 +280,232 @@ func InitAllEnv() error {
} }
} }
envData.StringEnv[constants.EnvKeyJwtPrivateKey] = privateKey envData[constants.EnvKeyJwtPrivateKey] = privateKey
envData.StringEnv[constants.EnvKeyJwtPublicKey] = publicKey envData[constants.EnvKeyJwtPublicKey] = publicKey
} }
if envData.StringEnv[constants.EnvKeyJwtRoleClaim] == "" { if val, ok := envData[constants.EnvKeyJwtRoleClaim]; !ok || val == "" {
envData.StringEnv[constants.EnvKeyJwtRoleClaim] = os.Getenv(constants.EnvKeyJwtRoleClaim) envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
if envData.StringEnv[constants.EnvKeyJwtRoleClaim] == "" { if envData[constants.EnvKeyJwtRoleClaim] == "" {
envData.StringEnv[constants.EnvKeyJwtRoleClaim] = "role" envData[constants.EnvKeyJwtRoleClaim] = "role"
}
}
if osJwtRoleClaim != "" && envData[constants.EnvKeyJwtRoleClaim] != osJwtRoleClaim {
envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
}
if val, ok := envData[constants.EnvKeyCustomAccessTokenScript]; !ok || val == "" {
envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
}
if osCustomAccessTokenScript != "" && envData[constants.EnvKeyCustomAccessTokenScript] != osCustomAccessTokenScript {
envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
}
if val, ok := envData[constants.EnvKeyGoogleClientID]; !ok || val == "" {
envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
}
if osGoogleClientID != "" && envData[constants.EnvKeyGoogleClientID] != osGoogleClientID {
envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
}
if val, ok := envData[constants.EnvKeyGoogleClientSecret]; !ok || val == "" {
envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
}
if osGoogleClientSecret != "" && envData[constants.EnvKeyGoogleClientSecret] != osGoogleClientSecret {
envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
}
if val, ok := envData[constants.EnvKeyGithubClientID]; !ok || val == "" {
envData[constants.EnvKeyGithubClientID] = osGithubClientID
}
if osGithubClientID != "" && envData[constants.EnvKeyGithubClientID] != osGithubClientID {
envData[constants.EnvKeyGithubClientID] = osGithubClientID
}
if val, ok := envData[constants.EnvKeyGithubClientSecret]; !ok || val == "" {
envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
}
if osGithubClientSecret != "" && envData[constants.EnvKeyGithubClientSecret] != osGithubClientSecret {
envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
}
if val, ok := envData[constants.EnvKeyFacebookClientID]; !ok || val == "" {
envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
}
if osFacebookClientID != "" && envData[constants.EnvKeyFacebookClientID] != osFacebookClientID {
envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
}
if val, ok := envData[constants.EnvKeyFacebookClientSecret]; !ok || val == "" {
envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
}
if osFacebookClientSecret != "" && envData[constants.EnvKeyFacebookClientSecret] != osFacebookClientSecret {
envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
}
if val, ok := envData[constants.EnvKeyResetPasswordURL]; !ok || val == "" {
envData[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(osResetPasswordURL, "/")
}
if osResetPasswordURL != "" && envData[constants.EnvKeyResetPasswordURL] != osResetPasswordURL {
envData[constants.EnvKeyResetPasswordURL] = osResetPasswordURL
}
if val, ok := envData[constants.EnvKeyOrganizationName]; !ok || val == "" {
envData[constants.EnvKeyOrganizationName] = osOrganizationName
}
if osOrganizationName != "" && envData[constants.EnvKeyOrganizationName] != osOrganizationName {
envData[constants.EnvKeyOrganizationName] = osOrganizationName
}
if val, ok := envData[constants.EnvKeyOrganizationLogo]; !ok || val == "" {
envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
}
if osOrganizationLogo != "" && envData[constants.EnvKeyOrganizationLogo] != osOrganizationLogo {
envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
}
if _, ok := envData[constants.EnvKeyDisableBasicAuthentication]; !ok {
envData[constants.EnvKeyDisableBasicAuthentication] = osDisableBasicAuthentication == "true"
}
if osDisableBasicAuthentication != "" {
boolValue, err := strconv.ParseBool(osDisableBasicAuthentication)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableBasicAuthentication].(bool) {
envData[constants.EnvKeyDisableBasicAuthentication] = boolValue
} }
} }
if envData.StringEnv[constants.EnvKeyCustomAccessTokenScript] == "" { if _, ok := envData[constants.EnvKeyDisableEmailVerification]; !ok {
envData.StringEnv[constants.EnvKeyCustomAccessTokenScript] = os.Getenv(constants.EnvKeyCustomAccessTokenScript) envData[constants.EnvKeyDisableEmailVerification] = osDisableEmailVerification == "true"
} }
if osDisableEmailVerification != "" {
if envData.StringEnv[constants.EnvKeyRedisURL] == "" { boolValue, err := strconv.ParseBool(osDisableEmailVerification)
envData.StringEnv[constants.EnvKeyRedisURL] = os.Getenv(constants.EnvKeyRedisURL) if err != nil {
} return err
}
if envData.StringEnv[constants.EnvKeyCookieName] == "" { if boolValue != envData[constants.EnvKeyDisableEmailVerification].(bool) {
envData.StringEnv[constants.EnvKeyCookieName] = os.Getenv(constants.EnvKeyCookieName) envData[constants.EnvKeyDisableEmailVerification] = boolValue
if envData.StringEnv[constants.EnvKeyCookieName] == "" {
envData.StringEnv[constants.EnvKeyCookieName] = "authorizer"
} }
} }
if envData.StringEnv[constants.EnvKeyGoogleClientID] == "" { if _, ok := envData[constants.EnvKeyDisableMagicLinkLogin]; !ok {
envData.StringEnv[constants.EnvKeyGoogleClientID] = os.Getenv(constants.EnvKeyGoogleClientID) envData[constants.EnvKeyDisableMagicLinkLogin] = osDisableMagicLinkLogin == "true"
}
if osDisableMagicLinkLogin != "" {
boolValue, err := strconv.ParseBool(osDisableMagicLinkLogin)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
}
} }
if envData.StringEnv[constants.EnvKeyGoogleClientSecret] == "" { if _, ok := envData[constants.EnvKeyDisableLoginPage]; !ok {
envData.StringEnv[constants.EnvKeyGoogleClientSecret] = os.Getenv(constants.EnvKeyGoogleClientSecret) envData[constants.EnvKeyDisableLoginPage] = osDisableLoginPage == "true"
}
if osDisableLoginPage != "" {
boolValue, err := strconv.ParseBool(osDisableLoginPage)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableLoginPage].(bool) {
envData[constants.EnvKeyDisableLoginPage] = boolValue
}
} }
if envData.StringEnv[constants.EnvKeyGithubClientID] == "" { if _, ok := envData[constants.EnvKeyDisableSignUp]; !ok {
envData.StringEnv[constants.EnvKeyGithubClientID] = os.Getenv(constants.EnvKeyGithubClientID) envData[constants.EnvKeyDisableSignUp] = osDisableSignUp == "true"
}
if osDisableSignUp != "" {
boolValue, err := strconv.ParseBool(osDisableSignUp)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableSignUp].(bool) {
envData[constants.EnvKeyDisableSignUp] = boolValue
}
} }
if envData.StringEnv[constants.EnvKeyGithubClientSecret] == "" { if _, ok := envData[constants.EnvKeyDisableRedisForEnv]; !ok {
envData.StringEnv[constants.EnvKeyGithubClientSecret] = os.Getenv(constants.EnvKeyGithubClientSecret) envData[constants.EnvKeyDisableRedisForEnv] = osDisableRedisForEnv == "true"
} }
if osDisableRedisForEnv != "" {
if envData.StringEnv[constants.EnvKeyFacebookClientID] == "" { boolValue, err := strconv.ParseBool(osDisableRedisForEnv)
envData.StringEnv[constants.EnvKeyFacebookClientID] = os.Getenv(constants.EnvKeyFacebookClientID) if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableRedisForEnv].(bool) {
envData[constants.EnvKeyDisableRedisForEnv] = boolValue
}
} }
if envData.StringEnv[constants.EnvKeyFacebookClientSecret] == "" {
envData.StringEnv[constants.EnvKeyFacebookClientSecret] = os.Getenv(constants.EnvKeyFacebookClientSecret)
}
if envData.StringEnv[constants.EnvKeyResetPasswordURL] == "" {
envData.StringEnv[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(os.Getenv(constants.EnvKeyResetPasswordURL), "/")
}
envData.BoolEnv[constants.EnvKeyDisableBasicAuthentication] = os.Getenv(constants.EnvKeyDisableBasicAuthentication) == "true"
envData.BoolEnv[constants.EnvKeyDisableEmailVerification] = os.Getenv(constants.EnvKeyDisableEmailVerification) == "true"
envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = os.Getenv(constants.EnvKeyDisableMagicLinkLogin) == "true"
envData.BoolEnv[constants.EnvKeyDisableLoginPage] = os.Getenv(constants.EnvKeyDisableLoginPage) == "true"
envData.BoolEnv[constants.EnvKeyDisableSignUp] = os.Getenv(constants.EnvKeyDisableSignUp) == "true"
// no need to add nil check as its already done above // no need to add nil check as its already done above
if envData.StringEnv[constants.EnvKeySmtpHost] == "" || envData.StringEnv[constants.EnvKeySmtpUsername] == "" || envData.StringEnv[constants.EnvKeySmtpPassword] == "" || envData.StringEnv[constants.EnvKeySenderEmail] == "" && envData.StringEnv[constants.EnvKeySmtpPort] == "" { if envData[constants.EnvKeySmtpHost] == "" || envData[constants.EnvKeySmtpUsername] == "" || envData[constants.EnvKeySmtpPassword] == "" || envData[constants.EnvKeySenderEmail] == "" && envData[constants.EnvKeySmtpPort] == "" {
envData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true envData[constants.EnvKeyDisableEmailVerification] = true
envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true envData[constants.EnvKeyDisableMagicLinkLogin] = true
} }
if envData.BoolEnv[constants.EnvKeyDisableEmailVerification] { if envData[constants.EnvKeyDisableEmailVerification].(bool) {
envData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true envData[constants.EnvKeyDisableMagicLinkLogin] = true
} }
allowedOriginsSplit := strings.Split(os.Getenv(constants.EnvKeyAllowedOrigins), ",") if val, ok := envData[constants.EnvKeyAllowedOrigins]; !ok || val == "" {
allowedOrigins := []string{} envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
hasWildCard := false if envData[constants.EnvKeyAllowedOrigins] == "" {
envData[constants.EnvKeyAllowedOrigins] = "*"
}
}
if osAllowedOrigins != "" && envData[constants.EnvKeyAllowedOrigins] != osAllowedOrigins {
envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
}
for _, val := range allowedOriginsSplit { if val, ok := envData[constants.EnvKeyRoles]; !ok || val == "" {
trimVal := strings.TrimSpace(val) envData[constants.EnvKeyRoles] = osRoles
if trimVal != "" { if envData[constants.EnvKeyRoles] == "" {
if trimVal != "*" { envData[constants.EnvKeyRoles] = "user"
host, port := utils.GetHostParts(trimVal) }
allowedOrigins = append(allowedOrigins, host+":"+port) }
} else { if osRoles != "" && envData[constants.EnvKeyRoles] != osRoles {
hasWildCard = true envData[constants.EnvKeyRoles] = osRoles
allowedOrigins = append(allowedOrigins, trimVal) }
break roles := strings.Split(envData[constants.EnvKeyRoles].(string), ",")
}
if val, ok := envData[constants.EnvKeyDefaultRoles]; !ok || val == "" {
envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
if envData[constants.EnvKeyDefaultRoles] == "" {
envData[constants.EnvKeyDefaultRoles] = "user"
}
}
if osDefaultRoles != "" && envData[constants.EnvKeyDefaultRoles] != osDefaultRoles {
envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
}
defaultRoles := strings.Split(envData[constants.EnvKeyDefaultRoles].(string), ",")
if len(defaultRoles) == 0 {
defaultRoles = []string{roles[0]}
}
for _, role := range defaultRoles {
if !utils.StringSliceContains(roles, role) {
return fmt.Errorf("Default role %s is not defined in roles", role)
} }
} }
if len(allowedOrigins) > 1 && hasWildCard { if val, ok := envData[constants.EnvKeyProtectedRoles]; !ok || val == "" {
allowedOrigins = []string{"*"} envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
}
if osProtectedRoles != "" && envData[constants.EnvKeyProtectedRoles] != osProtectedRoles {
envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
} }
if len(allowedOrigins) == 0 { err = memorystore.Provider.UpdateEnvStore(envData)
allowedOrigins = []string{"*"} if err != nil {
log.Debug("Error while updating env store: ", err)
return err
} }
envData.SliceEnv[constants.EnvKeyAllowedOrigins] = allowedOrigins
rolesEnv := strings.TrimSpace(os.Getenv(constants.EnvKeyRoles))
rolesSplit := strings.Split(rolesEnv, ",")
roles := []string{}
if len(rolesEnv) == 0 {
roles = []string{"user"}
}
defaultRolesEnv := strings.TrimSpace(os.Getenv(constants.EnvKeyDefaultRoles))
defaultRoleSplit := strings.Split(defaultRolesEnv, ",")
defaultRoles := []string{}
if len(defaultRolesEnv) == 0 {
defaultRoles = []string{"user"}
}
protectedRolesEnv := strings.TrimSpace(os.Getenv(constants.EnvKeyProtectedRoles))
protectedRolesSplit := strings.Split(protectedRolesEnv, ",")
protectedRoles := []string{}
if len(protectedRolesEnv) > 0 {
for _, val := range protectedRolesSplit {
trimVal := strings.TrimSpace(val)
protectedRoles = append(protectedRoles, trimVal)
}
}
for _, val := range rolesSplit {
trimVal := strings.TrimSpace(val)
if trimVal != "" {
roles = append(roles, trimVal)
if utils.StringSliceContains(defaultRoleSplit, trimVal) {
defaultRoles = append(defaultRoles, trimVal)
}
}
}
if len(roles) > 0 && len(defaultRoles) == 0 && len(defaultRolesEnv) > 0 {
log.Debug("Default roles not found in roles list. It can be one from ROLES only")
return errors.New(`invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
}
envData.SliceEnv[constants.EnvKeyRoles] = roles
envData.SliceEnv[constants.EnvKeyDefaultRoles] = defaultRoles
envData.SliceEnv[constants.EnvKeyProtectedRoles] = protectedRoles
if os.Getenv(constants.EnvKeyOrganizationName) != "" {
envData.StringEnv[constants.EnvKeyOrganizationName] = os.Getenv(constants.EnvKeyOrganizationName)
}
if os.Getenv(constants.EnvKeyOrganizationLogo) != "" {
envData.StringEnv[constants.EnvKeyOrganizationLogo] = os.Getenv(constants.EnvKeyOrganizationLogo)
}
envstore.EnvStoreObj.UpdateEnvStore(envData)
return nil return nil
} }

View File

@ -3,6 +3,7 @@ package env
import ( import (
"encoding/json" "encoding/json"
"os" "os"
"reflect"
"strconv" "strconv"
"strings" "strings"
@ -13,13 +14,50 @@ import (
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
func fixBackwardCompatibility(data map[string]interface{}) (bool, map[string]interface{}) {
result := data
// check if env data is stored in older format
hasOlderFormat := false
if _, ok := result["bool_env"]; ok {
for key, value := range result["bool_env"].(map[string]interface{}) {
result[key] = value
}
hasOlderFormat = true
delete(result, "bool_env")
}
if _, ok := result["string_env"]; ok {
for key, value := range result["string_env"].(map[string]interface{}) {
result[key] = value
}
hasOlderFormat = true
delete(result, "string_env")
}
if _, ok := result["slice_env"]; ok {
for key, value := range result["slice_env"].(map[string]interface{}) {
typeOfValue := reflect.TypeOf(value)
if strings.Contains(typeOfValue.String(), "[]string") {
result[key] = strings.Join(value.([]string), ",")
}
if strings.Contains(typeOfValue.String(), "[]interface") {
result[key] = strings.Join(utils.ConvertInterfaceToStringSlice(value), ",")
}
}
hasOlderFormat = true
delete(result, "slice_env")
}
return hasOlderFormat, result
}
// GetEnvData returns the env data from database // GetEnvData returns the env data from database
func GetEnvData() (envstore.Store, error) { func GetEnvData() (map[string]interface{}, error) {
var result envstore.Store var result map[string]interface{}
env, err := db.Provider.GetEnv() env, err := db.Provider.GetEnv()
// config not found in db // config not found in db
if err != nil { if err != nil {
@ -34,7 +72,7 @@ func GetEnvData() (envstore.Store, error) {
return result, err return result, err
} }
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData) b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
if err != nil { if err != nil {
@ -54,6 +92,17 @@ func GetEnvData() (envstore.Store, error) {
return result, err return result, err
} }
hasOlderFormat, result := fixBackwardCompatibility(result)
if hasOlderFormat {
err = memorystore.Provider.UpdateEnvStore(result)
if err != nil {
log.Debug("Error while updating env store: ", err)
return result, err
}
}
return result, err return result, err
} }
@ -64,10 +113,20 @@ func PersistEnv() error {
if err != nil { if err != nil {
// AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid // AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid
hash := uuid.New().String()[:36-4] hash := uuid.New().String()[:36-4]
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, hash) err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash)
if err != nil {
log.Debug("Error while updating encryption env variable: ", err)
return err
}
encodedHash := crypto.EncryptB64(hash) encodedHash := crypto.EncryptB64(hash)
encryptedConfig, err := crypto.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone()) res, err := memorystore.Provider.GetEnvStore()
if err != nil {
log.Debug("Error while getting env store: ", err)
return err
}
encryptedConfig, err := crypto.EncryptEnvData(res)
if err != nil { if err != nil {
log.Debug("Error while encrypting env data: ", err) log.Debug("Error while encrypting env data: ", err)
return err return err
@ -93,7 +152,7 @@ func PersistEnv() error {
return err return err
} }
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEncryptionKey, decryptedEncryptionKey) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData) b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
if err != nil { if err != nil {
@ -108,7 +167,7 @@ func PersistEnv() error {
} }
// temp store variable // temp store variable
var storeData envstore.Store storeData := map[string]interface{}{}
err = json.Unmarshal(decryptedConfigs, &storeData) err = json.Unmarshal(decryptedConfigs, &storeData)
if err != nil { if err != nil {
@ -116,75 +175,73 @@ func PersistEnv() error {
return err return err
} }
hasOlderFormat, result := fixBackwardCompatibility(storeData)
if hasOlderFormat {
err = memorystore.Provider.UpdateEnvStore(result)
if err != nil {
log.Debug("Error while updating env store: ", err)
return err
}
}
// if env is changed via env file or OS env // if env is changed via env file or OS env
// give that higher preference and update db, but we don't recommend it // give that higher preference and update db, but we don't recommend it
hasChanged := false hasChanged := false
for key, value := range storeData {
for key, value := range storeData.StringEnv {
// don't override unexposed envs // don't override unexposed envs
// check only for derivative keys
// No need to check for ENCRYPTION_KEY which special key we use for encrypting config data
// as we have removed it from json
if key != constants.EnvKeyEncryptionKey { if key != constants.EnvKeyEncryptionKey {
// check only for derivative keys
// No need to check for ENCRYPTION_KEY which special key we use for encrypting config data
// as we have removed it from json
envValue := strings.TrimSpace(os.Getenv(key)) envValue := strings.TrimSpace(os.Getenv(key))
// env is not empty
if envValue != "" { if envValue != "" {
if value != envValue { switch key {
storeData.StringEnv[key] = envValue case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv:
hasChanged = true if envValueBool, err := strconv.ParseBool(envValue); err == nil {
if value.(bool) != envValueBool {
storeData[key] = envValueBool
hasChanged = true
}
}
default:
if value != nil && value.(string) != envValue {
storeData[key] = envValue
hasChanged = true
}
} }
} }
} }
} }
for key, value := range storeData.BoolEnv {
envValue := strings.TrimSpace(os.Getenv(key))
// env is not empty
if envValue != "" {
envValueBool, _ := strconv.ParseBool(envValue)
if value != envValueBool {
storeData.BoolEnv[key] = envValueBool
hasChanged = true
}
}
}
for key, value := range storeData.SliceEnv {
envValue := strings.TrimSpace(os.Getenv(key))
// env is not empty
if envValue != "" {
envStringArr := strings.Split(envValue, ",")
if !utils.IsStringArrayEqual(value, envStringArr) {
storeData.SliceEnv[key] = envStringArr
hasChanged = true
}
}
}
// handle derivative cases like disabling email verification & magic login // handle derivative cases like disabling email verification & magic login
// in case SMTP is off but env is set to true // in case SMTP is off but env is set to true
if storeData.StringEnv[constants.EnvKeySmtpHost] == "" || storeData.StringEnv[constants.EnvKeySmtpUsername] == "" || storeData.StringEnv[constants.EnvKeySmtpPassword] == "" || storeData.StringEnv[constants.EnvKeySenderEmail] == "" && storeData.StringEnv[constants.EnvKeySmtpPort] == "" { if storeData[constants.EnvKeySmtpHost] == "" || storeData[constants.EnvKeySmtpUsername] == "" || storeData[constants.EnvKeySmtpPassword] == "" || storeData[constants.EnvKeySenderEmail] == "" && storeData[constants.EnvKeySmtpPort] == "" {
if !storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] { if !storeData[constants.EnvKeyDisableEmailVerification].(bool) {
storeData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true storeData[constants.EnvKeyDisableEmailVerification] = true
hasChanged = true hasChanged = true
} }
if !storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] { if !storeData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
storeData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true storeData[constants.EnvKeyDisableMagicLinkLogin] = true
hasChanged = true hasChanged = true
} }
} }
envstore.EnvStoreObj.UpdateEnvStore(storeData) err = memorystore.Provider.UpdateEnvStore(storeData)
if err != nil {
log.Debug("Error while updating env store: ", err)
return err
}
jwk, err := crypto.GenerateJWKBasedOnEnv() jwk, err := crypto.GenerateJWKBasedOnEnv()
if err != nil { if err != nil {
log.Debug("Error while generating JWK: ", err) log.Debug("Error while generating JWK: ", err)
return err return err
} }
// updating jwk // updating jwk
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
if hasChanged { if hasChanged {
encryptedConfig, err := crypto.EncryptEnvData(storeData) encryptedConfig, err := crypto.EncryptEnvData(storeData)

View File

@ -1,122 +0,0 @@
package envstore
import (
"sync"
"github.com/authorizerdev/authorizer/server/constants"
)
var (
// ARG_DB_URL is the cli arg variable for the database url
ARG_DB_URL *string
// ARG_DB_TYPE is the cli arg variable for the database type
ARG_DB_TYPE *string
// ARG_ENV_FILE is the cli arg variable for the env file
ARG_ENV_FILE *string
// ARG_LOG_LEVEL is the cli arg variable for the log level
ARG_LOG_LEVEL *string
)
// Store data structure
type Store struct {
StringEnv map[string]string `json:"string_env"`
BoolEnv map[string]bool `json:"bool_env"`
SliceEnv map[string][]string `json:"slice_env"`
}
// EnvStore struct
type EnvStore struct {
mutex sync.Mutex
store *Store
}
var defaultStore = &EnvStore{
store: &Store{
StringEnv: map[string]string{
constants.EnvKeyAdminCookieName: "authorizer-admin",
constants.EnvKeyJwtRoleClaim: "role",
constants.EnvKeyOrganizationName: "Authorizer",
constants.EnvKeyOrganizationLogo: "https://www.authorizer.dev/images/logo.png",
},
BoolEnv: map[string]bool{
constants.EnvKeyDisableBasicAuthentication: false,
constants.EnvKeyDisableMagicLinkLogin: false,
constants.EnvKeyDisableEmailVerification: false,
constants.EnvKeyDisableLoginPage: false,
constants.EnvKeyDisableSignUp: false,
},
SliceEnv: map[string][]string{},
},
}
// EnvStoreObj.GetBoolStoreEnvVariable global variable for EnvStore
var EnvStoreObj = defaultStore
// UpdateEnvStore to update the whole env store object
func (e *EnvStore) UpdateEnvStore(store Store) {
e.mutex.Lock()
defer e.mutex.Unlock()
// just override the keys + new keys
for key, value := range store.StringEnv {
e.store.StringEnv[key] = value
}
for key, value := range store.BoolEnv {
e.store.BoolEnv[key] = value
}
for key, value := range store.SliceEnv {
e.store.SliceEnv[key] = value
}
}
// UpdateEnvVariable to update the particular env variable
func (e *EnvStore) UpdateEnvVariable(storeIdentifier, key string, value interface{}) {
e.mutex.Lock()
defer e.mutex.Unlock()
switch storeIdentifier {
case constants.StringStoreIdentifier:
e.store.StringEnv[key] = value.(string)
case constants.BoolStoreIdentifier:
e.store.BoolEnv[key] = value.(bool)
case constants.SliceStoreIdentifier:
e.store.SliceEnv[key] = value.([]string)
}
}
// GetStringStoreEnvVariable to get the env variable from string store object
func (e *EnvStore) GetStringStoreEnvVariable(key string) string {
// e.mutex.Lock()
// defer e.mutex.Unlock()
return e.store.StringEnv[key]
}
// GetBoolStoreEnvVariable to get the env variable from bool store object
func (e *EnvStore) GetBoolStoreEnvVariable(key string) bool {
// e.mutex.Lock()
// defer e.mutex.Unlock()
return e.store.BoolEnv[key]
}
// GetSliceStoreEnvVariable to get the env variable from slice store object
func (e *EnvStore) GetSliceStoreEnvVariable(key string) []string {
// e.mutex.Lock()
// defer e.mutex.Unlock()
return e.store.SliceEnv[key]
}
// GetEnvStoreClone to get clone of current env store object
func (e *EnvStore) GetEnvStoreClone() Store {
e.mutex.Lock()
defer e.mutex.Unlock()
result := *e.store
return result
}
func (e *EnvStore) ResetStore() {
e.mutex.Lock()
defer e.mutex.Unlock()
e.store = defaultStore.store
}

View File

@ -20,7 +20,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
github.com/sirupsen/logrus v1.8.1 // indirect github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/ugorji/go v1.2.6 // indirect github.com/ugorji/go v1.2.6 // indirect
github.com/vektah/gqlparser/v2 v2.2.0 github.com/vektah/gqlparser/v2 v2.2.0

View File

@ -59,7 +59,6 @@ type ComplexityRoot struct {
AppURL func(childComplexity int) int AppURL func(childComplexity int) int
ClientID func(childComplexity int) int ClientID func(childComplexity int) int
ClientSecret func(childComplexity int) int ClientSecret func(childComplexity int) int
CookieName func(childComplexity int) int
CustomAccessTokenScript func(childComplexity int) int CustomAccessTokenScript func(childComplexity int) int
DatabaseHost func(childComplexity int) int DatabaseHost func(childComplexity int) int
DatabaseName func(childComplexity int) int DatabaseName func(childComplexity int) int
@ -73,6 +72,7 @@ type ComplexityRoot struct {
DisableEmailVerification func(childComplexity int) int DisableEmailVerification func(childComplexity int) int
DisableLoginPage func(childComplexity int) int DisableLoginPage func(childComplexity int) int
DisableMagicLinkLogin func(childComplexity int) int DisableMagicLinkLogin func(childComplexity int) int
DisableRedisForEnv func(childComplexity int) int
DisableSignUp func(childComplexity int) int DisableSignUp func(childComplexity int) int
FacebookClientID func(childComplexity int) int FacebookClientID func(childComplexity int) int
FacebookClientSecret func(childComplexity int) int FacebookClientSecret func(childComplexity int) int
@ -346,13 +346,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.ClientSecret(childComplexity), true return e.complexity.Env.ClientSecret(childComplexity), true
case "Env.COOKIE_NAME":
if e.complexity.Env.CookieName == nil {
break
}
return e.complexity.Env.CookieName(childComplexity), true
case "Env.CUSTOM_ACCESS_TOKEN_SCRIPT": case "Env.CUSTOM_ACCESS_TOKEN_SCRIPT":
if e.complexity.Env.CustomAccessTokenScript == nil { if e.complexity.Env.CustomAccessTokenScript == nil {
break break
@ -444,6 +437,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.DisableMagicLinkLogin(childComplexity), true return e.complexity.Env.DisableMagicLinkLogin(childComplexity), true
case "Env.DISABLE_REDIS_FOR_ENV":
if e.complexity.Env.DisableRedisForEnv == nil {
break
}
return e.complexity.Env.DisableRedisForEnv(childComplexity), true
case "Env.DISABLE_SIGN_UP": case "Env.DISABLE_SIGN_UP":
if e.complexity.Env.DisableSignUp == nil { if e.complexity.Env.DisableSignUp == nil {
break break
@ -1423,13 +1423,13 @@ type Response {
type Env { type Env {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
DATABASE_NAME: String! DATABASE_NAME: String
DATABASE_URL: String! DATABASE_URL: String
DATABASE_TYPE: String! DATABASE_TYPE: String
DATABASE_USERNAME: String! DATABASE_USERNAME: String
DATABASE_PASSWORD: String! DATABASE_PASSWORD: String
DATABASE_HOST: String! DATABASE_HOST: String
DATABASE_PORT: String! DATABASE_PORT: String
CLIENT_ID: String! CLIENT_ID: String!
CLIENT_SECRET: String! CLIENT_SECRET: String!
CUSTOM_ACCESS_TOKEN_SCRIPT: String CUSTOM_ACCESS_TOKEN_SCRIPT: String
@ -1445,13 +1445,13 @@ type Env {
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
REDIS_URL: String REDIS_URL: String
COOKIE_NAME: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
DISABLE_EMAIL_VERIFICATION: Boolean DISABLE_EMAIL_VERIFICATION: Boolean!
DISABLE_BASIC_AUTHENTICATION: Boolean DISABLE_BASIC_AUTHENTICATION: Boolean!
DISABLE_MAGIC_LINK_LOGIN: Boolean DISABLE_MAGIC_LINK_LOGIN: Boolean!
DISABLE_LOGIN_PAGE: Boolean DISABLE_LOGIN_PAGE: Boolean!
DISABLE_SIGN_UP: Boolean DISABLE_SIGN_UP: Boolean!
DISABLE_REDIS_FOR_ENV: Boolean!
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]
@ -1492,14 +1492,13 @@ input UpdateEnvInput {
JWT_PUBLIC_KEY: String JWT_PUBLIC_KEY: String
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
REDIS_URL: String
COOKIE_NAME: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
DISABLE_EMAIL_VERIFICATION: Boolean DISABLE_EMAIL_VERIFICATION: Boolean
DISABLE_BASIC_AUTHENTICATION: Boolean DISABLE_BASIC_AUTHENTICATION: Boolean
DISABLE_MAGIC_LINK_LOGIN: Boolean DISABLE_MAGIC_LINK_LOGIN: Boolean
DISABLE_LOGIN_PAGE: Boolean DISABLE_LOGIN_PAGE: Boolean
DISABLE_SIGN_UP: Boolean DISABLE_SIGN_UP: Boolean
DISABLE_REDIS_FOR_ENV: Boolean
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]
@ -2356,14 +2355,11 @@ func (ec *executionContext) _Env_DATABASE_NAME(ctx context.Context, field graphq
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2391,14 +2387,11 @@ func (ec *executionContext) _Env_DATABASE_URL(ctx context.Context, field graphql
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2426,14 +2419,11 @@ func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphq
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2461,14 +2451,11 @@ func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field gr
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2496,14 +2483,11 @@ func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field gr
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2531,14 +2515,11 @@ func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphq
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -2566,14 +2547,11 @@ func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphq
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(string) res := resTmp.(*string)
fc.Result = res fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -3062,38 +3040,6 @@ func (ec *executionContext) _Env_REDIS_URL(ctx context.Context, field graphql.Co
return ec.marshalOString2ᚖstring(ctx, field.Selections, res) return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_COOKIE_NAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Env",
Field: field,
Args: nil,
IsMethod: false,
IsResolver: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.CookieName, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) _Env_RESET_PASSWORD_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_RESET_PASSWORD_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -3151,11 +3097,14 @@ func (ec *executionContext) _Env_DISABLE_EMAIL_VERIFICATION(ctx context.Context,
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(*bool) res := resTmp.(bool)
fc.Result = res fc.Result = res
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) return ec.marshalNBoolean2bool(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -3183,11 +3132,14 @@ func (ec *executionContext) _Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Contex
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(*bool) res := resTmp.(bool)
fc.Result = res fc.Result = res
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) return ec.marshalNBoolean2bool(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -3215,11 +3167,14 @@ func (ec *executionContext) _Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, f
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(*bool) res := resTmp.(bool)
fc.Result = res fc.Result = res
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) return ec.marshalNBoolean2bool(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DISABLE_LOGIN_PAGE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DISABLE_LOGIN_PAGE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -3247,11 +3202,14 @@ func (ec *executionContext) _Env_DISABLE_LOGIN_PAGE(ctx context.Context, field g
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(*bool) res := resTmp.(bool)
fc.Result = res fc.Result = res
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) return ec.marshalNBoolean2bool(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_DISABLE_SIGN_UP(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_DISABLE_SIGN_UP(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -3279,11 +3237,49 @@ func (ec *executionContext) _Env_DISABLE_SIGN_UP(ctx context.Context, field grap
return graphql.Null return graphql.Null
} }
if resTmp == nil { if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null return graphql.Null
} }
res := resTmp.(*bool) res := resTmp.(bool)
fc.Result = res fc.Result = res
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) _Env_DISABLE_REDIS_FOR_ENV(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Env",
Field: field,
Args: nil,
IsMethod: false,
IsResolver: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableRedisForEnv, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
} }
func (ec *executionContext) _Env_ROLES(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_ROLES(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
@ -8431,22 +8427,6 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil { if err != nil {
return it, err return it, err
} }
case "REDIS_URL":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("REDIS_URL"))
it.RedisURL, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
case "COOKIE_NAME":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("COOKIE_NAME"))
it.CookieName, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
case "RESET_PASSWORD_URL": case "RESET_PASSWORD_URL":
var err error var err error
@ -8495,6 +8475,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil { if err != nil {
return it, err return it, err
} }
case "DISABLE_REDIS_FOR_ENV":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("DISABLE_REDIS_FOR_ENV"))
it.DisableRedisForEnv, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
if err != nil {
return it, err
}
case "ROLES": case "ROLES":
var err error var err error
@ -8943,39 +8931,18 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._Env_ADMIN_SECRET(ctx, field, obj) out.Values[i] = ec._Env_ADMIN_SECRET(ctx, field, obj)
case "DATABASE_NAME": case "DATABASE_NAME":
out.Values[i] = ec._Env_DATABASE_NAME(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_NAME(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_URL": case "DATABASE_URL":
out.Values[i] = ec._Env_DATABASE_URL(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_URL(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_TYPE": case "DATABASE_TYPE":
out.Values[i] = ec._Env_DATABASE_TYPE(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_TYPE(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_USERNAME": case "DATABASE_USERNAME":
out.Values[i] = ec._Env_DATABASE_USERNAME(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_USERNAME(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_PASSWORD": case "DATABASE_PASSWORD":
out.Values[i] = ec._Env_DATABASE_PASSWORD(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_PASSWORD(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_HOST": case "DATABASE_HOST":
out.Values[i] = ec._Env_DATABASE_HOST(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_HOST(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DATABASE_PORT": case "DATABASE_PORT":
out.Values[i] = ec._Env_DATABASE_PORT(ctx, field, obj) out.Values[i] = ec._Env_DATABASE_PORT(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "CLIENT_ID": case "CLIENT_ID":
out.Values[i] = ec._Env_CLIENT_ID(ctx, field, obj) out.Values[i] = ec._Env_CLIENT_ID(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@ -9012,20 +8979,38 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._Env_APP_URL(ctx, field, obj) out.Values[i] = ec._Env_APP_URL(ctx, field, obj)
case "REDIS_URL": case "REDIS_URL":
out.Values[i] = ec._Env_REDIS_URL(ctx, field, obj) out.Values[i] = ec._Env_REDIS_URL(ctx, field, obj)
case "COOKIE_NAME":
out.Values[i] = ec._Env_COOKIE_NAME(ctx, field, obj)
case "RESET_PASSWORD_URL": case "RESET_PASSWORD_URL":
out.Values[i] = ec._Env_RESET_PASSWORD_URL(ctx, field, obj) out.Values[i] = ec._Env_RESET_PASSWORD_URL(ctx, field, obj)
case "DISABLE_EMAIL_VERIFICATION": case "DISABLE_EMAIL_VERIFICATION":
out.Values[i] = ec._Env_DISABLE_EMAIL_VERIFICATION(ctx, field, obj) out.Values[i] = ec._Env_DISABLE_EMAIL_VERIFICATION(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DISABLE_BASIC_AUTHENTICATION": case "DISABLE_BASIC_AUTHENTICATION":
out.Values[i] = ec._Env_DISABLE_BASIC_AUTHENTICATION(ctx, field, obj) out.Values[i] = ec._Env_DISABLE_BASIC_AUTHENTICATION(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DISABLE_MAGIC_LINK_LOGIN": case "DISABLE_MAGIC_LINK_LOGIN":
out.Values[i] = ec._Env_DISABLE_MAGIC_LINK_LOGIN(ctx, field, obj) out.Values[i] = ec._Env_DISABLE_MAGIC_LINK_LOGIN(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DISABLE_LOGIN_PAGE": case "DISABLE_LOGIN_PAGE":
out.Values[i] = ec._Env_DISABLE_LOGIN_PAGE(ctx, field, obj) out.Values[i] = ec._Env_DISABLE_LOGIN_PAGE(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DISABLE_SIGN_UP": case "DISABLE_SIGN_UP":
out.Values[i] = ec._Env_DISABLE_SIGN_UP(ctx, field, obj) out.Values[i] = ec._Env_DISABLE_SIGN_UP(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "DISABLE_REDIS_FOR_ENV":
out.Values[i] = ec._Env_DISABLE_REDIS_FOR_ENV(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "ROLES": case "ROLES":
out.Values[i] = ec._Env_ROLES(ctx, field, obj) out.Values[i] = ec._Env_ROLES(ctx, field, obj)
case "PROTECTED_ROLES": case "PROTECTED_ROLES":

View File

@ -26,13 +26,13 @@ type DeleteUserInput struct {
type Env struct { type Env struct {
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"` AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"`
AdminSecret *string `json:"ADMIN_SECRET"` AdminSecret *string `json:"ADMIN_SECRET"`
DatabaseName string `json:"DATABASE_NAME"` DatabaseName *string `json:"DATABASE_NAME"`
DatabaseURL string `json:"DATABASE_URL"` DatabaseURL *string `json:"DATABASE_URL"`
DatabaseType string `json:"DATABASE_TYPE"` DatabaseType *string `json:"DATABASE_TYPE"`
DatabaseUsername string `json:"DATABASE_USERNAME"` DatabaseUsername *string `json:"DATABASE_USERNAME"`
DatabasePassword string `json:"DATABASE_PASSWORD"` DatabasePassword *string `json:"DATABASE_PASSWORD"`
DatabaseHost string `json:"DATABASE_HOST"` DatabaseHost *string `json:"DATABASE_HOST"`
DatabasePort string `json:"DATABASE_PORT"` DatabasePort *string `json:"DATABASE_PORT"`
ClientID string `json:"CLIENT_ID"` ClientID string `json:"CLIENT_ID"`
ClientSecret string `json:"CLIENT_SECRET"` ClientSecret string `json:"CLIENT_SECRET"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"` CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"`
@ -48,13 +48,13 @@ type Env struct {
AllowedOrigins []string `json:"ALLOWED_ORIGINS"` AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
AppURL *string `json:"APP_URL"` AppURL *string `json:"APP_URL"`
RedisURL *string `json:"REDIS_URL"` RedisURL *string `json:"REDIS_URL"`
CookieName *string `json:"COOKIE_NAME"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL"` ResetPasswordURL *string `json:"RESET_PASSWORD_URL"`
DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION"` DisableEmailVerification bool `json:"DISABLE_EMAIL_VERIFICATION"`
DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION"` DisableBasicAuthentication bool `json:"DISABLE_BASIC_AUTHENTICATION"`
DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN"` DisableMagicLinkLogin bool `json:"DISABLE_MAGIC_LINK_LOGIN"`
DisableLoginPage *bool `json:"DISABLE_LOGIN_PAGE"` DisableLoginPage bool `json:"DISABLE_LOGIN_PAGE"`
DisableSignUp *bool `json:"DISABLE_SIGN_UP"` DisableSignUp bool `json:"DISABLE_SIGN_UP"`
DisableRedisForEnv bool `json:"DISABLE_REDIS_FOR_ENV"`
Roles []string `json:"ROLES"` Roles []string `json:"ROLES"`
ProtectedRoles []string `json:"PROTECTED_ROLES"` ProtectedRoles []string `json:"PROTECTED_ROLES"`
DefaultRoles []string `json:"DEFAULT_ROLES"` DefaultRoles []string `json:"DEFAULT_ROLES"`
@ -199,14 +199,13 @@ type UpdateEnvInput struct {
JwtPublicKey *string `json:"JWT_PUBLIC_KEY"` JwtPublicKey *string `json:"JWT_PUBLIC_KEY"`
AllowedOrigins []string `json:"ALLOWED_ORIGINS"` AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
AppURL *string `json:"APP_URL"` AppURL *string `json:"APP_URL"`
RedisURL *string `json:"REDIS_URL"`
CookieName *string `json:"COOKIE_NAME"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL"` ResetPasswordURL *string `json:"RESET_PASSWORD_URL"`
DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION"` DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION"`
DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION"` DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION"`
DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN"` DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN"`
DisableLoginPage *bool `json:"DISABLE_LOGIN_PAGE"` DisableLoginPage *bool `json:"DISABLE_LOGIN_PAGE"`
DisableSignUp *bool `json:"DISABLE_SIGN_UP"` DisableSignUp *bool `json:"DISABLE_SIGN_UP"`
DisableRedisForEnv *bool `json:"DISABLE_REDIS_FOR_ENV"`
Roles []string `json:"ROLES"` Roles []string `json:"ROLES"`
ProtectedRoles []string `json:"PROTECTED_ROLES"` ProtectedRoles []string `json:"PROTECTED_ROLES"`
DefaultRoles []string `json:"DEFAULT_ROLES"` DefaultRoles []string `json:"DEFAULT_ROLES"`

View File

@ -89,13 +89,13 @@ type Response {
type Env { type Env {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
DATABASE_NAME: String! DATABASE_NAME: String
DATABASE_URL: String! DATABASE_URL: String
DATABASE_TYPE: String! DATABASE_TYPE: String
DATABASE_USERNAME: String! DATABASE_USERNAME: String
DATABASE_PASSWORD: String! DATABASE_PASSWORD: String
DATABASE_HOST: String! DATABASE_HOST: String
DATABASE_PORT: String! DATABASE_PORT: String
CLIENT_ID: String! CLIENT_ID: String!
CLIENT_SECRET: String! CLIENT_SECRET: String!
CUSTOM_ACCESS_TOKEN_SCRIPT: String CUSTOM_ACCESS_TOKEN_SCRIPT: String
@ -111,13 +111,13 @@ type Env {
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
REDIS_URL: String REDIS_URL: String
COOKIE_NAME: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
DISABLE_EMAIL_VERIFICATION: Boolean DISABLE_EMAIL_VERIFICATION: Boolean!
DISABLE_BASIC_AUTHENTICATION: Boolean DISABLE_BASIC_AUTHENTICATION: Boolean!
DISABLE_MAGIC_LINK_LOGIN: Boolean DISABLE_MAGIC_LINK_LOGIN: Boolean!
DISABLE_LOGIN_PAGE: Boolean DISABLE_LOGIN_PAGE: Boolean!
DISABLE_SIGN_UP: Boolean DISABLE_SIGN_UP: Boolean!
DISABLE_REDIS_FOR_ENV: Boolean!
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]
@ -158,14 +158,13 @@ input UpdateEnvInput {
JWT_PUBLIC_KEY: String JWT_PUBLIC_KEY: String
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
REDIS_URL: String
COOKIE_NAME: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
DISABLE_EMAIL_VERIFICATION: Boolean DISABLE_EMAIL_VERIFICATION: Boolean
DISABLE_BASIC_AUTHENTICATION: Boolean DISABLE_BASIC_AUTHENTICATION: Boolean
DISABLE_MAGIC_LINK_LOGIN: Boolean DISABLE_MAGIC_LINK_LOGIN: Boolean
DISABLE_LOGIN_PAGE: Boolean DISABLE_LOGIN_PAGE: Boolean
DISABLE_SIGN_UP: Boolean DISABLE_SIGN_UP: Boolean
DISABLE_REDIS_FOR_ENV: Boolean
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]

View File

@ -8,8 +8,9 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "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,8 +23,8 @@ 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 envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) { 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"})
return return
@ -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
@ -58,14 +59,27 @@ func AppHandler() gin.HandlerFunc {
log.Debug("Failed to push file path: ", err) log.Debug("Failed to push file path: ", err)
} }
} }
orgName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
if err != nil {
log.Debug("Failed to get organization name")
c.JSON(400, gin.H{"error": "failed to get organization name"})
return
}
orgLogo, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
if err != nil {
log.Debug("Failed to get organization logo")
c.JSON(400, gin.H{"error": "failed to get organization logo"})
return
}
c.HTML(http.StatusOK, "app.tmpl", gin.H{ c.HTML(http.StatusOK, "app.tmpl", gin.H{
"data": map[string]interface{}{ "data": map[string]interface{}{
"authorizerURL": hostname, "authorizerURL": hostname,
"redirectURL": redirect_uri, "redirectURL": redirect_uri,
"scope": scope, "scope": scope,
"state": state, "state": state,
"organizationName": envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName), "organizationName": orgName,
"organizationLogo": envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo), "organizationLogo": orgLogo,
}, },
}) })
} }

View File

@ -13,8 +13,7 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
) )
@ -80,7 +79,7 @@ func AuthorizeHandler() gin.HandlerFunc {
return return
} }
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) { if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); client != clientID || err != nil {
if isQuery { if isQuery {
gc.Redirect(http.StatusFound, loginURL) gc.Redirect(http.StatusFound, loginURL)
} else { } else {
@ -223,7 +222,10 @@ func AuthorizeHandler() gin.HandlerFunc {
// based on the response type, generate the response // based on the response type, generate the response
if isResponseTypeCode { if isResponseTypeCode {
// rollover the session for security // rollover the session for security
sessionstore.RemoveState(sessionToken) err = memorystore.Provider.RemoveState(sessionToken)
if err != nil {
log.Debug("Failed to remove state: ", err)
}
nonce := uuid.New().String() nonce := uuid.New().String()
newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope) newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope)
if err != nil { if err != nil {
@ -244,10 +246,10 @@ func AuthorizeHandler() gin.HandlerFunc {
return return
} }
sessionstore.SetState(newSessionToken, newSessionTokenData.Nonce+"@"+user.ID) memorystore.Provider.SetState(newSessionToken, newSessionTokenData.Nonce+"@"+user.ID)
cookie.SetSession(gc, newSessionToken) cookie.SetSession(gc, newSessionToken)
code := uuid.New().String() code := uuid.New().String()
sessionstore.SetState(codeChallenge, code+"@"+newSessionToken) memorystore.Provider.SetState(codeChallenge, code+"@"+newSessionToken)
gc.HTML(http.StatusOK, template, gin.H{ gc.HTML(http.StatusOK, template, gin.H{
"target_origin": redirectURI, "target_origin": redirectURI,
"authorization_response": map[string]interface{}{ "authorization_response": map[string]interface{}{
@ -281,9 +283,9 @@ func AuthorizeHandler() gin.HandlerFunc {
} }
return return
} }
sessionstore.RemoveState(sessionToken) memorystore.Provider.RemoveState(sessionToken)
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@ -306,7 +308,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token res["refresh_token"] = authToken.RefreshToken.Token
params += "&refresh_token=" + authToken.RefreshToken.Token params += "&refresh_token=" + authToken.RefreshToken.Token
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
if isQuery { if isQuery {

View File

@ -4,7 +4,7 @@ import (
"net/http" "net/http"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -12,8 +12,8 @@ import (
func DashboardHandler() gin.HandlerFunc { func DashboardHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
isOnboardingCompleted := false isOnboardingCompleted := false
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) != "" { if err != nil || adminSecret != "" {
isOnboardingCompleted = true isOnboardingCompleted = true
} }

View File

@ -7,14 +7,21 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
func JWKsHandler() gin.HandlerFunc { func JWKsHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
var data map[string]string var data map[string]string
jwk := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJWK) jwk, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJWK)
err := json.Unmarshal([]byte(jwk), &data) if err != nil {
log.Debug("Error getting JWK from memorystore: ", err)
c.JSON(500, gin.H{
"error": err.Error(),
})
return
}
err = json.Unmarshal([]byte(jwk), &data)
if err != nil { if err != nil {
log.Debug("Failed to parse JWK: ", err) log.Debug("Failed to parse JWK: ", err)
c.JSON(500, gin.H{ c.JSON(500, gin.H{

View File

@ -9,7 +9,7 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/sessionstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// Handler to logout user // Handler to logout user
@ -37,7 +37,10 @@ func LogoutHandler() gin.HandlerFunc {
fingerPrint := string(decryptedFingerPrint) fingerPrint := string(decryptedFingerPrint)
sessionstore.RemoveState(fingerPrint) err = memorystore.Provider.RemoveState(fingerPrint)
if err != nil {
log.Debug("Failed to remove state: ", err)
}
cookie.DeleteSession(gc) cookie.DeleteSession(gc)
if redirectURL != "" { if redirectURL != "" {

View File

@ -19,9 +19,8 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/oauth" "github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -32,12 +31,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
provider := c.Param("oauth_provider") provider := c.Param("oauth_provider")
state := c.Request.FormValue("state") state := c.Request.FormValue("state")
sessionState := sessionstore.GetState(state) sessionState, err := memorystore.Provider.GetState(state)
if sessionState == "" { if sessionState == "" || err != nil {
log.Debug("Invalid oauth state: ", state) log.Debug("Invalid oauth state: ", state)
c.JSON(400, gin.H{"error": "invalid oauth state"}) c.JSON(400, gin.H{"error": "invalid oauth state"})
} }
sessionstore.GetState(state) memorystore.Provider.GetState(state)
// contains random token, redirect url, role // contains random token, redirect url, role
sessionSplit := strings.Split(state, "___") sessionSplit := strings.Split(state, "___")
@ -52,7 +51,6 @@ func OAuthCallbackHandler() gin.HandlerFunc {
inputRoles := strings.Split(sessionSplit[2], ",") inputRoles := strings.Split(sessionSplit[2], ",")
scopes := strings.Split(sessionSplit[3], ",") scopes := strings.Split(sessionSplit[3], ",")
var err error
user := models.User{} user := models.User{}
code := c.Request.FormValue("code") code := c.Request.FormValue("code")
switch provider { switch provider {
@ -77,7 +75,13 @@ func OAuthCallbackHandler() gin.HandlerFunc {
log := log.WithField("user", user.Email) log := log.WithField("user", user.Email)
if err != nil { if err != nil {
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) { isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
if err != nil {
log.Debug("Failed to get signup disabled env variable: ", err)
c.JSON(400, gin.H{"error": err.Error()})
return
}
if isSignupDisabled {
log.Debug("Failed to signup as disabled") log.Debug("Failed to signup as disabled")
c.JSON(400, gin.H{"error": "signup is disabled for this instance"}) c.JSON(400, gin.H{"error": "signup is disabled for this instance"})
return return
@ -87,7 +91,15 @@ func OAuthCallbackHandler() gin.HandlerFunc {
// make sure inputRoles don't include protected roles // make sure inputRoles don't include protected roles
hasProtectedRole := false hasProtectedRole := false
for _, ir := range inputRoles { for _, ir := range inputRoles {
if utils.StringSliceContains(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ir) { protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
protectedRoles := []string{}
if err != nil {
log.Debug("Failed to get protected roles: ", err)
protectedRolesString = ""
} else {
protectedRoles = strings.Split(protectedRolesString, ",")
}
if utils.StringSliceContains(protectedRoles, ir) {
hasProtectedRole = true hasProtectedRole = true
} }
} }
@ -140,7 +152,15 @@ func OAuthCallbackHandler() gin.HandlerFunc {
// check if it contains protected unassigned role // check if it contains protected unassigned role
hasProtectedRole := false hasProtectedRole := false
for _, ur := range unasignedRoles { for _, ur := range unasignedRoles {
if utils.StringSliceContains(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ur) { protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
protectedRoles := []string{}
if err != nil {
log.Debug("Failed to get protected roles: ", err)
protectedRolesString = ""
} else {
protectedRoles = strings.Split(protectedRolesString, ",")
}
if utils.StringSliceContains(protectedRoles, ur) {
hasProtectedRole = true hasProtectedRole = true
} }
} }
@ -178,12 +198,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + stateValue + "&id_token=" + authToken.IDToken.Token params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + stateValue + "&id_token=" + authToken.IDToken.Token
cookie.SetSession(c, authToken.FingerPrintHash) cookie.SetSession(c, authToken.FingerPrintHash)
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
params = params + `&refresh_token=` + authToken.RefreshToken.Token params = params + `&refresh_token=` + authToken.RefreshToken.Token
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
go db.Provider.AddSession(models.Session{ go db.Provider.AddSession(models.Session{

View File

@ -8,16 +8,16 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/oauth" "github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/sessionstore" "github.com/authorizerdev/authorizer/server/parsers"
"github.com/authorizerdev/authorizer/server/utils" "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 == "" {
@ -56,7 +56,25 @@ func OAuthLoginHandler() gin.HandlerFunc {
// use protected roles verification for admin login only. // use protected roles verification for admin login only.
// though if not associated with user, it will be rejected from oauth_callback // though if not associated with user, it will be rejected from oauth_callback
if !utils.IsValidRoles(rolesSplit, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) { rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
roles := []string{}
if err != nil {
log.Debug("Error getting roles: ", err)
rolesString = ""
} else {
roles = strings.Split(rolesString, ",")
}
protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
protectedRoles := []string{}
if err != nil {
log.Debug("Error getting protected roles: ", err)
protectedRolesString = ""
} else {
protectedRoles = strings.Split(protectedRolesString, ",")
}
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",
@ -64,7 +82,16 @@ func OAuthLoginHandler() gin.HandlerFunc {
return return
} }
} else { } else {
roles = strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
log.Debug("Error getting default roles: ", err)
c.JSON(400, gin.H{
"error": "invalid role",
})
return
}
roles = defaultRoles
} }
oauthStateString := state + "___" + redirectURI + "___" + roles + "___" + strings.Join(scope, ",") oauthStateString := state + "___" + redirectURI + "___" + roles + "___" + strings.Join(scope, ",")
@ -78,7 +105,14 @@ func OAuthLoginHandler() gin.HandlerFunc {
isProviderConfigured = false isProviderConfigured = false
break break
} }
sessionstore.SetState(oauthStateString, constants.SignupMethodGoogle) err := memorystore.Provider.SetState(oauthStateString, constants.SignupMethodGoogle)
if err != nil {
log.Debug("Error setting state: ", err)
c.JSON(500, gin.H{
"error": "internal server error",
})
return
}
// during the init of OAuthProvider authorizer url might be empty // during the init of OAuthProvider authorizer url might be empty
oauth.OAuthProviders.GoogleConfig.RedirectURL = hostname + "/oauth_callback/google" oauth.OAuthProviders.GoogleConfig.RedirectURL = hostname + "/oauth_callback/google"
url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString) url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
@ -89,7 +123,14 @@ func OAuthLoginHandler() gin.HandlerFunc {
isProviderConfigured = false isProviderConfigured = false
break break
} }
sessionstore.SetState(oauthStateString, constants.SignupMethodGithub) err := memorystore.Provider.SetState(oauthStateString, constants.SignupMethodGithub)
if err != nil {
log.Debug("Error setting state: ", err)
c.JSON(500, gin.H{
"error": "internal server error",
})
return
}
oauth.OAuthProviders.GithubConfig.RedirectURL = hostname + "/oauth_callback/github" oauth.OAuthProviders.GithubConfig.RedirectURL = hostname + "/oauth_callback/github"
url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString) url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url) c.Redirect(http.StatusTemporaryRedirect, url)
@ -99,7 +140,14 @@ func OAuthLoginHandler() gin.HandlerFunc {
isProviderConfigured = false isProviderConfigured = false
break break
} }
sessionstore.SetState(oauthStateString, constants.SignupMethodFacebook) err := memorystore.Provider.SetState(oauthStateString, constants.SignupMethodFacebook)
if err != nil {
log.Debug("Error setting state: ", err)
c.JSON(500, gin.H{
"error": "internal server error",
})
return
}
oauth.OAuthProviders.FacebookConfig.RedirectURL = hostname + "/oauth_callback/facebook" oauth.OAuthProviders.FacebookConfig.RedirectURL = hostname + "/oauth_callback/facebook"
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString) url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url) c.Redirect(http.StatusTemporaryRedirect, url)

View File

@ -4,15 +4,15 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "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 := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType) jwtType, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"issuer": issuer, "issuer": issuer,

View File

@ -8,8 +8,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/sessionstore"
) )
// Revoke handler to revoke refresh token // Revoke handler to revoke refresh token
@ -37,7 +36,7 @@ func RevokeHandler() gin.HandlerFunc {
return return
} }
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) { if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); client != clientID || err != nil {
log.Debug("Client ID is invalid: ", clientID) log.Debug("Client ID is invalid: ", clientID)
gc.JSON(http.StatusBadRequest, gin.H{ gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id", "error": "invalid_client_id",
@ -46,7 +45,7 @@ func RevokeHandler() gin.HandlerFunc {
return return
} }
sessionstore.RemoveState(refreshToken) memorystore.Provider.RemoveState(refreshToken)
gc.JSON(http.StatusOK, gin.H{ gc.JSON(http.StatusOK, gin.H{
"message": "Token revoked successfully", "message": "Token revoked successfully",

View File

@ -13,8 +13,7 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
) )
@ -62,7 +61,7 @@ func TokenHandler() gin.HandlerFunc {
return return
} }
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) { if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); clientID != client || err != nil {
log.Debug("Client ID is invalid: ", clientID) log.Debug("Client ID is invalid: ", clientID)
gc.JSON(http.StatusBadRequest, gin.H{ gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id", "error": "invalid_client_id",
@ -98,8 +97,8 @@ func TokenHandler() gin.HandlerFunc {
encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-") encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-")
encryptedCode = strings.ReplaceAll(encryptedCode, "/", "_") encryptedCode = strings.ReplaceAll(encryptedCode, "/", "_")
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "") encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
sessionData := sessionstore.GetState(encryptedCode) sessionData, err := memorystore.Provider.GetState(encryptedCode)
if sessionData == "" { if sessionData == "" || err != nil {
log.Debug("Session data is empty") log.Debug("Session data is empty")
gc.JSON(http.StatusBadRequest, gin.H{ gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code_verifier", "error": "invalid_code_verifier",
@ -132,7 +131,7 @@ func TokenHandler() gin.HandlerFunc {
return return
} }
// rollover the session for security // rollover the session for security
sessionstore.RemoveState(sessionDataSplit[1]) memorystore.Provider.RemoveState(sessionDataSplit[1])
userID = claims.Subject userID = claims.Subject
roles = claims.Roles roles = claims.Roles
scope = claims.Scope scope = claims.Scope
@ -164,7 +163,7 @@ func TokenHandler() gin.HandlerFunc {
scope = append(scope, v.(string)) scope = append(scope, v.(string))
} }
// remove older refresh token and rotate it for security // remove older refresh token and rotate it for security
sessionstore.RemoveState(refreshToken) memorystore.Provider.RemoveState(refreshToken)
} }
user, err := db.Provider.GetUserByID(userID) user, err := db.Provider.GetUserByID(userID)
@ -186,8 +185,8 @@ func TokenHandler() gin.HandlerFunc {
}) })
return return
} }
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@ -205,7 +204,7 @@ func TokenHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token res["refresh_token"] = authToken.RefreshToken.Token
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
gc.JSON(http.StatusOK, res) gc.JSON(http.StatusOK, res)

View File

@ -12,7 +12,8 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"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/sessionstore" "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)
@ -99,12 +100,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + state + "&id_token=" + authToken.IDToken.Token params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + state + "&id_token=" + authToken.IDToken.Token
cookie.SetSession(c, authToken.FingerPrintHash) cookie.SetSession(c, authToken.FingerPrintHash)
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
params = params + `&refresh_token=${refresh_token}` params = params + `&refresh_token=${refresh_token}`
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
if redirectURL == "" { if redirectURL == "" {

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/envstore" "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/sessionstore"
) )
var VERSION string var VERSION string
@ -27,23 +27,22 @@ func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
} }
func main() { func main() {
envstore.ARG_DB_URL = flag.String("database_url", "", "Database connection string") cli.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
envstore.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")
envstore.ARG_ENV_FILE = flag.String("env_file", "", "Env file path") cli.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
envstore.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")
cli.ARG_REDIS_URL = flag.String("redis_url", "", "Redis connection string")
flag.Parse() flag.Parse()
// global log level // global log level
logrus.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}}) logrus.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
logrus.SetReportCaller(true)
// log instance for gin server // log instance for gin server
log := logrus.New() log := logrus.New()
log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}}) log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
log.SetReportCaller(true)
var logLevel logrus.Level var logLevel logrus.Level
switch *envstore.ARG_LOG_LEVEL { switch *cli.ARG_LOG_LEVEL {
case "debug": case "debug":
logLevel = logrus.DebugLevel logLevel = logrus.DebugLevel
case "info": case "info":
@ -62,14 +61,26 @@ func main() {
logrus.SetLevel(logLevel) logrus.SetLevel(logLevel)
log.SetLevel(logLevel) log.SetLevel(logLevel)
// show file path in log for debug or other log levels.
if logLevel != logrus.InfoLevel {
logrus.SetReportCaller(true)
log.SetReportCaller(true)
}
constants.VERSION = VERSION constants.VERSION = VERSION
// initialize required envs (mainly db & env file path) // initialize required envs (mainly db, env file path and redis)
err := env.InitRequiredEnv() err := memorystore.InitRequiredEnv()
if err != nil { if err != nil {
log.Fatal("Error while initializing required envs: ", err) log.Fatal("Error while initializing required envs: ", err)
} }
// initialize memory store
err = memorystore.InitMemStore()
if err != nil {
log.Fatal("Error while initializing memory store: ", err)
}
// initialize db provider // initialize db provider
err = db.InitDB() err = db.InitDB()
if err != nil { if err != nil {
@ -89,12 +100,6 @@ func main() {
log.Fatalln("Error while persisting env: ", err) log.Fatalln("Error while persisting env: ", err)
} }
// initialize session store (redis or in-memory based on env)
err = sessionstore.InitSession()
if err != nil {
log.Fatalln("Error while initializing session store: ", err)
}
// initialize oauth providers based on env // initialize oauth providers based on env
err = oauth.InitOAuth() err = oauth.InitOAuth()
if err != nil { if err != nil {
@ -103,5 +108,11 @@ func main() {
router := routes.InitRouter(log) router := routes.InitRouter(log)
log.Info("Starting Authorizer: ", VERSION) log.Info("Starting Authorizer: ", VERSION)
router.Run(":" + envstore.EnvStoreObj.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

@ -0,0 +1,76 @@
package memorystore
import (
"encoding/json"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore/providers"
"github.com/authorizerdev/authorizer/server/memorystore/providers/inmemory"
"github.com/authorizerdev/authorizer/server/memorystore/providers/redis"
)
// Provider returns the current database provider
var Provider providers.Provider
// InitMemStore initializes the memory store
func InitMemStore() error {
var err error
defaultEnvs := map[string]interface{}{
// string envs
constants.EnvKeyJwtRoleClaim: "role",
constants.EnvKeyOrganizationName: "Authorizer",
constants.EnvKeyOrganizationLogo: "https://www.authorizer.dev/images/logo.png",
// boolean envs
constants.EnvKeyDisableBasicAuthentication: false,
constants.EnvKeyDisableMagicLinkLogin: false,
constants.EnvKeyDisableEmailVerification: false,
constants.EnvKeyDisableLoginPage: false,
constants.EnvKeyDisableSignUp: false,
}
requiredEnvs := RequiredEnvStoreObj.GetRequiredEnv()
requiredEnvMap := make(map[string]interface{})
requiredEnvBytes, err := json.Marshal(requiredEnvs)
if err != nil {
log.Debug("Error while marshalling required envs: ", err)
return err
}
err = json.Unmarshal(requiredEnvBytes, &requiredEnvMap)
if err != nil {
log.Debug("Error while unmarshalling required envs: ", err)
return err
}
// merge default envs with required envs
for key, val := range requiredEnvMap {
defaultEnvs[key] = val
}
redisURL := requiredEnvs.RedisURL
if redisURL != "" && !requiredEnvs.disableRedisForEnv {
log.Info("Initializing Redis memory store")
Provider, err = redis.NewRedisProvider(redisURL)
if err != nil {
return err
}
// set default envs in redis
Provider.UpdateEnvStore(defaultEnvs)
return nil
}
log.Info("using in memory store to save sessions")
// if redis url is not set use in memory store
Provider, err = inmemory.NewInMemoryProvider()
if err != nil {
return err
}
// set default envs in local env
Provider.UpdateEnvStore(defaultEnvs)
return nil
}

View File

@ -0,0 +1,53 @@
package inmemory
import (
"os"
"sync"
)
// EnvStore struct to store the env variables
type EnvStore struct {
mutex sync.Mutex
store map[string]interface{}
}
// UpdateEnvStore to update the whole env store object
func (e *EnvStore) UpdateStore(store map[string]interface{}) {
if os.Getenv("ENV") != "test" {
e.mutex.Lock()
defer e.mutex.Unlock()
}
// just override the keys + new keys
for key, value := range store {
e.store[key] = value
}
}
// GetStore returns the env store
func (e *EnvStore) GetStore() map[string]interface{} {
if os.Getenv("ENV") != "test" {
e.mutex.Lock()
defer e.mutex.Unlock()
}
return e.store
}
// Get returns the value of the key in evn store
func (e *EnvStore) Get(key string) interface{} {
if os.Getenv("ENV") != "test" {
e.mutex.Lock()
defer e.mutex.Unlock()
}
return e.store[key]
}
// Set sets the value of the key in env store
func (e *EnvStore) Set(key string, value interface{}) {
if os.Getenv("ENV") != "test" {
e.mutex.Lock()
defer e.mutex.Unlock()
}
e.store[key] = value
}

View File

@ -0,0 +1,25 @@
package inmemory
import (
"sync"
)
type provider struct {
mutex sync.Mutex
sessionStore map[string]map[string]string
stateStore map[string]string
envStore *EnvStore
}
// NewInMemoryStore returns a new in-memory store.
func NewInMemoryProvider() (*provider, error) {
return &provider{
mutex: sync.Mutex{},
sessionStore: map[string]map[string]string{},
stateStore: map[string]string{},
envStore: &EnvStore{
mutex: sync.Mutex{},
store: map[string]interface{}{},
},
}, nil
}

View File

@ -0,0 +1,121 @@
package inmemory
import (
"fmt"
"os"
"strings"
)
// ClearStore clears the in-memory store.
func (c *provider) ClearStore() error {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
c.sessionStore = map[string]map[string]string{}
return nil
}
// GetUserSessions returns all the user session token from the in-memory store.
func (c *provider) GetUserSessions(userId string) map[string]string {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
res := map[string]string{}
for k, v := range c.stateStore {
split := strings.Split(v, "@")
if split[1] == userId {
res[k] = split[0]
}
}
return res
}
// DeleteAllUserSession deletes all the user sessions from in-memory store.
func (c *provider) DeleteAllUserSession(userId string) error {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
sessions := c.GetUserSessions(userId)
for k := range sessions {
c.RemoveState(k)
}
return nil
}
// SetState sets the state in the in-memory store.
func (c *provider) SetState(key, state string) error {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
c.stateStore[key] = state
return nil
}
// GetState gets the state from the in-memory store.
func (c *provider) GetState(key string) (string, error) {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
state := ""
if stateVal, ok := c.stateStore[key]; ok {
state = stateVal
}
return state, nil
}
// RemoveState removes the state from the in-memory store.
func (c *provider) RemoveState(key string) error {
if os.Getenv("ENV") != "test" {
c.mutex.Lock()
defer c.mutex.Unlock()
}
delete(c.stateStore, key)
return nil
}
// UpdateEnvStore to update the whole env store object
func (c *provider) UpdateEnvStore(store map[string]interface{}) error {
c.envStore.UpdateStore(store)
return nil
}
// GetEnvStore returns the env store object
func (c *provider) GetEnvStore() (map[string]interface{}, error) {
return c.envStore.GetStore(), nil
}
// UpdateEnvVariable to update the particular env variable
func (c *provider) UpdateEnvVariable(key string, value interface{}) error {
c.envStore.Set(key, value)
return nil
}
// GetStringStoreEnvVariable to get the env variable from string store object
func (c *provider) GetStringStoreEnvVariable(key string) (string, error) {
res := c.envStore.Get(key)
if res == nil {
return "", nil
}
return fmt.Sprintf("%v", res), nil
}
// GetBoolStoreEnvVariable to get the env variable from bool store object
func (c *provider) GetBoolStoreEnvVariable(key string) (bool, error) {
res := c.envStore.Get(key)
if res == nil {
return false, nil
}
return res.(bool), nil
}

View File

@ -0,0 +1,30 @@
package providers
// Provider defines current memory store provider
type Provider interface {
// DeleteAllSessions deletes all the sessions from the session store
DeleteAllUserSession(userId string) error
// GetUserSessions returns all the user sessions from the session store
GetUserSessions(userId string) map[string]string
// ClearStore clears the session store for authorizer tokens
ClearStore() error
// SetState sets the login state (key, value form) in the session store
SetState(key, state string) error
// GetState returns the state from the session store
GetState(key string) (string, error)
// RemoveState removes the social login state from the session store
RemoveState(key string) error
// methods for env store
// UpdateEnvStore to update the whole env store object
UpdateEnvStore(store map[string]interface{}) error
// GetEnvStore() returns the env store object
GetEnvStore() (map[string]interface{}, error)
// UpdateEnvVariable to update the particular env variable
UpdateEnvVariable(key string, value interface{}) error
// GetStringStoreEnvVariable to get the string env variable from env store
GetStringStoreEnvVariable(key string) (string, error)
// GetBoolStoreEnvVariable to get the bool env variable from env store
GetBoolStoreEnvVariable(key string) (bool, error)
}

View File

@ -0,0 +1,78 @@
package redis
import (
"context"
"strings"
"time"
"github.com/go-redis/redis/v8"
log "github.com/sirupsen/logrus"
)
// RedisClient is the interface for redis client & redis cluster client
type RedisClient interface {
HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd
Del(ctx context.Context, keys ...string) *redis.IntCmd
HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd
HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd
HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd
HGet(ctx context.Context, key, field string) *redis.StringCmd
HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd
Get(ctx context.Context, key string) *redis.StringCmd
Scan(ctx context.Context, cursor uint64, match string, count int64) *redis.ScanCmd
}
type provider struct {
ctx context.Context
store RedisClient
}
// NewRedisProvider returns a new redis provider
func NewRedisProvider(redisURL string) (*provider, error) {
redisURLHostPortsList := strings.Split(redisURL, ",")
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
log.Debug("error parsing redis url: ", err)
return nil, err
}
urls := []string{opt.Addr}
urlList := redisURLHostPortsList[1:]
urls = append(urls, urlList...)
clusterOpt := &redis.ClusterOptions{Addrs: urls}
rdb := redis.NewClusterClient(clusterOpt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return nil, err
}
return &provider{
ctx: ctx,
store: rdb,
}, nil
}
opt, err := redis.ParseURL(redisURL)
if err != nil {
log.Debug("error parsing redis url: ", err)
return nil, err
}
rdb := redis.NewClient(opt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return nil, err
}
return &provider{
ctx: ctx,
store: rdb,
}, nil
}

View File

@ -0,0 +1,158 @@
package redis
import (
"strconv"
"strings"
"github.com/authorizerdev/authorizer/server/constants"
log "github.com/sirupsen/logrus"
)
var (
// session store prefix
sessionStorePrefix = "authorizer_session:"
// env store prefix
envStorePrefix = "authorizer_env"
)
// ClearStore clears the redis store for authorizer related tokens
func (c *provider) ClearStore() error {
err := c.store.Del(c.ctx, sessionStorePrefix+"*").Err()
if err != nil {
log.Debug("Error clearing redis store: ", err)
return err
}
return nil
}
// GetUserSessions returns all the user session token from the redis store.
func (c *provider) GetUserSessions(userID string) map[string]string {
data, err := c.store.HGetAll(c.ctx, "*").Result()
if err != nil {
log.Debug("error getting token from redis store: ", err)
}
res := map[string]string{}
for k, v := range data {
split := strings.Split(v, "@")
if split[1] == userID {
res[k] = split[0]
}
}
return res
}
// DeleteAllUserSession deletes all the user session from redis
func (c *provider) DeleteAllUserSession(userId string) error {
sessions := c.GetUserSessions(userId)
for k, v := range sessions {
if k == "token" {
err := c.store.Del(c.ctx, v).Err()
if err != nil {
log.Debug("Error deleting redis token: ", err)
return err
}
}
}
return nil
}
// SetState sets the state in redis store.
func (c *provider) SetState(key, value string) error {
err := c.store.Set(c.ctx, sessionStorePrefix+key, value, 0).Err()
if err != nil {
log.Debug("Error saving redis token: ", err)
return err
}
return nil
}
// GetState gets the state from redis store.
func (c *provider) GetState(key string) (string, error) {
var res string
err := c.store.Get(c.ctx, sessionStorePrefix+key).Scan(&res)
if err != nil {
log.Debug("error getting token from redis store: ", err)
}
return res, err
}
// RemoveState removes the state from redis store.
func (c *provider) RemoveState(key string) error {
err := c.store.Del(c.ctx, sessionStorePrefix+key).Err()
if err != nil {
log.Fatalln("Error deleting redis token: ", err)
return err
}
return nil
}
// UpdateEnvStore to update the whole env store object
func (c *provider) UpdateEnvStore(store map[string]interface{}) error {
for key, value := range store {
err := c.store.HSet(c.ctx, envStorePrefix, key, value).Err()
if err != nil {
return err
}
}
return nil
}
// GetEnvStore returns the whole env store object
func (c *provider) GetEnvStore() (map[string]interface{}, error) {
res := make(map[string]interface{})
data, err := c.store.HGetAll(c.ctx, envStorePrefix).Result()
if err != nil {
return nil, err
}
for key, value := range data {
if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp {
boolValue, err := strconv.ParseBool(value)
if err != nil {
return res, err
}
res[key] = boolValue
} else {
res[key] = value
}
}
return res, nil
}
// UpdateEnvVariable to update the particular env variable
func (c *provider) UpdateEnvVariable(key string, value interface{}) error {
err := c.store.HSet(c.ctx, envStorePrefix, key, value).Err()
if err != nil {
log.Debug("Error saving redis token: ", err)
return err
}
return nil
}
// GetStringStoreEnvVariable to get the string env variable from env store
func (c *provider) GetStringStoreEnvVariable(key string) (string, error) {
var res string
err := c.store.HGet(c.ctx, envStorePrefix, key).Scan(&res)
if err != nil {
return "", nil
}
return res, nil
}
// GetBoolStoreEnvVariable to get the bool env variable from env store
func (c *provider) GetBoolStoreEnvVariable(key string) (bool, error) {
var res bool
err := c.store.HGet(c.ctx, envStorePrefix, key).Scan(res)
if err != nil {
return false, nil
}
return res, nil
}

View File

@ -0,0 +1,149 @@
package memorystore
import (
"errors"
"os"
"strings"
"sync"
"github.com/joho/godotenv"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cli"
"github.com/authorizerdev/authorizer/server/constants"
)
// RequiredEnv holds information about required envs
type RequiredEnv struct {
EnvPath string `json:"ENV_PATH"`
DatabaseURL string `json:"DATABASE_URL"`
DatabaseType string `json:"DATABASE_TYPE"`
DatabaseName string `json:"DATABASE_NAME"`
DatabaseHost string `json:"DATABASE_HOST"`
DatabasePort string `json:"DATABASE_PORT"`
DatabaseUsername string `json:"DATABASE_USERNAME"`
DatabasePassword string `json:"DATABASE_PASSWORD"`
DatabaseCert string `json:"DATABASE_CERT"`
DatabaseCertKey string `json:"DATABASE_CERT_KEY"`
DatabaseCACert string `json:"DATABASE_CA_CERT"`
RedisURL string `json:"REDIS_URL"`
disableRedisForEnv bool `json:"DISABLE_REDIS_FOR_ENV"`
}
// RequiredEnvObj is a simple in-memory store for sessions.
type RequiredEnvStore struct {
mutex sync.Mutex
requiredEnv RequiredEnv
}
// GetRequiredEnv to get required env
func (r *RequiredEnvStore) GetRequiredEnv() RequiredEnv {
r.mutex.Lock()
defer r.mutex.Unlock()
return r.requiredEnv
}
// SetRequiredEnv to set required env
func (r *RequiredEnvStore) SetRequiredEnv(requiredEnv RequiredEnv) {
r.mutex.Lock()
defer r.mutex.Unlock()
r.requiredEnv = requiredEnv
}
var RequiredEnvStoreObj *RequiredEnvStore
// InitRequiredEnv to initialize EnvData and through error if required env are not present
func InitRequiredEnv() error {
envPath := os.Getenv(constants.EnvKeyEnvPath)
if envPath == "" {
if envPath == "" {
envPath = `.env`
}
}
if cli.ARG_ENV_FILE != nil && *cli.ARG_ENV_FILE != "" {
envPath = *cli.ARG_ENV_FILE
}
log.Info("env path: ", envPath)
err := godotenv.Load(envPath)
if err != nil {
log.Infof("using OS env instead of %s file", envPath)
}
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
dbType := os.Getenv(constants.EnvKeyDatabaseType)
dbName := os.Getenv(constants.EnvKeyDatabaseName)
dbPort := os.Getenv(constants.EnvKeyDatabasePort)
dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
dbCert := os.Getenv(constants.EnvKeyDatabaseCert)
dbCertKey := os.Getenv(constants.EnvKeyDatabaseCertKey)
dbCACert := os.Getenv(constants.EnvKeyDatabaseCACert)
redisURL := os.Getenv(constants.EnvKeyRedisURL)
disableRedisForEnv := os.Getenv(constants.EnvKeyDisableRedisForEnv) == "true"
if strings.TrimSpace(redisURL) == "" {
if cli.ARG_REDIS_URL != nil && *cli.ARG_REDIS_URL != "" {
redisURL = *cli.ARG_REDIS_URL
}
}
// set default db name for non sql dbs
if dbName == "" {
dbName = "authorizer"
}
if strings.TrimSpace(dbType) == "" {
if cli.ARG_DB_TYPE != nil && *cli.ARG_DB_TYPE != "" {
dbType = strings.TrimSpace(*cli.ARG_DB_TYPE)
}
if dbType == "" {
log.Debug("DATABASE_TYPE is not set")
return errors.New("invalid database type. DATABASE_TYPE is empty")
}
}
if strings.TrimSpace(dbURL) == "" {
if cli.ARG_DB_URL != nil && *cli.ARG_DB_URL != "" {
dbURL = strings.TrimSpace(*cli.ARG_DB_URL)
}
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
log.Debug("DATABASE_URL is not set")
return errors.New("invalid database url. DATABASE_URL is required")
}
}
if dbName == "" {
if dbName == "" {
dbName = "authorizer"
}
}
requiredEnv := RequiredEnv{
EnvPath: envPath,
DatabaseURL: dbURL,
DatabaseType: dbType,
DatabaseName: dbName,
DatabaseHost: dbHost,
DatabasePort: dbPort,
DatabaseUsername: dbUsername,
DatabasePassword: dbPassword,
DatabaseCert: dbCert,
DatabaseCertKey: dbCertKey,
DatabaseCACert: dbCACert,
RedisURL: redisURL,
disableRedisForEnv: disableRedisForEnv,
}
RequiredEnvStoreObj = &RequiredEnvStore{
requiredEnv: requiredEnv,
}
return nil
}

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

@ -9,7 +9,7 @@ import (
githubOAuth2 "golang.org/x/oauth2/github" githubOAuth2 "golang.org/x/oauth2/github"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// OAuthProviders is a struct that contains reference all the OAuth providers // OAuthProviders is a struct that contains reference all the OAuth providers
@ -34,32 +34,58 @@ var (
// InitOAuth initializes the OAuth providers based on EnvData // InitOAuth initializes the OAuth providers based on EnvData
func InitOAuth() error { func InitOAuth() error {
ctx := context.Background() ctx := context.Background()
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret) != "" { googleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID)
if err != nil {
googleClientID = ""
}
googleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret)
if err != nil {
googleClientSecret = ""
}
if googleClientID != "" && googleClientSecret != "" {
p, err := oidc.NewProvider(ctx, "https://accounts.google.com") p, err := oidc.NewProvider(ctx, "https://accounts.google.com")
if err != nil { if err != nil {
return err return err
} }
OIDCProviders.GoogleOIDC = p OIDCProviders.GoogleOIDC = p
OAuthProviders.GoogleConfig = &oauth2.Config{ OAuthProviders.GoogleConfig = &oauth2.Config{
ClientID: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID), ClientID: googleClientID,
ClientSecret: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret), ClientSecret: googleClientSecret,
RedirectURL: "/oauth_callback/google", RedirectURL: "/oauth_callback/google",
Endpoint: OIDCProviders.GoogleOIDC.Endpoint(), Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
} }
} }
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret) != "" {
githubClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID)
if err != nil {
githubClientID = ""
}
githubClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret)
if err != nil {
githubClientSecret = ""
}
if githubClientID != "" && githubClientSecret != "" {
OAuthProviders.GithubConfig = &oauth2.Config{ OAuthProviders.GithubConfig = &oauth2.Config{
ClientID: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID), ClientID: githubClientID,
ClientSecret: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret), ClientSecret: githubClientSecret,
RedirectURL: "/oauth_callback/github", RedirectURL: "/oauth_callback/github",
Endpoint: githubOAuth2.Endpoint, Endpoint: githubOAuth2.Endpoint,
} }
} }
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID) != "" {
facebookClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID)
if err != nil {
facebookClientID = ""
}
facebookClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret)
if err != nil {
facebookClientSecret = ""
}
if facebookClientID != "" && facebookClientSecret != "" {
OAuthProviders.FacebookConfig = &oauth2.Config{ OAuthProviders.FacebookConfig = &oauth2.Config{
ClientID: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID), ClientID: facebookClientID,
ClientSecret: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret), ClientSecret: facebookClientSecret,
RedirectURL: "/oauth_callback/facebook", RedirectURL: "/oauth_callback/facebook",
Endpoint: facebookOAuth2.Endpoint, Endpoint: facebookOAuth2.Endpoint,
Scopes: []string{"public_profile", "email"}, Scopes: []string{"public_profile", "email"},

View File

@ -1,11 +1,11 @@
package utils package parsers
import ( import (
"net/url" "net/url"
"strings" "strings"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -19,7 +19,10 @@ func GetHost(c *gin.Context) string {
return authorizerURL return authorizerURL
} }
authorizerURL = envstore.EnvStoreObj.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 := envstore.EnvStoreObj.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

@ -9,8 +9,8 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/envstore"
"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/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -24,7 +24,11 @@ func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*mod
return res, err return res, err
} }
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if err != nil {
log.Debug("Error getting admin secret: ", err)
return res, err
}
if params.AdminSecret != adminSecret { if params.AdminSecret != adminSecret {
log.Debug("Admin secret is not correct") log.Debug("Admin secret is not correct")
return res, fmt.Errorf(`invalid admin secret`) return res, fmt.Errorf(`invalid admin secret`)

View File

@ -9,8 +9,8 @@ import (
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/envstore"
"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/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -30,7 +30,12 @@ func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
return res, fmt.Errorf("unauthorized") return res, fmt.Errorf("unauthorized")
} }
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if err != nil {
log.Debug("Error getting admin secret: ", err)
return res, fmt.Errorf("unauthorized")
}
hashedKey, err := crypto.EncryptPassword(adminSecret)
if err != nil { if err != nil {
log.Debug("Failed to encrypt key: ", err) log.Debug("Failed to encrypt key: ", err)
return res, err return res, err

View File

@ -2,7 +2,6 @@ package resolvers
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"strings" "strings"
@ -12,8 +11,8 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"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/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -39,7 +38,11 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
return res, err return res, err
} }
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if err != nil {
log.Debug("Error getting admin secret: ", err)
adminSecret = ""
}
if adminSecret != "" { if adminSecret != "" {
log.Debug("Admin secret is already set") log.Debug("Admin secret is already set")
@ -47,18 +50,11 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
return res, err return res, err
} }
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, params.AdminSecret) memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret)
// consvert EnvData to JSON // consvert EnvData to JSON
var storeData envstore.Store storeData, err := memorystore.Provider.GetEnvStore()
jsonBytes, err := json.Marshal(envstore.EnvStoreObj.GetEnvStoreClone())
if err != nil { if err != nil {
log.Debug("Failed to marshal envstore: ", err) log.Debug("Error getting env store: ", err)
return res, err
}
if err := json.Unmarshal(jsonBytes, &storeData); err != nil {
log.Debug("Failed to unmarshal envstore: ", err)
return res, err return res, err
} }

View File

@ -8,7 +8,7 @@ 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/sessionstore" "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"
) )
@ -38,7 +38,7 @@ func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*mod
return res, err return res, err
} }
go sessionstore.DeleteAllUserSession(fmt.Sprintf("%x", user.ID)) go memorystore.Provider.DeleteAllUserSession(fmt.Sprintf("%x", user.ID))
err = db.Provider.DeleteUser(user) err = db.Provider.DeleteUser(user)
if err != nil { if err != nil {

View File

@ -3,12 +3,13 @@ package resolvers
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"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/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -16,7 +17,7 @@ import (
// EnvResolver is a resolver for config query // EnvResolver is a resolver for config query
// This is admin only query // This is admin only query
func EnvResolver(ctx context.Context) (*model.Env, error) { func EnvResolver(ctx context.Context) (*model.Env, error) {
var res *model.Env res := &model.Env{}
gc, err := utils.GinContextFromContext(ctx) gc, err := utils.GinContextFromContext(ctx)
if err != nil { if err != nil {
@ -30,99 +31,124 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
} }
// get clone of store // get clone of store
store := envstore.EnvStoreObj.GetEnvStoreClone() store, err := memorystore.Provider.GetEnvStore()
accessTokenExpiryTime := store.StringEnv[constants.EnvKeyAccessTokenExpiryTime] if err != nil {
adminSecret := store.StringEnv[constants.EnvKeyAdminSecret] log.Debug("Failed to get env store: ", err)
clientID := store.StringEnv[constants.EnvKeyClientID] return res, err
clientSecret := store.StringEnv[constants.EnvKeyClientSecret]
databaseURL := store.StringEnv[constants.EnvKeyDatabaseURL]
databaseName := store.StringEnv[constants.EnvKeyDatabaseName]
databaseType := store.StringEnv[constants.EnvKeyDatabaseType]
databaseUsername := store.StringEnv[constants.EnvKeyDatabaseUsername]
databasePassword := store.StringEnv[constants.EnvKeyDatabasePassword]
databaseHost := store.StringEnv[constants.EnvKeyDatabaseHost]
databasePort := store.StringEnv[constants.EnvKeyDatabasePort]
customAccessTokenScript := store.StringEnv[constants.EnvKeyCustomAccessTokenScript]
smtpHost := store.StringEnv[constants.EnvKeySmtpHost]
smtpPort := store.StringEnv[constants.EnvKeySmtpPort]
smtpUsername := store.StringEnv[constants.EnvKeySmtpUsername]
smtpPassword := store.StringEnv[constants.EnvKeySmtpPassword]
senderEmail := store.StringEnv[constants.EnvKeySenderEmail]
jwtType := store.StringEnv[constants.EnvKeyJwtType]
jwtSecret := store.StringEnv[constants.EnvKeyJwtSecret]
jwtRoleClaim := store.StringEnv[constants.EnvKeyJwtRoleClaim]
jwtPublicKey := store.StringEnv[constants.EnvKeyJwtPublicKey]
jwtPrivateKey := store.StringEnv[constants.EnvKeyJwtPrivateKey]
allowedOrigins := store.SliceEnv[constants.EnvKeyAllowedOrigins]
appURL := store.StringEnv[constants.EnvKeyAppURL]
redisURL := store.StringEnv[constants.EnvKeyRedisURL]
cookieName := store.StringEnv[constants.EnvKeyCookieName]
resetPasswordURL := store.StringEnv[constants.EnvKeyResetPasswordURL]
disableEmailVerification := store.BoolEnv[constants.EnvKeyDisableEmailVerification]
disableBasicAuthentication := store.BoolEnv[constants.EnvKeyDisableBasicAuthentication]
disableMagicLinkLogin := store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin]
disableLoginPage := store.BoolEnv[constants.EnvKeyDisableLoginPage]
disableSignUp := store.BoolEnv[constants.EnvKeyDisableSignUp]
roles := store.SliceEnv[constants.EnvKeyRoles]
defaultRoles := store.SliceEnv[constants.EnvKeyDefaultRoles]
protectedRoles := store.SliceEnv[constants.EnvKeyProtectedRoles]
googleClientID := store.StringEnv[constants.EnvKeyGoogleClientID]
googleClientSecret := store.StringEnv[constants.EnvKeyGoogleClientSecret]
facebookClientID := store.StringEnv[constants.EnvKeyFacebookClientID]
facebookClientSecret := store.StringEnv[constants.EnvKeyFacebookClientSecret]
githubClientID := store.StringEnv[constants.EnvKeyGithubClientID]
githubClientSecret := store.StringEnv[constants.EnvKeyGithubClientSecret]
organizationName := store.StringEnv[constants.EnvKeyOrganizationName]
organizationLogo := store.StringEnv[constants.EnvKeyOrganizationLogo]
if accessTokenExpiryTime == "" {
accessTokenExpiryTime = "30m"
} }
res = &model.Env{ if val, ok := store[constants.EnvKeyAccessTokenExpiryTime]; ok {
AccessTokenExpiryTime: &accessTokenExpiryTime, res.AccessTokenExpiryTime = utils.NewStringRef(val.(string))
AdminSecret: &adminSecret,
DatabaseName: databaseName,
DatabaseURL: databaseURL,
DatabaseType: databaseType,
DatabaseUsername: databaseUsername,
DatabasePassword: databasePassword,
DatabaseHost: databaseHost,
DatabasePort: databasePort,
ClientID: clientID,
ClientSecret: clientSecret,
CustomAccessTokenScript: &customAccessTokenScript,
SMTPHost: &smtpHost,
SMTPPort: &smtpPort,
SMTPPassword: &smtpPassword,
SMTPUsername: &smtpUsername,
SenderEmail: &senderEmail,
JwtType: &jwtType,
JwtSecret: &jwtSecret,
JwtPrivateKey: &jwtPrivateKey,
JwtPublicKey: &jwtPublicKey,
JwtRoleClaim: &jwtRoleClaim,
AllowedOrigins: allowedOrigins,
AppURL: &appURL,
RedisURL: &redisURL,
CookieName: &cookieName,
ResetPasswordURL: &resetPasswordURL,
DisableEmailVerification: &disableEmailVerification,
DisableBasicAuthentication: &disableBasicAuthentication,
DisableMagicLinkLogin: &disableMagicLinkLogin,
DisableLoginPage: &disableLoginPage,
DisableSignUp: &disableSignUp,
Roles: roles,
ProtectedRoles: protectedRoles,
DefaultRoles: defaultRoles,
GoogleClientID: &googleClientID,
GoogleClientSecret: &googleClientSecret,
GithubClientID: &githubClientID,
GithubClientSecret: &githubClientSecret,
FacebookClientID: &facebookClientID,
FacebookClientSecret: &facebookClientSecret,
OrganizationName: &organizationName,
OrganizationLogo: &organizationLogo,
} }
if val, ok := store[constants.EnvKeyAdminSecret]; ok {
res.AdminSecret = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyClientID]; ok {
res.ClientID = val.(string)
}
if val, ok := store[constants.EnvKeyClientSecret]; ok {
res.ClientSecret = val.(string)
}
if val, ok := store[constants.EnvKeyDatabaseURL]; ok {
res.DatabaseURL = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabaseName]; ok {
res.DatabaseName = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabaseType]; ok {
res.DatabaseType = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabaseUsername]; ok {
res.DatabaseUsername = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabasePassword]; ok {
res.DatabasePassword = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabaseHost]; ok {
res.DatabaseHost = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDatabasePort]; ok {
res.DatabasePort = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyCustomAccessTokenScript]; ok {
res.CustomAccessTokenScript = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySmtpHost]; ok {
res.SMTPHost = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySmtpPort]; ok {
res.SMTPPort = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySmtpUsername]; ok {
res.SMTPUsername = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySmtpPassword]; ok {
res.SMTPPassword = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySenderEmail]; ok {
res.SenderEmail = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyJwtType]; ok {
res.JwtType = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyJwtSecret]; ok {
res.JwtSecret = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyJwtRoleClaim]; ok {
res.JwtRoleClaim = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyJwtPublicKey]; ok {
res.JwtPublicKey = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyJwtPrivateKey]; ok {
res.JwtPrivateKey = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyAppURL]; ok {
res.AppURL = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyRedisURL]; ok {
res.RedisURL = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyResetPasswordURL]; ok {
res.ResetPasswordURL = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyGoogleClientID]; ok {
res.GoogleClientID = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyGoogleClientSecret]; ok {
res.GoogleClientSecret = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyFacebookClientID]; ok {
res.FacebookClientID = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyFacebookClientSecret]; ok {
res.FacebookClientSecret = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyGithubClientID]; ok {
res.GithubClientID = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyGithubClientSecret]; ok {
res.GithubClientSecret = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyOrganizationName]; ok {
res.OrganizationName = utils.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyOrganizationLogo]; ok {
res.OrganizationLogo = utils.NewStringRef(val.(string))
}
// string slice vars
res.AllowedOrigins = strings.Split(store[constants.EnvKeyAllowedOrigins].(string), ",")
res.Roles = strings.Split(store[constants.EnvKeyRoles].(string), ",")
res.DefaultRoles = strings.Split(store[constants.EnvKeyDefaultRoles].(string), ",")
res.ProtectedRoles = strings.Split(store[constants.EnvKeyProtectedRoles].(string), ",")
// bool vars
res.DisableEmailVerification = store[constants.EnvKeyDisableEmailVerification].(bool)
res.DisableBasicAuthentication = store[constants.EnvKeyDisableBasicAuthentication].(bool)
res.DisableMagicLinkLogin = store[constants.EnvKeyDisableMagicLinkLogin].(bool)
res.DisableLoginPage = store[constants.EnvKeyDisableLoginPage].(bool)
res.DisableSignUp = store[constants.EnvKeyDisableSignUp].(bool)
return res, nil return res, nil
} }

View File

@ -12,10 +12,12 @@ 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/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"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/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
@ -28,13 +30,18 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
return res, err return res, err
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil {
log.Debug("Error getting basic auth disabled: ", err)
isBasicAuthDisabled = true
}
if isBasicAuthDisabled {
log.Debug("Basic authentication is disabled") log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
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")
} }
@ -48,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

@ -6,8 +6,8 @@ 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/envstore"
"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/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -26,7 +26,11 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
return nil, fmt.Errorf("unauthorized") return nil, fmt.Errorf("unauthorized")
} }
clientID := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
if err != nil {
log.Debug("Error getting client id: ", err)
return nil, err
}
if crypto.IsHMACA(params.Type) { if crypto.IsHMACA(params.Type) {
secret, _, err := crypto.NewHMACKey(params.Type, clientID) secret, _, err := crypto.NewHMACKey(params.Type, clientID)
if err != nil { if err != nil {

View File

@ -13,10 +13,12 @@ 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"
emailservice "github.com/authorizerdev/authorizer/server/email" emailservice "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"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/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
@ -33,12 +35,20 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
} }
// this feature is only allowed if email server is configured // this feature is only allowed if email server is configured
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil {
log.Debug("Error getting email verification disabled: ", err)
isEmailVerificationDisabled = true
}
if isEmailVerificationDisabled {
log.Debug("Email server is not configured") log.Debug("Email server is not configured")
return nil, errors.New("email sending is disabled") return nil, errors.New("email sending is disabled")
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) && envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) { isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
if isBasicAuthDisabled && isMagicLinkLoginDisabled {
log.Debug("Basic authentication and Magic link login is disabled.") log.Debug("Basic authentication and Magic link login is disabled.")
return nil, errors.New("either basic authentication or magic link login is required") return nil, errors.New("either basic authentication or magic link login is required")
} }
@ -46,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)
} }
} }
@ -77,13 +87,22 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
// invite new emails // invite new emails
for _, email := range newEmails { for _, email := range newEmails {
defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
defaultRoles := []string{}
if err != nil {
log.Debug("Error getting default roles: ", err)
defaultRolesString = ""
} else {
defaultRoles = strings.Split(defaultRolesString, ",")
}
user := models.User{ user := models.User{
Email: email, Email: email,
Roles: strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ","), 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 {
@ -109,7 +128,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
} }
// use magic link login if that option is on // use magic link login if that option is on
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) { if !isMagicLinkLoginDisabled {
user.SignupMethods = constants.SignupMethodMagicLinkLogin user.SignupMethods = constants.SignupMethodMagicLinkLogin
verificationRequest.Identifier = constants.VerificationTypeMagicLinkLogin verificationRequest.Identifier = constants.VerificationTypeMagicLinkLogin
} else { } else {

View File

@ -13,11 +13,11 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"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/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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
@ -30,7 +30,13 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
return res, err return res, err
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { isBasiAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil {
log.Debug("Error getting basic auth disabled: ", err)
isBasiAuthDisabled = true
}
if isBasiAuthDisabled {
log.Debug("Basic authentication is disabled.") log.Debug("Basic authentication is disabled.")
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
@ -66,10 +72,19 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
log.Debug("Failed to compare password: ", err) log.Debug("Failed to compare password: ", err)
return res, fmt.Errorf(`invalid password`) return res, fmt.Errorf(`invalid password`)
} }
roles := envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles)
defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
roles := []string{}
if err != nil {
log.Debug("Error getting default roles: ", err)
defaultRolesString = ""
} else {
roles = strings.Split(defaultRolesString, ",")
}
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`)
} }
@ -102,12 +117,12 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
} }
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
go db.Provider.AddSession(models.Session{ go db.Provider.AddSession(models.Session{

View File

@ -8,7 +8,7 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -37,7 +37,7 @@ func LogoutResolver(ctx context.Context) (*model.Response, error) {
fingerPrint := string(decryptedFingerPrint) fingerPrint := string(decryptedFingerPrint)
sessionstore.RemoveState(fingerPrint) memorystore.Provider.RemoveState(fingerPrint)
cookie.DeleteSession(gc) cookie.DeleteSession(gc)
res = &model.Response{ res = &model.Response{

View File

@ -12,10 +12,12 @@ 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/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"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/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
@ -28,14 +30,20 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
return res, err return res, err
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) { isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
if err != nil {
log.Debug("Error getting magic link login disabled: ", err)
isMagicLinkLoginDisabled = true
}
if isMagicLinkLoginDisabled {
log.Debug("Magic link login is disabled.") log.Debug("Magic link login is disabled.")
return res, fmt.Errorf(`magic link login is disabled for this instance`) return res, fmt.Errorf(`magic link login is disabled for this instance`)
} }
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`)
} }
@ -53,7 +61,11 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
// find user with email // find user with email
existingUser, err := db.Provider.GetUserByEmail(params.Email) existingUser, err := db.Provider.GetUserByEmail(params.Email)
if err != nil { if err != nil {
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) { isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
if err != nil {
log.Debug("Error getting signup disabled: ", err)
}
if isSignupDisabled {
log.Debug("Signup is disabled.") log.Debug("Signup is disabled.")
return res, fmt.Errorf(`signup is disabled for this instance`) return res, fmt.Errorf(`signup is disabled for this instance`)
} }
@ -62,14 +74,28 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
// define roles for new user // define roles for new user
if len(params.Roles) > 0 { if len(params.Roles) > 0 {
// check if roles exists // check if roles exists
if !utils.IsValidRoles(params.Roles, envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles)) { rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
roles := []string{}
if err != nil {
log.Debug("Error getting roles: ", err)
return res, err
} else {
roles = strings.Split(rolesString, ",")
}
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 {
inputRoles = params.Roles inputRoles = params.Roles
} }
} else { } else {
inputRoles = envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
log.Debug("Error getting default roles: ", err)
return res, fmt.Errorf(`invalid roles`)
} else {
inputRoles = strings.Split(inputRolesString, ",")
}
} }
user.Roles = strings.Join(inputRoles, ",") user.Roles = strings.Join(inputRoles, ",")
@ -88,7 +114,13 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
// find the unassigned roles // find the unassigned roles
if len(params.Roles) <= 0 { if len(params.Roles) <= 0 {
inputRoles = envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
log.Debug("Error getting default roles: ", err)
return res, fmt.Errorf(`invalid default roles`)
} else {
inputRoles = strings.Split(inputRolesString, ",")
}
} }
existingRoles := strings.Split(existingUser.Roles, ",") existingRoles := strings.Split(existingUser.Roles, ",")
unasignedRoles := []string{} unasignedRoles := []string{}
@ -101,8 +133,16 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
if len(unasignedRoles) > 0 { if len(unasignedRoles) > 0 {
// check if it contains protected unassigned role // check if it contains protected unassigned role
hasProtectedRole := false hasProtectedRole := false
protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
protectedRoles := []string{}
if err != nil {
log.Debug("Error getting protected roles: ", err)
return res, err
} else {
protectedRoles = strings.Split(protectedRolesString, ",")
}
for _, ur := range unasignedRoles { for _, ur := range unasignedRoles {
if utils.StringSliceContains(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles), ur) { if utils.StringSliceContains(protectedRoles, ur) {
hasProtectedRole = true hasProtectedRole = true
} }
} }
@ -129,8 +169,13 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
} }
} }
hostname := utils.GetHost(gc) hostname := parsers.GetHost(gc)
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil {
log.Debug("Error getting email verification disabled: ", err)
isEmailVerificationDisabled = true
}
if !isEmailVerificationDisabled {
// insert verification request // insert verification request
_, nonceHash, err := utils.GenerateNonce() _, nonceHash, err := utils.GenerateNonce()
if err != nil { if err != nil {
@ -144,7 +189,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

@ -11,10 +11,12 @@ 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/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"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/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
@ -26,7 +28,13 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
log.Debug("Failed to get GinContext: ", err) log.Debug("Failed to get GinContext: ", err)
return res, err return res, err
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil {
log.Debug("Error getting basic auth disabled: ", err)
isBasicAuthDisabled = true
}
if isBasicAuthDisabled {
log.Debug("Basic authentication is disabled") log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
@ -42,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

@ -4,12 +4,12 @@ import (
"context" "context"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
// RevokeResolver resolver to revoke refresh token // RevokeResolver resolver to revoke refresh token
func RevokeResolver(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) { func RevokeResolver(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) {
sessionstore.RemoveState(params.RefreshToken) memorystore.Provider.RemoveState(params.RefreshToken)
return &model.Response{ return &model.Response{
Message: "Token revoked", Message: "Token revoked",
}, nil }, nil

View File

@ -9,7 +9,7 @@ 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/sessionstore" "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"
) )
@ -47,7 +47,7 @@ func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (
return res, err return res, err
} }
go sessionstore.DeleteAllUserSession(fmt.Sprintf("%x", user.ID)) go memorystore.Provider.DeleteAllUserSession(fmt.Sprintf("%x", user.ID))
res = &model.Response{ res = &model.Response{
Message: `user access revoked successfully`, Message: `user access revoked successfully`,

View File

@ -11,7 +11,7 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"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/sessionstore" "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"
) )
@ -76,9 +76,9 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
} }
// rollover the session for security // rollover the session for security
sessionstore.RemoveState(sessionToken) memorystore.Provider.RemoveState(sessionToken)
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@ -96,7 +96,7 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
} }
return res, nil return res, nil

View File

@ -14,11 +14,12 @@ 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/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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
@ -31,12 +32,23 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, err return res, err
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) { isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
if err != nil {
log.Debug("Error getting signup disabled: ", err)
isSignupDisabled = true
}
if isSignupDisabled {
log.Debug("Signup is disabled") log.Debug("Signup is disabled")
return res, fmt.Errorf(`signup is disabled for this instance`) return res, fmt.Errorf(`signup is disabled for this instance`)
} }
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) { isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil {
log.Debug("Error getting basic auth disabled: ", err)
isBasicAuthDisabled = true
}
if isBasicAuthDisabled {
log.Debug("Basic authentication is disabled") log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
@ -46,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`)
} }
@ -80,14 +92,28 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
if len(params.Roles) > 0 { if len(params.Roles) > 0 {
// check if roles exists // check if roles exists
if !utils.IsValidRoles(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) { rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
roles := []string{}
if err != nil {
log.Debug("Error getting roles: ", err)
return res, err
} else {
roles = strings.Split(rolesString, ",")
}
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 {
inputRoles = params.Roles inputRoles = params.Roles
} }
} else { } else {
inputRoles = envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles) inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
log.Debug("Error getting default roles: ", err)
return res, err
} else {
inputRoles = strings.Split(inputRolesString, ",")
}
} }
user := models.User{ user := models.User{
@ -132,7 +158,12 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
} }
user.SignupMethods = constants.SignupMethodBasicAuth user.SignupMethods = constants.SignupMethodBasicAuth
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil {
log.Debug("Error getting email verification disabled: ", err)
isEmailVerificationDisabled = true
}
if isEmailVerificationDisabled {
now := time.Now().Unix() now := time.Now().Unix()
user.EmailVerifiedAt = &now user.EmailVerifiedAt = &now
} }
@ -144,8 +175,8 @@ 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 !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { if !isEmailVerificationDisabled {
// insert verification request // insert verification request
_, nonceHash, err := utils.GenerateNonce() _, nonceHash, err := utils.GenerateNonce()
if err != nil { if err != nil {
@ -153,7 +184,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
} }
@ -194,7 +225,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, err return res, err
} }
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
go db.Provider.AddSession(models.Session{ go db.Provider.AddSession(models.Session{
UserID: user.ID, UserID: user.ID,

View File

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
"strings"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -13,10 +14,9 @@ import (
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"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/oauth" "github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
) )
@ -37,10 +37,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
return res, fmt.Errorf("unauthorized") return res, fmt.Errorf("unauthorized")
} }
updatedData := envstore.EnvStoreObj.GetEnvStoreClone() updatedData, err := memorystore.Provider.GetEnvStore()
if err != nil {
log.Debug("Failed to get env store: ", err)
return res, err
}
isJWTUpdated := false isJWTUpdated := false
algo := updatedData.StringEnv[constants.EnvKeyJwtType] algo := updatedData[constants.EnvKeyJwtType].(string)
if params.JwtType != nil { if params.JwtType != nil {
algo = *params.JwtType algo = *params.JwtType
if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) { if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
@ -48,7 +52,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
return res, fmt.Errorf("invalid jwt type") return res, fmt.Errorf("invalid jwt type")
} }
updatedData.StringEnv[constants.EnvKeyJwtType] = algo updatedData[constants.EnvKeyJwtType] = algo
isJWTUpdated = true isJWTUpdated = true
} }
@ -136,8 +140,12 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
log.Debug("Old admin secret is required for admin secret update") log.Debug("Old admin secret is required for admin secret update")
return res, errors.New("admin secret and old admin secret are required for secret change") return res, errors.New("admin secret and old admin secret are required for secret change")
} }
oldAdminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if *params.OldAdminSecret != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) { if err != nil {
log.Debug("Failed to get old admin secret: ", err)
return res, err
}
if *params.OldAdminSecret != oldAdminSecret {
log.Debug("Old admin secret is invalid") log.Debug("Old admin secret is invalid")
return res, errors.New("old admin secret is not correct") return res, errors.New("old admin secret is not correct")
} }
@ -155,31 +163,28 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
fieldType := reflect.TypeOf(value).String() fieldType := reflect.TypeOf(value).String()
if fieldType == "string" { if fieldType == "string" {
updatedData.StringEnv[key] = value.(string) updatedData[key] = value.(string)
} }
if fieldType == "bool" { if fieldType == "bool" {
updatedData.BoolEnv[key] = value.(bool) updatedData[key] = value.(bool)
} }
if fieldType == "[]interface {}" { if fieldType == "[]interface {}" {
stringArr := []string{} stringArr := utils.ConvertInterfaceToStringSlice(value)
for _, v := range value.([]interface{}) { updatedData[key] = strings.Join(stringArr, ",")
stringArr = append(stringArr, v.(string))
}
updatedData.SliceEnv[key] = stringArr
} }
} }
} }
// handle derivative cases like disabling email verification & magic login // handle derivative cases like disabling email verification & magic login
// in case SMTP is off but env is set to true // in case SMTP is off but env is set to true
if updatedData.StringEnv[constants.EnvKeySmtpHost] == "" || updatedData.StringEnv[constants.EnvKeySmtpUsername] == "" || updatedData.StringEnv[constants.EnvKeySmtpPassword] == "" || updatedData.StringEnv[constants.EnvKeySenderEmail] == "" && updatedData.StringEnv[constants.EnvKeySmtpPort] == "" { if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" || updatedData[constants.EnvKeySenderEmail] == "" && updatedData[constants.EnvKeySmtpPort] == "" {
if !updatedData.BoolEnv[constants.EnvKeyDisableEmailVerification] { if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) {
updatedData.BoolEnv[constants.EnvKeyDisableEmailVerification] = true updatedData[constants.EnvKeyDisableEmailVerification] = true
} }
if !updatedData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] { if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
updatedData.BoolEnv[constants.EnvKeyDisableMagicLinkLogin] = true updatedData[constants.EnvKeyDisableMagicLinkLogin] = true
} }
} }
@ -206,19 +211,25 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
} }
// Update local store // Update local store
envstore.EnvStoreObj.UpdateEnvStore(updatedData) memorystore.Provider.UpdateEnvStore(updatedData)
jwk, err := crypto.GenerateJWKBasedOnEnv() jwk, err := crypto.GenerateJWKBasedOnEnv()
if err != nil { if err != nil {
log.Debug("Failed to generate JWK: ", err) log.Debug("Failed to generate JWK: ", err)
return res, err return res, err
} }
// updating jwk // updating jwk
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk) err = memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
err = sessionstore.InitSession()
if err != nil { if err != nil {
log.Debug("Failed to init session store: ", err) log.Debug("Failed to update JWK: ", err)
return res, err return res, err
} }
// TODO check how to update session store based on env change.
// err = sessionstore.InitSession()
// if err != nil {
// log.Debug("Failed to init session store: ", err)
// return res, err
// }
err = oauth.InitOAuth() err = oauth.InitOAuth()
if err != nil { if err != nil {
return res, err return res, err
@ -232,7 +243,12 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
} }
if params.AdminSecret != nil { if params.AdminSecret != nil {
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if err != nil {
log.Debug("Failed to get admin secret: ", err)
return res, err
}
hashedKey, err := crypto.EncryptPassword(adminSecret)
if err != nil { if err != nil {
log.Debug("Failed to encrypt admin secret: ", err) log.Debug("Failed to encrypt admin secret: ", err)
return res, err return res, err

View File

@ -14,11 +14,12 @@ 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/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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"
) )
@ -122,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")
} }
@ -141,12 +142,17 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
return res, fmt.Errorf("user with this email address already exists") return res, fmt.Errorf("user with this email address already exists")
} }
go sessionstore.DeleteAllUserSession(user.ID) go memorystore.Provider.DeleteAllUserSession(user.ID)
go cookie.DeleteSession(gc) go cookie.DeleteSession(gc)
user.Email = newEmail user.Email = newEmail
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) { isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
hostname := utils.GetHost(gc) if err != nil {
log.Debug("Failed to get disable email verification env variable: ", err)
return res, err
}
if !isEmailVerificationDisabled {
hostname := parsers.GetHost(gc)
user.EmailVerifiedAt = nil user.EmailVerifiedAt = nil
hasEmailChanged = true hasEmailChanged = true
// insert verification request // insert verification request
@ -156,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

@ -12,11 +12,12 @@ 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/email" "github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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
@ -98,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")
} }
@ -112,9 +113,9 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
} }
// TODO figure out how to do this // TODO figure out how to do this
go sessionstore.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
@ -124,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)
@ -155,16 +156,33 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
inputRoles = append(inputRoles, *item) inputRoles = append(inputRoles, *item)
} }
if !utils.IsValidRoles(inputRoles, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) { rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
roles := []string{}
if err != nil {
log.Debug("Error getting roles: ", err)
rolesString = ""
} else {
roles = strings.Split(rolesString, ",")
}
protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
protectedRoles := []string{}
if err != nil {
log.Debug("Error getting protected roles: ", err)
protectedRolesString = ""
} else {
protectedRoles = strings.Split(protectedRolesString, ",")
}
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, ",")
} }
go sessionstore.DeleteAllUserSession(user.ID) go memorystore.Provider.DeleteAllUserSession(user.ID)
} }
if rolesToSave != "" { if rolesToSave != "" {

View File

@ -10,7 +10,8 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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"
) )
@ -38,8 +39,8 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
nonce := "" nonce := ""
// access_token and refresh_token should be validated from session store as well // access_token and refresh_token should be validated from session store as well
if tokenType == "access_token" || tokenType == "refresh_token" { if tokenType == "access_token" || tokenType == "refresh_token" {
savedSession := sessionstore.GetState(params.Token) savedSession, err := memorystore.Provider.GetState(params.Token)
if savedSession == "" { if savedSession == "" || err != nil {
return &model.ValidateJWTTokenResponse{ return &model.ValidateJWTTokenResponse{
IsValid: false, IsValid: false,
}, nil }, nil
@ -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

@ -12,7 +12,8 @@ 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/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore" "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)
@ -74,8 +75,8 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
return res, err return res, err
} }
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID) memorystore.Provider.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
go db.Provider.AddSession(models.Session{ go db.Provider.AddSession(models.Session{
UserID: user.ID, UserID: user.ID,

View File

@ -1,74 +0,0 @@
package sessionstore
import (
"strings"
"sync"
)
// InMemoryStore is a simple in-memory store for sessions.
type InMemoryStore struct {
mutex sync.Mutex
sessionStore map[string]map[string]string
stateStore map[string]string
}
// ClearStore clears the in-memory store.
func (c *InMemoryStore) ClearStore() {
c.mutex.Lock()
defer c.mutex.Unlock()
c.sessionStore = map[string]map[string]string{}
}
// GetUserSessions returns all the user session token from the in-memory store.
func (c *InMemoryStore) GetUserSessions(userId string) map[string]string {
// c.mutex.Lock()
// defer c.mutex.Unlock()
res := map[string]string{}
for k, v := range c.stateStore {
split := strings.Split(v, "@")
if split[1] == userId {
res[k] = split[0]
}
}
return res
}
// DeleteAllUserSession deletes all the user sessions from in-memory store.
func (c *InMemoryStore) DeleteAllUserSession(userId string) {
// c.mutex.Lock()
// defer c.mutex.Unlock()
sessions := GetUserSessions(userId)
for k := range sessions {
RemoveState(k)
}
}
// SetState sets the state in the in-memory store.
func (c *InMemoryStore) SetState(key, state string) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.stateStore[key] = state
}
// 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.stateStore[key]; ok {
state = stateVal
}
return state
}
// RemoveState removes the state from the in-memory store.
func (c *InMemoryStore) RemoveState(key string) {
c.mutex.Lock()
defer c.mutex.Unlock()
delete(c.stateStore, key)
}

View File

@ -1,18 +0,0 @@
package sessionstore
import (
"context"
"time"
"github.com/go-redis/redis/v8"
)
type RedisSessionClient interface {
HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd
Del(ctx context.Context, keys ...string) *redis.IntCmd
HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd
HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd
HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd
Get(ctx context.Context, key string) *redis.StringCmd
}

View File

@ -1,79 +0,0 @@
package sessionstore
import (
"context"
"strings"
log "github.com/sirupsen/logrus"
)
type RedisStore struct {
ctx context.Context
store RedisSessionClient
}
// ClearStore clears the redis store for authorizer related tokens
func (c *RedisStore) ClearStore() {
err := c.store.Del(c.ctx, "authorizer_*").Err()
if err != nil {
log.Debug("Error clearing redis store: ", err)
}
}
// GetUserSessions returns all the user session token from the redis store.
func (c *RedisStore) GetUserSessions(userID string) map[string]string {
data, err := c.store.HGetAll(c.ctx, "*").Result()
if err != nil {
log.Debug("error getting token from redis store: ", err)
}
res := map[string]string{}
for k, v := range data {
split := strings.Split(v, "@")
if split[1] == userID {
res[k] = split[0]
}
}
return res
}
// DeleteAllUserSession deletes all the user session from redis
func (c *RedisStore) DeleteAllUserSession(userId string) {
sessions := GetUserSessions(userId)
for k, v := range sessions {
if k == "token" {
err := c.store.Del(c.ctx, v)
if err != nil {
log.Debug("Error deleting redis token: ", err)
}
}
}
}
// SetState sets the state in redis store.
func (c *RedisStore) SetState(key, value string) {
err := c.store.Set(c.ctx, "authorizer_"+key, value, 0).Err()
if err != nil {
log.Debug("Error saving redis token: ", err)
}
}
// GetState gets the state from redis store.
func (c *RedisStore) GetState(key string) string {
state := ""
state, err := c.store.Get(c.ctx, "authorizer_"+key).Result()
if err != nil {
log.Debug("error getting token from redis store: ", err)
}
return state
}
// RemoveState removes the state from redis store.
func (c *RedisStore) RemoveState(key string) {
err := c.store.Del(c.ctx, "authorizer_"+key).Err()
if err != nil {
log.Fatalln("Error deleting redis token: ", err)
}
}

View File

@ -1,156 +0,0 @@
package sessionstore
import (
"context"
"strings"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/go-redis/redis/v8"
)
// SessionStore is a struct that defines available session stores
// If redis store is available, higher preference is given to that store.
// Else in memory store is used.
type SessionStore struct {
InMemoryStoreObj *InMemoryStore
RedisMemoryStoreObj *RedisStore
}
// SessionStoreObj is a global variable that holds the
// reference to various session store instances
var SessionStoreObj SessionStore
// DeleteAllSessions deletes all the sessions from the session store
func DeleteAllUserSession(userId string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.DeleteAllUserSession(userId)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.DeleteAllUserSession(userId)
}
}
// GetUserSessions returns all the user sessions from the session store
func GetUserSessions(userId string) map[string]string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetUserSessions(userId)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetUserSessions(userId)
}
return nil
}
// ClearStore clears the session store for authorizer tokens
func ClearStore() {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.ClearStore()
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.ClearStore()
}
}
// SetState sets the login state (key, value form) in the session store
func SetState(key, state string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.SetState(key, state)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.SetState(key, state)
}
}
// GetState returns the state from the session store
func GetState(key string) string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetState(key)
}
return ""
}
// RemoveState removes the social login state from the session store
func RemoveState(key string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.RemoveState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.RemoveState(key)
}
}
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
func InitSession() error {
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" {
log.Info("using redis store to save sessions")
redisURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)
redisURLHostPortsList := strings.Split(redisURL, ",")
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
urls := []string{opt.Addr}
urlList := redisURLHostPortsList[1:]
urls = append(urls, urlList...)
clusterOpt := &redis.ClusterOptions{Addrs: urls}
rdb := redis.NewClusterClient(clusterOpt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
ctx: ctx,
store: rdb,
}
// return on successful initialization
return nil
}
opt, err := redis.ParseURL(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
rdb := redis.NewClient(opt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
ctx: ctx,
store: rdb,
}
// return on successful initialization
return nil
}
log.Info("using in memory store to save sessions")
// if redis url is not set use in memory store
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
sessionStore: map[string]map[string]string{},
stateStore: map[string]string{},
}
return nil
}

View File

@ -4,8 +4,8 @@ import (
"testing" "testing"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -20,8 +20,10 @@ func adminLoginTests(t *testing.T, s TestSetup) {
assert.NotNil(t, err) assert.NotNil(t, err)
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err)
_, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{ _, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
AdminSecret: envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret), AdminSecret: adminSecret,
}) })
assert.Nil(t, err) assert.Nil(t, err)

View File

@ -6,7 +6,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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -18,9 +18,12 @@ func adminLogoutTests(t *testing.T, s TestSetup) {
_, err := resolvers.AdminLogoutResolver(ctx) _, err := resolvers.AdminLogoutResolver(ctx)
assert.NotNil(t, err) assert.NotNil(t, err)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
_, err = resolvers.AdminLogoutResolver(ctx) _, err = resolvers.AdminLogoutResolver(ctx)
assert.Nil(t, err) assert.Nil(t, err)

View File

@ -6,7 +6,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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -18,9 +18,12 @@ func adminSessionTests(t *testing.T, s TestSetup) {
_, err := resolvers.AdminSessionResolver(ctx) _, err := resolvers.AdminSessionResolver(ctx)
assert.NotNil(t, err) assert.NotNil(t, err)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
_, err = resolvers.AdminSessionResolver(ctx) _, err = resolvers.AdminSessionResolver(ctx)
assert.Nil(t, err) assert.Nil(t, err)

View File

@ -4,8 +4,8 @@ import (
"testing" "testing"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -20,7 +20,7 @@ func adminSignupTests(t *testing.T, s TestSetup) {
assert.NotNil(t, err) assert.NotNil(t, err)
// reset env for test to pass // reset env for test to pass
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, "") memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, "")
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{ _, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
AdminSecret: "admin123", AdminSecret: "admin123",

View File

@ -6,8 +6,8 @@ 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/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -27,10 +27,12 @@ func deleteUserTest(t *testing.T, s TestSetup) {
Email: email, Email: email,
}) })
assert.NotNil(t, err, "unauthorized") assert.NotNil(t, err, "unauthorized")
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
_, err = resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{ _, err = resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{
Email: email, Email: email,

View File

@ -7,8 +7,8 @@ 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/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -28,10 +28,11 @@ func enableAccessTest(t *testing.T, s TestSetup) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, verifyRes.AccessToken) assert.NotNil(t, verifyRes.AccessToken)
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h)) h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
res, err := resolvers.RevokeAccessResolver(ctx, model.UpdateAccessInput{ res, err := resolvers.RevokeAccessResolver(ctx, model.UpdateAccessInput{
UserID: verifyRes.User.ID, UserID: verifyRes.User.ID,

View File

@ -1,26 +1,33 @@
package test package test
import ( import (
"os"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/env" "github.com/authorizerdev/authorizer/server/env"
"github.com/authorizerdev/authorizer/server/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/stretchr/testify/assert"
) )
func TestEnvs(t *testing.T) { func TestEnvs(t *testing.T) {
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, "../../.env.sample") err := os.Setenv(constants.EnvKeyEnvPath, "../../.env.test")
env.InitAllEnv() assert.Nil(t, err)
store := envstore.EnvStoreObj.GetEnvStoreClone() err = memorystore.InitRequiredEnv()
assert.Nil(t, err)
err = env.InitAllEnv()
assert.Nil(t, err)
store, err := memorystore.Provider.GetEnvStore()
assert.Nil(t, err)
assert.Equal(t, store.StringEnv[constants.EnvKeyEnv], "production") assert.Equal(t, "test", store[constants.EnvKeyEnv].(string))
assert.False(t, store.BoolEnv[constants.EnvKeyDisableEmailVerification]) assert.False(t, store[constants.EnvKeyDisableEmailVerification].(bool))
assert.False(t, store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin]) assert.False(t, store[constants.EnvKeyDisableMagicLinkLogin].(bool))
assert.False(t, store.BoolEnv[constants.EnvKeyDisableBasicAuthentication]) assert.False(t, store[constants.EnvKeyDisableBasicAuthentication].(bool))
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtType], "RS256") assert.Equal(t, "RS256", store[constants.EnvKeyJwtType].(string))
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtRoleClaim], "role") assert.Equal(t, store[constants.EnvKeyJwtRoleClaim].(string), "role")
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyRoles], []string{"user"}) assert.EqualValues(t, store[constants.EnvKeyRoles].(string), "user")
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyDefaultRoles], []string{"user"}) assert.EqualValues(t, store[constants.EnvKeyDefaultRoles].(string), "user")
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyAllowedOrigins], []string{"*"}) assert.EqualValues(t, store[constants.EnvKeyAllowedOrigins].(string), "*")
} }

View File

@ -6,7 +6,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/envstore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -18,12 +18,14 @@ func envTests(t *testing.T, s TestSetup) {
_, err := resolvers.EnvResolver(ctx) _, err := resolvers.EnvResolver(ctx)
assert.NotNil(t, err) assert.NotNil(t, err)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
res, err := resolvers.EnvResolver(ctx)
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, *res.AdminSecret, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
res, err := resolvers.EnvResolver(ctx)
assert.Nil(t, err)
assert.Equal(t, *res.AdminSecret, adminSecret)
}) })
} }

View File

@ -6,8 +6,8 @@ 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/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -30,9 +30,13 @@ func generateJWTkeyTest(t *testing.T, s TestSetup) {
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, res) assert.Nil(t, res)
}) })
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
t.Run(`should generate HS256 secret`, func(t *testing.T) { t.Run(`should generate HS256 secret`, func(t *testing.T) {
res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{ res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
Type: "HS256", Type: "HS256",

View File

@ -6,8 +6,8 @@ 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/envstore"
"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/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -26,9 +26,12 @@ func inviteUserTest(t *testing.T, s TestSetup) {
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, res) assert.Nil(t, res)
h, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)) adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), h))
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
// invalid emails test // invalid emails test
invalidEmailsTest := []string{ invalidEmailsTest := []string{

Some files were not shown because too many files have changed in this diff Show More