feat: add support for database cert, key, ca-cert
This commit is contained in:
parent
4778827545
commit
075c287f34
|
@ -9,3 +9,4 @@ build
|
||||||
data.db
|
data.db
|
||||||
app/node_modules
|
app/node_modules
|
||||||
app/build
|
app/build
|
||||||
|
certs/
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ data.db
|
||||||
.vscode/
|
.vscode/
|
||||||
.yalc
|
.yalc
|
||||||
yalc.lock
|
yalc.lock
|
||||||
|
certs/
|
|
@ -38,6 +38,12 @@ const (
|
||||||
EnvKeyDatabasePort = "DATABASE_PORT"
|
EnvKeyDatabasePort = "DATABASE_PORT"
|
||||||
// EnvKeyDatabaseHost key for env variable DATABASE_HOST
|
// EnvKeyDatabaseHost key for env variable DATABASE_HOST
|
||||||
EnvKeyDatabaseHost = "DATABASE_HOST"
|
EnvKeyDatabaseHost = "DATABASE_HOST"
|
||||||
|
// EnvKeyDatabaseCert key for env variable DATABASE_CERT
|
||||||
|
EnvKeyDatabaseCert = "DATABASE_CERT"
|
||||||
|
// EnvKeyDatabaseCertKey key for env variable DATABASE_KEY
|
||||||
|
EnvKeyDatabaseCertKey = "DATABASE_CERT_KEY"
|
||||||
|
// EnvKeyDatabaseCACert key for env variable DATABASE_CA_CERT
|
||||||
|
EnvKeyDatabaseCACert = "DATABASE_CA_CERT"
|
||||||
// EnvKeySmtpHost key for env variable SMTP_HOST
|
// EnvKeySmtpHost key for env variable SMTP_HOST
|
||||||
EnvKeySmtpHost = "SMTP_HOST"
|
EnvKeySmtpHost = "SMTP_HOST"
|
||||||
// EnvKeySmtpPort key for env variable SMTP_PORT
|
// EnvKeySmtpPort key for env variable SMTP_PORT
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
package cassandradb
|
package cassandradb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
"github.com/gocql/gocql"
|
||||||
cansandraDriver "github.com/gocql/gocql"
|
cansandraDriver "github.com/gocql/gocql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +25,13 @@ var KeySpace string
|
||||||
// NewProvider to initialize arangodb connection
|
// NewProvider to initialize arangodb connection
|
||||||
func NewProvider() (*provider, error) {
|
func NewProvider() (*provider, error) {
|
||||||
dbURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)
|
dbURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL)
|
||||||
|
if dbURL == "" {
|
||||||
|
dbURL = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseHost)
|
||||||
|
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePort) != "" {
|
||||||
|
dbURL = fmt.Sprintf("%s:%s", dbURL, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabasePort))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeySpace = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)
|
KeySpace = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName)
|
||||||
clusterURL := []string{}
|
clusterURL := []string{}
|
||||||
if strings.Contains(dbURL, ",") {
|
if strings.Contains(dbURL, ",") {
|
||||||
|
@ -36,10 +47,44 @@ func NewProvider() (*provider, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCert) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCACert) != "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCertKey) != "" {
|
||||||
|
certString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCert))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCertKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
caString, err := crypto.DecryptB64(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseCACert))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair([]byte(certString), []byte(keyString))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
caCertPool := x509.NewCertPool()
|
||||||
|
caCertPool.AppendCertsFromPEM([]byte(caString))
|
||||||
|
|
||||||
|
cassandraClient.SslOpts = &cansandraDriver.SslOptions{
|
||||||
|
Config: &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
RootCAs: caCertPool,
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
EnableHostVerification: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cassandraClient.RetryPolicy = &cansandraDriver.SimpleRetryPolicy{
|
cassandraClient.RetryPolicy = &cansandraDriver.SimpleRetryPolicy{
|
||||||
NumRetries: 3,
|
NumRetries: 3,
|
||||||
}
|
}
|
||||||
cassandraClient.Consistency = cansandraDriver.Quorum
|
cassandraClient.Consistency = gocql.LocalQuorum
|
||||||
|
|
||||||
session, err := cassandraClient.CreateSession()
|
session, err := cassandraClient.CreateSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,12 +92,31 @@ func NewProvider() (*provider, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
keyspaceQuery := fmt.Sprintf("CREATE KEYSPACE IF NOT EXISTS %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor':1}",
|
// Note for astra keyspaces can only be created from there console
|
||||||
KeySpace)
|
// https://docs.datastax.com/en/astra/docs/datastax-astra-faq.html#_i_am_trying_to_create_a_keyspace_in_the_cql_shell_and_i_am_running_into_an_error_how_do_i_fix_this
|
||||||
err = session.Query(keyspaceQuery).Exec()
|
getKeyspaceQuery := fmt.Sprintf("SELECT keyspace_name FROM system_schema.keyspaces;")
|
||||||
if err != nil {
|
scanner := session.Query(getKeyspaceQuery).Iter().Scanner()
|
||||||
log.Println("Unable to create keyspace:", err)
|
hasAuthorizerKeySpace := false
|
||||||
return nil, err
|
for scanner.Next() {
|
||||||
|
var keySpace string
|
||||||
|
err := scanner.Scan(&keySpace)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while getting keyspace information", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if keySpace == KeySpace {
|
||||||
|
hasAuthorizerKeySpace = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasAuthorizerKeySpace {
|
||||||
|
createKeySpaceQuery := fmt.Sprintf("CREATE KEYSPACE %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};", KeySpace)
|
||||||
|
err = session.Query(createKeySpaceQuery).Exec()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while creating keyspace", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure collections are present
|
// make sure collections are present
|
||||||
|
|
7
server/env/env.go
vendored
7
server/env/env.go
vendored
|
@ -42,6 +42,9 @@ func InitRequiredEnv() error {
|
||||||
dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
|
dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
|
||||||
dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
|
dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
|
||||||
dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
|
dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
|
||||||
|
dbCert := os.Getenv(constants.EnvKeyDatabaseCert)
|
||||||
|
dbCertKey := os.Getenv(constants.EnvKeyDatabaseCertKey)
|
||||||
|
dbCACert := os.Getenv(constants.EnvKeyDatabaseCACert)
|
||||||
|
|
||||||
if strings.TrimSpace(dbType) == "" {
|
if strings.TrimSpace(dbType) == "" {
|
||||||
if envstore.ARG_DB_TYPE != nil && *envstore.ARG_DB_TYPE != "" {
|
if envstore.ARG_DB_TYPE != nil && *envstore.ARG_DB_TYPE != "" {
|
||||||
|
@ -77,6 +80,10 @@ func InitRequiredEnv() error {
|
||||||
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePort, dbPort)
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePort, dbPort)
|
||||||
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseUsername, dbUsername)
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseUsername, dbUsername)
|
||||||
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePassword, dbPassword)
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabasePassword, dbPassword)
|
||||||
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCert, dbCert)
|
||||||
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCertKey, dbCertKey)
|
||||||
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseCACert, dbCACert)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
|
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
go utils.SaveSessionInDB(c, user.ID)
|
go db.Provider.AddSession(models.Session{
|
||||||
|
UserID: user.ID,
|
||||||
|
UserAgent: utils.GetUserAgent(c.Request),
|
||||||
|
IP: utils.GetIP(c.Request),
|
||||||
|
})
|
||||||
if strings.Contains(redirectURL, "?") {
|
if strings.Contains(redirectURL, "?") {
|
||||||
redirectURL = redirectURL + "&" + params
|
redirectURL = redirectURL + "&" + params
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
@ -109,7 +110,11 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
redirectURL = redirectURL + "?" + params
|
redirectURL = redirectURL + "?" + params
|
||||||
}
|
}
|
||||||
|
|
||||||
go utils.SaveSessionInDB(c, user.ID)
|
go db.Provider.AddSession(models.Session{
|
||||||
|
UserID: user.ID,
|
||||||
|
UserAgent: utils.GetUserAgent(c.Request),
|
||||||
|
IP: utils.GetIP(c.Request),
|
||||||
|
})
|
||||||
|
|
||||||
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
|
@ -96,7 +97,11 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
|
||||||
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
|
sessionstore.SetState(authToken.RefreshToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
go utils.SaveSessionInDB(gc, user.ID)
|
go db.Provider.AddSession(models.Session{
|
||||||
|
UserID: user.ID,
|
||||||
|
UserAgent: utils.GetUserAgent(gc.Request),
|
||||||
|
IP: utils.GetIP(gc.Request),
|
||||||
|
})
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,11 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
|
|
||||||
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
|
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
|
||||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||||
go utils.SaveSessionInDB(gc, user.ID)
|
go db.Provider.AddSession(models.Session{
|
||||||
|
UserID: user.ID,
|
||||||
|
UserAgent: utils.GetUserAgent(gc.Request),
|
||||||
|
IP: utils.GetIP(gc.Request),
|
||||||
|
})
|
||||||
|
|
||||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||||
if expiresIn <= 0 {
|
if expiresIn <= 0 {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
@ -62,7 +63,11 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
|
||||||
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
|
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
|
||||||
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
|
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||||
go utils.SaveSessionInDB(gc, user.ID)
|
go db.Provider.AddSession(models.Session{
|
||||||
|
UserID: user.ID,
|
||||||
|
UserAgent: utils.GetUserAgent(gc.Request),
|
||||||
|
IP: utils.GetIP(gc.Request),
|
||||||
|
})
|
||||||
|
|
||||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||||
if expiresIn <= 0 {
|
if expiresIn <= 0 {
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// StringSliceContains checks if a string slice contains a particular string
|
// StringSliceContains checks if a string slice contains a particular string
|
||||||
|
@ -19,23 +14,6 @@ func StringSliceContains(s []string, e string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveSessionInDB saves sessions generated for a given user with meta information
|
|
||||||
// Do not store token here as that could be security breach
|
|
||||||
func SaveSessionInDB(c *gin.Context, userId string) {
|
|
||||||
sessionData := models.Session{
|
|
||||||
UserID: userId,
|
|
||||||
UserAgent: GetUserAgent(c.Request),
|
|
||||||
IP: GetIP(c.Request),
|
|
||||||
}
|
|
||||||
|
|
||||||
err := db.Provider.AddSession(sessionData)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("=> error saving session in db:", err)
|
|
||||||
} else {
|
|
||||||
log.Println("=> session saved in db:", sessionData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveDuplicateString removes duplicate strings from a string slice
|
// RemoveDuplicateString removes duplicate strings from a string slice
|
||||||
func RemoveDuplicateString(strSlice []string) []string {
|
func RemoveDuplicateString(strSlice []string) []string {
|
||||||
allKeys := make(map[string]bool)
|
allKeys := make(map[string]bool)
|
||||||
|
|
48
server/utils/file.go
Normal file
48
server/utils/file.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateFolder creates a folder in Current working dir
|
||||||
|
func CreateFolder(dir string) (string, error) {
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
path := pwd + "/" + dir
|
||||||
|
err = os.Mkdir(path, 0o755)
|
||||||
|
if err == nil {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
if os.IsExist(err) {
|
||||||
|
// check that the existing path is a directory
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return "", errors.New("path exists but is not a directory")
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
return path, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateFile creates a file on given path with given content
|
||||||
|
func CreateFile(filePath string, content string) error {
|
||||||
|
f, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = f.WriteString(content)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user