Feat/dashboard (#105)
This commit is contained in:
parent
7ce96367a3
commit
f1b4141367
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
|
@ -70,7 +70,11 @@ docker run --name arangodb -d -p 8529:8529 -e ARANGO_NO_AUTH=1 arangodb/arangodb
|
||||||
If you are adding new resolver,
|
If you are adding new resolver,
|
||||||
|
|
||||||
1. create new resolver test file [here](https://github.com/authorizerdev/authorizer/tree/main/server/__test__)
|
1. create new resolver test file [here](https://github.com/authorizerdev/authorizer/tree/main/server/__test__)
|
||||||
|
<<<<<<< HEAD
|
||||||
|
Naming convention filename: `resolver_name_test.go` function name: `resolverNameTest(t *testing.T, s TestSetup)`
|
||||||
|
=======
|
||||||
Naming convention filename: `resolver_name_test.go` function name: `resolverNameTest(s TestSetup, t *testing.T)`
|
Naming convention filename: `resolver_name_test.go` function name: `resolverNameTest(s TestSetup, t *testing.T)`
|
||||||
|
>>>>>>> main
|
||||||
2. Add your tests [here](https://github.com/authorizerdev/authorizer/blob/main/server/__test__/resolvers_test.go#L38)
|
2. Add your tests [here](https://github.com/authorizerdev/authorizer/blob/main/server/__test__/resolvers_test.go#L38)
|
||||||
|
|
||||||
**Command to run tests:**
|
**Command to run tests:**
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -10,4 +10,4 @@ build-dashboard:
|
||||||
clean:
|
clean:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
test:
|
test:
|
||||||
cd server && go clean --testcache && go test -v ./__test__
|
cd server && go clean --testcache && go test -v ./test
|
||||||
|
|
|
@ -42,7 +42,11 @@ export default function App() {
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<AuthorizerProvider
|
<AuthorizerProvider
|
||||||
config={{
|
config={{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
authorizerURL: window.location.origin,
|
||||||
|
=======
|
||||||
authorizerURL: globalState.authorizerURL,
|
authorizerURL: globalState.authorizerURL,
|
||||||
|
>>>>>>> main
|
||||||
redirectURL: globalState.redirectURL,
|
redirectURL: globalState.redirectURL,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
0
dashboard/src/Router.tsx
Normal file
0
dashboard/src/Router.tsx
Normal file
5
dashboard/src/components/layouts/AuthLayout.tsx
Normal file
5
dashboard/src/components/layouts/AuthLayout.tsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function AuthLayout() {
|
||||||
|
return <h1>Auth Layout</h1>;
|
||||||
|
}
|
5
dashboard/src/components/layouts/DefaultLayout.tsx
Normal file
5
dashboard/src/components/layouts/DefaultLayout.tsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function DefaultLayout() {
|
||||||
|
return <h1>Default Layout</h1>;
|
||||||
|
}
|
0
dashboard/src/contexts/AuthContext.tsx
Normal file
0
dashboard/src/contexts/AuthContext.tsx
Normal file
|
@ -1,26 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func adminLogoutTests(s TestSetup, t *testing.T) {
|
|
||||||
t.Run(`should get admin session`, func(t *testing.T) {
|
|
||||||
req, ctx := createContext(s)
|
|
||||||
_, err := resolvers.AdminLogout(ctx)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
|
|
||||||
h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
|
||||||
_, err = resolvers.AdminLogout(ctx)
|
|
||||||
|
|
||||||
assert.Nil(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func adminSessionTests(s TestSetup, t *testing.T) {
|
|
||||||
t.Run(`should get admin session`, func(t *testing.T) {
|
|
||||||
req, ctx := createContext(s)
|
|
||||||
_, err := resolvers.AdminSession(ctx)
|
|
||||||
log.Println("error:", err)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
|
|
||||||
h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
|
||||||
_, err = resolvers.AdminSession(ctx)
|
|
||||||
|
|
||||||
assert.Nil(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEnvs(t *testing.T) {
|
|
||||||
constants.EnvData.ENV_PATH = "../../.env.sample"
|
|
||||||
|
|
||||||
assert.Equal(t, constants.EnvData.ADMIN_SECRET, "admin")
|
|
||||||
assert.Equal(t, constants.EnvData.ENV, "production")
|
|
||||||
assert.False(t, constants.EnvData.DISABLE_EMAIL_VERIFICATION)
|
|
||||||
assert.False(t, constants.EnvData.DISABLE_MAGIC_LINK_LOGIN)
|
|
||||||
assert.False(t, constants.EnvData.DISABLE_BASIC_AUTHENTICATION)
|
|
||||||
assert.Equal(t, constants.EnvData.JWT_TYPE, "HS256")
|
|
||||||
assert.Equal(t, constants.EnvData.JWT_SECRET, "random_string")
|
|
||||||
assert.Equal(t, constants.EnvData.JWT_ROLE_CLAIM, "role")
|
|
||||||
assert.EqualValues(t, constants.EnvData.ROLES, []string{"user"})
|
|
||||||
assert.EqualValues(t, constants.EnvData.DEFAULT_ROLES, []string{"user"})
|
|
||||||
assert.EqualValues(t, constants.EnvData.PROTECTED_ROLES, []string{"admin"})
|
|
||||||
assert.EqualValues(t, constants.EnvData.ALLOWED_ORIGINS, []string{"*"})
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/env"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestResolvers(t *testing.T) {
|
|
||||||
databases := map[string]string{
|
|
||||||
enum.Sqlite.String(): "../../data.db",
|
|
||||||
enum.Arangodb.String(): "http://localhost:8529",
|
|
||||||
enum.Mongodb.String(): "mongodb://localhost:27017",
|
|
||||||
}
|
|
||||||
|
|
||||||
for dbType, dbURL := range databases {
|
|
||||||
constants.EnvData.DATABASE_URL = dbURL
|
|
||||||
constants.EnvData.DATABASE_TYPE = dbType
|
|
||||||
db.InitDB()
|
|
||||||
|
|
||||||
// clean the persisted config for test to use fresh config
|
|
||||||
config, err := db.Mgr.GetConfig()
|
|
||||||
if err == nil {
|
|
||||||
config.Config = []byte{}
|
|
||||||
db.Mgr.UpdateConfig(config)
|
|
||||||
}
|
|
||||||
env.PersistEnv()
|
|
||||||
|
|
||||||
s := testSetup()
|
|
||||||
defer s.Server.Close()
|
|
||||||
|
|
||||||
log.Println("EnvData:", constants.EnvData)
|
|
||||||
t.Run("should pass tests for "+dbType, func(t *testing.T) {
|
|
||||||
// admin tests
|
|
||||||
adminSignupTests(s, t)
|
|
||||||
verificationRequestsTest(s, t)
|
|
||||||
usersTest(s, t)
|
|
||||||
deleteUserTest(s, t)
|
|
||||||
updateUserTest(s, t)
|
|
||||||
adminLoginTests(s, t)
|
|
||||||
adminLogoutTests(s, t)
|
|
||||||
adminSessionTests(s, t)
|
|
||||||
updateConfigTests(s, t)
|
|
||||||
configTests(s, t)
|
|
||||||
|
|
||||||
// user tests
|
|
||||||
loginTests(s, t)
|
|
||||||
signupTests(s, t)
|
|
||||||
forgotPasswordTest(s, t)
|
|
||||||
resendVerifyEmailTests(s, t)
|
|
||||||
resetPasswordTest(s, t)
|
|
||||||
verifyEmailTest(s, t)
|
|
||||||
sessionTests(s, t)
|
|
||||||
profileTests(s, t)
|
|
||||||
updateProfileTests(s, t)
|
|
||||||
magicLinkLoginTests(s, t)
|
|
||||||
logoutTests(s, t)
|
|
||||||
metaTests(s, t)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package constants
|
|
||||||
|
|
||||||
type EnvConst struct {
|
|
||||||
ADMIN_SECRET string
|
|
||||||
ENV string
|
|
||||||
ENV_PATH string
|
|
||||||
VERSION string
|
|
||||||
DATABASE_TYPE string
|
|
||||||
DATABASE_URL string
|
|
||||||
DATABASE_NAME string
|
|
||||||
SMTP_HOST string
|
|
||||||
SMTP_PORT string
|
|
||||||
SMTP_PASSWORD string
|
|
||||||
SMTP_USERNAME string
|
|
||||||
SENDER_EMAIL string
|
|
||||||
JWT_TYPE string
|
|
||||||
JWT_SECRET string
|
|
||||||
ALLOWED_ORIGINS []string
|
|
||||||
AUTHORIZER_URL string
|
|
||||||
APP_URL string
|
|
||||||
PORT string
|
|
||||||
REDIS_URL string
|
|
||||||
COOKIE_NAME string
|
|
||||||
ADMIN_COOKIE_NAME string
|
|
||||||
RESET_PASSWORD_URL string
|
|
||||||
ENCRYPTION_KEY string `json:"-"`
|
|
||||||
IS_PROD bool
|
|
||||||
DISABLE_EMAIL_VERIFICATION bool
|
|
||||||
DISABLE_BASIC_AUTHENTICATION bool
|
|
||||||
DISABLE_MAGIC_LINK_LOGIN bool
|
|
||||||
DISABLE_LOGIN_PAGE bool
|
|
||||||
|
|
||||||
// ROLES
|
|
||||||
ROLES []string
|
|
||||||
PROTECTED_ROLES []string
|
|
||||||
DEFAULT_ROLES []string
|
|
||||||
JWT_ROLE_CLAIM string
|
|
||||||
|
|
||||||
// OAuth login
|
|
||||||
GOOGLE_CLIENT_ID string
|
|
||||||
GOOGLE_CLIENT_SECRET string
|
|
||||||
GITHUB_CLIENT_ID string
|
|
||||||
GITHUB_CLIENT_SECRET string
|
|
||||||
FACEBOOK_CLIENT_ID string
|
|
||||||
FACEBOOK_CLIENT_SECRET string
|
|
||||||
|
|
||||||
// Org envs
|
|
||||||
ORGANIZATION_NAME string
|
|
||||||
ORGANIZATION_LOGO string
|
|
||||||
}
|
|
||||||
|
|
||||||
var EnvData = EnvConst{
|
|
||||||
ADMIN_COOKIE_NAME: "authorizer-admin",
|
|
||||||
JWT_ROLE_CLAIM: "role",
|
|
||||||
ORGANIZATION_NAME: "Authorizer",
|
|
||||||
ORGANIZATION_LOGO: "https://authorizer.dev/images/logo.png",
|
|
||||||
DISABLE_EMAIL_VERIFICATION: false,
|
|
||||||
DISABLE_BASIC_AUTHENTICATION: false,
|
|
||||||
DISABLE_MAGIC_LINK_LOGIN: false,
|
|
||||||
DISABLE_LOGIN_PAGE: false,
|
|
||||||
IS_PROD: false,
|
|
||||||
}
|
|
16
server/constants/db_types.go
Normal file
16
server/constants/db_types.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DbTypePostgres is the postgres database type
|
||||||
|
DbTypePostgres = "postgres"
|
||||||
|
// DbTypeSqlite is the sqlite database type
|
||||||
|
DbTypeSqlite = "sqlite"
|
||||||
|
// DbTypeMysql is the mysql database type
|
||||||
|
DbTypeMysql = "mysql"
|
||||||
|
// DbTypeSqlserver is the sqlserver database type
|
||||||
|
DbTypeSqlserver = "sqlserver"
|
||||||
|
// DbTypeArangodb is the arangodb database type
|
||||||
|
DbTypeArangodb = "arangodb"
|
||||||
|
// DbTypeMongodb is the mongodb database type
|
||||||
|
DbTypeMongodb = "mongodb"
|
||||||
|
)
|
87
server/constants/env.go
Normal file
87
server/constants/env.go
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EnvKeyEnv key for env variable ENV
|
||||||
|
EnvKeyEnv = "ENV"
|
||||||
|
// EnvKeyEnvPath key for cli arg variable ENV_PATH
|
||||||
|
EnvKeyEnvPath = "ENV_PATH"
|
||||||
|
// EnvKeyVersion key for build arg version
|
||||||
|
EnvKeyVersion = "VERSION"
|
||||||
|
// EnvKeyAuthorizerURL key for env variable AUTHORIZER_URL
|
||||||
|
EnvKeyAuthorizerURL = "AUTHORIZER_URL"
|
||||||
|
// EnvKeyPort key for env variable PORT
|
||||||
|
EnvKeyPort = "PORT"
|
||||||
|
|
||||||
|
// EnvKeyAdminSecret key for env variable ADMIN_SECRET
|
||||||
|
EnvKeyAdminSecret = "ADMIN_SECRET"
|
||||||
|
// EnvKeyDatabaseType key for env variable DATABASE_TYPE
|
||||||
|
EnvKeyDatabaseType = "DATABASE_TYPE"
|
||||||
|
// EnvKeyDatabaseURL key for env variable DATABASE_URL
|
||||||
|
EnvKeyDatabaseURL = "DATABASE_URL"
|
||||||
|
// EnvKeyDatabaseName key for env variable DATABASE_NAME
|
||||||
|
EnvKeyDatabaseName = "DATABASE_NAME"
|
||||||
|
// EnvKeySmtpHost key for env variable SMTP_HOST
|
||||||
|
EnvKeySmtpHost = "SMTP_HOST"
|
||||||
|
// EnvKeySmtpPort key for env variable SMTP_PORT
|
||||||
|
EnvKeySmtpPort = "SMTP_PORT"
|
||||||
|
// EnvKeySmtpUsername key for env variable SMTP_USERNAME
|
||||||
|
EnvKeySmtpUsername = "SMTP_USERNAME"
|
||||||
|
// EnvKeySmtpPassword key for env variable SMTP_PASSWORD
|
||||||
|
EnvKeySmtpPassword = "SMTP_PASSWORD"
|
||||||
|
// EnvKeySenderEmail key for env variable SENDER_EMAIL
|
||||||
|
EnvKeySenderEmail = "SENDER_EMAIL"
|
||||||
|
// EnvKeyJwtType key for env variable JWT_TYPE
|
||||||
|
EnvKeyJwtType = "JWT_TYPE"
|
||||||
|
// EnvKeyJwtSecret key for env variable JWT_SECRET
|
||||||
|
EnvKeyJwtSecret = "JWT_SECRET"
|
||||||
|
// EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
|
||||||
|
EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
|
||||||
|
// EnvKeyAppURL key for env variable APP_URL
|
||||||
|
EnvKeyAppURL = "APP_URL"
|
||||||
|
// EnvKeyRedisURL key for env variable 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 = "RESET_PASSWORD_URL"
|
||||||
|
// EnvKeyEncryptionKey key for env variable ENCRYPTION_KEY
|
||||||
|
EnvKeyEncryptionKey = "ENCRYPTION_KEY"
|
||||||
|
// 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"
|
||||||
|
// 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 = "JWT_ROLE_CLAIM"
|
||||||
|
// EnvKeyGoogleClientID key for env variable GOOGLE_CLIENT_ID
|
||||||
|
EnvKeyGoogleClientID = "GOOGLE_CLIENT_ID"
|
||||||
|
// EnvKeyGoogleClientSecret key for env variable GOOGLE_CLIENT_SECRET
|
||||||
|
EnvKeyGoogleClientSecret = "GOOGLE_CLIENT_SECRET"
|
||||||
|
// EnvKeyGithubClientID key for env variable GITHUB_CLIENT_ID
|
||||||
|
EnvKeyGithubClientID = "GITHUB_CLIENT_ID"
|
||||||
|
// EnvKeyGithubClientSecret key for env variable GITHUB_CLIENT_SECRET
|
||||||
|
EnvKeyGithubClientSecret = "GITHUB_CLIENT_SECRET"
|
||||||
|
// EnvKeyFacebookClientID key for env variable FACEBOOK_CLIENT_ID
|
||||||
|
EnvKeyFacebookClientID = "FACEBOOK_CLIENT_ID"
|
||||||
|
// EnvKeyFacebookClientSecret key for env variable FACEBOOK_CLIENT_SECRET
|
||||||
|
EnvKeyFacebookClientSecret = "FACEBOOK_CLIENT_SECRET"
|
||||||
|
// EnvKeyOrganizationName key for env variable ORGANIZATION_NAME
|
||||||
|
EnvKeyOrganizationName = "ORGANIZATION_NAME"
|
||||||
|
// EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO
|
||||||
|
EnvKeyOrganizationLogo = "ORGANIZATION_LOGO"
|
||||||
|
// EnvKeyIsProd key for env variable IS_PROD
|
||||||
|
EnvKeyIsProd = "IS_PROD"
|
||||||
|
// EnvKeyCustomAccessTokenScript key for env variable CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||||
|
EnvKeyCustomAccessTokenScript = "CUSTOM_ACCESS_TOKEN_SCRIPT"
|
||||||
|
)
|
|
@ -1,6 +1,6 @@
|
||||||
package constants
|
package constants
|
||||||
|
|
||||||
var (
|
const (
|
||||||
// Ref: https://github.com/qor/auth/blob/master/providers/google/google.go
|
// Ref: https://github.com/qor/auth/blob/master/providers/google/google.go
|
||||||
// deprecated and not used. instead we follow open id approach for google login
|
// deprecated and not used. instead we follow open id approach for google login
|
||||||
GoogleUserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo"
|
GoogleUserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo"
|
||||||
|
|
14
server/constants/signup_methods.go
Normal file
14
server/constants/signup_methods.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SignupMethodBasicAuth is the basic_auth signup method
|
||||||
|
SignupMethodBasicAuth = "basic_auth"
|
||||||
|
// SignupMethodMagicLinkLogin is the magic_link_login signup method
|
||||||
|
SignupMethodMagicLinkLogin = "magic_link_login"
|
||||||
|
// SignupMethodGoogle is the google signup method
|
||||||
|
SignupMethodGoogle = "google"
|
||||||
|
// SignupMethodGithub is the github signup method
|
||||||
|
SignupMethodGithub = "github"
|
||||||
|
// SignupMethodFacebook is the facebook signup method
|
||||||
|
SignupMethodFacebook = "facebook"
|
||||||
|
)
|
8
server/constants/token_types.go
Normal file
8
server/constants/token_types.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TokenTypeRefreshToken is the refresh_token token type
|
||||||
|
TokenTypeRefreshToken = "refresh_token"
|
||||||
|
// TokenTypeAccessToken is the access_token token type
|
||||||
|
TokenTypeAccessToken = "access_token"
|
||||||
|
)
|
12
server/constants/verification_types.go
Normal file
12
server/constants/verification_types.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VerificationTypeBasicAuthSignup is the basic_auth_signup verification type
|
||||||
|
VerificationTypeBasicAuthSignup = "basic_auth_signup"
|
||||||
|
// VerificationTypeMagicLinkLogin is the magic_link_login verification type
|
||||||
|
VerificationTypeMagicLinkLogin = "magic_link_login"
|
||||||
|
// VerificationTypeUpdateEmail is the update_email verification type
|
||||||
|
VerificationTypeUpdateEmail = "update_email"
|
||||||
|
// VerificationTypeForgotPassword is the forgot_password verification type
|
||||||
|
VerificationTypeForgotPassword = "forgot_password"
|
||||||
|
)
|
|
@ -8,6 +8,7 @@ import (
|
||||||
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/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
// for this we need arangodb instance up and running
|
// for this we need arangodb instance up and running
|
||||||
|
@ -17,7 +18,7 @@ import (
|
||||||
func initArangodb() (arangoDriver.Database, error) {
|
func initArangodb() (arangoDriver.Database, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
conn, err := http.NewConnection(http.ConnectionConfig{
|
conn, err := http.NewConnection(http.ConnectionConfig{
|
||||||
Endpoints: []string{constants.EnvData.DATABASE_URL},
|
Endpoints: []string{envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -32,16 +33,16 @@ func initArangodb() (arangoDriver.Database, error) {
|
||||||
|
|
||||||
var arangodb driver.Database
|
var arangodb driver.Database
|
||||||
|
|
||||||
arangodb_exists, err := arangoClient.DatabaseExists(nil, constants.EnvData.DATABASE_NAME)
|
arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string))
|
||||||
|
|
||||||
if arangodb_exists {
|
if arangodb_exists {
|
||||||
log.Println(constants.EnvData.DATABASE_NAME + " db exists already")
|
log.Println(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string) + " db exists already")
|
||||||
arangodb, err = arangoClient.Database(nil, constants.EnvData.DATABASE_NAME)
|
arangodb, err = arangoClient.Database(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
arangodb, err = arangoClient.CreateDatabase(nil, constants.EnvData.DATABASE_NAME, nil)
|
arangodb, err = arangoClient.CreateDatabase(nil, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
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/enum"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
|
@ -66,9 +66,9 @@ func InitDB() {
|
||||||
var sqlDB *gorm.DB
|
var sqlDB *gorm.DB
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
IsORMSupported = constants.EnvData.DATABASE_TYPE != enum.Arangodb.String() && constants.EnvData.DATABASE_TYPE != enum.Mongodb.String()
|
IsORMSupported = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) != constants.DbTypeArangodb && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) != constants.DbTypeMongodb
|
||||||
IsArangoDB = constants.EnvData.DATABASE_TYPE == enum.Arangodb.String()
|
IsArangoDB = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) == constants.DbTypeArangodb
|
||||||
IsMongoDB = constants.EnvData.DATABASE_TYPE == enum.Mongodb.String()
|
IsMongoDB = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) == constants.DbTypeMongodb
|
||||||
|
|
||||||
// sql db orm config
|
// sql db orm config
|
||||||
ormConfig := &gorm.Config{
|
ormConfig := &gorm.Config{
|
||||||
|
@ -77,22 +77,22 @@ func InitDB() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("db type:", constants.EnvData.DATABASE_TYPE)
|
log.Println("db type:", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string))
|
||||||
|
|
||||||
switch constants.EnvData.DATABASE_TYPE {
|
switch envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseType).(string) {
|
||||||
case enum.Postgres.String():
|
case constants.DbTypePostgres:
|
||||||
sqlDB, err = gorm.Open(postgres.Open(constants.EnvData.DATABASE_URL), ormConfig)
|
sqlDB, err = gorm.Open(postgres.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig)
|
||||||
break
|
break
|
||||||
case enum.Sqlite.String():
|
case constants.DbTypeSqlite:
|
||||||
sqlDB, err = gorm.Open(sqlite.Open(constants.EnvData.DATABASE_URL), ormConfig)
|
sqlDB, err = gorm.Open(sqlite.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig)
|
||||||
break
|
break
|
||||||
case enum.Mysql.String():
|
case constants.DbTypeMysql:
|
||||||
sqlDB, err = gorm.Open(mysql.Open(constants.EnvData.DATABASE_URL), ormConfig)
|
sqlDB, err = gorm.Open(mysql.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig)
|
||||||
break
|
break
|
||||||
case enum.SQLServer.String():
|
case constants.DbTypeSqlserver:
|
||||||
sqlDB, err = gorm.Open(sqlserver.Open(constants.EnvData.DATABASE_URL), ormConfig)
|
sqlDB, err = gorm.Open(sqlserver.Open(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string)), ormConfig)
|
||||||
break
|
break
|
||||||
case enum.Arangodb.String():
|
case constants.DbTypeArangodb:
|
||||||
arangodb, err := initArangodb()
|
arangodb, err := initArangodb()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("error initializing arangodb:", err)
|
log.Fatal("error initializing arangodb:", err)
|
||||||
|
@ -105,7 +105,7 @@ func InitDB() {
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
case enum.Mongodb.String():
|
case constants.DbTypeMongodb:
|
||||||
mongodb, err := initMongodb()
|
mongodb, err := initMongodb()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("error initializing mongodb connection:", err)
|
log.Fatal("error initializing mongodb connection:", err)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"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"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func initMongodb() (*mongo.Database, error) {
|
func initMongodb() (*mongo.Database, error) {
|
||||||
mongodbOptions := options.Client().ApplyURI(constants.EnvData.DATABASE_URL)
|
mongodbOptions := options.Client().ApplyURI(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseURL).(string))
|
||||||
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)
|
||||||
|
@ -30,7 +31,7 @@ func initMongodb() (*mongo.Database, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mongodb := mongoClient.Database(constants.EnvData.DATABASE_NAME, options.Database())
|
mongodb := mongoClient.Database(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDatabaseName).(string), options.Database())
|
||||||
|
|
||||||
mongodb.CreateCollection(ctx, Collections.User, options.CreateCollection())
|
mongodb.CreateCollection(ctx, Collections.User, options.CreateCollection())
|
||||||
userCollection := mongodb.Collection(Collections.User, options.Collection())
|
userCollection := mongodb.Collection(Collections.User, options.Collection())
|
||||||
|
|
|
@ -3,11 +3,13 @@ package db
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"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/envstore"
|
||||||
"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"
|
||||||
|
@ -43,7 +45,7 @@ func (mgr *manager) AddUser(user User) (User, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Roles == "" {
|
if user.Roles == "" {
|
||||||
user.Roles = constants.EnvData.DEFAULT_ROLES[0]
|
user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsORMSupported {
|
if IsORMSupported {
|
||||||
|
@ -185,6 +187,7 @@ func (mgr *manager) GetUsers() ([]User, error) {
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserByEmail function to get user by email
|
||||||
func (mgr *manager) GetUserByEmail(email string) (User, error) {
|
func (mgr *manager) GetUserByEmail(email string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
|
|
||||||
|
@ -233,6 +236,7 @@ func (mgr *manager) GetUserByEmail(email string) (User, error) {
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserByID function to get user by ID
|
||||||
func (mgr *manager) GetUserByID(id string) (User, error) {
|
func (mgr *manager) GetUserByID(id string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
|
|
||||||
|
@ -281,6 +285,7 @@ func (mgr *manager) GetUserByID(id string) (User, error) {
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteUser function to delete user
|
||||||
func (mgr *manager) DeleteUser(user User) error {
|
func (mgr *manager) DeleteUser(user User) error {
|
||||||
if IsORMSupported {
|
if IsORMSupported {
|
||||||
result := mgr.sqlDB.Delete(&user)
|
result := mgr.sqlDB.Delete(&user)
|
||||||
|
|
|
@ -1,23 +1,44 @@
|
||||||
package email
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
gomail "gopkg.in/mail.v2"
|
gomail "gopkg.in/mail.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// addEmailTemplate is used to add html template in email body
|
||||||
|
func addEmailTemplate(a string, b map[string]interface{}, templateName string) string {
|
||||||
|
tmpl, err := template.New(templateName).Parse(a)
|
||||||
|
if err != nil {
|
||||||
|
output, _ := json.Marshal(b)
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err = tmpl.Execute(buf, b)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
s := buf.String()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMail function to send mail
|
||||||
func SendMail(to []string, Subject, bodyMessage string) error {
|
func SendMail(to []string, Subject, bodyMessage string) error {
|
||||||
m := gomail.NewMessage()
|
m := gomail.NewMessage()
|
||||||
m.SetHeader("From", constants.EnvData.SENDER_EMAIL)
|
m.SetHeader("From", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySenderEmail).(string))
|
||||||
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(constants.EnvData.SMTP_PORT)
|
port, _ := strconv.Atoi(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpPort).(string))
|
||||||
d := gomail.NewDialer(constants.EnvData.SMTP_HOST, port, constants.EnvData.SMTP_USERNAME, constants.EnvData.SMTP_PASSWORD)
|
d := gomail.NewDialer(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpHost).(string), port, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpUsername).(string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeySmtpPassword).(string))
|
||||||
if constants.EnvData.ENV == "development" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyEnv).(string) == "development" {
|
||||||
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 {
|
||||||
|
|
112
server/email/forgot_password_email.go
Normal file
112
server/email/forgot_password_email.go
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
package email
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SendForgotPasswordMail to send forgot password email
|
||||||
|
func SendForgotPasswordMail(toEmail, token, host string) error {
|
||||||
|
resetPasswordUrl := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyResetPasswordURL).(string)
|
||||||
|
if resetPasswordUrl == "" {
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyResetPasswordURL, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)+"/app/reset-password")
|
||||||
|
}
|
||||||
|
|
||||||
|
// The receiver needs to be in slice as the receive supports multiple receiver
|
||||||
|
Receiver := []string{toEmail}
|
||||||
|
|
||||||
|
Subject := "Reset Password"
|
||||||
|
|
||||||
|
message := `
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta content="telephone=no" name="format-detection">
|
||||||
|
<title></title>
|
||||||
|
<!--[if (mso 16)]>
|
||||||
|
<style type="text/css">
|
||||||
|
a {}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<!--[if gte mso 9]><style>sup { font-size: 100%% !important; }</style><![endif]-->
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings>
|
||||||
|
<o:AllowPNG></o:AllowPNG>
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body style="font-family: sans-serif;">
|
||||||
|
<div class="es-wrapper-color">
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
||||||
|
<v:fill type="tile" color="#ffffff"></v:fill>
|
||||||
|
</v:background>
|
||||||
|
<![endif]-->
|
||||||
|
<table class="es-wrapper" width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-email-paddings" valign="top">
|
||||||
|
<table class="es-content esd-footer-popover" cellspacing="0" cellpadding="0" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-stripe" align="center">
|
||||||
|
<table class="es-content-body" style="border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;border-bottom:1px solid transparent;padding:20px 0px;" width="600" cellspacing="0" cellpadding="0" bgcolor="#ffffff" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-structure es-p20t es-p40b es-p40r es-p40l" esd-custom-block-id="8537" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-container-frame" width="518" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-block-image es-m-txt-c es-p5b" style="font-size:0;padding:10px" align="center"><a target="_blank" clicktracking="off"><img src="{{.org_logo}}" alt="icon" style="display: block;" title="icon" width="30"></a></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="background: rgb(249,250,251);padding: 10px;margin-bottom:10px;border-radius:5px;">
|
||||||
|
<td class="esd-block-text es-m-txt-c es-p15t" align="center" style="padding:10px;padding-bottom:30px;">
|
||||||
|
<p>Hey there 👋</p>
|
||||||
|
<p>We have received a request to reset password for email: <b>{{.org_name}}</b>. If this is correct, please reset the password clicking the button below.</p> <br/>
|
||||||
|
<a clicktracking="off" href="{{.verification_url}}" class="es-button" target="_blank" style="text-decoration: none;padding:10px 15px;background-color: rgba(59,130,246,1);color: #fff;font-size: 1em;border-radius:5px;">Reset Password</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; left: -9999px; top: -9999px; margin: 0px;"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
|
||||||
|
data := make(map[string]interface{}, 3)
|
||||||
|
data["org_logo"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string)
|
||||||
|
data["org_name"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string)
|
||||||
|
data["verification_url"] = resetPasswordUrl + "?token=" + token
|
||||||
|
message = addEmailTemplate(message, data, "reset_password_email.tmpl")
|
||||||
|
|
||||||
|
return SendMail(Receiver, Subject, message)
|
||||||
|
}
|
107
server/email/verification_email.go
Normal file
107
server/email/verification_email.go
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
package email
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SendVerificationMail to send verification email
|
||||||
|
func SendVerificationMail(toEmail, token string) error {
|
||||||
|
// The receiver needs to be in slice as the receive supports multiple receiver
|
||||||
|
Receiver := []string{toEmail}
|
||||||
|
|
||||||
|
Subject := "Please verify your email"
|
||||||
|
message := `
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta content="telephone=no" name="format-detection">
|
||||||
|
<title></title>
|
||||||
|
<!--[if (mso 16)]>
|
||||||
|
<style type="text/css">
|
||||||
|
a {}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<!--[if gte mso 9]><style>sup { font-size: 100%% !important; }</style><![endif]-->
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings>
|
||||||
|
<o:AllowPNG></o:AllowPNG>
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body style="font-family: sans-serif;">
|
||||||
|
<div class="es-wrapper-color">
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
||||||
|
<v:fill type="tile" color="#ffffff"></v:fill>
|
||||||
|
</v:background>
|
||||||
|
<![endif]-->
|
||||||
|
<table class="es-wrapper" width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-email-paddings" valign="top">
|
||||||
|
<table class="es-content esd-footer-popover" cellspacing="0" cellpadding="0" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-stripe" align="center">
|
||||||
|
<table class="es-content-body" style="border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;border-bottom:1px solid transparent;padding:20px 0px;" width="600" cellspacing="0" cellpadding="0" bgcolor="#ffffff" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-structure es-p20t es-p40b es-p40r es-p40l" esd-custom-block-id="8537" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-container-frame" width="518" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-block-image es-m-txt-c es-p5b" style="font-size:0;padding:10px" align="center"><a target="_blank" clicktracking="off"><img src="{{.org_logo}}" alt="icon" style="display: block;" title="icon" width="30"></a></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="background: rgb(249,250,251);padding: 10px;margin-bottom:10px;border-radius:5px;">
|
||||||
|
<td class="esd-block-text es-m-txt-c es-p15t" align="center" style="padding:10px;padding-bottom:30px;">
|
||||||
|
<p>Hey there 👋</p>
|
||||||
|
<p>We have received request to verify email for <b>{{.org_name}}</b>. If this is correct, please confirm your email address by clicking the button below.</p> <br/>
|
||||||
|
<a
|
||||||
|
clicktracking="off" href="{{.verification_url}}" class="es-button" target="_blank" style="text-decoration: none;padding:10px 15px;background-color: rgba(59,130,246,1);color: #fff;font-size: 1em;border-radius:5px;">Confirm Email</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; left: -9999px; top: -9999px; margin: 0px;"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
data := make(map[string]interface{}, 3)
|
||||||
|
data["org_logo"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string)
|
||||||
|
data["org_name"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string)
|
||||||
|
data["verification_url"] = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/verify_email?token=" + token
|
||||||
|
message = addEmailTemplate(message, data, "verify_email.tmpl")
|
||||||
|
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
||||||
|
|
||||||
|
return SendMail(Receiver, Subject, message)
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
package enum
|
|
||||||
|
|
||||||
type DbType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
Postgres DbType = iota
|
|
||||||
Sqlite
|
|
||||||
Mysql
|
|
||||||
SQLServer
|
|
||||||
Arangodb
|
|
||||||
Mongodb
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d DbType) String() string {
|
|
||||||
return [...]string{
|
|
||||||
"postgres",
|
|
||||||
"sqlite",
|
|
||||||
"mysql",
|
|
||||||
"sqlserver",
|
|
||||||
"arangodb",
|
|
||||||
"mongodb",
|
|
||||||
}[d]
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package enum
|
|
||||||
|
|
||||||
type OAuthProvider int
|
|
||||||
|
|
||||||
const (
|
|
||||||
GoogleProvider OAuthProvider = iota
|
|
||||||
GithubProvider
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d OAuthProvider) String() string {
|
|
||||||
return [...]string{
|
|
||||||
"google_provider",
|
|
||||||
"github_provider",
|
|
||||||
}[d]
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package enum
|
|
||||||
|
|
||||||
type SignupMethod int
|
|
||||||
|
|
||||||
const (
|
|
||||||
BasicAuth SignupMethod = iota
|
|
||||||
MagicLinkLogin
|
|
||||||
Google
|
|
||||||
Github
|
|
||||||
Facebook
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d SignupMethod) String() string {
|
|
||||||
return [...]string{
|
|
||||||
"basic_auth",
|
|
||||||
"magic_link_login",
|
|
||||||
"google",
|
|
||||||
"github",
|
|
||||||
"facebook",
|
|
||||||
}[d]
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package enum
|
|
||||||
|
|
||||||
type TokenType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
RefreshToken TokenType = iota
|
|
||||||
AccessToken
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d TokenType) String() string {
|
|
||||||
return [...]string{
|
|
||||||
"refresh_token",
|
|
||||||
"access_token",
|
|
||||||
}[d]
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package enum
|
|
||||||
|
|
||||||
type VerificationType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
BasicAuthSignup VerificationType = iota
|
|
||||||
UpdateEmail
|
|
||||||
ForgotPassword
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d VerificationType) String() string {
|
|
||||||
return [...]string{
|
|
||||||
"basic_auth_signup",
|
|
||||||
"update_email",
|
|
||||||
"forgot_password",
|
|
||||||
}[d]
|
|
||||||
}
|
|
247
server/env/env.go
vendored
247
server/env/env.go
vendored
|
@ -6,188 +6,197 @@ import (
|
||||||
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// build variables
|
// TODO move this to env store
|
||||||
var (
|
var (
|
||||||
|
// ARG_DB_URL is the cli arg variable for the database url
|
||||||
ARG_DB_URL *string
|
ARG_DB_URL *string
|
||||||
|
// ARG_DB_TYPE is the cli arg variable for the database type
|
||||||
ARG_DB_TYPE *string
|
ARG_DB_TYPE *string
|
||||||
ARG_AUTHORIZER_URL *string
|
// ARG_ENV_FILE is the cli arg variable for the env file
|
||||||
ARG_ENV_FILE *string
|
ARG_ENV_FILE *string
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitEnv -> to initialize env and through error if required env are not present
|
// InitEnv to initialize EnvData and through error if required env are not present
|
||||||
func InitEnv() {
|
func InitEnv() {
|
||||||
if constants.EnvData.ENV_PATH == "" {
|
// get clone of current store
|
||||||
constants.EnvData.ENV_PATH = `.env`
|
envData := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||||
|
|
||||||
|
if envData[constants.EnvKeyEnv] == nil || envData[constants.EnvKeyEnv] == "" {
|
||||||
|
envData[constants.EnvKeyEnv] = os.Getenv("ENV")
|
||||||
|
if envData[constants.EnvKeyEnv] == "" {
|
||||||
|
envData[constants.EnvKeyEnv] = "production"
|
||||||
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeyEnv] == "production" {
|
||||||
|
envData[constants.EnvKeyIsProd] = true
|
||||||
|
os.Setenv("GIN_MODE", "release")
|
||||||
|
} else {
|
||||||
|
envData[constants.EnvKeyIsProd] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set authorizer url to empty string so that fresh url is obtained with every server start
|
||||||
|
envData[constants.EnvKeyAuthorizerURL] = ""
|
||||||
|
if envData[constants.EnvKeyAppURL] == nil || envData[constants.EnvKeyAppURL] == "" {
|
||||||
|
envData[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeyEnvPath] == nil || envData[constants.EnvKeyEnvPath].(string) == "" {
|
||||||
|
envData[constants.EnvKeyEnvPath] = `.env`
|
||||||
}
|
}
|
||||||
|
|
||||||
if ARG_ENV_FILE != nil && *ARG_ENV_FILE != "" {
|
if ARG_ENV_FILE != nil && *ARG_ENV_FILE != "" {
|
||||||
constants.EnvData.ENV_PATH = *ARG_ENV_FILE
|
envData[constants.EnvKeyEnvPath] = *ARG_ENV_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
err := godotenv.Load(constants.EnvData.ENV_PATH)
|
err := godotenv.Load(envData[constants.EnvKeyEnvPath].(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error loading %s file", constants.EnvData.ENV_PATH)
|
log.Printf("error loading %s file", envData[constants.EnvKeyEnvPath])
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.ADMIN_SECRET == "" {
|
if envData[constants.EnvKeyPort] == nil || envData[constants.EnvKeyPort].(string) == "" {
|
||||||
constants.EnvData.ADMIN_SECRET = os.Getenv("ADMIN_SECRET")
|
envData[constants.EnvKeyPort] = os.Getenv("PORT")
|
||||||
|
if envData[constants.EnvKeyPort].(string) == "" {
|
||||||
|
envData[constants.EnvKeyPort] = "8080"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DATABASE_TYPE == "" {
|
if envData[constants.EnvKeyAdminSecret] == nil || envData[constants.EnvKeyAdminSecret].(string) == "" {
|
||||||
constants.EnvData.DATABASE_TYPE = os.Getenv("DATABASE_TYPE")
|
envData[constants.EnvKeyAdminSecret] = os.Getenv("ADMIN_SECRET")
|
||||||
log.Println(constants.EnvData.DATABASE_TYPE)
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeyDatabaseType] == nil || envData[constants.EnvKeyDatabaseType].(string) == "" {
|
||||||
|
envData[constants.EnvKeyDatabaseType] = os.Getenv("DATABASE_TYPE")
|
||||||
|
log.Println(envData[constants.EnvKeyDatabaseType].(string))
|
||||||
|
|
||||||
if ARG_DB_TYPE != nil && *ARG_DB_TYPE != "" {
|
if ARG_DB_TYPE != nil && *ARG_DB_TYPE != "" {
|
||||||
constants.EnvData.DATABASE_TYPE = *ARG_DB_TYPE
|
envData[constants.EnvKeyDatabaseType] = *ARG_DB_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DATABASE_TYPE == "" {
|
if envData[constants.EnvKeyDatabaseType].(string) == "" {
|
||||||
panic("DATABASE_TYPE is required")
|
panic("DATABASE_TYPE is required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DATABASE_URL == "" {
|
if envData[constants.EnvKeyDatabaseURL] == nil || envData[constants.EnvKeyDatabaseURL].(string) == "" {
|
||||||
constants.EnvData.DATABASE_URL = os.Getenv("DATABASE_URL")
|
envData[constants.EnvKeyDatabaseURL] = os.Getenv("DATABASE_URL")
|
||||||
|
|
||||||
if ARG_DB_URL != nil && *ARG_DB_URL != "" {
|
if ARG_DB_URL != nil && *ARG_DB_URL != "" {
|
||||||
constants.EnvData.DATABASE_URL = *ARG_DB_URL
|
envData[constants.EnvKeyDatabaseURL] = *ARG_DB_URL
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DATABASE_URL == "" {
|
if envData[constants.EnvKeyDatabaseURL] == "" {
|
||||||
panic("DATABASE_URL is required")
|
panic("DATABASE_URL is required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DATABASE_NAME == "" {
|
if envData[constants.EnvKeyDatabaseName] == nil || envData[constants.EnvKeyDatabaseName].(string) == "" {
|
||||||
constants.EnvData.DATABASE_NAME = os.Getenv("DATABASE_NAME")
|
envData[constants.EnvKeyDatabaseName] = os.Getenv("DATABASE_NAME")
|
||||||
if constants.EnvData.DATABASE_NAME == "" {
|
if envData[constants.EnvKeyDatabaseName].(string) == "" {
|
||||||
constants.EnvData.DATABASE_NAME = "authorizer"
|
envData[constants.EnvKeyDatabaseName] = "authorizer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.ENV == "" {
|
if envData[constants.EnvKeySmtpHost] == nil || envData[constants.EnvKeySmtpHost].(string) == "" {
|
||||||
constants.EnvData.ENV = os.Getenv("ENV")
|
envData[constants.EnvKeySmtpHost] = os.Getenv("SMTP_HOST")
|
||||||
if constants.EnvData.ENV == "" {
|
|
||||||
constants.EnvData.ENV = "production"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.ENV == "production" {
|
if envData[constants.EnvKeySmtpPort] == nil || envData[constants.EnvKeySmtpPort].(string) == "" {
|
||||||
constants.EnvData.IS_PROD = true
|
envData[constants.EnvKeySmtpPort] = os.Getenv("SMTP_PORT")
|
||||||
os.Setenv("GIN_MODE", "release")
|
}
|
||||||
} else {
|
|
||||||
constants.EnvData.IS_PROD = false
|
if envData[constants.EnvKeySmtpUsername] == nil || envData[constants.EnvKeySmtpUsername].(string) == "" {
|
||||||
|
envData[constants.EnvKeySmtpUsername] = os.Getenv("SMTP_USERNAME")
|
||||||
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeySmtpPassword] == nil || envData[constants.EnvKeySmtpPassword].(string) == "" {
|
||||||
|
envData[constants.EnvKeySmtpPassword] = os.Getenv("SMTP_PASSWORD")
|
||||||
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeySenderEmail] == nil || envData[constants.EnvKeySenderEmail].(string) == "" {
|
||||||
|
envData[constants.EnvKeySenderEmail] = os.Getenv("SENDER_EMAIL")
|
||||||
|
}
|
||||||
|
|
||||||
|
if envData[constants.EnvKeyJwtSecret] == nil || envData[constants.EnvKeyJwtSecret].(string) == "" {
|
||||||
|
envData[constants.EnvKeyJwtSecret] = os.Getenv("JWT_SECRET")
|
||||||
|
if envData[constants.EnvKeyJwtSecret].(string) == "" {
|
||||||
|
envData[constants.EnvKeyJwtSecret] = uuid.New().String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.SMTP_HOST == "" {
|
if envData[constants.EnvKeyJwtType] == nil || envData[constants.EnvKeyJwtType].(string) == "" {
|
||||||
constants.EnvData.SMTP_HOST = os.Getenv("SMTP_HOST")
|
envData[constants.EnvKeyJwtType] = os.Getenv("JWT_TYPE")
|
||||||
}
|
if envData[constants.EnvKeyJwtType].(string) == "" {
|
||||||
|
envData[constants.EnvKeyJwtType] = "HS256"
|
||||||
if constants.EnvData.SMTP_PORT == "" {
|
|
||||||
constants.EnvData.SMTP_PORT = os.Getenv("SMTP_PORT")
|
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.SMTP_USERNAME == "" {
|
|
||||||
constants.EnvData.SMTP_USERNAME = os.Getenv("SMTP_USERNAME")
|
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.SMTP_PASSWORD == "" {
|
|
||||||
constants.EnvData.SMTP_PASSWORD = os.Getenv("SMTP_PASSWORD")
|
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.SENDER_EMAIL == "" {
|
|
||||||
constants.EnvData.SENDER_EMAIL = os.Getenv("SENDER_EMAIL")
|
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.JWT_SECRET == "" {
|
|
||||||
constants.EnvData.JWT_SECRET = os.Getenv("JWT_SECRET")
|
|
||||||
if constants.EnvData.JWT_SECRET == "" {
|
|
||||||
constants.EnvData.JWT_SECRET = uuid.New().String()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.JWT_TYPE == "" {
|
if envData[constants.EnvKeyJwtRoleClaim] == nil || envData[constants.EnvKeyJwtRoleClaim].(string) == "" {
|
||||||
constants.EnvData.JWT_TYPE = os.Getenv("JWT_TYPE")
|
envData[constants.EnvKeyJwtRoleClaim] = os.Getenv("JWT_ROLE_CLAIM")
|
||||||
if constants.EnvData.JWT_TYPE == "" {
|
|
||||||
constants.EnvData.JWT_TYPE = "HS256"
|
if envData[constants.EnvKeyJwtRoleClaim].(string) == "" {
|
||||||
|
envData[constants.EnvKeyJwtRoleClaim] = "role"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.JWT_ROLE_CLAIM == "" {
|
if envData[constants.EnvKeyRedisURL] == nil || envData[constants.EnvKeyRedisURL].(string) == "" {
|
||||||
constants.EnvData.JWT_ROLE_CLAIM = os.Getenv("JWT_ROLE_CLAIM")
|
envData[constants.EnvKeyRedisURL] = os.Getenv("REDIS_URL")
|
||||||
|
}
|
||||||
|
|
||||||
if constants.EnvData.JWT_ROLE_CLAIM == "" {
|
if envData[constants.EnvKeyCookieName] == nil || envData[constants.EnvKeyCookieName].(string) == "" {
|
||||||
constants.EnvData.JWT_ROLE_CLAIM = "role"
|
envData[constants.EnvKeyCookieName] = os.Getenv("COOKIE_NAME")
|
||||||
|
if envData[constants.EnvKeyCookieName].(string) == "" {
|
||||||
|
envData[constants.EnvKeyCookieName] = "authorizer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.AUTHORIZER_URL == "" {
|
if envData[constants.EnvKeyGoogleClientID] == nil || envData[constants.EnvKeyGoogleClientID].(string) == "" {
|
||||||
constants.EnvData.AUTHORIZER_URL = strings.TrimSuffix(os.Getenv("AUTHORIZER_URL"), "/")
|
envData[constants.EnvKeyGoogleClientID] = os.Getenv("GOOGLE_CLIENT_ID")
|
||||||
|
|
||||||
if ARG_AUTHORIZER_URL != nil && *ARG_AUTHORIZER_URL != "" {
|
|
||||||
constants.EnvData.AUTHORIZER_URL = *ARG_AUTHORIZER_URL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.PORT == "" {
|
if envData[constants.EnvKeyGoogleClientSecret] == nil || envData[constants.EnvKeyGoogleClientSecret].(string) == "" {
|
||||||
constants.EnvData.PORT = os.Getenv("PORT")
|
envData[constants.EnvKeyGoogleClientSecret] = os.Getenv("GOOGLE_CLIENT_SECRET")
|
||||||
if constants.EnvData.PORT == "" {
|
|
||||||
constants.EnvData.PORT = "8080"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.REDIS_URL == "" {
|
if envData[constants.EnvKeyGithubClientID] == nil || envData[constants.EnvKeyGithubClientID].(string) == "" {
|
||||||
constants.EnvData.REDIS_URL = os.Getenv("REDIS_URL")
|
envData[constants.EnvKeyGithubClientID] = os.Getenv("GITHUB_CLIENT_ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.COOKIE_NAME == "" {
|
if envData[constants.EnvKeyGithubClientSecret] == nil || envData[constants.EnvKeyGithubClientSecret].(string) == "" {
|
||||||
constants.EnvData.COOKIE_NAME = os.Getenv("COOKIE_NAME")
|
envData[constants.EnvKeyGithubClientSecret] = os.Getenv("GITHUB_CLIENT_SECRET")
|
||||||
if constants.EnvData.COOKIE_NAME == "" {
|
|
||||||
constants.EnvData.COOKIE_NAME = "authorizer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.GOOGLE_CLIENT_ID == "" {
|
if envData[constants.EnvKeyFacebookClientID] == nil || envData[constants.EnvKeyFacebookClientID].(string) == "" {
|
||||||
constants.EnvData.GOOGLE_CLIENT_ID = os.Getenv("GOOGLE_CLIENT_ID")
|
envData[constants.EnvKeyFacebookClientID] = os.Getenv("FACEBOOK_CLIENT_ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.GOOGLE_CLIENT_SECRET == "" {
|
if envData[constants.EnvKeyFacebookClientSecret] == nil || envData[constants.EnvKeyFacebookClientSecret].(string) == "" {
|
||||||
constants.EnvData.GOOGLE_CLIENT_SECRET = os.Getenv("GOOGLE_CLIENT_SECRET")
|
envData[constants.EnvKeyFacebookClientSecret] = os.Getenv("FACEBOOK_CLIENT_SECRET")
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.GITHUB_CLIENT_ID == "" {
|
if envData[constants.EnvKeyResetPasswordURL] == nil || envData[constants.EnvKeyResetPasswordURL].(string) == "" {
|
||||||
constants.EnvData.GITHUB_CLIENT_ID = os.Getenv("GITHUB_CLIENT_ID")
|
envData[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(os.Getenv("RESET_PASSWORD_URL"), "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.GITHUB_CLIENT_SECRET == "" {
|
envData[constants.EnvKeyDisableBasicAuthentication] = os.Getenv("DISABLE_BASIC_AUTHENTICATION") == "true"
|
||||||
constants.EnvData.GITHUB_CLIENT_SECRET = os.Getenv("GITHUB_CLIENT_SECRET")
|
envData[constants.EnvKeyDisableEmailVerification] = os.Getenv("DISABLE_EMAIL_VERIFICATION") == "true"
|
||||||
|
envData[constants.EnvKeyDisableMagicLinkLogin] = os.Getenv("DISABLE_MAGIC_LINK_LOGIN") == "true"
|
||||||
|
envData[constants.EnvKeyDisableLoginPage] = os.Getenv("DISABLE_LOGIN_PAGE") == "true"
|
||||||
|
|
||||||
|
// no need to add nil check as its already done above
|
||||||
|
if envData[constants.EnvKeySmtpHost].(string) == "" || envData[constants.EnvKeySmtpUsername].(string) == "" || envData[constants.EnvKeySmtpPassword].(string) == "" || envData[constants.EnvKeySenderEmail].(string) == "" {
|
||||||
|
envData[constants.EnvKeyDisableEmailVerification] = true
|
||||||
|
envData[constants.EnvKeyDisableMagicLinkLogin] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.FACEBOOK_CLIENT_ID == "" {
|
if envData[constants.EnvKeyDisableEmailVerification].(bool) {
|
||||||
constants.EnvData.FACEBOOK_CLIENT_ID = os.Getenv("FACEBOOK_CLIENT_ID")
|
envData[constants.EnvKeyDisableMagicLinkLogin] = true
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.FACEBOOK_CLIENT_SECRET == "" {
|
|
||||||
constants.EnvData.FACEBOOK_CLIENT_SECRET = os.Getenv("FACEBOOK_CLIENT_SECRET")
|
|
||||||
}
|
|
||||||
|
|
||||||
if constants.EnvData.RESET_PASSWORD_URL == "" {
|
|
||||||
constants.EnvData.RESET_PASSWORD_URL = strings.TrimPrefix(os.Getenv("RESET_PASSWORD_URL"), "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
constants.EnvData.DISABLE_BASIC_AUTHENTICATION = os.Getenv("DISABLE_BASIC_AUTHENTICATION") == "true"
|
|
||||||
constants.EnvData.DISABLE_EMAIL_VERIFICATION = os.Getenv("DISABLE_EMAIL_VERIFICATION") == "true"
|
|
||||||
constants.EnvData.DISABLE_MAGIC_LINK_LOGIN = os.Getenv("DISABLE_MAGIC_LINK_LOGIN") == "true"
|
|
||||||
constants.EnvData.DISABLE_LOGIN_PAGE = os.Getenv("DISABLE_LOGIN_PAGE") == "true"
|
|
||||||
|
|
||||||
if constants.EnvData.SMTP_HOST == "" || constants.EnvData.SMTP_USERNAME == "" || constants.EnvData.SMTP_PASSWORD == "" || constants.EnvData.SENDER_EMAIL == "" {
|
|
||||||
constants.EnvData.DISABLE_EMAIL_VERIFICATION = true
|
|
||||||
constants.EnvData.DISABLE_MAGIC_LINK_LOGIN = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allowedOriginsSplit := strings.Split(os.Getenv("ALLOWED_ORIGINS"), ",")
|
allowedOriginsSplit := strings.Split(os.Getenv("ALLOWED_ORIGINS"), ",")
|
||||||
|
@ -216,11 +225,7 @@ func InitEnv() {
|
||||||
allowedOrigins = []string{"*"}
|
allowedOrigins = []string{"*"}
|
||||||
}
|
}
|
||||||
|
|
||||||
constants.EnvData.ALLOWED_ORIGINS = allowedOrigins
|
envData[constants.EnvKeyAllowedOrigins] = allowedOrigins
|
||||||
|
|
||||||
if constants.EnvData.DISABLE_EMAIL_VERIFICATION {
|
|
||||||
constants.EnvData.DISABLE_MAGIC_LINK_LOGIN = true
|
|
||||||
}
|
|
||||||
|
|
||||||
rolesEnv := strings.TrimSpace(os.Getenv("ROLES"))
|
rolesEnv := strings.TrimSpace(os.Getenv("ROLES"))
|
||||||
rolesSplit := strings.Split(rolesEnv, ",")
|
rolesSplit := strings.Split(rolesEnv, ",")
|
||||||
|
@ -263,15 +268,17 @@ func InitEnv() {
|
||||||
panic(`Invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
panic(`Invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
||||||
}
|
}
|
||||||
|
|
||||||
constants.EnvData.ROLES = roles
|
envData[constants.EnvKeyRoles] = roles
|
||||||
constants.EnvData.DEFAULT_ROLES = defaultRoles
|
envData[constants.EnvKeyDefaultRoles] = defaultRoles
|
||||||
constants.EnvData.PROTECTED_ROLES = protectedRoles
|
envData[constants.EnvKeyProtectedRoles] = protectedRoles
|
||||||
|
|
||||||
if os.Getenv("ORGANIZATION_NAME") != "" {
|
if os.Getenv("ORGANIZATION_NAME") != "" {
|
||||||
constants.EnvData.ORGANIZATION_NAME = os.Getenv("ORGANIZATION_NAME")
|
envData[constants.EnvKeyOrganizationName] = os.Getenv("ORGANIZATION_NAME")
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("ORGANIZATION_LOGO") != "" {
|
if os.Getenv("ORGANIZATION_LOGO") != "" {
|
||||||
constants.EnvData.ORGANIZATION_LOGO = os.Getenv("ORGANIZATION_LOGO")
|
envData[constants.EnvKeyOrganizationLogo] = os.Getenv("ORGANIZATION_LOGO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvStore(envData)
|
||||||
}
|
}
|
||||||
|
|
11
server/env/persist_env.go
vendored
11
server/env/persist_env.go
vendored
|
@ -9,20 +9,22 @@ import (
|
||||||
|
|
||||||
"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/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PersistEnv persists the environment variables to the database
|
||||||
func PersistEnv() error {
|
func PersistEnv() error {
|
||||||
config, err := db.Mgr.GetConfig()
|
config, err := db.Mgr.GetConfig()
|
||||||
// config not found in db
|
// config not found in db
|
||||||
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]
|
||||||
constants.EnvData.ENCRYPTION_KEY = hash
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash)
|
||||||
encodedHash := utils.EncryptB64(hash)
|
encodedHash := utils.EncryptB64(hash)
|
||||||
|
|
||||||
configData, err := json.Marshal(constants.EnvData)
|
configData, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -45,7 +47,8 @@ func PersistEnv() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
constants.EnvData.ENCRYPTION_KEY = decryptedEncryptionKey
|
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
|
||||||
decryptedConfigs, err := utils.DecryptAES(config.Config)
|
decryptedConfigs, err := utils.DecryptAES(config.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -119,7 +122,7 @@ func PersistEnv() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasChanged {
|
if hasChanged {
|
||||||
encryptedConfig, err := utils.EncryptConfig(jsonData)
|
encryptedConfig, err := utils.EncryptEnvData(jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
65
server/envstore/store.go
Normal file
65
server/envstore/store.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package envstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnvInMemoryStore struct
|
||||||
|
type EnvInMemoryStore struct {
|
||||||
|
mutex sync.Mutex
|
||||||
|
store map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvInMemoryStoreObj global variable for EnvInMemoryStore
|
||||||
|
var EnvInMemoryStoreObj = &EnvInMemoryStore{
|
||||||
|
store: map[string]interface{}{
|
||||||
|
constants.EnvKeyAdminCookieName: "authorizer-admin",
|
||||||
|
constants.EnvKeyJwtRoleClaim: "role",
|
||||||
|
constants.EnvKeyOrganizationName: "Authorizer",
|
||||||
|
constants.EnvKeyOrganizationLogo: "https://www.authorizer.io/images/logo.png",
|
||||||
|
constants.EnvKeyDisableBasicAuthentication: false,
|
||||||
|
constants.EnvKeyDisableMagicLinkLogin: false,
|
||||||
|
constants.EnvKeyDisableEmailVerification: false,
|
||||||
|
constants.EnvKeyDisableLoginPage: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEnvStore to update the whole env store object
|
||||||
|
func (e *EnvInMemoryStore) UpdateEnvStore(data map[string]interface{}) {
|
||||||
|
e.mutex.Lock()
|
||||||
|
defer e.mutex.Unlock()
|
||||||
|
// just override the keys + new keys
|
||||||
|
for key, value := range data {
|
||||||
|
e.store[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateEnvVariable to update the particular env variable
|
||||||
|
func (e *EnvInMemoryStore) UpdateEnvVariable(key string, value interface{}) map[string]interface{} {
|
||||||
|
e.mutex.Lock()
|
||||||
|
defer e.mutex.Unlock()
|
||||||
|
e.store[key] = value
|
||||||
|
return e.store
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnvStore to get the env variable from env store object
|
||||||
|
func (e *EnvInMemoryStore) GetEnvVariable(key string) interface{} {
|
||||||
|
// e.mutex.Lock()
|
||||||
|
// defer e.mutex.Unlock()
|
||||||
|
return e.store[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnvStoreClone to get clone of current env store object
|
||||||
|
func (e *EnvInMemoryStore) GetEnvStoreClone() map[string]interface{} {
|
||||||
|
e.mutex.Lock()
|
||||||
|
defer e.mutex.Unlock()
|
||||||
|
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
for key, value := range e.store {
|
||||||
|
result[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
|
@ -1182,6 +1182,7 @@ input UpdateProfileInput {
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
email: String
|
email: String
|
||||||
|
email_verified: Boolean
|
||||||
given_name: String
|
given_name: String
|
||||||
family_name: String
|
family_name: String
|
||||||
middle_name: String
|
middle_name: String
|
||||||
|
@ -6646,6 +6647,14 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "email_verified":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email_verified"))
|
||||||
|
it.EmailVerified, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
case "given_name":
|
case "given_name":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,7 @@ type UpdateProfileInput struct {
|
||||||
type UpdateUserInput struct {
|
type UpdateUserInput struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Email *string `json:"email"`
|
Email *string `json:"email"`
|
||||||
|
EmailVerified *bool `json:"email_verified"`
|
||||||
GivenName *string `json:"given_name"`
|
GivenName *string `json:"given_name"`
|
||||||
FamilyName *string `json:"family_name"`
|
FamilyName *string `json:"family_name"`
|
||||||
MiddleName *string `json:"middle_name"`
|
MiddleName *string `json:"middle_name"`
|
||||||
|
|
|
@ -189,6 +189,7 @@ input UpdateProfileInput {
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
email: String
|
email: String
|
||||||
|
email_verified: Boolean
|
||||||
given_name: String
|
given_name: String
|
||||||
family_name: String
|
family_name: String
|
||||||
middle_name: String
|
middle_name: String
|
||||||
|
|
|
@ -12,47 +12,47 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
||||||
return resolvers.Signup(ctx, params)
|
return resolvers.SignupResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
func (r *mutationResolver) Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
||||||
return resolvers.Login(ctx, params)
|
return resolvers.LoginResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
func (r *mutationResolver) MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
||||||
return resolvers.MagicLinkLogin(ctx, params)
|
return resolvers.MagicLinkLoginResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error) {
|
func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error) {
|
||||||
return resolvers.Logout(ctx)
|
return resolvers.LogoutResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
func (r *mutationResolver) UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||||
return resolvers.UpdateProfile(ctx, params)
|
return resolvers.UpdateProfileResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
func (r *mutationResolver) VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
||||||
return resolvers.VerifyEmail(ctx, params)
|
return resolvers.VerifyEmailResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
func (r *mutationResolver) ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
||||||
return resolvers.ResendVerifyEmail(ctx, params)
|
return resolvers.ResendVerifyEmailResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
func (r *mutationResolver) ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
||||||
return resolvers.ForgotPassword(ctx, params)
|
return resolvers.ForgotPasswordResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
func (r *mutationResolver) ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
||||||
return resolvers.ResetPassword(ctx, params)
|
return resolvers.ResetPasswordResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
||||||
return resolvers.DeleteUser(ctx, params)
|
return resolvers.DeleteUserResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
func (r *mutationResolver) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
||||||
return resolvers.UpdateUser(ctx, params)
|
return resolvers.UpdateUserResolver(ctx, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
|
func (r *mutationResolver) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
|
||||||
|
@ -64,7 +64,7 @@ func (r *mutationResolver) AdminLogin(ctx context.Context, params model.AdminLog
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) AdminLogout(ctx context.Context) (*model.Response, error) {
|
func (r *mutationResolver) AdminLogout(ctx context.Context) (*model.Response, error) {
|
||||||
return resolvers.AdminLogout(ctx)
|
return resolvers.AdminLogoutResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) UpdateConfig(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) {
|
func (r *mutationResolver) UpdateConfig(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) {
|
||||||
|
@ -72,27 +72,27 @@ func (r *mutationResolver) UpdateConfig(ctx context.Context, params model.Update
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) {
|
func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) {
|
||||||
return resolvers.Meta(ctx)
|
return resolvers.MetaResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
func (r *queryResolver) Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
||||||
return resolvers.Session(ctx, roles)
|
return resolvers.SessionResolver(ctx, roles)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Profile(ctx context.Context) (*model.User, error) {
|
func (r *queryResolver) Profile(ctx context.Context) (*model.User, error) {
|
||||||
return resolvers.Profile(ctx)
|
return resolvers.ProfileResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
|
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
|
||||||
return resolvers.Users(ctx)
|
return resolvers.UsersResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error) {
|
func (r *queryResolver) VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error) {
|
||||||
return resolvers.VerificationRequests(ctx)
|
return resolvers.VerificationRequestsResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) AdminSession(ctx context.Context) (*model.Response, error) {
|
func (r *queryResolver) AdminSession(ctx context.Context) (*model.Response, error) {
|
||||||
return resolvers.AdminSession(ctx)
|
return resolvers.AdminSessionResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Config(ctx context.Context) (*model.Config, error) {
|
func (r *queryResolver) Config(ctx context.Context) (*model.Config, error) {
|
||||||
|
@ -105,5 +105,7 @@ func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResol
|
||||||
// Query returns generated.QueryResolver implementation.
|
// Query returns generated.QueryResolver implementation.
|
||||||
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
||||||
|
|
||||||
type mutationResolver struct{ *Resolver }
|
type (
|
||||||
type queryResolver struct{ *Resolver }
|
mutationResolver struct{ *Resolver }
|
||||||
|
queryResolver struct{ *Resolver }
|
||||||
|
)
|
||||||
|
|
|
@ -7,15 +7,19 @@ import (
|
||||||
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// State is the struct that holds authorizer url and redirect url
|
||||||
|
// They are provided via query string in the request
|
||||||
type State struct {
|
type State struct {
|
||||||
AuthorizerURL string `json:"authorizerURL"`
|
AuthorizerURL string `json:"authorizerURL"`
|
||||||
RedirectURL string `json:"redirectURL"`
|
RedirectURL string `json:"redirectURL"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
state := c.Query("state")
|
state := c.Query("state")
|
||||||
|
@ -23,14 +27,8 @@ func AppHandler() gin.HandlerFunc {
|
||||||
var stateObj State
|
var stateObj State
|
||||||
|
|
||||||
if state == "" {
|
if state == "" {
|
||||||
// cookie, err := utils.GetAuthToken(c)
|
stateObj.AuthorizerURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string)
|
||||||
// if err != nil {
|
stateObj.RedirectURL = stateObj.AuthorizerURL + "/app"
|
||||||
// c.JSON(400, gin.H{"error": "invalid state"})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
stateObj.AuthorizerURL = constants.EnvData.AUTHORIZER_URL
|
|
||||||
stateObj.RedirectURL = constants.EnvData.AUTHORIZER_URL + "/app"
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
decodedState, err := utils.DecryptB64(state)
|
decodedState, err := utils.DecryptB64(state)
|
||||||
|
@ -59,7 +57,7 @@ func AppHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate host and domain of authorizer url
|
// validate host and domain of authorizer url
|
||||||
if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != constants.EnvData.AUTHORIZER_URL {
|
if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) {
|
||||||
c.JSON(400, gin.H{"error": "invalid host url"})
|
c.JSON(400, gin.H{"error": "invalid host url"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -76,8 +74,8 @@ func AppHandler() gin.HandlerFunc {
|
||||||
"data": map[string]string{
|
"data": map[string]string{
|
||||||
"authorizerURL": stateObj.AuthorizerURL,
|
"authorizerURL": stateObj.AuthorizerURL,
|
||||||
"redirectURL": stateObj.RedirectURL,
|
"redirectURL": stateObj.RedirectURL,
|
||||||
"organizationName": constants.EnvData.ORGANIZATION_NAME,
|
"organizationName": envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationName).(string),
|
||||||
"organizationLogo": constants.EnvData.ORGANIZATION_LOGO,
|
"organizationLogo": envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyOrganizationLogo).(string),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,16 @@ 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/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DashboardHandler is the handler for the /dashboard route
|
||||||
func DashboardHandler() gin.HandlerFunc {
|
func DashboardHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
isOnboardingCompleted := false
|
isOnboardingCompleted := false
|
||||||
|
|
||||||
if constants.EnvData.ADMIN_SECRET != "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret) != nil && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string) != "" {
|
||||||
isOnboardingCompleted = true
|
isOnboardingCompleted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Defining the Graphql handler
|
// GraphqlHandler is the main handler that handels all the graphql requests
|
||||||
func GraphqlHandler() gin.HandlerFunc {
|
func GraphqlHandler() gin.HandlerFunc {
|
||||||
// NewExecutableSchema and Config are in the generated.go file
|
// NewExecutableSchema and Config are in the generated.go file
|
||||||
// Resolver is in the resolver.go file
|
// Resolver is in the resolver.go file
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/oauth"
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
@ -21,6 +21,131 @@ import (
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OAuthCallbackHandler handles the OAuth callback for various oauth providers
|
||||||
|
func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
provider := c.Param("oauth_provider")
|
||||||
|
state := c.Request.FormValue("state")
|
||||||
|
|
||||||
|
sessionState := session.GetSocailLoginState(state)
|
||||||
|
if sessionState == "" {
|
||||||
|
c.JSON(400, gin.H{"error": "invalid oauth state"})
|
||||||
|
}
|
||||||
|
session.RemoveSocialLoginState(state)
|
||||||
|
// contains random token, redirect url, role
|
||||||
|
sessionSplit := strings.Split(state, "___")
|
||||||
|
|
||||||
|
// TODO validate redirect url
|
||||||
|
if len(sessionSplit) < 2 {
|
||||||
|
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inputRoles := strings.Split(sessionSplit[2], ",")
|
||||||
|
redirectURL := sessionSplit[1]
|
||||||
|
|
||||||
|
var err error
|
||||||
|
user := db.User{}
|
||||||
|
code := c.Request.FormValue("code")
|
||||||
|
switch provider {
|
||||||
|
case constants.SignupMethodGoogle:
|
||||||
|
user, err = processGoogleUserInfo(code)
|
||||||
|
case constants.SignupMethodGithub:
|
||||||
|
user, err = processGithubUserInfo(code)
|
||||||
|
case constants.SignupMethodFacebook:
|
||||||
|
user, err = processFacebookUserInfo(code)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf(`invalid oauth provider`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
existingUser, err := db.Mgr.GetUserByEmail(user.Email)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// user not registered, register user and generate session token
|
||||||
|
user.SignupMethods = provider
|
||||||
|
// make sure inputRoles don't include protected roles
|
||||||
|
hasProtectedRole := false
|
||||||
|
for _, ir := range inputRoles {
|
||||||
|
if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ir) {
|
||||||
|
hasProtectedRole = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasProtectedRole {
|
||||||
|
c.JSON(400, gin.H{"error": "invalid role"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user.Roles = strings.Join(inputRoles, ",")
|
||||||
|
now := time.Now().Unix()
|
||||||
|
user.EmailVerifiedAt = &now
|
||||||
|
user, _ = db.Mgr.AddUser(user)
|
||||||
|
} else {
|
||||||
|
// user exists in db, check if method was google
|
||||||
|
// if not append google to existing signup method and save it
|
||||||
|
|
||||||
|
signupMethod := existingUser.SignupMethods
|
||||||
|
if !strings.Contains(signupMethod, provider) {
|
||||||
|
signupMethod = signupMethod + "," + provider
|
||||||
|
}
|
||||||
|
user.SignupMethods = signupMethod
|
||||||
|
user.Password = existingUser.Password
|
||||||
|
|
||||||
|
// There multiple scenarios with roles here in social login
|
||||||
|
// 1. user has access to protected roles + roles and trying to login
|
||||||
|
// 2. user has not signed up for one of the available role but trying to signup.
|
||||||
|
// Need to modify roles in this case
|
||||||
|
|
||||||
|
// find the unassigned roles
|
||||||
|
existingRoles := strings.Split(existingUser.Roles, ",")
|
||||||
|
unasignedRoles := []string{}
|
||||||
|
for _, ir := range inputRoles {
|
||||||
|
if !utils.StringSliceContains(existingRoles, ir) {
|
||||||
|
unasignedRoles = append(unasignedRoles, ir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(unasignedRoles) > 0 {
|
||||||
|
// check if it contains protected unassigned role
|
||||||
|
hasProtectedRole := false
|
||||||
|
for _, ur := range unasignedRoles {
|
||||||
|
if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ur) {
|
||||||
|
hasProtectedRole = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasProtectedRole {
|
||||||
|
c.JSON(400, gin.H{"error": "invalid role"})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
user.Roles = existingUser.Roles
|
||||||
|
}
|
||||||
|
user.Key = existingUser.Key
|
||||||
|
user.ID = existingUser.ID
|
||||||
|
user, err = db.Mgr.UpdateUser(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, _ = db.Mgr.GetUserByEmail(user.Email)
|
||||||
|
userIdStr := fmt.Sprintf("%v", user.ID)
|
||||||
|
refreshToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeRefreshToken, inputRoles)
|
||||||
|
|
||||||
|
accessToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeAccessToken, inputRoles)
|
||||||
|
utils.SetCookie(c, accessToken)
|
||||||
|
session.SetUserSession(userIdStr, accessToken, refreshToken)
|
||||||
|
utils.SaveSessionInDB(user.ID, c)
|
||||||
|
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func processGoogleUserInfo(code string) (db.User, error) {
|
func processGoogleUserInfo(code string) (db.User, error) {
|
||||||
user := db.User{}
|
user := db.User{}
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -145,127 +270,3 @@ func processFacebookUserInfo(code string) (db.User, error) {
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func OAuthCallbackHandler() gin.HandlerFunc {
|
|
||||||
return func(c *gin.Context) {
|
|
||||||
provider := c.Param("oauth_provider")
|
|
||||||
state := c.Request.FormValue("state")
|
|
||||||
|
|
||||||
sessionState := session.GetSocailLoginState(state)
|
|
||||||
if sessionState == "" {
|
|
||||||
c.JSON(400, gin.H{"error": "invalid oauth state"})
|
|
||||||
}
|
|
||||||
session.RemoveSocialLoginState(state)
|
|
||||||
// contains random token, redirect url, role
|
|
||||||
sessionSplit := strings.Split(state, "___")
|
|
||||||
|
|
||||||
// TODO validate redirect url
|
|
||||||
if len(sessionSplit) < 2 {
|
|
||||||
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
inputRoles := strings.Split(sessionSplit[2], ",")
|
|
||||||
redirectURL := sessionSplit[1]
|
|
||||||
|
|
||||||
var err error
|
|
||||||
user := db.User{}
|
|
||||||
code := c.Request.FormValue("code")
|
|
||||||
switch provider {
|
|
||||||
case enum.Google.String():
|
|
||||||
user, err = processGoogleUserInfo(code)
|
|
||||||
case enum.Github.String():
|
|
||||||
user, err = processGithubUserInfo(code)
|
|
||||||
case enum.Facebook.String():
|
|
||||||
user, err = processFacebookUserInfo(code)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf(`invalid oauth provider`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(400, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
existingUser, err := db.Mgr.GetUserByEmail(user.Email)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// user not registered, register user and generate session token
|
|
||||||
user.SignupMethods = provider
|
|
||||||
// make sure inputRoles don't include protected roles
|
|
||||||
hasProtectedRole := false
|
|
||||||
for _, ir := range inputRoles {
|
|
||||||
if utils.StringSliceContains(constants.EnvData.PROTECTED_ROLES, ir) {
|
|
||||||
hasProtectedRole = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasProtectedRole {
|
|
||||||
c.JSON(400, gin.H{"error": "invalid role"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
user.Roles = strings.Join(inputRoles, ",")
|
|
||||||
now := time.Now().Unix()
|
|
||||||
user.EmailVerifiedAt = &now
|
|
||||||
user, _ = db.Mgr.AddUser(user)
|
|
||||||
} else {
|
|
||||||
// user exists in db, check if method was google
|
|
||||||
// if not append google to existing signup method and save it
|
|
||||||
|
|
||||||
signupMethod := existingUser.SignupMethods
|
|
||||||
if !strings.Contains(signupMethod, provider) {
|
|
||||||
signupMethod = signupMethod + "," + provider
|
|
||||||
}
|
|
||||||
user.SignupMethods = signupMethod
|
|
||||||
user.Password = existingUser.Password
|
|
||||||
|
|
||||||
// There multiple scenarios with roles here in social login
|
|
||||||
// 1. user has access to protected roles + roles and trying to login
|
|
||||||
// 2. user has not signed up for one of the available role but trying to signup.
|
|
||||||
// Need to modify roles in this case
|
|
||||||
|
|
||||||
// find the unassigned roles
|
|
||||||
existingRoles := strings.Split(existingUser.Roles, ",")
|
|
||||||
unasignedRoles := []string{}
|
|
||||||
for _, ir := range inputRoles {
|
|
||||||
if !utils.StringSliceContains(existingRoles, ir) {
|
|
||||||
unasignedRoles = append(unasignedRoles, ir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(unasignedRoles) > 0 {
|
|
||||||
// check if it contains protected unassigned role
|
|
||||||
hasProtectedRole := false
|
|
||||||
for _, ur := range unasignedRoles {
|
|
||||||
if utils.StringSliceContains(constants.EnvData.PROTECTED_ROLES, ur) {
|
|
||||||
hasProtectedRole = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasProtectedRole {
|
|
||||||
c.JSON(400, gin.H{"error": "invalid role"})
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
user.Roles = existingUser.Roles
|
|
||||||
}
|
|
||||||
user.Key = existingUser.Key
|
|
||||||
user.ID = existingUser.ID
|
|
||||||
user, err = db.Mgr.UpdateUser(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
user, _ = db.Mgr.GetUserByEmail(user.Email)
|
|
||||||
userIdStr := fmt.Sprintf("%v", user.ID)
|
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, inputRoles)
|
|
||||||
|
|
||||||
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, inputRoles)
|
|
||||||
utils.SetCookie(c, accessToken)
|
|
||||||
session.SetToken(userIdStr, accessToken, refreshToken)
|
|
||||||
utils.CreateSession(user.ID, c)
|
|
||||||
|
|
||||||
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/oauth"
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
@ -13,8 +13,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// set host in the oauth state that is useful for redirecting
|
// 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) {
|
||||||
// TODO validate redirect URL
|
// TODO validate redirect URL
|
||||||
|
@ -34,14 +33,14 @@ 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(append([]string{}, append(constants.EnvData.ROLES, constants.EnvData.PROTECTED_ROLES...)...), rolesSplit) {
|
if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string)...)...), rolesSplit) {
|
||||||
c.JSON(400, gin.H{
|
c.JSON(400, gin.H{
|
||||||
"error": "invalid role",
|
"error": "invalid role",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
roles = strings.Join(constants.EnvData.DEFAULT_ROLES, ",")
|
roles = strings.Join(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid := uuid.New()
|
uuid := uuid.New()
|
||||||
|
@ -50,32 +49,32 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
provider := c.Param("oauth_provider")
|
provider := c.Param("oauth_provider")
|
||||||
isProviderConfigured := true
|
isProviderConfigured := true
|
||||||
switch provider {
|
switch provider {
|
||||||
case enum.Google.String():
|
case constants.SignupMethodGoogle:
|
||||||
if oauth.OAuthProviders.GoogleConfig == nil {
|
if oauth.OAuthProviders.GoogleConfig == nil {
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
session.SetSocailLoginState(oauthStateString, enum.Google.String())
|
session.SetSocailLoginState(oauthStateString, constants.SignupMethodGoogle)
|
||||||
// during the init of OAuthProvider authorizer url might be empty
|
// during the init of OAuthProvider authorizer url might be empty
|
||||||
oauth.OAuthProviders.GoogleConfig.RedirectURL = constants.EnvData.AUTHORIZER_URL + "/oauth_callback/google"
|
oauth.OAuthProviders.GoogleConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/google"
|
||||||
url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
case enum.Github.String():
|
case constants.SignupMethodGithub:
|
||||||
if oauth.OAuthProviders.GithubConfig == nil {
|
if oauth.OAuthProviders.GithubConfig == nil {
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
session.SetSocailLoginState(oauthStateString, enum.Github.String())
|
session.SetSocailLoginState(oauthStateString, constants.SignupMethodGithub)
|
||||||
oauth.OAuthProviders.GithubConfig.RedirectURL = constants.EnvData.AUTHORIZER_URL + "/oauth_callback/github"
|
oauth.OAuthProviders.GithubConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/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)
|
||||||
case enum.Facebook.String():
|
case constants.SignupMethodFacebook:
|
||||||
if oauth.OAuthProviders.FacebookConfig == nil {
|
if oauth.OAuthProviders.FacebookConfig == nil {
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
session.SetSocailLoginState(oauthStateString, enum.Facebook.String())
|
session.SetSocailLoginState(oauthStateString, constants.SignupMethodFacebook)
|
||||||
oauth.OAuthProviders.FacebookConfig.RedirectURL = constants.EnvData.AUTHORIZER_URL + "/oauth_callback/facebook"
|
oauth.OAuthProviders.FacebookConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/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)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PlaygroundHandler is the handler for the /playground route
|
||||||
func PlaygroundHandler() gin.HandlerFunc {
|
func PlaygroundHandler() gin.HandlerFunc {
|
||||||
h := playground.Handler("GraphQL", "/graphql")
|
h := playground.Handler("GraphQL", "/graphql")
|
||||||
|
|
||||||
|
|
14
server/handlers/root.go
Normal file
14
server/handlers/root.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RootHandler is the handler for / root route.
|
||||||
|
func RootHandler() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, "/dashboard")
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VerifyEmailHandler handles the verify email route.
|
||||||
|
// It verifies email based on JWT token in query string
|
||||||
func VerifyEmailHandler() gin.HandlerFunc {
|
func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
errorRes := gin.H{
|
errorRes := gin.H{
|
||||||
|
@ -54,12 +56,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
db.Mgr.DeleteVerificationRequest(verificationRequest)
|
db.Mgr.DeleteVerificationRequest(verificationRequest)
|
||||||
|
|
||||||
roles := strings.Split(user.Roles, ",")
|
roles := strings.Split(user.Roles, ",")
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, roles)
|
refreshToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeRefreshToken, roles)
|
||||||
|
|
||||||
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
|
accessToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeAccessToken, roles)
|
||||||
|
|
||||||
session.SetToken(user.ID, accessToken, refreshToken)
|
session.SetUserSession(user.ID, accessToken, refreshToken)
|
||||||
utils.CreateSession(user.ID, c)
|
utils.SaveSessionInDB(user.ID, c)
|
||||||
utils.SetCookie(c, accessToken)
|
utils.SetCookie(c, accessToken)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, claim.RedirectURL)
|
c.Redirect(http.StatusTemporaryRedirect, claim.RedirectURL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,10 @@ import (
|
||||||
"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/handlers"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/oauth"
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
"github.com/authorizerdev/authorizer/server/router"
|
"github.com/authorizerdev/authorizer/server/routes"
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var VERSION string
|
var VERSION string
|
||||||
|
@ -18,11 +17,10 @@ var VERSION string
|
||||||
func main() {
|
func main() {
|
||||||
env.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
env.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
||||||
env.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
env.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
||||||
env.ARG_AUTHORIZER_URL = flag.String("authorizer_url", "", "URL for authorizer instance, eg: https://xyz.herokuapp.com")
|
|
||||||
env.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
env.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
constants.EnvData.VERSION = VERSION
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyVersion, VERSION)
|
||||||
|
|
||||||
env.InitEnv()
|
env.InitEnv()
|
||||||
db.InitDB()
|
db.InitDB()
|
||||||
|
@ -30,27 +28,8 @@ func main() {
|
||||||
|
|
||||||
session.InitSession()
|
session.InitSession()
|
||||||
oauth.InitOAuth()
|
oauth.InitOAuth()
|
||||||
utils.InitServer()
|
|
||||||
|
|
||||||
router := router.InitRouter()
|
router := routes.InitRouter()
|
||||||
|
|
||||||
router.LoadHTMLGlob("templates/*")
|
router.Run(":" + envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyPort).(string))
|
||||||
// login page app related routes.
|
|
||||||
// if we put them in router file then tests would fail as templates or build path will be different
|
|
||||||
if !constants.EnvData.DISABLE_LOGIN_PAGE {
|
|
||||||
app := router.Group("/app")
|
|
||||||
{
|
|
||||||
app.Static("/build", "app/build")
|
|
||||||
app.GET("/", handlers.AppHandler())
|
|
||||||
app.GET("/reset-password", handlers.AppHandler())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app := router.Group("/dashboard")
|
|
||||||
{
|
|
||||||
app.Static("/build", "dashboard/build")
|
|
||||||
app.GET("/", handlers.DashboardHandler())
|
|
||||||
}
|
|
||||||
|
|
||||||
router.Run(":" + constants.EnvData.PORT)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,19 @@ package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/gin-contrib/location"
|
"github.com/gin-contrib/location"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GinContextToContextMiddleware is a middleware to add gin context in context
|
||||||
func GinContextToContextMiddleware() gin.HandlerFunc {
|
func GinContextToContextMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
if constants.EnvData.AUTHORIZER_URL == "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) == "" {
|
||||||
url := location.Get(c)
|
url := location.Get(c)
|
||||||
constants.EnvData.AUTHORIZER_URL = url.Scheme + "://" + c.Request.Host
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAuthorizerURL, url.Scheme+"://"+c.Request.Host)
|
||||||
log.Println("authorizer url:", constants.EnvData.AUTHORIZER_URL)
|
|
||||||
}
|
}
|
||||||
ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
|
ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
|
||||||
c.Request = c.Request.WithContext(ctx)
|
c.Request = c.Request.WithContext(ctx)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CORSMiddleware is a middleware to add cors headers
|
||||||
func CORSMiddleware() gin.HandlerFunc {
|
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")
|
||||||
|
|
|
@ -5,56 +5,62 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
facebookOAuth2 "golang.org/x/oauth2/facebook"
|
facebookOAuth2 "golang.org/x/oauth2/facebook"
|
||||||
githubOAuth2 "golang.org/x/oauth2/github"
|
githubOAuth2 "golang.org/x/oauth2/github"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OAuthProviders is a struct that contains reference all the OAuth providers
|
||||||
type OAuthProvider struct {
|
type OAuthProvider struct {
|
||||||
GoogleConfig *oauth2.Config
|
GoogleConfig *oauth2.Config
|
||||||
GithubConfig *oauth2.Config
|
GithubConfig *oauth2.Config
|
||||||
FacebookConfig *oauth2.Config
|
FacebookConfig *oauth2.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OIDCProviders is a struct that contains reference all the OpenID providers
|
||||||
type OIDCProvider struct {
|
type OIDCProvider struct {
|
||||||
GoogleOIDC *oidc.Provider
|
GoogleOIDC *oidc.Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// OAuthProviders is a global variable that contains instance for all enabled the OAuth providers
|
||||||
OAuthProviders OAuthProvider
|
OAuthProviders OAuthProvider
|
||||||
|
// OIDCProviders is a global variable that contains instance for all enabled the OpenID providers
|
||||||
OIDCProviders OIDCProvider
|
OIDCProviders OIDCProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// InitOAuth initializes the OAuth providers based on EnvData
|
||||||
func InitOAuth() {
|
func InitOAuth() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if constants.EnvData.GOOGLE_CLIENT_ID != "" && constants.EnvData.GOOGLE_CLIENT_SECRET != "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientSecret).(string) != "" {
|
||||||
p, err := oidc.NewProvider(ctx, "https://accounts.google.com")
|
p, err := oidc.NewProvider(ctx, "https://accounts.google.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("error creating oidc provider for google:", err)
|
log.Fatalln("error creating oidc provider for google:", err)
|
||||||
}
|
}
|
||||||
OIDCProviders.GoogleOIDC = p
|
OIDCProviders.GoogleOIDC = p
|
||||||
OAuthProviders.GoogleConfig = &oauth2.Config{
|
OAuthProviders.GoogleConfig = &oauth2.Config{
|
||||||
ClientID: constants.EnvData.GOOGLE_CLIENT_ID,
|
ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string),
|
||||||
ClientSecret: constants.EnvData.GOOGLE_CLIENT_SECRET,
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientSecret).(string),
|
||||||
RedirectURL: constants.EnvData.AUTHORIZER_URL + "/oauth_callback/google",
|
RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/google",
|
||||||
Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
|
Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
|
||||||
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constants.EnvData.GITHUB_CLIENT_ID != "" && constants.EnvData.GITHUB_CLIENT_SECRET != "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientSecret).(string) != "" {
|
||||||
OAuthProviders.GithubConfig = &oauth2.Config{
|
OAuthProviders.GithubConfig = &oauth2.Config{
|
||||||
ClientID: constants.EnvData.GITHUB_CLIENT_ID,
|
ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientID).(string),
|
||||||
ClientSecret: constants.EnvData.GITHUB_CLIENT_SECRET,
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGithubClientSecret).(string),
|
||||||
RedirectURL: constants.EnvData.AUTHORIZER_URL + "/oauth_callback/github",
|
RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/github",
|
||||||
Endpoint: githubOAuth2.Endpoint,
|
Endpoint: githubOAuth2.Endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constants.EnvData.FACEBOOK_CLIENT_ID != "" && constants.EnvData.FACEBOOK_CLIENT_SECRET != "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientID).(string) != "" && envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyGoogleClientID).(string) != "" {
|
||||||
OAuthProviders.FacebookConfig = &oauth2.Config{
|
OAuthProviders.FacebookConfig = &oauth2.Config{
|
||||||
ClientID: constants.EnvData.FACEBOOK_CLIENT_ID,
|
ClientID: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientID).(string),
|
||||||
ClientSecret: constants.EnvData.FACEBOOK_CLIENT_SECRET,
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyFacebookClientSecret).(string),
|
||||||
RedirectURL: constants.EnvData.AUTHORIZER_URL + "/oauth_callback/facebook",
|
RedirectURL: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAuthorizerURL).(string) + "/oauth_callback/facebook",
|
||||||
Endpoint: facebookOAuth2.Endpoint,
|
Endpoint: facebookOAuth2.Endpoint,
|
||||||
Scopes: []string{"public_profile", "email"},
|
Scopes: []string{"public_profile", "email"},
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AdminLoginResolver is a resolver for admin login mutation
|
||||||
func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) {
|
func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
@ -17,11 +19,12 @@ func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*mod
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.AdminSecret != constants.EnvData.ADMIN_SECRET {
|
adminSecret := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)
|
||||||
|
if params.AdminSecret != adminSecret {
|
||||||
return res, fmt.Errorf(`invalid admin secret`)
|
return res, fmt.Errorf(`invalid admin secret`)
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedKey, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
hashedKey, err := utils.EncryptPassword(adminSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AdminLogout(ctx context.Context) (*model.Response, error) {
|
// AdminLogoutResolver is a resolver for admin logout mutation
|
||||||
|
func AdminLogoutResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AdminSession(ctx context.Context) (*model.Response, error) {
|
// AdminSessionResolver is a resolver for admin session query
|
||||||
|
func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
@ -21,7 +23,7 @@ func AdminSession(ctx context.Context) (*model.Response, error) {
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedKey, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,12 @@ import (
|
||||||
|
|
||||||
"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/envstore"
|
||||||
"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/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AdminSignupResolver is a resolver for admin signup mutation
|
||||||
func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
|
func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
@ -30,17 +32,18 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.ADMIN_SECRET != "" {
|
adminSecret := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string)
|
||||||
|
|
||||||
|
if adminSecret != "" {
|
||||||
err = fmt.Errorf("admin sign up already completed")
|
err = fmt.Errorf("admin sign up already completed")
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
constants.EnvData.ADMIN_SECRET = params.AdminSecret
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret)
|
||||||
|
|
||||||
// consvert EnvData to JSON
|
// consvert EnvData to JSON
|
||||||
var jsonData map[string]interface{}
|
var jsonData map[string]interface{}
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(constants.EnvData)
|
jsonBytes, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -54,7 +57,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
configData, err := utils.EncryptConfig(jsonData)
|
configData, err := utils.EncryptEnvData(jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -64,7 +67,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedKey, err := utils.HashPassword(params.AdminSecret)
|
hashedKey, err := utils.EncryptPassword(params.AdminSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO rename to env_data
|
||||||
|
|
||||||
|
// ConfigResolver is a resolver for config query
|
||||||
|
// This is admin only query
|
||||||
func ConfigResolver(ctx context.Context) (*model.Config, error) {
|
func ConfigResolver(ctx context.Context) (*model.Config, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Config
|
var res *model.Config
|
||||||
|
@ -21,40 +26,76 @@ func ConfigResolver(ctx context.Context) (*model.Config, error) {
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get clone of store
|
||||||
|
store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||||
|
adminSecret := store[constants.EnvKeyAdminSecret].(string)
|
||||||
|
databaseType := store[constants.EnvKeyDatabaseType].(string)
|
||||||
|
databaseURL := store[constants.EnvKeyDatabaseURL].(string)
|
||||||
|
databaseName := store[constants.EnvKeyDatabaseName].(string)
|
||||||
|
smtpHost := store[constants.EnvKeySmtpHost].(string)
|
||||||
|
smtpPort := store[constants.EnvKeySmtpPort].(string)
|
||||||
|
smtpUsername := store[constants.EnvKeySmtpUsername].(string)
|
||||||
|
smtpPassword := store[constants.EnvKeySmtpPassword].(string)
|
||||||
|
senderEmail := store[constants.EnvKeySenderEmail].(string)
|
||||||
|
jwtType := store[constants.EnvKeyJwtType].(string)
|
||||||
|
jwtSecret := store[constants.EnvKeyJwtSecret].(string)
|
||||||
|
jwtRoleClaim := store[constants.EnvKeyJwtRoleClaim].(string)
|
||||||
|
allowedOrigins := store[constants.EnvKeyAllowedOrigins].([]string)
|
||||||
|
authorizerURL := store[constants.EnvKeyAuthorizerURL].(string)
|
||||||
|
appURL := store[constants.EnvKeyAppURL].(string)
|
||||||
|
redisURL := store[constants.EnvKeyRedisURL].(string)
|
||||||
|
cookieName := store[constants.EnvKeyCookieName].(string)
|
||||||
|
resetPasswordURL := store[constants.EnvKeyResetPasswordURL].(string)
|
||||||
|
disableEmailVerification := store[constants.EnvKeyDisableEmailVerification].(bool)
|
||||||
|
disableBasicAuthentication := store[constants.EnvKeyDisableBasicAuthentication].(bool)
|
||||||
|
disableMagicLinkLogin := store[constants.EnvKeyDisableMagicLinkLogin].(bool)
|
||||||
|
disableLoginPage := store[constants.EnvKeyDisableLoginPage].(bool)
|
||||||
|
roles := store[constants.EnvKeyRoles].([]string)
|
||||||
|
defaultRoles := store[constants.EnvKeyDefaultRoles].([]string)
|
||||||
|
protectedRoles := store[constants.EnvKeyProtectedRoles].([]string)
|
||||||
|
googleClientID := store[constants.EnvKeyGoogleClientID].(string)
|
||||||
|
googleClientSecret := store[constants.EnvKeyGoogleClientSecret].(string)
|
||||||
|
facebookClientID := store[constants.EnvKeyFacebookClientID].(string)
|
||||||
|
facebookClientSecret := store[constants.EnvKeyFacebookClientSecret].(string)
|
||||||
|
githubClientID := store[constants.EnvKeyGithubClientID].(string)
|
||||||
|
githubClientSecret := store[constants.EnvKeyGithubClientSecret].(string)
|
||||||
|
organizationName := store[constants.EnvKeyOrganizationName].(string)
|
||||||
|
organizationLogo := store[constants.EnvKeyOrganizationLogo].(string)
|
||||||
|
|
||||||
res = &model.Config{
|
res = &model.Config{
|
||||||
AdminSecret: &constants.EnvData.ADMIN_SECRET,
|
AdminSecret: &adminSecret,
|
||||||
DatabaseType: &constants.EnvData.DATABASE_TYPE,
|
DatabaseType: &databaseType,
|
||||||
DatabaseURL: &constants.EnvData.DATABASE_URL,
|
DatabaseURL: &databaseURL,
|
||||||
DatabaseName: &constants.EnvData.DATABASE_NAME,
|
DatabaseName: &databaseName,
|
||||||
SMTPHost: &constants.EnvData.SMTP_HOST,
|
SMTPHost: &smtpHost,
|
||||||
SMTPPort: &constants.EnvData.SMTP_PORT,
|
SMTPPort: &smtpPort,
|
||||||
SMTPPassword: &constants.EnvData.SMTP_PASSWORD,
|
SMTPPassword: &smtpPassword,
|
||||||
SMTPUsername: &constants.EnvData.SMTP_USERNAME,
|
SMTPUsername: &smtpUsername,
|
||||||
SenderEmail: &constants.EnvData.SENDER_EMAIL,
|
SenderEmail: &senderEmail,
|
||||||
JwtType: &constants.EnvData.JWT_TYPE,
|
JwtType: &jwtType,
|
||||||
JwtSecret: &constants.EnvData.JWT_SECRET,
|
JwtSecret: &jwtSecret,
|
||||||
AllowedOrigins: constants.EnvData.ALLOWED_ORIGINS,
|
JwtRoleClaim: &jwtRoleClaim,
|
||||||
AuthorizerURL: &constants.EnvData.AUTHORIZER_URL,
|
AllowedOrigins: allowedOrigins,
|
||||||
AppURL: &constants.EnvData.APP_URL,
|
AuthorizerURL: &authorizerURL,
|
||||||
RedisURL: &constants.EnvData.REDIS_URL,
|
AppURL: &appURL,
|
||||||
CookieName: &constants.EnvData.COOKIE_NAME,
|
RedisURL: &redisURL,
|
||||||
ResetPasswordURL: &constants.EnvData.RESET_PASSWORD_URL,
|
CookieName: &cookieName,
|
||||||
DisableEmailVerification: &constants.EnvData.DISABLE_EMAIL_VERIFICATION,
|
ResetPasswordURL: &resetPasswordURL,
|
||||||
DisableBasicAuthentication: &constants.EnvData.DISABLE_BASIC_AUTHENTICATION,
|
DisableEmailVerification: &disableEmailVerification,
|
||||||
DisableMagicLinkLogin: &constants.EnvData.DISABLE_MAGIC_LINK_LOGIN,
|
DisableBasicAuthentication: &disableBasicAuthentication,
|
||||||
DisableLoginPage: &constants.EnvData.DISABLE_LOGIN_PAGE,
|
DisableMagicLinkLogin: &disableMagicLinkLogin,
|
||||||
Roles: constants.EnvData.ROLES,
|
DisableLoginPage: &disableLoginPage,
|
||||||
ProtectedRoles: constants.EnvData.PROTECTED_ROLES,
|
Roles: roles,
|
||||||
DefaultRoles: constants.EnvData.DEFAULT_ROLES,
|
ProtectedRoles: protectedRoles,
|
||||||
JwtRoleClaim: &constants.EnvData.JWT_ROLE_CLAIM,
|
DefaultRoles: defaultRoles,
|
||||||
GoogleClientID: &constants.EnvData.GOOGLE_CLIENT_ID,
|
GoogleClientID: &googleClientID,
|
||||||
GoogleClientSecret: &constants.EnvData.GOOGLE_CLIENT_SECRET,
|
GoogleClientSecret: &googleClientSecret,
|
||||||
GithubClientID: &constants.EnvData.GITHUB_CLIENT_ID,
|
GithubClientID: &githubClientID,
|
||||||
GithubClientSecret: &constants.EnvData.GITHUB_CLIENT_SECRET,
|
GithubClientSecret: &githubClientSecret,
|
||||||
FacebookClientID: &constants.EnvData.FACEBOOK_CLIENT_ID,
|
FacebookClientID: &facebookClientID,
|
||||||
FacebookClientSecret: &constants.EnvData.FACEBOOK_CLIENT_SECRET,
|
FacebookClientSecret: &facebookClientSecret,
|
||||||
OrganizationName: &constants.EnvData.ORGANIZATION_NAME,
|
OrganizationName: &organizationName,
|
||||||
OrganizationLogo: &constants.EnvData.ORGANIZATION_LOGO,
|
OrganizationLogo: &organizationLogo,
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
// DeleteUserResolver is a resolver for delete user mutation
|
||||||
|
func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,7 +28,7 @@ func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Respo
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
session.DeleteUserSession(fmt.Sprintf("%x", user.ID))
|
session.DeleteAllUserSession(fmt.Sprintf("%x", user.ID))
|
||||||
|
|
||||||
err = db.Mgr.DeleteUser(user)
|
err = db.Mgr.DeleteUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,18 +9,20 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
// ForgotPasswordResolver is a resolver for forgot password mutation
|
||||||
|
func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
if constants.EnvData.DISABLE_BASIC_AUTHENTICATION {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) {
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
host := gc.Request.Host
|
host := gc.Request.Host
|
||||||
|
@ -35,20 +37,20 @@ func ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*mod
|
||||||
return res, fmt.Errorf(`user with this email not found`)
|
return res, fmt.Errorf(`user with this email not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := utils.CreateVerificationToken(params.Email, enum.ForgotPassword.String())
|
token, err := utils.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
db.Mgr.AddVerification(db.VerificationRequest{
|
db.Mgr.AddVerification(db.VerificationRequest{
|
||||||
Token: token,
|
Token: token,
|
||||||
Identifier: enum.ForgotPassword.String(),
|
Identifier: constants.VerificationTypeForgotPassword,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
Email: params.Email,
|
Email: params.Email,
|
||||||
})
|
})
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendForgotPasswordMail(params.Email, token, host)
|
email.SendForgotPasswordMail(params.Email, token, host)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
|
|
|
@ -8,21 +8,22 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
// LoginResolver is a resolver for login mutation
|
||||||
|
func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DISABLE_BASIC_AUTHENTICATION {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) {
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
|
||||||
return res, fmt.Errorf(`user with this email not found`)
|
return res, fmt.Errorf(`user with this email not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(user.SignupMethods, enum.BasicAuth.String()) {
|
if !strings.Contains(user.SignupMethods, constants.SignupMethodBasicAuth) {
|
||||||
return res, fmt.Errorf(`user has not signed up email & password`)
|
return res, fmt.Errorf(`user has not signed up email & password`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
|
||||||
log.Println("compare password error:", err)
|
log.Println("compare password error:", err)
|
||||||
return res, fmt.Errorf(`invalid password`)
|
return res, fmt.Errorf(`invalid password`)
|
||||||
}
|
}
|
||||||
roles := constants.EnvData.DEFAULT_ROLES
|
roles := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
|
||||||
currentRoles := strings.Split(user.Roles, ",")
|
currentRoles := strings.Split(user.Roles, ",")
|
||||||
if len(params.Roles) > 0 {
|
if len(params.Roles) > 0 {
|
||||||
if !utils.IsValidRoles(currentRoles, params.Roles) {
|
if !utils.IsValidRoles(currentRoles, params.Roles) {
|
||||||
|
@ -55,12 +56,12 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
|
||||||
|
|
||||||
roles = params.Roles
|
roles = params.Roles
|
||||||
}
|
}
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, roles)
|
refreshToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeRefreshToken, roles)
|
||||||
|
|
||||||
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
|
accessToken, expiresAt, _ := utils.CreateAuthToken(user, constants.TokenTypeAccessToken, roles)
|
||||||
|
|
||||||
session.SetToken(user.ID, accessToken, refreshToken)
|
session.SetUserSession(user.ID, accessToken, refreshToken)
|
||||||
utils.CreateSession(user.ID, gc)
|
utils.SaveSessionInDB(user.ID, gc)
|
||||||
|
|
||||||
res = &model.AuthResponse{
|
res = &model.AuthResponse{
|
||||||
Message: `Logged in successfully`,
|
Message: `Logged in successfully`,
|
||||||
|
|
|
@ -9,7 +9,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Logout(ctx context.Context) (*model.Response, error) {
|
// LogoutResolver is a resolver for logout mutation
|
||||||
|
func LogoutResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,7 +28,7 @@ func Logout(ctx context.Context) (*model.Response, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
userId := fmt.Sprintf("%v", claim["id"])
|
userId := fmt.Sprintf("%v", claim["id"])
|
||||||
session.DeleteVerificationRequest(userId, token)
|
session.DeleteUserSession(userId, token)
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
Message: "Logged out successfully",
|
Message: "Logged out successfully",
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,17 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
// MagicLinkLoginResolver is a resolver for magic link login mutation
|
||||||
|
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
if constants.EnvData.DISABLE_MAGIC_LINK_LOGIN {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableMagicLinkLogin).(bool) {
|
||||||
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,17 +39,17 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
|
||||||
existingUser, err := db.Mgr.GetUserByEmail(params.Email)
|
existingUser, err := db.Mgr.GetUserByEmail(params.Email)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.SignupMethods = enum.MagicLinkLogin.String()
|
user.SignupMethods = constants.SignupMethodMagicLinkLogin
|
||||||
// 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(constants.EnvData.ROLES, params.Roles) {
|
if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), 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 = constants.EnvData.DEFAULT_ROLES
|
inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
user.Roles = strings.Join(inputRoles, ",")
|
user.Roles = strings.Join(inputRoles, ",")
|
||||||
|
@ -72,7 +74,7 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
|
||||||
// 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(constants.EnvData.PROTECTED_ROLES, ur) {
|
if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ur) {
|
||||||
hasProtectedRole = true
|
hasProtectedRole = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,8 +89,8 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
|
||||||
}
|
}
|
||||||
|
|
||||||
signupMethod := existingUser.SignupMethods
|
signupMethod := existingUser.SignupMethods
|
||||||
if !strings.Contains(signupMethod, enum.MagicLinkLogin.String()) {
|
if !strings.Contains(signupMethod, constants.SignupMethodMagicLinkLogin) {
|
||||||
signupMethod = signupMethod + "," + enum.MagicLinkLogin.String()
|
signupMethod = signupMethod + "," + constants.SignupMethodMagicLinkLogin
|
||||||
}
|
}
|
||||||
|
|
||||||
user.SignupMethods = signupMethod
|
user.SignupMethods = signupMethod
|
||||||
|
@ -98,9 +100,9 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !constants.EnvData.DISABLE_EMAIL_VERIFICATION {
|
if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) {
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := enum.MagicLinkLogin.String()
|
verificationType := constants.VerificationTypeMagicLinkLogin
|
||||||
token, err := utils.CreateVerificationToken(params.Email, verificationType)
|
token, err := utils.CreateVerificationToken(params.Email, verificationType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
|
@ -114,7 +116,7 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendVerificationMail(params.Email, token)
|
email.SendVerificationMail(params.Email, token)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Meta(ctx context.Context) (*model.Meta, error) {
|
// MetaResolver is a resolver for meta query
|
||||||
|
func MetaResolver(ctx context.Context) (*model.Meta, error) {
|
||||||
metaInfo := utils.GetMetaInfo()
|
metaInfo := utils.GetMetaInfo()
|
||||||
return &metaInfo, nil
|
return &metaInfo, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Profile(ctx context.Context) (*model.User, error) {
|
// ProfileResolver is a resolver for profile query
|
||||||
|
func ProfileResolver(ctx context.Context) (*model.User, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.User
|
var res *model.User
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -29,7 +30,7 @@ func Profile(ctx context.Context) (*model.User, error) {
|
||||||
|
|
||||||
userID := fmt.Sprintf("%v", claim["id"])
|
userID := fmt.Sprintf("%v", claim["id"])
|
||||||
email := fmt.Sprintf("%v", claim["email"])
|
email := fmt.Sprintf("%v", claim["email"])
|
||||||
sessionToken := session.GetToken(userID, token)
|
sessionToken := session.GetUserSession(userID, token)
|
||||||
|
|
||||||
if sessionToken == "" {
|
if sessionToken == "" {
|
||||||
return res, fmt.Errorf(`unauthorized`)
|
return res, fmt.Errorf(`unauthorized`)
|
||||||
|
|
|
@ -8,11 +8,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
|
||||||
|
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ func ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput)
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendVerificationMail(params.Email, token)
|
email.SendVerificationMail(params.Email, token)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
|
|
|
@ -8,14 +8,15 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
// ResetPasswordResolver is a resolver for reset password mutation
|
||||||
|
func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
if constants.EnvData.DISABLE_BASIC_AUTHENTICATION {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) {
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +40,12 @@ func ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
password, _ := utils.HashPassword(params.Password)
|
password, _ := utils.EncryptPassword(params.Password)
|
||||||
user.Password = &password
|
user.Password = &password
|
||||||
|
|
||||||
signupMethod := user.SignupMethods
|
signupMethod := user.SignupMethods
|
||||||
if !strings.Contains(signupMethod, enum.BasicAuth.String()) {
|
if !strings.Contains(signupMethod, constants.SignupMethodBasicAuth) {
|
||||||
signupMethod = signupMethod + "," + enum.BasicAuth.String()
|
signupMethod = signupMethod + "," + constants.SignupMethodBasicAuth
|
||||||
}
|
}
|
||||||
user.SignupMethods = signupMethod
|
user.SignupMethods = signupMethod
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
// SessionResolver is a resolver for session query
|
||||||
|
func SessionResolver(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
|
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
|
@ -36,7 +37,7 @@ func Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
||||||
|
|
||||||
userIdStr := fmt.Sprintf("%v", user.ID)
|
userIdStr := fmt.Sprintf("%v", user.ID)
|
||||||
|
|
||||||
sessionToken := session.GetToken(userIdStr, token)
|
sessionToken := session.GetUserSession(userIdStr, token)
|
||||||
|
|
||||||
if sessionToken == "" {
|
if sessionToken == "" {
|
||||||
return res, fmt.Errorf(`unauthorized`)
|
return res, fmt.Errorf(`unauthorized`)
|
||||||
|
@ -45,7 +46,7 @@ func Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
||||||
expiresTimeObj := time.Unix(expiresAt, 0)
|
expiresTimeObj := time.Unix(expiresAt, 0)
|
||||||
currentTimeObj := time.Now()
|
currentTimeObj := time.Now()
|
||||||
|
|
||||||
claimRoleInterface := claim[constants.EnvData.JWT_ROLE_CLAIM].([]interface{})
|
claimRoleInterface := claim[envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyJwtRoleClaim).(string)].([]interface{})
|
||||||
claimRoles := make([]string, len(claimRoleInterface))
|
claimRoles := make([]string, len(claimRoleInterface))
|
||||||
for i, v := range claimRoleInterface {
|
for i, v := range claimRoleInterface {
|
||||||
claimRoles[i] = v.(string)
|
claimRoles[i] = v.(string)
|
||||||
|
@ -59,14 +60,15 @@ func Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO change this logic to make it more secure
|
||||||
if accessTokenErr != nil || expiresTimeObj.Sub(currentTimeObj).Minutes() <= 5 {
|
if accessTokenErr != nil || expiresTimeObj.Sub(currentTimeObj).Minutes() <= 5 {
|
||||||
// if access token has expired and refresh/session token is valid
|
// if access token has expired and refresh/session token is valid
|
||||||
// generate new accessToken
|
// generate new accessToken
|
||||||
currentRefreshToken := session.GetToken(userIdStr, token)
|
currentRefreshToken := session.GetUserSession(userIdStr, token)
|
||||||
session.DeleteVerificationRequest(userIdStr, token)
|
session.DeleteUserSession(userIdStr, token)
|
||||||
token, expiresAt, _ = utils.CreateAuthToken(user, enum.AccessToken, claimRoles)
|
token, expiresAt, _ = utils.CreateAuthToken(user, constants.TokenTypeAccessToken, claimRoles)
|
||||||
session.SetToken(userIdStr, token, currentRefreshToken)
|
session.SetUserSession(userIdStr, token, currentRefreshToken)
|
||||||
utils.CreateSession(user.ID, gc)
|
utils.SaveSessionInDB(user.ID, gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SetCookie(gc, token)
|
utils.SetCookie(gc, token)
|
||||||
|
|
|
@ -9,20 +9,23 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
// SignupResolver is a resolver for signup mutation
|
||||||
|
func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
||||||
|
log.Println(envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if constants.EnvData.DISABLE_BASIC_AUTHENTICATION {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) {
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
if params.ConfirmPassword != params.Password {
|
if params.ConfirmPassword != params.Password {
|
||||||
|
@ -52,13 +55,13 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
|
|
||||||
if len(params.Roles) > 0 {
|
if len(params.Roles) > 0 {
|
||||||
// check if roles exists
|
// check if roles exists
|
||||||
if !utils.IsValidRoles(constants.EnvData.ROLES, params.Roles) {
|
if !utils.IsValidRoles(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), 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 = constants.EnvData.DEFAULT_ROLES
|
inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := db.User{
|
user := db.User{
|
||||||
|
@ -67,7 +70,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
|
|
||||||
user.Roles = strings.Join(inputRoles, ",")
|
user.Roles = strings.Join(inputRoles, ",")
|
||||||
|
|
||||||
password, _ := utils.HashPassword(params.Password)
|
password, _ := utils.EncryptPassword(params.Password)
|
||||||
user.Password = &password
|
user.Password = &password
|
||||||
|
|
||||||
if params.GivenName != nil {
|
if params.GivenName != nil {
|
||||||
|
@ -102,8 +105,8 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
user.Picture = params.Picture
|
user.Picture = params.Picture
|
||||||
}
|
}
|
||||||
|
|
||||||
user.SignupMethods = enum.BasicAuth.String()
|
user.SignupMethods = constants.SignupMethodBasicAuth
|
||||||
if constants.EnvData.DISABLE_EMAIL_VERIFICATION {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
user.EmailVerifiedAt = &now
|
user.EmailVerifiedAt = &now
|
||||||
}
|
}
|
||||||
|
@ -115,9 +118,9 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
roles := strings.Split(user.Roles, ",")
|
roles := strings.Split(user.Roles, ",")
|
||||||
userToReturn := utils.GetResponseUserData(user)
|
userToReturn := utils.GetResponseUserData(user)
|
||||||
|
|
||||||
if !constants.EnvData.DISABLE_EMAIL_VERIFICATION {
|
if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) {
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := enum.BasicAuthSignup.String()
|
verificationType := constants.VerificationTypeBasicAuthSignup
|
||||||
token, err := utils.CreateVerificationToken(params.Email, verificationType)
|
token, err := utils.CreateVerificationToken(params.Email, verificationType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
|
@ -131,7 +134,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendVerificationMail(params.Email, token)
|
email.SendVerificationMail(params.Email, token)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.AuthResponse{
|
res = &model.AuthResponse{
|
||||||
|
@ -140,12 +143,12 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, roles)
|
refreshToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeRefreshToken, roles)
|
||||||
|
|
||||||
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
|
accessToken, expiresAt, _ := utils.CreateAuthToken(user, constants.TokenTypeAccessToken, roles)
|
||||||
|
|
||||||
session.SetToken(userIdStr, accessToken, refreshToken)
|
session.SetUserSession(userIdStr, accessToken, refreshToken)
|
||||||
utils.CreateSession(user.ID, gc)
|
utils.SaveSessionInDB(user.ID, gc)
|
||||||
res = &model.AuthResponse{
|
res = &model.AuthResponse{
|
||||||
Message: `Signed up successfully.`,
|
Message: `Signed up successfully.`,
|
||||||
AccessToken: &accessToken,
|
AccessToken: &accessToken,
|
||||||
|
|
|
@ -9,10 +9,15 @@ import (
|
||||||
|
|
||||||
"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/envstore"
|
||||||
"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/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO rename to UpdateEnvDataResolver
|
||||||
|
|
||||||
|
// UpdateConfigResolver is a resolver for update config mutation
|
||||||
|
// This is admin only mutation
|
||||||
func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) {
|
func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
@ -57,13 +62,13 @@ func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (
|
||||||
|
|
||||||
// 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["SMTP_HOST"] == "" || updatedData["SENDER_EMAIL"] == "" || updatedData["SENDER_PASSWORD"] == "" {
|
if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySenderEmail] == "" || updatedData[constants.EnvKeySmtpPort] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" {
|
||||||
if !updatedData["DISABLE_EMAIL_VERIFICATION"].(bool) {
|
if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) {
|
||||||
updatedData["DISABLE_EMAIL_VERIFICATION"] = true
|
updatedData[constants.EnvKeyDisableEmailVerification] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !updatedData["DISABLE_MAGIC_LINK_LOGIN"].(bool) {
|
if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
|
||||||
updatedData["DISABLE_MAGIC_LINK_LOGIN"] = true
|
updatedData[constants.EnvKeyDisableMagicLinkLogin] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +77,9 @@ func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedConfig, err := utils.EncryptConfig(updatedData)
|
envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData)
|
||||||
|
|
||||||
|
encryptedConfig, err := utils.EncryptEnvData(updatedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -84,7 +91,7 @@ func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (
|
||||||
|
|
||||||
// in case of admin secret change update the cookie with new hash
|
// in case of admin secret change update the cookie with new hash
|
||||||
if params.AdminSecret != nil {
|
if params.AdminSecret != nil {
|
||||||
hashedKey, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
hashedKey, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
"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/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
// UpdateProfileResolver is resolver for update profile mutation
|
||||||
|
func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,7 +35,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
id := fmt.Sprintf("%v", claim["id"])
|
id := fmt.Sprintf("%v", claim["id"])
|
||||||
sessionToken := session.GetToken(id, token)
|
sessionToken := session.GetUserSession(id, token)
|
||||||
|
|
||||||
if sessionToken == "" {
|
if sessionToken == "" {
|
||||||
return res, fmt.Errorf(`unauthorized`)
|
return res, fmt.Errorf(`unauthorized`)
|
||||||
|
@ -44,8 +46,8 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
|
||||||
return res, fmt.Errorf("please enter atleast one param to update")
|
return res, fmt.Errorf("please enter atleast one param to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
email := fmt.Sprintf("%v", claim["email"])
|
userEmail := fmt.Sprintf("%v", claim["email"])
|
||||||
user, err := db.Mgr.GetUserByEmail(email)
|
user, err := db.Mgr.GetUserByEmail(userEmail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -99,7 +101,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
|
||||||
return res, fmt.Errorf(`password and confirm password does not match`)
|
return res, fmt.Errorf(`password and confirm password does not match`)
|
||||||
}
|
}
|
||||||
|
|
||||||
password, _ := utils.HashPassword(*params.NewPassword)
|
password, _ := utils.EncryptPassword(*params.NewPassword)
|
||||||
|
|
||||||
user.Password = &password
|
user.Password = &password
|
||||||
}
|
}
|
||||||
|
@ -120,14 +122,14 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
|
||||||
return res, fmt.Errorf("user with this email address already exists")
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
|
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
||||||
utils.DeleteCookie(gc)
|
utils.DeleteCookie(gc)
|
||||||
|
|
||||||
user.Email = newEmail
|
user.Email = newEmail
|
||||||
user.EmailVerifiedAt = nil
|
user.EmailVerifiedAt = nil
|
||||||
hasEmailChanged = true
|
hasEmailChanged = true
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := enum.UpdateEmail.String()
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
token, err := utils.CreateVerificationToken(newEmail, verificationType)
|
token, err := utils.CreateVerificationToken(newEmail, verificationType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
|
@ -141,7 +143,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendVerificationMail(newEmail, token)
|
email.SendVerificationMail(newEmail, token)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,16 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
// UpdateUserResolver is a resolver for update user mutation
|
||||||
|
// This is admin only mutation
|
||||||
|
func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.User
|
var res *model.User
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -67,6 +70,15 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
|
||||||
user.Picture = params.Picture
|
user.Picture = params.Picture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.EmailVerified != nil {
|
||||||
|
if *params.EmailVerified {
|
||||||
|
now := time.Now().Unix()
|
||||||
|
user.EmailVerifiedAt = &now
|
||||||
|
} else {
|
||||||
|
user.EmailVerifiedAt = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 !utils.IsValidEmail(*params.Email) {
|
||||||
|
@ -80,13 +92,13 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
|
||||||
return res, fmt.Errorf("user with this email address already exists")
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
|
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
||||||
utils.DeleteCookie(gc)
|
utils.DeleteCookie(gc)
|
||||||
|
|
||||||
user.Email = newEmail
|
user.Email = newEmail
|
||||||
user.EmailVerifiedAt = nil
|
user.EmailVerifiedAt = nil
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := enum.UpdateEmail.String()
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
token, err := utils.CreateVerificationToken(newEmail, verificationType)
|
token, err := utils.CreateVerificationToken(newEmail, verificationType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
|
@ -100,7 +112,7 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
utils.SendVerificationMail(newEmail, token)
|
email.SendVerificationMail(newEmail, token)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +124,7 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
|
||||||
inputRoles = append(inputRoles, *item)
|
inputRoles = append(inputRoles, *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidRoles(append([]string{}, append(constants.EnvData.ROLES, constants.EnvData.PROTECTED_ROLES...)...), inputRoles) {
|
if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRoles).([]string), envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string)...)...), inputRoles) {
|
||||||
return res, fmt.Errorf("invalid list of roles")
|
return res, fmt.Errorf("invalid list of roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +132,7 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
|
||||||
rolesToSave = strings.Join(inputRoles, ",")
|
rolesToSave = strings.Join(inputRoles, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
|
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
||||||
utils.DeleteCookie(gc)
|
utils.DeleteCookie(gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Users(ctx context.Context) ([]*model.User, error) {
|
// UsersResolver is a resolver for users query
|
||||||
|
// This is admin only query
|
||||||
|
func UsersResolver(ctx context.Context) ([]*model.User, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res []*model.User
|
var res []*model.User
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,7 +9,9 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func VerificationRequests(ctx context.Context) ([]*model.VerificationRequest, error) {
|
// VerificationRequestsResolver is a resolver for verification requests query
|
||||||
|
// This is admin only query
|
||||||
|
func VerificationRequestsResolver(ctx context.Context) ([]*model.VerificationRequest, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res []*model.VerificationRequest
|
var res []*model.VerificationRequest
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,14 +6,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
// VerifyEmailResolver is a resolver for verify email mutation
|
||||||
|
func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -44,12 +45,11 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
|
||||||
db.Mgr.DeleteVerificationRequest(verificationRequest)
|
db.Mgr.DeleteVerificationRequest(verificationRequest)
|
||||||
|
|
||||||
roles := strings.Split(user.Roles, ",")
|
roles := strings.Split(user.Roles, ",")
|
||||||
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, roles)
|
refreshToken, _, _ := utils.CreateAuthToken(user, constants.TokenTypeRefreshToken, roles)
|
||||||
|
accessToken, expiresAt, _ := utils.CreateAuthToken(user, constants.TokenTypeAccessToken, roles)
|
||||||
|
|
||||||
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
|
session.SetUserSession(user.ID, accessToken, refreshToken)
|
||||||
|
utils.SaveSessionInDB(user.ID, gc)
|
||||||
session.SetToken(user.ID, accessToken, refreshToken)
|
|
||||||
utils.CreateSession(user.ID, gc)
|
|
||||||
|
|
||||||
res = &model.AuthResponse{
|
res = &model.AuthResponse{
|
||||||
Message: `Email verified successfully.`,
|
Message: `Email verified successfully.`,
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package router
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/authorizerdev/authorizer/server/handlers"
|
|
||||||
"github.com/authorizerdev/authorizer/server/middlewares"
|
|
||||||
"github.com/gin-contrib/location"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitRouter() *gin.Engine {
|
|
||||||
router := gin.Default()
|
|
||||||
router.Use(location.Default())
|
|
||||||
router.Use(middlewares.GinContextToContextMiddleware())
|
|
||||||
router.Use(middlewares.CORSMiddleware())
|
|
||||||
|
|
||||||
router.GET("/", handlers.PlaygroundHandler())
|
|
||||||
router.POST("/graphql", handlers.GraphqlHandler())
|
|
||||||
router.GET("/verify_email", handlers.VerifyEmailHandler())
|
|
||||||
router.GET("/oauth_login/:oauth_provider", handlers.OAuthLoginHandler())
|
|
||||||
router.GET("/oauth_callback/:oauth_provider", handlers.OAuthCallbackHandler())
|
|
||||||
|
|
||||||
return router
|
|
||||||
}
|
|
44
server/routes/routes.go
Normal file
44
server/routes/routes.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/handlers"
|
||||||
|
"github.com/authorizerdev/authorizer/server/middlewares"
|
||||||
|
"github.com/gin-contrib/location"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitRouter initializes gin router
|
||||||
|
func InitRouter() *gin.Engine {
|
||||||
|
router := gin.Default()
|
||||||
|
router.Use(location.Default())
|
||||||
|
router.Use(middlewares.GinContextToContextMiddleware())
|
||||||
|
router.Use(middlewares.CORSMiddleware())
|
||||||
|
|
||||||
|
router.GET("/", handlers.RootHandler())
|
||||||
|
router.POST("/graphql", handlers.GraphqlHandler())
|
||||||
|
router.GET("/playground", handlers.PlaygroundHandler())
|
||||||
|
router.GET("/oauth_login/:oauth_provider", handlers.OAuthLoginHandler())
|
||||||
|
router.GET("/oauth_callback/:oauth_provider", handlers.OAuthCallbackHandler())
|
||||||
|
router.GET("/verify_email", handlers.VerifyEmailHandler())
|
||||||
|
|
||||||
|
router.LoadHTMLGlob("templates/*")
|
||||||
|
// login page app related routes.
|
||||||
|
if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableLoginPage).(bool) {
|
||||||
|
app := router.Group("/app")
|
||||||
|
{
|
||||||
|
app.Static("/build", "app/build")
|
||||||
|
app.GET("/", handlers.AppHandler())
|
||||||
|
app.GET("/reset-password", handlers.AppHandler())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dashboard related routes
|
||||||
|
app := router.Group("/dashboard")
|
||||||
|
{
|
||||||
|
app.Static("/build", "dashboard/build")
|
||||||
|
app.GET("/", handlers.DashboardHandler())
|
||||||
|
}
|
||||||
|
return router
|
||||||
|
}
|
|
@ -4,14 +4,17 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// InMemoryStore is a simple in-memory store for sessions.
|
||||||
type InMemoryStore struct {
|
type InMemoryStore struct {
|
||||||
mu sync.Mutex
|
mutex sync.Mutex
|
||||||
store map[string]map[string]string
|
store map[string]map[string]string
|
||||||
socialLoginState map[string]string
|
socialLoginState map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryStore) AddToken(userId, accessToken, refreshToken string) {
|
// AddUserSession adds a user session to the in-memory store.
|
||||||
c.mu.Lock()
|
func (c *InMemoryStore) AddUserSession(userId, accessToken, refreshToken string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
// delete sessions > 500 // not recommended for production
|
// delete sessions > 500 // not recommended for production
|
||||||
if len(c.store) >= 500 {
|
if len(c.store) >= 500 {
|
||||||
c.store = map[string]map[string]string{}
|
c.store = map[string]map[string]string{}
|
||||||
|
@ -28,48 +31,57 @@ func (c *InMemoryStore) AddToken(userId, accessToken, refreshToken string) {
|
||||||
}
|
}
|
||||||
c.store[userId] = tempMap
|
c.store[userId] = tempMap
|
||||||
}
|
}
|
||||||
|
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryStore) DeleteUserSession(userId string) {
|
// DeleteAllUserSession deletes all the user sessions from in-memory store.
|
||||||
c.mu.Lock()
|
func (c *InMemoryStore) DeleteAllUserSession(userId string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
delete(c.store, userId)
|
delete(c.store, userId)
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryStore) DeleteVerificationRequest(userId, accessToken string) {
|
// DeleteUserSession deletes the particular user session from in-memory store.
|
||||||
c.mu.Lock()
|
func (c *InMemoryStore) DeleteUserSession(userId, accessToken string) {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
delete(c.store[userId], accessToken)
|
delete(c.store[userId], accessToken)
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearStore clears the in-memory store.
|
||||||
func (c *InMemoryStore) ClearStore() {
|
func (c *InMemoryStore) ClearStore() {
|
||||||
c.mu.Lock()
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
c.store = map[string]map[string]string{}
|
c.store = map[string]map[string]string{}
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *InMemoryStore) GetToken(userId, accessToken string) string {
|
// GetUserSession returns the user session token from the in-memory store.
|
||||||
|
func (c *InMemoryStore) GetUserSession(userId, accessToken string) string {
|
||||||
|
// c.mutex.Lock()
|
||||||
|
// defer c.mutex.Unlock()
|
||||||
|
|
||||||
token := ""
|
token := ""
|
||||||
c.mu.Lock()
|
|
||||||
if sessionMap, ok := c.store[userId]; ok {
|
if sessionMap, ok := c.store[userId]; ok {
|
||||||
if val, ok := sessionMap[accessToken]; ok {
|
if val, ok := sessionMap[accessToken]; ok {
|
||||||
token = val
|
token = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.mu.Unlock()
|
|
||||||
|
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocialLoginState sets the social login state in the in-memory store.
|
||||||
func (c *InMemoryStore) SetSocialLoginState(key, state string) {
|
func (c *InMemoryStore) SetSocialLoginState(key, state string) {
|
||||||
c.mu.Lock()
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
c.socialLoginState[key] = state
|
c.socialLoginState[key] = state
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSocialLoginState gets the social login state from the in-memory store.
|
||||||
func (c *InMemoryStore) GetSocialLoginState(key string) string {
|
func (c *InMemoryStore) GetSocialLoginState(key string) string {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
state := ""
|
state := ""
|
||||||
if stateVal, ok := c.socialLoginState[key]; ok {
|
if stateVal, ok := c.socialLoginState[key]; ok {
|
||||||
state = stateVal
|
state = stateVal
|
||||||
|
@ -78,8 +90,10 @@ func (c *InMemoryStore) GetSocialLoginState(key string) string {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveSocialLoginState removes the social login state from the in-memory store.
|
||||||
func (c *InMemoryStore) RemoveSocialLoginState(key string) {
|
func (c *InMemoryStore) RemoveSocialLoginState(key string) {
|
||||||
c.mu.Lock()
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
delete(c.socialLoginState, key)
|
delete(c.socialLoginState, key)
|
||||||
c.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ type RedisStore struct {
|
||||||
store *redis.Client
|
store *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RedisStore) AddToken(userId, accessToken, refreshToken string) {
|
// AddUserSession adds the user session to redis
|
||||||
|
func (c *RedisStore) AddUserSession(userId, accessToken, refreshToken string) {
|
||||||
err := c.store.HMSet(c.ctx, "authorizer_"+userId, map[string]string{
|
err := c.store.HMSet(c.ctx, "authorizer_"+userId, map[string]string{
|
||||||
accessToken: refreshToken,
|
accessToken: refreshToken,
|
||||||
}).Err()
|
}).Err()
|
||||||
|
@ -22,20 +23,23 @@ func (c *RedisStore) AddToken(userId, accessToken, refreshToken string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RedisStore) DeleteUserSession(userId string) {
|
// DeleteAllUserSession deletes all the user session from redis
|
||||||
|
func (c *RedisStore) DeleteAllUserSession(userId string) {
|
||||||
err := c.store.Del(c.ctx, "authorizer_"+userId).Err()
|
err := c.store.Del(c.ctx, "authorizer_"+userId).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Error deleting redis token:", err)
|
log.Fatalln("Error deleting redis token:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RedisStore) DeleteVerificationRequest(userId, accessToken string) {
|
// DeleteUserSession deletes the particular user session from redis
|
||||||
|
func (c *RedisStore) DeleteUserSession(userId, accessToken string) {
|
||||||
err := c.store.HDel(c.ctx, "authorizer_"+userId, accessToken).Err()
|
err := c.store.HDel(c.ctx, "authorizer_"+userId, accessToken).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Error deleting redis token:", err)
|
log.Fatalln("Error deleting redis token:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearStore clears the redis store for authorizer related tokens
|
||||||
func (c *RedisStore) ClearStore() {
|
func (c *RedisStore) ClearStore() {
|
||||||
err := c.store.Del(c.ctx, "authorizer_*").Err()
|
err := c.store.Del(c.ctx, "authorizer_*").Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,7 +47,8 @@ func (c *RedisStore) ClearStore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RedisStore) GetToken(userId, accessToken string) string {
|
// GetUserSession returns the user session token from the redis store.
|
||||||
|
func (c *RedisStore) GetUserSession(userId, accessToken string) string {
|
||||||
token := ""
|
token := ""
|
||||||
res, err := c.store.HMGet(c.ctx, "authorizer_"+userId, accessToken).Result()
|
res, err := c.store.HMGet(c.ctx, "authorizer_"+userId, accessToken).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -55,6 +60,7 @@ func (c *RedisStore) GetToken(userId, accessToken string) string {
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocialLoginState sets the social login state in redis store.
|
||||||
func (c *RedisStore) SetSocialLoginState(key, state string) {
|
func (c *RedisStore) SetSocialLoginState(key, state string) {
|
||||||
err := c.store.Set(c.ctx, key, state, 0).Err()
|
err := c.store.Set(c.ctx, key, state, 0).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,6 +68,7 @@ func (c *RedisStore) SetSocialLoginState(key, state string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSocialLoginState gets the social login state from redis store.
|
||||||
func (c *RedisStore) GetSocialLoginState(key string) string {
|
func (c *RedisStore) GetSocialLoginState(key string) string {
|
||||||
state := ""
|
state := ""
|
||||||
state, err := c.store.Get(c.ctx, key).Result()
|
state, err := c.store.Get(c.ctx, key).Result()
|
||||||
|
@ -72,6 +79,7 @@ func (c *RedisStore) GetSocialLoginState(key string) string {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveSocialLoginState removes the social login state from redis store.
|
||||||
func (c *RedisStore) RemoveSocialLoginState(key string) {
|
func (c *RedisStore) RemoveSocialLoginState(key string) {
|
||||||
err := c.store.Del(c.ctx, key).Err()
|
err := c.store.Del(c.ctx, key).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,57 +5,65 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/go-redis/redis/v8"
|
"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 {
|
type SessionStore struct {
|
||||||
InMemoryStoreObj *InMemoryStore
|
InMemoryStoreObj *InMemoryStore
|
||||||
RedisMemoryStoreObj *RedisStore
|
RedisMemoryStoreObj *RedisStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SessionStoreObj is a global variable that holds the
|
||||||
|
// reference to various session store instances
|
||||||
var SessionStoreObj SessionStore
|
var SessionStoreObj SessionStore
|
||||||
|
|
||||||
func SetToken(userId, accessToken, refreshToken string) {
|
// SetUserSession sets the user session in the session store
|
||||||
// TODO: Set session information in db for all the sessions that gets generated
|
func SetUserSession(userId, accessToken, refreshToken string) {
|
||||||
// it should async go function
|
|
||||||
|
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.AddToken(userId, accessToken, refreshToken)
|
SessionStoreObj.RedisMemoryStoreObj.AddUserSession(userId, accessToken, refreshToken)
|
||||||
}
|
}
|
||||||
if SessionStoreObj.InMemoryStoreObj != nil {
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
||||||
SessionStoreObj.InMemoryStoreObj.AddToken(userId, accessToken, refreshToken)
|
SessionStoreObj.InMemoryStoreObj.AddUserSession(userId, accessToken, refreshToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteVerificationRequest(userId, accessToken string) {
|
// DeleteUserSession deletes the particular user session from the session store
|
||||||
|
func DeleteUserSession(userId, accessToken string) {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.DeleteVerificationRequest(userId, accessToken)
|
SessionStoreObj.RedisMemoryStoreObj.DeleteUserSession(userId, accessToken)
|
||||||
}
|
}
|
||||||
if SessionStoreObj.InMemoryStoreObj != nil {
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
||||||
SessionStoreObj.InMemoryStoreObj.DeleteVerificationRequest(userId, accessToken)
|
SessionStoreObj.InMemoryStoreObj.DeleteUserSession(userId, accessToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteUserSession(userId string) {
|
// DeleteAllSessions deletes all the sessions from the session store
|
||||||
|
func DeleteAllUserSession(userId string) {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.DeleteUserSession(userId)
|
SessionStoreObj.RedisMemoryStoreObj.DeleteAllUserSession(userId)
|
||||||
}
|
}
|
||||||
if SessionStoreObj.InMemoryStoreObj != nil {
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
||||||
SessionStoreObj.InMemoryStoreObj.DeleteUserSession(userId)
|
SessionStoreObj.InMemoryStoreObj.DeleteAllUserSession(userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetToken(userId, accessToken string) string {
|
// GetUserSession returns the user session from the session store
|
||||||
|
func GetUserSession(userId, accessToken string) string {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
return SessionStoreObj.RedisMemoryStoreObj.GetToken(userId, accessToken)
|
return SessionStoreObj.RedisMemoryStoreObj.GetUserSession(userId, accessToken)
|
||||||
}
|
}
|
||||||
if SessionStoreObj.InMemoryStoreObj != nil {
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
||||||
return SessionStoreObj.InMemoryStoreObj.GetToken(userId, accessToken)
|
return SessionStoreObj.InMemoryStoreObj.GetUserSession(userId, accessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearStore clears the session store for authorizer tokens
|
||||||
func ClearStore() {
|
func ClearStore() {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.ClearStore()
|
SessionStoreObj.RedisMemoryStoreObj.ClearStore()
|
||||||
|
@ -65,6 +73,7 @@ func ClearStore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSocialLoginState sets the social login state in the session store
|
||||||
func SetSocailLoginState(key, state string) {
|
func SetSocailLoginState(key, state string) {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.SetSocialLoginState(key, state)
|
SessionStoreObj.RedisMemoryStoreObj.SetSocialLoginState(key, state)
|
||||||
|
@ -74,6 +83,7 @@ func SetSocailLoginState(key, state string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSocialLoginState returns the social login state from the session store
|
||||||
func GetSocailLoginState(key string) string {
|
func GetSocailLoginState(key string) string {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
return SessionStoreObj.RedisMemoryStoreObj.GetSocialLoginState(key)
|
return SessionStoreObj.RedisMemoryStoreObj.GetSocialLoginState(key)
|
||||||
|
@ -85,6 +95,7 @@ func GetSocailLoginState(key string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveSocialLoginState removes the social login state from the session store
|
||||||
func RemoveSocialLoginState(key string) {
|
func RemoveSocialLoginState(key string) {
|
||||||
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
||||||
SessionStoreObj.RedisMemoryStoreObj.RemoveSocialLoginState(key)
|
SessionStoreObj.RedisMemoryStoreObj.RemoveSocialLoginState(key)
|
||||||
|
@ -94,10 +105,11 @@ func RemoveSocialLoginState(key string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
|
||||||
func InitSession() {
|
func InitSession() {
|
||||||
if constants.EnvData.REDIS_URL != "" {
|
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRedisURL).(string) != "" {
|
||||||
log.Println("using redis store to save sessions")
|
log.Println("using redis store to save sessions")
|
||||||
opt, err := redis.ParseURL(constants.EnvData.REDIS_URL)
|
opt, err := redis.ParseURL(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyRedisURL).(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Error parsing redis url:", err)
|
log.Fatalln("Error parsing redis url:", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@ 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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func adminLoginTests(s TestSetup, t *testing.T) {
|
func adminLoginTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should complete admin login`, func(t *testing.T) {
|
t.Run(`should complete admin login`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
_, err := resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
|
_, err := resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
|
||||||
|
@ -19,7 +21,7 @@ func adminLoginTests(s TestSetup, t *testing.T) {
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
_, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
|
_, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
|
||||||
AdminSecret: constants.EnvData.ADMIN_SECRET,
|
AdminSecret: envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string),
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
28
server/test/admin_logout_test.go
Normal file
28
server/test/admin_logout_test.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func adminLogoutTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
|
t.Run(`should get admin session`, func(t *testing.T) {
|
||||||
|
req, ctx := createContext(s)
|
||||||
|
_, err := resolvers.AdminLogoutResolver(ctx)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
|
_, err = resolvers.AdminLogoutResolver(ctx)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
30
server/test/admin_session_test.go
Normal file
30
server/test/admin_session_test.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func adminSessionTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
|
t.Run(`should get admin session`, func(t *testing.T) {
|
||||||
|
req, ctx := createContext(s)
|
||||||
|
_, err := resolvers.AdminSessionResolver(ctx)
|
||||||
|
log.Println("error:", err)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
|
_, err = resolvers.AdminSessionResolver(ctx)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,26 +1,27 @@
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func adminSignupTests(s TestSetup, t *testing.T) {
|
func adminSignupTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should complete admin login`, func(t *testing.T) {
|
t.Run(`should complete admin login`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
_, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: "admin",
|
AdminSecret: "admin",
|
||||||
})
|
})
|
||||||
log.Println("err", err)
|
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
// reset env for test to pass
|
// reset env for test to pass
|
||||||
constants.EnvData.ADMIN_SECRET = ""
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAdminSecret, "")
|
||||||
|
|
||||||
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: uuid.New().String(),
|
AdminSecret: uuid.New().String(),
|
|
@ -6,24 +6,26 @@ 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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func configTests(s TestSetup, t *testing.T) {
|
func configTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should get config`, func(t *testing.T) {
|
t.Run(`should get config`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
_, err := resolvers.ConfigResolver(ctx)
|
_, err := resolvers.ConfigResolver(ctx)
|
||||||
log.Println("error:", err)
|
log.Println("error:", err)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
res, err := resolvers.ConfigResolver(ctx)
|
res, err := resolvers.ConfigResolver(ctx)
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, *res.AdminSecret, constants.EnvData.ADMIN_SECRET)
|
assert.Equal(t, *res.AdminSecret, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -5,32 +5,34 @@ 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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func deleteUserTest(s TestSetup, t *testing.T) {
|
func deleteUserTest(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should delete users with admin secret only`, func(t *testing.T) {
|
t.Run(`should delete users with admin secret only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "delete_user." + s.TestInfo.Email
|
email := "delete_user." + s.TestInfo.Email
|
||||||
resolvers.Signup(ctx, model.SignUpInput{
|
resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := resolvers.DeleteUser(ctx, model.DeleteUserInput{
|
_, err := resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
|
|
||||||
_, err = resolvers.DeleteUser(ctx, model.DeleteUserInput{
|
_, err = resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
29
server/test/env_test.go
Normal file
29
server/test/env_test.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/env"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEnvs(t *testing.T) {
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEnvPath, "../../.env.sample")
|
||||||
|
env.InitEnv()
|
||||||
|
store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||||
|
|
||||||
|
assert.Equal(t, store[constants.EnvKeyAdminSecret].(string), "admin")
|
||||||
|
assert.Equal(t, store[constants.EnvKeyEnv].(string), "production")
|
||||||
|
assert.False(t, store[constants.EnvKeyDisableEmailVerification].(bool))
|
||||||
|
assert.False(t, store[constants.EnvKeyDisableMagicLinkLogin].(bool))
|
||||||
|
assert.False(t, store[constants.EnvKeyDisableBasicAuthentication].(bool))
|
||||||
|
assert.Equal(t, store[constants.EnvKeyJwtType].(string), "HS256")
|
||||||
|
assert.Equal(t, store[constants.EnvKeyJwtSecret].(string), "random_string")
|
||||||
|
assert.Equal(t, store[constants.EnvKeyJwtRoleClaim].(string), "role")
|
||||||
|
assert.EqualValues(t, store[constants.EnvKeyRoles].([]string), []string{"user"})
|
||||||
|
assert.EqualValues(t, store[constants.EnvKeyDefaultRoles].([]string), []string{"user"})
|
||||||
|
assert.EqualValues(t, store[constants.EnvKeyProtectedRoles].([]string), []string{"admin"})
|
||||||
|
assert.EqualValues(t, store[constants.EnvKeyAllowedOrigins].([]string), []string{"*"})
|
||||||
|
}
|
|
@ -3,32 +3,33 @@ package test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func forgotPasswordTest(s TestSetup, t *testing.T) {
|
func forgotPasswordTest(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should run forgot password`, func(t *testing.T) {
|
t.Run(`should run forgot password`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "forgot_password." + s.TestInfo.Email
|
email := "forgot_password." + s.TestInfo.Email
|
||||||
_, err := resolvers.Signup(ctx, model.SignUpInput{
|
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = resolvers.ForgotPassword(ctx, model.ForgotPasswordInput{
|
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err, "no errors for forgot password")
|
assert.Nil(t, err, "no errors for forgot password")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.ForgotPassword.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, verificationRequest.Identifier, enum.ForgotPassword.String())
|
assert.Equal(t, verificationRequest.Identifier, constants.VerificationTypeForgotPassword)
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
})
|
})
|
|
@ -3,49 +3,50 @@ package test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loginTests(s TestSetup, t *testing.T) {
|
func loginTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should login`, func(t *testing.T) {
|
t.Run(`should login`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "login." + s.TestInfo.Email
|
email := "login." + s.TestInfo.Email
|
||||||
_, err := resolvers.Signup(ctx, model.SignUpInput{
|
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = resolvers.Login(ctx, model.LoginInput{
|
_, err = resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NotNil(t, err, "should fail because email is not verified")
|
assert.NotNil(t, err, "should fail because email is not verified")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = resolvers.Login(ctx, model.LoginInput{
|
_, err = resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
Roles: []string{"test"},
|
Roles: []string{"test"},
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid roles")
|
assert.NotNil(t, err, "invalid roles")
|
||||||
|
|
||||||
_, err = resolvers.Login(ctx, model.LoginInput{
|
_, err = resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password + "s",
|
Password: s.TestInfo.Password + "s",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.NotNil(t, err, "invalid password")
|
||||||
|
|
||||||
loginRes, err := resolvers.Login(ctx, model.LoginInput{
|
loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
})
|
})
|
|
@ -6,31 +6,32 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func logoutTests(s TestSetup, t *testing.T) {
|
func logoutTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should logout user`, func(t *testing.T) {
|
t.Run(`should logout user`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "logout." + s.TestInfo.Email
|
email := "logout." + s.TestInfo.Email
|
||||||
|
|
||||||
_, err := resolvers.MagicLinkLogin(ctx, model.MagicLinkLoginInput{
|
_, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.MagicLinkLogin.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeMagicLinkLogin)
|
||||||
verifyRes, err := resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
token := *verifyRes.AccessToken
|
token := *verifyRes.AccessToken
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.COOKIE_NAME, token))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token))
|
||||||
_, err = resolvers.Logout(ctx)
|
_, err = resolvers.LogoutResolver(ctx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
_, err = resolvers.Profile(ctx)
|
_, err = resolvers.ProfileResolver(ctx)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
})
|
})
|
|
@ -6,30 +6,31 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func magicLinkLoginTests(s TestSetup, t *testing.T) {
|
func magicLinkLoginTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should login with magic link`, func(t *testing.T) {
|
t.Run(`should login with magic link`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "magic_link_login." + s.TestInfo.Email
|
email := "magic_link_login." + s.TestInfo.Email
|
||||||
|
|
||||||
_, err := resolvers.MagicLinkLogin(ctx, model.MagicLinkLoginInput{
|
_, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.MagicLinkLogin.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeMagicLinkLogin)
|
||||||
verifyRes, err := resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
token := *verifyRes.AccessToken
|
token := *verifyRes.AccessToken
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.COOKIE_NAME, token))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token))
|
||||||
_, err = resolvers.Profile(ctx)
|
_, err = resolvers.ProfileResolver(ctx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
|
@ -2,18 +2,17 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func metaTests(s TestSetup, t *testing.T) {
|
func metaTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should get meta information`, func(t *testing.T) {
|
t.Run(`should get meta information`, func(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
meta, err := resolvers.Meta(ctx)
|
meta, err := resolvers.MetaResolver(ctx)
|
||||||
log.Println("=> meta:", meta)
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.False(t, meta.IsFacebookLoginEnabled)
|
assert.False(t, meta.IsFacebookLoginEnabled)
|
||||||
assert.False(t, meta.IsGoogleLoginEnabled)
|
assert.False(t, meta.IsGoogleLoginEnabled)
|
|
@ -6,34 +6,35 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func profileTests(s TestSetup, t *testing.T) {
|
func profileTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should get profile only with token`, func(t *testing.T) {
|
t.Run(`should get profile only with token`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "profile." + s.TestInfo.Email
|
email := "profile." + s.TestInfo.Email
|
||||||
|
|
||||||
resolvers.Signup(ctx, model.SignUpInput{
|
resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := resolvers.Profile(ctx)
|
_, err := resolvers.ProfileResolver(ctx)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
verifyRes, err := resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
token := *verifyRes.AccessToken
|
token := *verifyRes.AccessToken
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.COOKIE_NAME, token))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token))
|
||||||
profileRes, err := resolvers.Profile(ctx)
|
profileRes, err := resolvers.ProfileResolver(ctx)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
newEmail := *&profileRes.Email
|
newEmail := *&profileRes.Email
|
|
@ -3,25 +3,26 @@ package test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func resendVerifyEmailTests(s TestSetup, t *testing.T) {
|
func resendVerifyEmailTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should resend verification email`, func(t *testing.T) {
|
t.Run(`should resend verification email`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "resend_verify_email." + s.TestInfo.Email
|
email := "resend_verify_email." + s.TestInfo.Email
|
||||||
_, err := resolvers.Signup(ctx, model.SignUpInput{
|
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = resolvers.ResendVerifyEmail(ctx, model.ResendVerifyEmailInput{
|
_, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Identifier: enum.BasicAuthSignup.String(),
|
Identifier: constants.VerificationTypeBasicAuthSignup,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
|
@ -3,32 +3,33 @@ package test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func resetPasswordTest(s TestSetup, t *testing.T) {
|
func resetPasswordTest(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should reset password`, func(t *testing.T) {
|
t.Run(`should reset password`, func(t *testing.T) {
|
||||||
email := "reset_password." + s.TestInfo.Email
|
email := "reset_password." + s.TestInfo.Email
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
_, err := resolvers.Signup(ctx, model.SignUpInput{
|
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = resolvers.ForgotPassword(ctx, model.ForgotPasswordInput{
|
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err, "no errors for forgot password")
|
assert.Nil(t, err, "no errors for forgot password")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.ForgotPassword.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err, "should get forgot password request")
|
assert.Nil(t, err, "should get forgot password request")
|
||||||
|
|
||||||
_, err = resolvers.ResetPassword(ctx, model.ResetPasswordInput{
|
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
Password: "test1",
|
Password: "test1",
|
||||||
ConfirmPassword: "test",
|
ConfirmPassword: "test",
|
||||||
|
@ -36,7 +37,7 @@ func resetPasswordTest(s TestSetup, t *testing.T) {
|
||||||
|
|
||||||
assert.NotNil(t, err, "passowrds don't match")
|
assert.NotNil(t, err, "passowrds don't match")
|
||||||
|
|
||||||
_, err = resolvers.ResetPassword(ctx, model.ResetPasswordInput{
|
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
Password: "test1",
|
Password: "test1",
|
||||||
ConfirmPassword: "test1",
|
ConfirmPassword: "test1",
|
65
server/test/resolvers_test.go
Normal file
65
server/test/resolvers_test.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/env"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResolvers(t *testing.T) {
|
||||||
|
databases := map[string]string{
|
||||||
|
constants.DbTypeSqlite: "../../data.db",
|
||||||
|
// constants.DbTypeArangodb: "http://localhost:8529",
|
||||||
|
// constants.DbTypeMongodb: "mongodb://localhost:27017",
|
||||||
|
}
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyVersion, "test")
|
||||||
|
for dbType, dbURL := range databases {
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL)
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyDatabaseType, dbType)
|
||||||
|
|
||||||
|
env.InitEnv()
|
||||||
|
db.InitDB()
|
||||||
|
|
||||||
|
// clean the persisted config for test to use fresh config
|
||||||
|
config, err := db.Mgr.GetConfig()
|
||||||
|
if err == nil {
|
||||||
|
config.Config = []byte{}
|
||||||
|
db.Mgr.UpdateConfig(config)
|
||||||
|
}
|
||||||
|
env.PersistEnv()
|
||||||
|
|
||||||
|
s := testSetup()
|
||||||
|
defer s.Server.Close()
|
||||||
|
|
||||||
|
t.Run("should pass tests for "+dbType, func(t *testing.T) {
|
||||||
|
// admin tests
|
||||||
|
adminSignupTests(t, s)
|
||||||
|
verificationRequestsTest(t, s)
|
||||||
|
usersTest(t, s)
|
||||||
|
deleteUserTest(t, s)
|
||||||
|
updateUserTest(t, s)
|
||||||
|
adminLoginTests(t, s)
|
||||||
|
adminLogoutTests(t, s)
|
||||||
|
adminSessionTests(t, s)
|
||||||
|
updateConfigTests(t, s)
|
||||||
|
configTests(t, s)
|
||||||
|
|
||||||
|
// user tests
|
||||||
|
loginTests(t, s)
|
||||||
|
signupTests(t, s)
|
||||||
|
forgotPasswordTest(t, s)
|
||||||
|
resendVerifyEmailTests(t, s)
|
||||||
|
resetPasswordTest(t, s)
|
||||||
|
verifyEmailTest(t, s)
|
||||||
|
sessionTests(t, s)
|
||||||
|
profileTests(t, s)
|
||||||
|
updateProfileTests(t, s)
|
||||||
|
magicLinkLoginTests(t, s)
|
||||||
|
logoutTests(t, s)
|
||||||
|
metaTests(t, s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,35 +6,36 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sessionTests(s TestSetup, t *testing.T) {
|
func sessionTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should allow access to profile with session only`, func(t *testing.T) {
|
t.Run(`should allow access to profile with session only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "session." + s.TestInfo.Email
|
email := "session." + s.TestInfo.Email
|
||||||
|
|
||||||
resolvers.Signup(ctx, model.SignUpInput{
|
resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := resolvers.Session(ctx, []string{})
|
_, err := resolvers.SessionResolver(ctx, []string{})
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
verifyRes, err := resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
token := *verifyRes.AccessToken
|
token := *verifyRes.AccessToken
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.COOKIE_NAME, token))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token))
|
||||||
|
|
||||||
sessionRes, err := resolvers.Session(ctx, []string{})
|
sessionRes, err := resolvers.SessionResolver(ctx, []string{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
newToken := *sessionRes.AccessToken
|
newToken := *sessionRes.AccessToken
|
|
@ -3,25 +3,26 @@ package test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func signupTests(s TestSetup, t *testing.T) {
|
func signupTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should complete the signup and check duplicates`, func(t *testing.T) {
|
t.Run(`should complete the signup and check duplicates`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "signup." + s.TestInfo.Email
|
email := "signup." + s.TestInfo.Email
|
||||||
res, err := resolvers.Signup(ctx, model.SignUpInput{
|
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password + "s",
|
ConfirmPassword: s.TestInfo.Password + "s",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password errors")
|
assert.NotNil(t, err, "invalid password errors")
|
||||||
|
|
||||||
res, err = resolvers.Signup(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
|
@ -31,7 +32,7 @@ func signupTests(s TestSetup, t *testing.T) {
|
||||||
assert.Equal(t, email, user.Email)
|
assert.Equal(t, email, user.Email)
|
||||||
assert.Nil(t, res.AccessToken, "access token should be nil")
|
assert.Nil(t, res.AccessToken, "access token should be nil")
|
||||||
|
|
||||||
res, err = resolvers.Signup(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
|
@ -39,7 +40,7 @@ func signupTests(s TestSetup, t *testing.T) {
|
||||||
|
|
||||||
assert.NotNil(t, err, "should throw duplicate email error")
|
assert.NotNil(t, err, "should throw duplicate email error")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, email, verificationRequest.Email)
|
assert.Equal(t, email, verificationRequest.Email)
|
||||||
cleanData(email)
|
cleanData(email)
|
|
@ -9,8 +9,8 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
|
||||||
"github.com/authorizerdev/authorizer/server/env"
|
"github.com/authorizerdev/authorizer/server/env"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/handlers"
|
"github.com/authorizerdev/authorizer/server/handlers"
|
||||||
"github.com/authorizerdev/authorizer/server/middlewares"
|
"github.com/authorizerdev/authorizer/server/middlewares"
|
||||||
"github.com/authorizerdev/authorizer/server/session"
|
"github.com/authorizerdev/authorizer/server/session"
|
||||||
|
@ -32,17 +32,17 @@ type TestSetup struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanData(email string) {
|
func cleanData(email string) {
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Mgr.GetVerificationByEmail(email, enum.ForgotPassword.String())
|
verificationRequest, err = db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeForgotPassword)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Mgr.GetVerificationByEmail(email, enum.UpdateEmail.String())
|
verificationRequest, err = db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeUpdateEmail)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
err = db.Mgr.DeleteVerificationRequest(verificationRequest)
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,7 @@ func testSetup() TestSetup {
|
||||||
Password: "test",
|
Password: "test",
|
||||||
}
|
}
|
||||||
|
|
||||||
constants.EnvData.ENV_PATH = "../../.env.sample"
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyEnvPath, "../../.env.sample")
|
||||||
|
|
||||||
env.InitEnv()
|
env.InitEnv()
|
||||||
session.InitSession()
|
session.InitSession()
|
||||||
|
|
|
@ -6,26 +6,27 @@ 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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateConfigTests(s TestSetup, t *testing.T) {
|
func updateConfigTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should update configs`, func(t *testing.T) {
|
t.Run(`should update configs`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
originalAppURL := constants.EnvData.APP_URL
|
originalAppURL := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAppURL).(string)
|
||||||
log.Println("=> originalAppURL:", constants.EnvData.APP_URL)
|
|
||||||
|
|
||||||
data := model.UpdateConfigInput{}
|
data := model.UpdateConfigInput{}
|
||||||
_, err := resolvers.UpdateConfigResolver(ctx, data)
|
_, err := resolvers.UpdateConfigResolver(ctx, data)
|
||||||
log.Println("error:", err)
|
log.Println("error:", err)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
h, _ := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
assert.Nil(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
newURL := "https://test.com"
|
newURL := "https://test.com"
|
||||||
data = model.UpdateConfigInput{
|
data = model.UpdateConfigInput{
|
||||||
AppURL: &newURL,
|
AppURL: &newURL,
|
||||||
|
@ -33,8 +34,7 @@ func updateConfigTests(s TestSetup, t *testing.T) {
|
||||||
_, err = resolvers.UpdateConfigResolver(ctx, data)
|
_, err = resolvers.UpdateConfigResolver(ctx, data)
|
||||||
log.Println("error:", err)
|
log.Println("error:", err)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, constants.EnvData.APP_URL, newURL)
|
assert.Equal(t, envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAppURL).(string), newURL)
|
||||||
assert.NotEqual(t, constants.EnvData.APP_URL, originalAppURL)
|
|
||||||
data = model.UpdateConfigInput{
|
data = model.UpdateConfigInput{
|
||||||
AppURL: &originalAppURL,
|
AppURL: &originalAppURL,
|
||||||
}
|
}
|
|
@ -6,47 +6,48 @@ import (
|
||||||
|
|
||||||
"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/enum"
|
"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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateProfileTests(s TestSetup, t *testing.T) {
|
func updateProfileTests(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should update the profile with access token only`, func(t *testing.T) {
|
t.Run(`should update the profile with access token only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "update_profile." + s.TestInfo.Email
|
email := "update_profile." + s.TestInfo.Email
|
||||||
|
|
||||||
resolvers.Signup(ctx, model.SignUpInput{
|
resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
fName := "samani"
|
fName := "samani"
|
||||||
_, err := resolvers.UpdateProfile(ctx, model.UpdateProfileInput{
|
_, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
||||||
FamilyName: &fName,
|
FamilyName: &fName,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, enum.BasicAuthSignup.String())
|
verificationRequest, err := db.Mgr.GetVerificationByEmail(email, constants.VerificationTypeBasicAuthSignup)
|
||||||
verifyRes, err := resolvers.VerifyEmail(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
||||||
token := *verifyRes.AccessToken
|
token := *verifyRes.AccessToken
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.COOKIE_NAME, token))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyCookieName).(string), token))
|
||||||
_, err = resolvers.UpdateProfile(ctx, model.UpdateProfileInput{
|
_, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
||||||
FamilyName: &fName,
|
FamilyName: &fName,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
newEmail := "new_" + email
|
newEmail := "new_" + email
|
||||||
_, err = resolvers.UpdateProfile(ctx, model.UpdateProfileInput{
|
_, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
||||||
Email: &newEmail,
|
Email: &newEmail,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
_, err = resolvers.Profile(ctx)
|
_, err = resolvers.ProfileResolver(ctx)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
cleanData(newEmail)
|
cleanData(newEmail)
|
|
@ -5,17 +5,19 @@ 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/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateUserTest(s TestSetup, t *testing.T) {
|
func updateUserTest(t *testing.T, s TestSetup) {
|
||||||
|
t.Helper()
|
||||||
t.Run(`should update the user with admin secret only`, func(t *testing.T) {
|
t.Run(`should update the user with admin secret only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "update_user." + s.TestInfo.Email
|
email := "update_user." + s.TestInfo.Email
|
||||||
signupRes, _ := resolvers.Signup(ctx, model.SignUpInput{
|
signupRes, _ := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
|
@ -25,16 +27,16 @@ func updateUserTest(s TestSetup, t *testing.T) {
|
||||||
adminRole := "admin"
|
adminRole := "admin"
|
||||||
userRole := "user"
|
userRole := "user"
|
||||||
newRoles := []*string{&adminRole, &userRole}
|
newRoles := []*string{&adminRole, &userRole}
|
||||||
_, err := resolvers.UpdateUser(ctx, model.UpdateUserInput{
|
_, err := resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
|
||||||
ID: user.ID,
|
ID: user.ID,
|
||||||
Roles: newRoles,
|
Roles: newRoles,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
h, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
|
h, err := utils.EncryptPassword(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminSecret).(string))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.EnvData.ADMIN_COOKIE_NAME, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyAdminCookieName).(string), h))
|
||||||
_, err = resolvers.UpdateUser(ctx, model.UpdateUserInput{
|
_, err = resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
|
||||||
ID: user.ID,
|
ID: user.ID,
|
||||||
Roles: newRoles,
|
Roles: newRoles,
|
||||||
})
|
})
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user