Feat/dashboard (#105)

This commit is contained in:
Lakhan Samani
2022-01-17 11:32:13 +05:30
committed by GitHub
parent 7ce96367a3
commit f1b4141367
120 changed files with 3381 additions and 3044 deletions

View File

@@ -5,10 +5,12 @@ import (
"fmt"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
"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) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
@@ -17,11 +19,12 @@ func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*mod
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`)
}
hashedKey, err := utils.HashPassword(constants.EnvData.ADMIN_SECRET)
hashedKey, err := utils.EncryptPassword(adminSecret)
if err != nil {
return res, err
}

View File

@@ -8,7 +8,8 @@ import (
"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)
var res *model.Response

View File

@@ -5,11 +5,13 @@ import (
"fmt"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
"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)
var res *model.Response
@@ -21,7 +23,7 @@ func AdminSession(ctx context.Context) (*model.Response, error) {
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 {
return res, err
}

View File

@@ -8,10 +8,12 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
"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) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
@@ -30,17 +32,18 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
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")
return res, err
}
constants.EnvData.ADMIN_SECRET = params.AdminSecret
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret)
// consvert EnvData to JSON
var jsonData map[string]interface{}
jsonBytes, err := json.Marshal(constants.EnvData)
jsonBytes, err := json.Marshal(envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
if err != nil {
return res, err
}
@@ -54,7 +57,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
return res, err
}
configData, err := utils.EncryptConfig(jsonData)
configData, err := utils.EncryptEnvData(jsonData)
if err != nil {
return res, err
}
@@ -64,7 +67,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
return res, err
}
hashedKey, err := utils.HashPassword(params.AdminSecret)
hashedKey, err := utils.EncryptPassword(params.AdminSecret)
if err != nil {
return res, err
}

View File

@@ -5,10 +5,15 @@ import (
"fmt"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
"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) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Config
@@ -21,40 +26,76 @@ func ConfigResolver(ctx context.Context) (*model.Config, error) {
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{
AdminSecret: &constants.EnvData.ADMIN_SECRET,
DatabaseType: &constants.EnvData.DATABASE_TYPE,
DatabaseURL: &constants.EnvData.DATABASE_URL,
DatabaseName: &constants.EnvData.DATABASE_NAME,
SMTPHost: &constants.EnvData.SMTP_HOST,
SMTPPort: &constants.EnvData.SMTP_PORT,
SMTPPassword: &constants.EnvData.SMTP_PASSWORD,
SMTPUsername: &constants.EnvData.SMTP_USERNAME,
SenderEmail: &constants.EnvData.SENDER_EMAIL,
JwtType: &constants.EnvData.JWT_TYPE,
JwtSecret: &constants.EnvData.JWT_SECRET,
AllowedOrigins: constants.EnvData.ALLOWED_ORIGINS,
AuthorizerURL: &constants.EnvData.AUTHORIZER_URL,
AppURL: &constants.EnvData.APP_URL,
RedisURL: &constants.EnvData.REDIS_URL,
CookieName: &constants.EnvData.COOKIE_NAME,
ResetPasswordURL: &constants.EnvData.RESET_PASSWORD_URL,
DisableEmailVerification: &constants.EnvData.DISABLE_EMAIL_VERIFICATION,
DisableBasicAuthentication: &constants.EnvData.DISABLE_BASIC_AUTHENTICATION,
DisableMagicLinkLogin: &constants.EnvData.DISABLE_MAGIC_LINK_LOGIN,
DisableLoginPage: &constants.EnvData.DISABLE_LOGIN_PAGE,
Roles: constants.EnvData.ROLES,
ProtectedRoles: constants.EnvData.PROTECTED_ROLES,
DefaultRoles: constants.EnvData.DEFAULT_ROLES,
JwtRoleClaim: &constants.EnvData.JWT_ROLE_CLAIM,
GoogleClientID: &constants.EnvData.GOOGLE_CLIENT_ID,
GoogleClientSecret: &constants.EnvData.GOOGLE_CLIENT_SECRET,
GithubClientID: &constants.EnvData.GITHUB_CLIENT_ID,
GithubClientSecret: &constants.EnvData.GITHUB_CLIENT_SECRET,
FacebookClientID: &constants.EnvData.FACEBOOK_CLIENT_ID,
FacebookClientSecret: &constants.EnvData.FACEBOOK_CLIENT_SECRET,
OrganizationName: &constants.EnvData.ORGANIZATION_NAME,
OrganizationLogo: &constants.EnvData.ORGANIZATION_LOGO,
AdminSecret: &adminSecret,
DatabaseType: &databaseType,
DatabaseURL: &databaseURL,
DatabaseName: &databaseName,
SMTPHost: &smtpHost,
SMTPPort: &smtpPort,
SMTPPassword: &smtpPassword,
SMTPUsername: &smtpUsername,
SenderEmail: &senderEmail,
JwtType: &jwtType,
JwtSecret: &jwtSecret,
JwtRoleClaim: &jwtRoleClaim,
AllowedOrigins: allowedOrigins,
AuthorizerURL: &authorizerURL,
AppURL: &appURL,
RedisURL: &redisURL,
CookieName: &cookieName,
ResetPasswordURL: &resetPasswordURL,
DisableEmailVerification: &disableEmailVerification,
DisableBasicAuthentication: &disableBasicAuthentication,
DisableMagicLinkLogin: &disableMagicLinkLogin,
DisableLoginPage: &disableLoginPage,
Roles: roles,
ProtectedRoles: protectedRoles,
DefaultRoles: defaultRoles,
GoogleClientID: &googleClientID,
GoogleClientSecret: &googleClientSecret,
GithubClientID: &githubClientID,
GithubClientSecret: &githubClientSecret,
FacebookClientID: &facebookClientID,
FacebookClientSecret: &facebookClientSecret,
OrganizationName: &organizationName,
OrganizationLogo: &organizationLogo,
}
return res, nil
}

View File

@@ -11,7 +11,8 @@ import (
"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)
var res *model.Response
if err != nil {
@@ -27,7 +28,7 @@ func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Respo
return res, err
}
session.DeleteUserSession(fmt.Sprintf("%x", user.ID))
session.DeleteAllUserSession(fmt.Sprintf("%x", user.ID))
err = db.Mgr.DeleteUser(user)
if err != nil {

View File

@@ -9,18 +9,20 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/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)
var res *model.Response
if err != nil {
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`)
}
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`)
}
token, err := utils.CreateVerificationToken(params.Email, enum.ForgotPassword.String())
token, err := utils.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword)
if err != nil {
log.Println(`error generating token`, err)
}
db.Mgr.AddVerification(db.VerificationRequest{
Token: token,
Identifier: enum.ForgotPassword.String(),
Identifier: constants.VerificationTypeForgotPassword,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
Email: params.Email,
})
// exec it as go routin so that we can reduce the api latency
go func() {
utils.SendForgotPasswordMail(params.Email, token, host)
email.SendForgotPasswordMail(params.Email, token, host)
}()
res = &model.Response{

View File

@@ -8,21 +8,22 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/session"
"github.com/authorizerdev/authorizer/server/utils"
"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)
var res *model.AuthResponse
if err != nil {
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`)
}
@@ -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`)
}
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`)
}
@@ -46,7 +47,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
log.Println("compare password error:", err)
return res, fmt.Errorf(`invalid password`)
}
roles := constants.EnvData.DEFAULT_ROLES
roles := envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
currentRoles := strings.Split(user.Roles, ",")
if len(params.Roles) > 0 {
if !utils.IsValidRoles(currentRoles, params.Roles) {
@@ -55,12 +56,12 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
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)
utils.CreateSession(user.ID, gc)
session.SetUserSession(user.ID, accessToken, refreshToken)
utils.SaveSessionInDB(user.ID, gc)
res = &model.AuthResponse{
Message: `Logged in successfully`,

View File

@@ -9,7 +9,8 @@ import (
"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)
var res *model.Response
if err != nil {
@@ -27,7 +28,7 @@ func Logout(ctx context.Context) (*model.Response, error) {
}
userId := fmt.Sprintf("%v", claim["id"])
session.DeleteVerificationRequest(userId, token)
session.DeleteUserSession(userId, token)
res = &model.Response{
Message: "Logged out successfully",
}

View File

@@ -9,15 +9,17 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/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
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`)
}
@@ -37,17 +39,17 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
existingUser, err := db.Mgr.GetUserByEmail(params.Email)
if err != nil {
user.SignupMethods = enum.MagicLinkLogin.String()
user.SignupMethods = constants.SignupMethodMagicLinkLogin
// define roles for new user
if len(params.Roles) > 0 {
// 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`)
} else {
inputRoles = params.Roles
}
} else {
inputRoles = constants.EnvData.DEFAULT_ROLES
inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
}
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
hasProtectedRole := false
for _, ur := range unasignedRoles {
if utils.StringSliceContains(constants.EnvData.PROTECTED_ROLES, ur) {
if utils.StringSliceContains(envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyProtectedRoles).([]string), ur) {
hasProtectedRole = true
}
}
@@ -87,8 +89,8 @@ func MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*mod
}
signupMethod := existingUser.SignupMethods
if !strings.Contains(signupMethod, enum.MagicLinkLogin.String()) {
signupMethod = signupMethod + "," + enum.MagicLinkLogin.String()
if !strings.Contains(signupMethod, constants.SignupMethodMagicLinkLogin) {
signupMethod = signupMethod + "," + constants.SignupMethodMagicLinkLogin
}
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
verificationType := enum.MagicLinkLogin.String()
verificationType := constants.VerificationTypeMagicLinkLogin
token, err := utils.CreateVerificationToken(params.Email, verificationType)
if err != nil {
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
go func() {
utils.SendVerificationMail(params.Email, token)
email.SendVerificationMail(params.Email, token)
}()
}

View File

@@ -7,7 +7,8 @@ import (
"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()
return &metaInfo, nil
}

View File

@@ -10,7 +10,8 @@ import (
"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)
var res *model.User
if err != nil {
@@ -29,7 +30,7 @@ func Profile(ctx context.Context) (*model.User, error) {
userID := fmt.Sprintf("%v", claim["id"])
email := fmt.Sprintf("%v", claim["email"])
sessionToken := session.GetToken(userID, token)
sessionToken := session.GetUserSession(userID, token)
if sessionToken == "" {
return res, fmt.Errorf(`unauthorized`)

View File

@@ -8,11 +8,13 @@ import (
"time"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/email"
"github.com/authorizerdev/authorizer/server/graph/model"
"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
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
go func() {
utils.SendVerificationMail(params.Email, token)
email.SendVerificationMail(params.Email, token)
}()
res = &model.Response{

View File

@@ -8,14 +8,15 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/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
if constants.EnvData.DISABLE_BASIC_AUTHENTICATION {
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableBasicAuthentication).(bool) {
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
}
password, _ := utils.HashPassword(params.Password)
password, _ := utils.EncryptPassword(params.Password)
user.Password = &password
signupMethod := user.SignupMethods
if !strings.Contains(signupMethod, enum.BasicAuth.String()) {
signupMethod = signupMethod + "," + enum.BasicAuth.String()
if !strings.Contains(signupMethod, constants.SignupMethodBasicAuth) {
signupMethod = signupMethod + "," + constants.SignupMethodBasicAuth
}
user.SignupMethods = signupMethod

View File

@@ -7,13 +7,14 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/session"
"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
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)
sessionToken := session.GetToken(userIdStr, token)
sessionToken := session.GetUserSession(userIdStr, token)
if sessionToken == "" {
return res, fmt.Errorf(`unauthorized`)
@@ -45,7 +46,7 @@ func Session(ctx context.Context, roles []string) (*model.AuthResponse, error) {
expiresTimeObj := time.Unix(expiresAt, 0)
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))
for i, v := range claimRoleInterface {
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 access token has expired and refresh/session token is valid
// generate new accessToken
currentRefreshToken := session.GetToken(userIdStr, token)
session.DeleteVerificationRequest(userIdStr, token)
token, expiresAt, _ = utils.CreateAuthToken(user, enum.AccessToken, claimRoles)
session.SetToken(userIdStr, token, currentRefreshToken)
utils.CreateSession(user.ID, gc)
currentRefreshToken := session.GetUserSession(userIdStr, token)
session.DeleteUserSession(userIdStr, token)
token, expiresAt, _ = utils.CreateAuthToken(user, constants.TokenTypeAccessToken, claimRoles)
session.SetUserSession(userIdStr, token, currentRefreshToken)
utils.SaveSessionInDB(user.ID, gc)
}
utils.SetCookie(gc, token)

View File

@@ -9,20 +9,23 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/session"
"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)
var res *model.AuthResponse
if err != nil {
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`)
}
if params.ConfirmPassword != params.Password {
@@ -52,13 +55,13 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
if len(params.Roles) > 0 {
// 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`)
} else {
inputRoles = params.Roles
}
} else {
inputRoles = constants.EnvData.DEFAULT_ROLES
inputRoles = envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDefaultRoles).([]string)
}
user := db.User{
@@ -67,7 +70,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
user.Roles = strings.Join(inputRoles, ",")
password, _ := utils.HashPassword(params.Password)
password, _ := utils.EncryptPassword(params.Password)
user.Password = &password
if params.GivenName != nil {
@@ -102,8 +105,8 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
user.Picture = params.Picture
}
user.SignupMethods = enum.BasicAuth.String()
if constants.EnvData.DISABLE_EMAIL_VERIFICATION {
user.SignupMethods = constants.SignupMethodBasicAuth
if envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) {
now := time.Now().Unix()
user.EmailVerifiedAt = &now
}
@@ -115,9 +118,9 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
roles := strings.Split(user.Roles, ",")
userToReturn := utils.GetResponseUserData(user)
if !constants.EnvData.DISABLE_EMAIL_VERIFICATION {
if !envstore.EnvInMemoryStoreObj.GetEnvVariable(constants.EnvKeyDisableEmailVerification).(bool) {
// insert verification request
verificationType := enum.BasicAuthSignup.String()
verificationType := constants.VerificationTypeBasicAuthSignup
token, err := utils.CreateVerificationToken(params.Email, verificationType)
if err != nil {
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
go func() {
utils.SendVerificationMail(params.Email, token)
email.SendVerificationMail(params.Email, token)
}()
res = &model.AuthResponse{
@@ -140,12 +143,12 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
}
} 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)
utils.CreateSession(user.ID, gc)
session.SetUserSession(userIdStr, accessToken, refreshToken)
utils.SaveSessionInDB(user.ID, gc)
res = &model.AuthResponse{
Message: `Signed up successfully.`,
AccessToken: &accessToken,

View File

@@ -9,10 +9,15 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
"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) {
gc, err := utils.GinContextFromContext(ctx)
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
// in case SMTP is off but env is set to true
if updatedData["SMTP_HOST"] == "" || updatedData["SENDER_EMAIL"] == "" || updatedData["SENDER_PASSWORD"] == "" {
if !updatedData["DISABLE_EMAIL_VERIFICATION"].(bool) {
updatedData["DISABLE_EMAIL_VERIFICATION"] = true
if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySenderEmail] == "" || updatedData[constants.EnvKeySmtpPort] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" {
if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) {
updatedData[constants.EnvKeyDisableEmailVerification] = true
}
if !updatedData["DISABLE_MAGIC_LINK_LOGIN"].(bool) {
updatedData["DISABLE_MAGIC_LINK_LOGIN"] = true
if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
updatedData[constants.EnvKeyDisableMagicLinkLogin] = true
}
}
@@ -72,7 +77,9 @@ func UpdateConfigResolver(ctx context.Context, params model.UpdateConfigInput) (
return res, err
}
encryptedConfig, err := utils.EncryptConfig(updatedData)
envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData)
encryptedConfig, err := utils.EncryptEnvData(updatedData)
if err != nil {
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
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 {
return res, err
}

View File

@@ -7,15 +7,17 @@ import (
"strings"
"time"
"github.com/authorizerdev/authorizer/server/constants"
"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/session"
"github.com/authorizerdev/authorizer/server/utils"
"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)
var res *model.Response
if err != nil {
@@ -33,7 +35,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
}
id := fmt.Sprintf("%v", claim["id"])
sessionToken := session.GetToken(id, token)
sessionToken := session.GetUserSession(id, token)
if sessionToken == "" {
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")
}
email := fmt.Sprintf("%v", claim["email"])
user, err := db.Mgr.GetUserByEmail(email)
userEmail := fmt.Sprintf("%v", claim["email"])
user, err := db.Mgr.GetUserByEmail(userEmail)
if err != nil {
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`)
}
password, _ := utils.HashPassword(*params.NewPassword)
password, _ := utils.EncryptPassword(*params.NewPassword)
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")
}
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
user.Email = newEmail
user.EmailVerifiedAt = nil
hasEmailChanged = true
// insert verification request
verificationType := enum.UpdateEmail.String()
verificationType := constants.VerificationTypeUpdateEmail
token, err := utils.CreateVerificationToken(newEmail, verificationType)
if err != nil {
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
go func() {
utils.SendVerificationMail(newEmail, token)
email.SendVerificationMail(newEmail, token)
}()
}

View File

@@ -9,13 +9,16 @@ import (
"github.com/authorizerdev/authorizer/server/constants"
"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/session"
"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)
var res *model.User
if err != nil {
@@ -67,6 +70,15 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
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 {
// check if valid 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")
}
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
user.Email = newEmail
user.EmailVerifiedAt = nil
// insert verification request
verificationType := enum.UpdateEmail.String()
verificationType := constants.VerificationTypeUpdateEmail
token, err := utils.CreateVerificationToken(newEmail, verificationType)
if err != nil {
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
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)
}
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")
}
@@ -120,7 +132,7 @@ func UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User,
rolesToSave = strings.Join(inputRoles, ",")
}
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
session.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
}

View File

@@ -9,7 +9,9 @@ import (
"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)
var res []*model.User
if err != nil {

View File

@@ -9,7 +9,9 @@ import (
"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)
var res []*model.VerificationRequest
if err != nil {

View File

@@ -6,14 +6,15 @@ import (
"strings"
"time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/enum"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/session"
"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)
var res *model.AuthResponse
if err != nil {
@@ -44,12 +45,11 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
db.Mgr.DeleteVerificationRequest(verificationRequest)
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.SetToken(user.ID, accessToken, refreshToken)
utils.CreateSession(user.ID, gc)
session.SetUserSession(user.ID, accessToken, refreshToken)
utils.SaveSessionInDB(user.ID, gc)
res = &model.AuthResponse{
Message: `Email verified successfully.`,