Merge pull request #173 from authorizerdev/feat/logging
feat: add logging system
This commit is contained in:
commit
d722fe258d
|
@ -1,6 +1,8 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db/providers"
|
"github.com/authorizerdev/authorizer/server/db/providers"
|
||||||
"github.com/authorizerdev/authorizer/server/db/providers/arangodb"
|
"github.com/authorizerdev/authorizer/server/db/providers/arangodb"
|
||||||
|
@ -22,29 +24,37 @@ func InitDB() error {
|
||||||
isCassandra := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeCassandraDB
|
isCassandra := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeCassandraDB
|
||||||
|
|
||||||
if isSQL {
|
if isSQL {
|
||||||
|
log.Info("Initializing SQL Driver for: ", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType))
|
||||||
Provider, err = sql.NewProvider()
|
Provider, err = sql.NewProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Fatal("Failed to initialize SQL driver: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isArangoDB {
|
if isArangoDB {
|
||||||
|
log.Info("Initializing ArangoDB Driver")
|
||||||
Provider, err = arangodb.NewProvider()
|
Provider, err = arangodb.NewProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Fatal("Failed to initialize ArangoDB driver: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isMongoDB {
|
if isMongoDB {
|
||||||
|
log.Info("Initializing MongoDB Driver")
|
||||||
Provider, err = mongodb.NewProvider()
|
Provider, err = mongodb.NewProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Fatal("Failed to initialize MongoDB driver: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isCassandra {
|
if isCassandra {
|
||||||
|
log.Info("Initializing CassandraDB Driver")
|
||||||
Provider, err = cassandradb.NewProvider()
|
Provider, err = cassandradb.NewProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Fatal("Failed to initialize CassandraDB driver: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package arangodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
arangoDriver "github.com/arangodb/go-driver"
|
arangoDriver "github.com/arangodb/go-driver"
|
||||||
|
@ -22,7 +21,6 @@ func (p *provider) AddEnv(env models.Env) (models.Env, error) {
|
||||||
configCollection, _ := p.db.Collection(nil, models.Collections.Env)
|
configCollection, _ := p.db.Collection(nil, models.Collections.Env)
|
||||||
meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(nil), env)
|
meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(nil), env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding config:", err)
|
|
||||||
return env, err
|
return env, err
|
||||||
}
|
}
|
||||||
env.Key = meta.Key
|
env.Key = meta.Key
|
||||||
|
@ -36,7 +34,6 @@ func (p *provider) UpdateEnv(env models.Env) (models.Env, error) {
|
||||||
collection, _ := p.db.Collection(nil, models.Collections.Env)
|
collection, _ := p.db.Collection(nil, models.Collections.Env)
|
||||||
meta, err := collection.UpdateDocument(nil, env.Key, env)
|
meta, err := collection.UpdateDocument(nil, env.Key, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating config:", err)
|
|
||||||
return env, err
|
return env, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package arangodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/arangodb/go-driver"
|
"github.com/arangodb/go-driver"
|
||||||
arangoDriver "github.com/arangodb/go-driver"
|
arangoDriver "github.com/arangodb/go-driver"
|
||||||
|
@ -42,7 +41,6 @@ func NewProvider() (*provider, error) {
|
||||||
arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName))
|
arangodb_exists, err := arangoClient.DatabaseExists(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName))
|
||||||
|
|
||||||
if arangodb_exists {
|
if arangodb_exists {
|
||||||
log.Println(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName) + " db exists already")
|
|
||||||
arangodb, err = arangoClient.Database(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName))
|
arangodb, err = arangoClient.Database(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -55,12 +53,10 @@ func NewProvider() (*provider, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User)
|
userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User)
|
||||||
if userCollectionExists {
|
if !userCollectionExists {
|
||||||
log.Println(models.Collections.User + " collection exists already")
|
|
||||||
} else {
|
|
||||||
_, err = arangodb.CreateCollection(ctx, models.Collections.User, nil)
|
_, err = arangodb.CreateCollection(ctx, models.Collections.User, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating collection("+models.Collections.User+"):", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
userCollection, _ := arangodb.Collection(nil, models.Collections.User)
|
userCollection, _ := arangodb.Collection(nil, models.Collections.User)
|
||||||
|
@ -74,12 +70,10 @@ func NewProvider() (*provider, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.VerificationRequest)
|
verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.VerificationRequest)
|
||||||
if verificationRequestCollectionExists {
|
if !verificationRequestCollectionExists {
|
||||||
log.Println(models.Collections.VerificationRequest + " collection exists already")
|
|
||||||
} else {
|
|
||||||
_, err = arangodb.CreateCollection(ctx, models.Collections.VerificationRequest, nil)
|
_, err = arangodb.CreateCollection(ctx, models.Collections.VerificationRequest, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating collection("+models.Collections.VerificationRequest+"):", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,12 +87,10 @@ func NewProvider() (*provider, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
sessionCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Session)
|
sessionCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Session)
|
||||||
if sessionCollectionExists {
|
if !sessionCollectionExists {
|
||||||
log.Println(models.Collections.Session + " collection exists already")
|
|
||||||
} else {
|
|
||||||
_, err = arangodb.CreateCollection(ctx, models.Collections.Session, nil)
|
_, err = arangodb.CreateCollection(ctx, models.Collections.Session, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating collection("+models.Collections.Session+"):", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +100,10 @@ func NewProvider() (*provider, error) {
|
||||||
})
|
})
|
||||||
|
|
||||||
configCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Env)
|
configCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Env)
|
||||||
if configCollectionExists {
|
if !configCollectionExists {
|
||||||
log.Println(models.Collections.Env + " collection exists already")
|
|
||||||
} else {
|
|
||||||
_, err = arangodb.CreateCollection(ctx, models.Collections.Env, nil)
|
_, err = arangodb.CreateCollection(ctx, models.Collections.Env, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating collection("+models.Collections.Env+"):", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package arangodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -20,7 +19,6 @@ func (p *provider) AddSession(session models.Session) error {
|
||||||
sessionCollection, _ := p.db.Collection(nil, models.Collections.Session)
|
sessionCollection, _ := p.db.Collection(nil, models.Collections.Session)
|
||||||
_, err := sessionCollection.CreateDocument(nil, session)
|
_, err := sessionCollection.CreateDocument(nil, session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error saving session`, err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -3,7 +3,6 @@ package arangodb
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
|
||||||
userCollection, _ := p.db.Collection(nil, models.Collections.User)
|
userCollection, _ := p.db.Collection(nil, models.Collections.User)
|
||||||
meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(nil), user)
|
meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(nil), user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding user:", err)
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
user.Key = meta.Key
|
user.Key = meta.Key
|
||||||
|
@ -46,7 +44,6 @@ func (p *provider) UpdateUser(user models.User) (models.User, error) {
|
||||||
collection, _ := p.db.Collection(nil, models.Collections.User)
|
collection, _ := p.db.Collection(nil, models.Collections.User)
|
||||||
meta, err := collection.UpdateDocument(nil, user.Key, user)
|
meta, err := collection.UpdateDocument(nil, user.Key, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +57,6 @@ func (p *provider) DeleteUser(user models.User) error {
|
||||||
collection, _ := p.db.Collection(nil, models.Collections.User)
|
collection, _ := p.db.Collection(nil, models.Collections.User)
|
||||||
_, err := collection.RemoveDocument(nil, user.Key)
|
_, err := collection.RemoveDocument(nil, user.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error deleting user:`, err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package arangodb
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arangodb/go-driver"
|
"github.com/arangodb/go-driver"
|
||||||
|
@ -23,7 +22,6 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
|
||||||
verificationRequestRequestCollection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
|
verificationRequestRequestCollection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
|
||||||
meta, err := verificationRequestRequestCollection.CreateDocument(nil, verificationRequest)
|
meta, err := verificationRequestRequestCollection.CreateDocument(nil, verificationRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error saving verificationRequest record:", err)
|
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
verificationRequest.Key = meta.Key
|
verificationRequest.Key = meta.Key
|
||||||
|
@ -136,7 +134,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
|
||||||
collection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
|
collection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
|
||||||
_, err := collection.RemoveDocument(nil, verificationRequest.Key)
|
_, err := collection.RemoveDocument(nil, verificationRequest.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error deleting verification request:`, err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
@ -88,7 +87,6 @@ func NewProvider() (*provider, error) {
|
||||||
|
|
||||||
session, err := cassandraClient.CreateSession()
|
session, err := cassandraClient.CreateSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error while creating connection to cassandra db", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +99,6 @@ func NewProvider() (*provider, error) {
|
||||||
var keySpace string
|
var keySpace string
|
||||||
err := scanner.Scan(&keySpace)
|
err := scanner.Scan(&keySpace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error while getting keyspace information", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if keySpace == KeySpace {
|
if keySpace == KeySpace {
|
||||||
|
@ -114,7 +111,6 @@ func NewProvider() (*provider, error) {
|
||||||
createKeySpaceQuery := fmt.Sprintf("CREATE KEYSPACE %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};", KeySpace)
|
createKeySpaceQuery := fmt.Sprintf("CREATE KEYSPACE %s WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};", KeySpace)
|
||||||
err = session.Query(createKeySpaceQuery).Exec()
|
err = session.Query(createKeySpaceQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error while creating keyspace", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,27 +120,23 @@ func NewProvider() (*provider, error) {
|
||||||
KeySpace, models.Collections.Env)
|
KeySpace, models.Collections.Env)
|
||||||
err = session.Query(envCollectionQuery).Exec()
|
err = session.Query(envCollectionQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create env collection:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, user_agent text, ip text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.Session)
|
sessionCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, user_agent text, ip text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.Session)
|
||||||
err = session.Query(sessionCollectionQuery).Exec()
|
err = session.Query(sessionCollectionQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create session collection:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, email_verified_at bigint, password text, signup_methods text, given_name text, family_name text, middle_name text, nickname text, gender text, birthdate text, phone_number text, phone_number_verified_at bigint, picture text, roles text, updated_at bigint, created_at bigint, revoked_timestamp bigint, PRIMARY KEY (id))", KeySpace, models.Collections.User)
|
userCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, email_verified_at bigint, password text, signup_methods text, given_name text, family_name text, middle_name text, nickname text, gender text, birthdate text, phone_number text, phone_number_verified_at bigint, picture text, roles text, updated_at bigint, created_at bigint, revoked_timestamp bigint, PRIMARY KEY (id))", KeySpace, models.Collections.User)
|
||||||
err = session.Query(userCollectionQuery).Exec()
|
err = session.Query(userCollectionQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create user collection:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_email ON %s.%s (email)", KeySpace, models.Collections.User)
|
userIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_email ON %s.%s (email)", KeySpace, models.Collections.User)
|
||||||
err = session.Query(userIndexQuery).Exec()
|
err = session.Query(userIndexQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create user index:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,25 +144,21 @@ func NewProvider() (*provider, error) {
|
||||||
verificationRequestCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, jwt_token text, identifier text, expires_at bigint, email text, nonce text, redirect_uri text, created_at bigint, updated_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.VerificationRequest)
|
verificationRequestCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, jwt_token text, identifier text, expires_at bigint, email text, nonce text, redirect_uri text, created_at bigint, updated_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.VerificationRequest)
|
||||||
err = session.Query(verificationRequestCollectionQuery).Exec()
|
err = session.Query(verificationRequestCollectionQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create verification request collection:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
verificationRequestIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_email ON %s.%s (email)", KeySpace, models.Collections.VerificationRequest)
|
verificationRequestIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_email ON %s.%s (email)", KeySpace, models.Collections.VerificationRequest)
|
||||||
err = session.Query(verificationRequestIndexQuery).Exec()
|
err = session.Query(verificationRequestIndexQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create verification_requests index:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_identifier ON %s.%s (identifier)", KeySpace, models.Collections.VerificationRequest)
|
verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_identifier ON %s.%s (identifier)", KeySpace, models.Collections.VerificationRequest)
|
||||||
err = session.Query(verificationRequestIndexQuery).Exec()
|
err = session.Query(verificationRequestIndexQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create verification_requests index:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_jwt_token ON %s.%s (jwt_token)", KeySpace, models.Collections.VerificationRequest)
|
verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_jwt_token ON %s.%s (jwt_token)", KeySpace, models.Collections.VerificationRequest)
|
||||||
err = session.Query(verificationRequestIndexQuery).Exec()
|
err = session.Query(verificationRequestIndexQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to create verification_requests index:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cassandradb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -61,7 +60,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
|
||||||
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest)
|
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest)
|
||||||
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error while quering verification request", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +75,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
|
||||||
var verificationRequest models.VerificationRequest
|
var verificationRequest models.VerificationRequest
|
||||||
err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
|
err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error while parsing verification request", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
|
verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
|
||||||
|
|
|
@ -2,7 +2,6 @@ package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -23,7 +22,6 @@ func (p *provider) AddEnv(env models.Env) (models.Env, error) {
|
||||||
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
|
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
|
||||||
_, err := configCollection.InsertOne(nil, env)
|
_, err := configCollection.InsertOne(nil, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding config:", err)
|
|
||||||
return env, err
|
return env, err
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
|
@ -35,7 +33,6 @@ func (p *provider) UpdateEnv(env models.Env) (models.Env, error) {
|
||||||
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
|
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
|
||||||
_, err := configCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions())
|
_, err := configCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating config:", err)
|
|
||||||
return env, err
|
return env, err
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package mongodb
|
package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -22,7 +21,6 @@ func (p *provider) AddSession(session models.Session) error {
|
||||||
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
|
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
|
||||||
_, err := sessionCollection.InsertOne(nil, session)
|
_, err := sessionCollection.InsertOne(nil, session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error saving session`, err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -33,7 +31,6 @@ func (p *provider) DeleteSession(userId string) error {
|
||||||
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
|
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
|
||||||
_, err := sessionCollection.DeleteMany(nil, bson.M{"user_id": userId}, options.Delete())
|
_, err := sessionCollection.DeleteMany(nil, bson.M{"user_id": userId}, options.Delete())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting session:", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package mongodb
|
package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
|
||||||
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
||||||
_, err := userCollection.InsertOne(nil, user)
|
_, err := userCollection.InsertOne(nil, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding user:", err)
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +40,6 @@ func (p *provider) UpdateUser(user models.User) (models.User, error) {
|
||||||
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
||||||
_, err := userCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions())
|
_, err := userCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
|
@ -53,7 +50,6 @@ func (p *provider) DeleteUser(user models.User) error {
|
||||||
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
||||||
_, err := userCollection.DeleteOne(nil, bson.M{"_id": user.ID}, options.Delete())
|
_, err := userCollection.DeleteOne(nil, bson.M{"_id": user.ID}, options.Delete())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting user:", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +70,6 @@ func (p *provider) ListUsers(pagination model.Pagination) (*model.Users, error)
|
||||||
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
userCollection := p.db.Collection(models.Collections.User, options.Collection())
|
||||||
count, err := userCollection.CountDocuments(nil, bson.M{}, options.Count())
|
count, err := userCollection.CountDocuments(nil, bson.M{}, options.Count())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting total users:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +77,6 @@ func (p *provider) ListUsers(pagination model.Pagination) (*model.Users, error)
|
||||||
|
|
||||||
cursor, err := userCollection.Find(nil, bson.M{}, opts)
|
cursor, err := userCollection.Find(nil, bson.M{}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting users:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close(nil)
|
defer cursor.Close(nil)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package mongodb
|
package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -22,7 +21,6 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
|
||||||
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
|
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
|
||||||
_, err := verificationRequestCollection.InsertOne(nil, verificationRequest)
|
_, err := verificationRequestCollection.InsertOne(nil, verificationRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error saving verification record:", err)
|
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +71,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
|
||||||
|
|
||||||
cursor, err := verificationRequestCollection.Find(nil, bson.M{}, opts)
|
cursor, err := verificationRequestCollection.Find(nil, bson.M{}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting verification requests:", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close(nil)
|
defer cursor.Close(nil)
|
||||||
|
@ -98,7 +95,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
|
||||||
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
|
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
|
||||||
_, err := verificationRequestCollection.DeleteOne(nil, bson.M{"_id": verificationRequest.ID}, options.Delete())
|
_, err := verificationRequestCollection.DeleteOne(nil, bson.M{"_id": verificationRequest.ID}, options.Delete())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting verification request::", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -20,7 +19,6 @@ func (p *provider) AddEnv(env models.Env) (models.Env, error) {
|
||||||
|
|
||||||
result := p.db.Create(&env)
|
result := p.db.Create(&env)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error adding config:", result.Error)
|
|
||||||
return env, result.Error
|
return env, result.Error
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
|
@ -32,7 +30,6 @@ func (p *provider) UpdateEnv(env models.Env) (models.Env, error) {
|
||||||
result := p.db.Save(&env)
|
result := p.db.Save(&env)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error updating config:", result.Error)
|
|
||||||
return env, result.Error
|
return env, result.Error
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -23,7 +22,6 @@ func (p *provider) AddSession(session models.Session) error {
|
||||||
DoNothing: true,
|
DoNothing: true,
|
||||||
}).Create(&session)
|
}).Create(&session)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log.Println(`error saving session`, res.Error)
|
|
||||||
return res.Error
|
return res.Error
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -34,7 +32,6 @@ func (p *provider) DeleteSession(userId string) error {
|
||||||
result := p.db.Where("user_id = ?", userId).Delete(&models.Session{})
|
result := p.db.Where("user_id = ?", userId).Delete(&models.Session{})
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error deleting session:`, result.Error)
|
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -33,7 +32,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
|
||||||
}).Create(&user)
|
}).Create(&user)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error adding user:", result.Error)
|
|
||||||
return user, result.Error
|
return user, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +45,6 @@ func (p *provider) UpdateUser(user models.User) (models.User, error) {
|
||||||
result := p.db.Save(&user)
|
result := p.db.Save(&user)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error updating user:", result.Error)
|
|
||||||
return user, result.Error
|
return user, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +56,6 @@ func (p *provider) DeleteUser(user models.User) error {
|
||||||
result := p.db.Delete(&user)
|
result := p.db.Delete(&user)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error deleting user:`, result.Error)
|
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +67,6 @@ func (p *provider) ListUsers(pagination model.Pagination) (*model.Users, error)
|
||||||
var users []models.User
|
var users []models.User
|
||||||
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users)
|
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error getting users:", result.Error)
|
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -25,7 +24,6 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
|
||||||
}).Create(&verificationRequest)
|
}).Create(&verificationRequest)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error saving verification request record`, result.Error)
|
|
||||||
return verificationRequest, result.Error
|
return verificationRequest, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +36,6 @@ func (p *provider) GetVerificationRequestByToken(token string) (models.Verificat
|
||||||
result := p.db.Where("token = ?", token).First(&verificationRequest)
|
result := p.db.Where("token = ?", token).First(&verificationRequest)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error getting verification request:`, result.Error)
|
|
||||||
return verificationRequest, result.Error
|
return verificationRequest, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +49,6 @@ func (p *provider) GetVerificationRequestByEmail(email string, identifier string
|
||||||
result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest)
|
result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error getting verification token:`, result.Error)
|
|
||||||
return verificationRequest, result.Error
|
return verificationRequest, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +61,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
|
||||||
|
|
||||||
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&verificationRequests)
|
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&verificationRequests)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error getting verification requests:", result.Error)
|
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +89,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
|
||||||
result := p.db.Delete(&verificationRequest)
|
result := p.db.Delete(&verificationRequest)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println(`error deleting verification request:`, result.Error)
|
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
gomail "gopkg.in/mail.v2"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
gomail "gopkg.in/mail.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// addEmailTemplate is used to add html template in email body
|
// addEmailTemplate is used to add html template in email body
|
||||||
|
@ -46,7 +47,7 @@ func SendMail(to []string, Subject, bodyMessage string) error {
|
||||||
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 {
|
||||||
log.Printf("smtp error: %s", err)
|
log.Debug("SMTP Failed: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package email
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
@ -107,7 +107,7 @@ func InviteEmail(toEmail, token, verificationURL, redirectURI string) error {
|
||||||
|
|
||||||
err := SendMail(Receiver, Subject, message)
|
err := SendMail(Receiver, Subject, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error sending email:", err)
|
log.Warn("error sending email: ", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package email
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
|
@ -107,7 +107,7 @@ func SendVerificationMail(toEmail, token, hostname string) error {
|
||||||
|
|
||||||
err := SendMail(Receiver, Subject, message)
|
err := SendMail(Receiver, Subject, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error sending email:", err)
|
log.Warn("error sending email: ", err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
18
server/env/env.go
vendored
18
server/env/env.go
vendored
|
@ -2,17 +2,17 @@ package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitRequiredEnv to initialize EnvData and through error if required env are not present
|
// InitRequiredEnv to initialize EnvData and through error if required env are not present
|
||||||
|
@ -29,10 +29,11 @@ func InitRequiredEnv() error {
|
||||||
if envstore.ARG_ENV_FILE != nil && *envstore.ARG_ENV_FILE != "" {
|
if envstore.ARG_ENV_FILE != nil && *envstore.ARG_ENV_FILE != "" {
|
||||||
envPath = *envstore.ARG_ENV_FILE
|
envPath = *envstore.ARG_ENV_FILE
|
||||||
}
|
}
|
||||||
|
log.Info("env path: ", envPath)
|
||||||
|
|
||||||
err := godotenv.Load(envPath)
|
err := godotenv.Load(envPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("using OS env instead of %s file", envPath)
|
log.Info("using OS env instead of %s file", envPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
|
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
|
||||||
|
@ -52,6 +53,7 @@ func InitRequiredEnv() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if dbType == "" {
|
if dbType == "" {
|
||||||
|
log.Debug("DATABASE_TYPE is not set")
|
||||||
return errors.New("invalid database type. DATABASE_TYPE is empty")
|
return errors.New("invalid database type. DATABASE_TYPE is empty")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +64,7 @@ func InitRequiredEnv() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
|
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
|
||||||
|
log.Debug("DATABASE_URL is not set")
|
||||||
return errors.New("invalid database url. DATABASE_URL is required")
|
return errors.New("invalid database url. DATABASE_URL is required")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +94,7 @@ func InitRequiredEnv() error {
|
||||||
func InitAllEnv() error {
|
func InitAllEnv() error {
|
||||||
envData, err := GetEnvData()
|
envData, err := GetEnvData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("No env data found in db, using local clone of env data")
|
log.Info("No env data found in db, using local clone of env data")
|
||||||
// get clone of current store
|
// get clone of current store
|
||||||
envData = envstore.EnvStoreObj.GetEnvStoreClone()
|
envData = envstore.EnvStoreObj.GetEnvStoreClone()
|
||||||
}
|
}
|
||||||
|
@ -118,7 +121,6 @@ func InitAllEnv() error {
|
||||||
|
|
||||||
if envData.StringEnv[constants.EnvKeyEnv] == "production" {
|
if envData.StringEnv[constants.EnvKeyEnv] == "production" {
|
||||||
envData.BoolEnv[constants.EnvKeyIsProd] = true
|
envData.BoolEnv[constants.EnvKeyIsProd] = true
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
} else {
|
} else {
|
||||||
envData.BoolEnv[constants.EnvKeyIsProd] = false
|
envData.BoolEnv[constants.EnvKeyIsProd] = false
|
||||||
}
|
}
|
||||||
|
@ -179,6 +181,7 @@ func InitAllEnv() error {
|
||||||
} else {
|
} else {
|
||||||
algo = envData.StringEnv[constants.EnvKeyJwtType]
|
algo = envData.StringEnv[constants.EnvKeyJwtType]
|
||||||
if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
|
if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
|
||||||
|
log.Debug("Invalid JWT Algorithm")
|
||||||
return errors.New("invalid JWT_TYPE")
|
return errors.New("invalid JWT_TYPE")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,6 +387,7 @@ func InitAllEnv() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(roles) > 0 && len(defaultRoles) == 0 && len(defaultRolesEnv) > 0 {
|
if len(roles) > 0 && len(defaultRoles) == 0 && len(defaultRolesEnv) > 0 {
|
||||||
|
log.Debug("Default roles not found in roles list. It can be one from ROLES only")
|
||||||
return errors.New(`invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
return errors.New(`invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
server/env/persist_env.go
vendored
17
server/env/persist_env.go
vendored
|
@ -2,12 +2,12 @@ package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -23,12 +23,14 @@ func GetEnvData() (envstore.Store, error) {
|
||||||
env, err := db.Provider.GetEnv()
|
env, err := db.Provider.GetEnv()
|
||||||
// config not found in db
|
// config not found in db
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while getting env data from db: ", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionKey := env.Hash
|
encryptionKey := env.Hash
|
||||||
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
|
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting encryption key: ", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,16 +38,19 @@ func GetEnvData() (envstore.Store, error) {
|
||||||
|
|
||||||
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
|
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting env data from B64: ", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
|
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting env data from AES: ", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(decryptedConfigs, &result)
|
err = json.Unmarshal(decryptedConfigs, &result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while unmarshalling env data: ", err)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +69,7 @@ func PersistEnv() error {
|
||||||
|
|
||||||
encryptedConfig, err := crypto.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone())
|
encryptedConfig, err := crypto.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while encrypting env data: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +80,7 @@ func PersistEnv() error {
|
||||||
|
|
||||||
env, err = db.Provider.AddEnv(env)
|
env, err = db.Provider.AddEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while persisting env data to db: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,6 +89,7 @@ func PersistEnv() error {
|
||||||
encryptionKey := env.Hash
|
encryptionKey := env.Hash
|
||||||
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
|
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting encryption key: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +97,13 @@ func PersistEnv() error {
|
||||||
|
|
||||||
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
|
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting env data from B64: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
|
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while decrypting env data from AES: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +112,7 @@ func PersistEnv() error {
|
||||||
|
|
||||||
err = json.Unmarshal(decryptedConfigs, &storeData)
|
err = json.Unmarshal(decryptedConfigs, &storeData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while unmarshalling env data: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +180,7 @@ func PersistEnv() error {
|
||||||
envstore.EnvStoreObj.UpdateEnvStore(storeData)
|
envstore.EnvStoreObj.UpdateEnvStore(storeData)
|
||||||
jwk, err := crypto.GenerateJWKBasedOnEnv()
|
jwk, err := crypto.GenerateJWKBasedOnEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while generating JWK: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// updating jwk
|
// updating jwk
|
||||||
|
@ -177,13 +189,14 @@ func PersistEnv() error {
|
||||||
if hasChanged {
|
if hasChanged {
|
||||||
encryptedConfig, err := crypto.EncryptEnvData(storeData)
|
encryptedConfig, err := crypto.EncryptEnvData(storeData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error while encrypting env data: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
env.EnvData = encryptedConfig
|
env.EnvData = encryptedConfig
|
||||||
_, err = db.Provider.UpdateEnv(env)
|
_, err = db.Provider.UpdateEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating config:", err)
|
log.Debug("Failed to Update Config: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ var (
|
||||||
ARG_DB_TYPE *string
|
ARG_DB_TYPE *string
|
||||||
// ARG_ENV_FILE is the cli arg variable for the env file
|
// ARG_ENV_FILE is the cli arg variable for the env file
|
||||||
ARG_ENV_FILE *string
|
ARG_ENV_FILE *string
|
||||||
|
// ARG_LOG_LEVEL is the cli arg variable for the log level
|
||||||
|
ARG_LOG_LEVEL *string
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store data structure
|
// Store data structure
|
||||||
|
|
|
@ -20,6 +20,7 @@ require (
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
||||||
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/ugorji/go v1.2.6 // indirect
|
github.com/ugorji/go v1.2.6 // indirect
|
||||||
github.com/vektah/gqlparser/v2 v2.2.0
|
github.com/vektah/gqlparser/v2 v2.2.0
|
||||||
|
|
|
@ -331,6 +331,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// State is the struct that holds authorizer url and redirect url
|
// State is the struct that holds authorizer url and redirect url
|
||||||
|
@ -23,6 +24,7 @@ func AppHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
hostname := utils.GetHost(c)
|
hostname := utils.GetHost(c)
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
||||||
|
log.Debug("Login page is disabled")
|
||||||
c.JSON(400, gin.H{"error": "login page is not enabled"})
|
c.JSON(400, gin.H{"error": "login page is not enabled"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -43,6 +45,7 @@ func AppHandler() gin.HandlerFunc {
|
||||||
} else {
|
} else {
|
||||||
// validate redirect url with allowed origins
|
// validate redirect url with allowed origins
|
||||||
if !utils.IsValidOrigin(redirect_uri) {
|
if !utils.IsValidOrigin(redirect_uri) {
|
||||||
|
log.Debug("Invalid redirect_uri")
|
||||||
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -52,7 +55,7 @@ func AppHandler() gin.HandlerFunc {
|
||||||
if pusher := c.Writer.Pusher(); pusher != nil {
|
if pusher := c.Writer.Pusher(); pusher != nil {
|
||||||
// use pusher.Push() to do server push
|
// use pusher.Push() to do server push
|
||||||
if err := pusher.Push("/app/build/bundle.js", nil); err != nil {
|
if err := pusher.Push("/app/build/bundle.js", nil); err != nil {
|
||||||
log.Printf("Failed to push: %v", err)
|
log.Debug("Failed to push file path: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "app.tmpl", gin.H{
|
c.HTML(http.StatusOK, "app.tmpl", gin.H{
|
||||||
|
|
|
@ -6,14 +6,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"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/gin-gonic/gin"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthorizeHandler is the handler for the /authorize route
|
// AuthorizeHandler is the handler for the /authorize route
|
||||||
|
@ -48,6 +50,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if responseMode != "query" && responseMode != "web_message" {
|
if responseMode != "query" && responseMode != "web_message" {
|
||||||
|
log.Debug("Invalid response_mode: ", responseMode)
|
||||||
gc.JSON(400, gin.H{"error": "invalid response mode"})
|
gc.JSON(400, gin.H{"error": "invalid response mode"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +66,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isQuery {
|
if isQuery {
|
||||||
gc.Redirect(http.StatusFound, loginURL)
|
gc.Redirect(http.StatusFound, loginURL)
|
||||||
} else {
|
} else {
|
||||||
|
log.Debug("Failed to get client_id: ", clientID)
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
|
@ -80,6 +84,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isQuery {
|
if isQuery {
|
||||||
gc.Redirect(http.StatusFound, loginURL)
|
gc.Redirect(http.StatusFound, loginURL)
|
||||||
} else {
|
} else {
|
||||||
|
log.Debug("Invalid client_id: ", clientID)
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
|
@ -97,6 +102,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isQuery {
|
if isQuery {
|
||||||
gc.Redirect(http.StatusFound, loginURL)
|
gc.Redirect(http.StatusFound, loginURL)
|
||||||
} else {
|
} else {
|
||||||
|
log.Debug("Failed to get state: ", state)
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
|
@ -121,6 +127,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isQuery {
|
if isQuery {
|
||||||
gc.Redirect(http.StatusFound, loginURL)
|
gc.Redirect(http.StatusFound, loginURL)
|
||||||
} else {
|
} else {
|
||||||
|
log.Debug("Invalid response_type: ", responseType)
|
||||||
gc.HTML(http.StatusOK, template, gin.H{
|
gc.HTML(http.StatusOK, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
|
@ -139,6 +146,7 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
if isQuery {
|
if isQuery {
|
||||||
gc.Redirect(http.StatusFound, loginURL)
|
gc.Redirect(http.StatusFound, loginURL)
|
||||||
} else {
|
} else {
|
||||||
|
log.Debug("Failed to get code_challenge: ", codeChallenge)
|
||||||
gc.HTML(http.StatusBadRequest, template, gin.H{
|
gc.HTML(http.StatusBadRequest, template, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": map[string]interface{}{
|
"authorization_response": map[string]interface{}{
|
||||||
|
|
|
@ -3,9 +3,11 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func JWKsHandler() gin.HandlerFunc {
|
func JWKsHandler() gin.HandlerFunc {
|
||||||
|
@ -14,6 +16,7 @@ func JWKsHandler() gin.HandlerFunc {
|
||||||
jwk := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJWK)
|
jwk := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJWK)
|
||||||
err := json.Unmarshal([]byte(jwk), &data)
|
err := json.Unmarshal([]byte(jwk), &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to parse JWK: ", err)
|
||||||
c.JSON(500, gin.H{
|
c.JSON(500, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,10 +4,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler to logout user
|
// Handler to logout user
|
||||||
|
@ -17,6 +19,7 @@ func LogoutHandler() gin.HandlerFunc {
|
||||||
// get fingerprint hash
|
// get fingerprint hash
|
||||||
fingerprintHash, err := cookie.GetSession(gc)
|
fingerprintHash, err := cookie.GetSession(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get session: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
@ -25,6 +28,7 @@ func LogoutHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
|
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to decrypt fingerprint: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,12 +5,16 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"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"
|
||||||
|
@ -20,9 +24,6 @@ import (
|
||||||
"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"
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuthCallbackHandler handles the OAuth callback for various oauth providers
|
// OAuthCallbackHandler handles the OAuth callback for various oauth providers
|
||||||
|
@ -33,6 +34,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
sessionState := sessionstore.GetState(state)
|
sessionState := sessionstore.GetState(state)
|
||||||
if sessionState == "" {
|
if sessionState == "" {
|
||||||
|
log.Debug("Invalid oauth state: ", state)
|
||||||
c.JSON(400, gin.H{"error": "invalid oauth state"})
|
c.JSON(400, gin.H{"error": "invalid oauth state"})
|
||||||
}
|
}
|
||||||
sessionstore.GetState(state)
|
sessionstore.GetState(state)
|
||||||
|
@ -40,6 +42,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
sessionSplit := strings.Split(state, "___")
|
sessionSplit := strings.Split(state, "___")
|
||||||
|
|
||||||
if len(sessionSplit) < 3 {
|
if len(sessionSplit) < 3 {
|
||||||
|
log.Debug("Unable to get redirect url from state: ", state)
|
||||||
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -60,18 +63,22 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
case constants.SignupMethodFacebook:
|
case constants.SignupMethodFacebook:
|
||||||
user, err = processFacebookUserInfo(code)
|
user, err = processFacebookUserInfo(code)
|
||||||
default:
|
default:
|
||||||
|
log.Info("Invalid oauth provider")
|
||||||
err = fmt.Errorf(`invalid oauth provider`)
|
err = fmt.Errorf(`invalid oauth provider`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to process user info: ", err)
|
||||||
c.JSON(400, gin.H{"error": err.Error()})
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
existingUser, err := db.Provider.GetUserByEmail(user.Email)
|
existingUser, err := db.Provider.GetUserByEmail(user.Email)
|
||||||
|
log := log.WithField("user", user.Email)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
||||||
|
log.Debug("Failed to signup as disabled")
|
||||||
c.JSON(400, gin.H{"error": "signup is disabled for this instance"})
|
c.JSON(400, gin.H{"error": "signup is disabled for this instance"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -86,6 +93,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasProtectedRole {
|
if hasProtectedRole {
|
||||||
|
log.Debug("Signup is not allowed with protected roles:", inputRoles)
|
||||||
c.JSON(400, gin.H{"error": "invalid role"})
|
c.JSON(400, gin.H{"error": "invalid role"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -96,6 +104,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
user, _ = db.Provider.AddUser(user)
|
user, _ = db.Provider.AddUser(user)
|
||||||
} else {
|
} else {
|
||||||
if user.RevokedTimestamp != nil {
|
if user.RevokedTimestamp != nil {
|
||||||
|
log.Debug("User access revoked at: ", user.RevokedTimestamp)
|
||||||
c.JSON(400, gin.H{"error": "user access has been revoked"})
|
c.JSON(400, gin.H{"error": "user access has been revoked"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +146,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasProtectedRole {
|
if hasProtectedRole {
|
||||||
|
log.Debug("Invalid role. User is using protected unassigned role")
|
||||||
c.JSON(400, gin.H{"error": "invalid role"})
|
c.JSON(400, gin.H{"error": "invalid role"})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,6 +158,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
user, err = db.Provider.UpdateUser(user)
|
user, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to update user: ", err)
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -155,6 +166,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(c, user, inputRoles, scopes)
|
authToken, err := token.CreateAuthToken(c, user, inputRoles, scopes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create auth token: ", err)
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +206,7 @@ func processGoogleUserInfo(code string) (models.User, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
|
oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to exchange code for token: ", err)
|
||||||
return user, fmt.Errorf("invalid google exchange code: %s", err.Error())
|
return user, fmt.Errorf("invalid google exchange code: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,16 +215,19 @@ func processGoogleUserInfo(code string) (models.User, error) {
|
||||||
// Extract the ID Token from OAuth2 token.
|
// Extract the ID Token from OAuth2 token.
|
||||||
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
|
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
log.Debug("Failed to extract ID Token from OAuth2 token")
|
||||||
return user, fmt.Errorf("unable to extract id_token")
|
return user, fmt.Errorf("unable to extract id_token")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse and verify ID Token payload.
|
// Parse and verify ID Token payload.
|
||||||
idToken, err := verifier.Verify(ctx, rawIDToken)
|
idToken, err := verifier.Verify(ctx, rawIDToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to verify ID Token: ", err)
|
||||||
return user, fmt.Errorf("unable to verify id_token: %s", err.Error())
|
return user, fmt.Errorf("unable to verify id_token: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := idToken.Claims(&user); err != nil {
|
if err := idToken.Claims(&user); err != nil {
|
||||||
|
log.Debug("Failed to parse ID Token claims: ", err)
|
||||||
return user, fmt.Errorf("unable to extract claims")
|
return user, fmt.Errorf("unable to extract claims")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,11 +238,13 @@ func processGithubUserInfo(code string) (models.User, error) {
|
||||||
user := models.User{}
|
user := models.User{}
|
||||||
token, err := oauth.OAuthProviders.GithubConfig.Exchange(oauth2.NoContext, code)
|
token, err := oauth.OAuthProviders.GithubConfig.Exchange(oauth2.NoContext, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to exchange code for token: ", err)
|
||||||
return user, fmt.Errorf("invalid github exchange code: %s", err.Error())
|
return user, fmt.Errorf("invalid github exchange code: %s", err.Error())
|
||||||
}
|
}
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
req, err := http.NewRequest("GET", constants.GithubUserInfoURL, nil)
|
req, err := http.NewRequest("GET", constants.GithubUserInfoURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create github user info request: ", err)
|
||||||
return user, fmt.Errorf("error creating github user info request: %s", err.Error())
|
return user, fmt.Errorf("error creating github user info request: %s", err.Error())
|
||||||
}
|
}
|
||||||
req.Header = http.Header{
|
req.Header = http.Header{
|
||||||
|
@ -235,12 +253,14 @@ func processGithubUserInfo(code string) (models.User, error) {
|
||||||
|
|
||||||
response, err := client.Do(req)
|
response, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to request github user info: ", err)
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
body, err := ioutil.ReadAll(response.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to read github user info response body: ", err)
|
||||||
return user, fmt.Errorf("failed to read github response body: %s", err.Error())
|
return user, fmt.Errorf("failed to read github response body: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,23 +293,26 @@ func processFacebookUserInfo(code string) (models.User, error) {
|
||||||
user := models.User{}
|
user := models.User{}
|
||||||
token, err := oauth.OAuthProviders.FacebookConfig.Exchange(oauth2.NoContext, code)
|
token, err := oauth.OAuthProviders.FacebookConfig.Exchange(oauth2.NoContext, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Invalid facebook exchange code: ", err)
|
||||||
return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
|
return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
|
||||||
}
|
}
|
||||||
client := http.Client{}
|
client := http.Client{}
|
||||||
req, err := http.NewRequest("GET", constants.FacebookUserInfoURL+token.AccessToken, nil)
|
req, err := http.NewRequest("GET", constants.FacebookUserInfoURL+token.AccessToken, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error creating facebook user info request: ", err)
|
||||||
return user, fmt.Errorf("error creating facebook user info request: %s", err.Error())
|
return user, fmt.Errorf("error creating facebook user info request: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := client.Do(req)
|
response, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error processing facebook user info:", err)
|
log.Debug("Failed to process facebook user: ", err)
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
body, err := ioutil.ReadAll(response.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to read facebook response: ", err)
|
||||||
return user, fmt.Errorf("failed to read facebook response body: %s", err.Error())
|
return user, fmt.Errorf("failed to read facebook response body: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,14 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/oauth"
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
|
// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
|
||||||
|
@ -26,6 +28,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
scopeString := strings.TrimSpace(c.Query("scope"))
|
scopeString := strings.TrimSpace(c.Query("scope"))
|
||||||
|
|
||||||
if redirectURI == "" {
|
if redirectURI == "" {
|
||||||
|
log.Debug("redirect_uri is empty")
|
||||||
c.JSON(400, gin.H{
|
c.JSON(400, gin.H{
|
||||||
"error": "invalid redirect uri",
|
"error": "invalid redirect uri",
|
||||||
})
|
})
|
||||||
|
@ -33,6 +36,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if state == "" {
|
if state == "" {
|
||||||
|
log.Debug("state is empty")
|
||||||
c.JSON(400, gin.H{
|
c.JSON(400, gin.H{
|
||||||
"error": "invalid state",
|
"error": "invalid state",
|
||||||
})
|
})
|
||||||
|
@ -53,6 +57,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
// use protected roles verification for admin login only.
|
// use protected roles verification for admin login only.
|
||||||
// though if not associated with user, it will be rejected from oauth_callback
|
// though if not associated with user, it will be rejected from oauth_callback
|
||||||
if !utils.IsValidRoles(rolesSplit, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) {
|
if !utils.IsValidRoles(rolesSplit, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) {
|
||||||
|
log.Debug("Invalid roles: ", roles)
|
||||||
c.JSON(400, gin.H{
|
c.JSON(400, gin.H{
|
||||||
"error": "invalid role",
|
"error": "invalid role",
|
||||||
})
|
})
|
||||||
|
@ -69,6 +74,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
switch provider {
|
switch provider {
|
||||||
case constants.SignupMethodGoogle:
|
case constants.SignupMethodGoogle:
|
||||||
if oauth.OAuthProviders.GoogleConfig == nil {
|
if oauth.OAuthProviders.GoogleConfig == nil {
|
||||||
|
log.Debug("Google OAuth provider is not configured")
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -79,6 +85,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
case constants.SignupMethodGithub:
|
case constants.SignupMethodGithub:
|
||||||
if oauth.OAuthProviders.GithubConfig == nil {
|
if oauth.OAuthProviders.GithubConfig == nil {
|
||||||
|
log.Debug("Github OAuth provider is not configured")
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -88,6 +95,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
case constants.SignupMethodFacebook:
|
case constants.SignupMethodFacebook:
|
||||||
if oauth.OAuthProviders.FacebookConfig == nil {
|
if oauth.OAuthProviders.FacebookConfig == nil {
|
||||||
|
log.Debug("Facebook OAuth provider is not configured")
|
||||||
isProviderConfigured = false
|
isProviderConfigured = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -96,6 +104,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
default:
|
default:
|
||||||
|
log.Debug("Invalid oauth provider: ", provider)
|
||||||
c.JSON(422, gin.H{
|
c.JSON(422, gin.H{
|
||||||
"message": "Invalid oauth provider",
|
"message": "Invalid oauth provider",
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,10 +4,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Revoke handler to revoke refresh token
|
// Revoke handler to revoke refresh token
|
||||||
|
@ -15,6 +17,7 @@ func RevokeHandler() gin.HandlerFunc {
|
||||||
return func(gc *gin.Context) {
|
return func(gc *gin.Context) {
|
||||||
var reqBody map[string]string
|
var reqBody map[string]string
|
||||||
if err := gc.BindJSON(&reqBody); err != nil {
|
if err := gc.BindJSON(&reqBody); err != nil {
|
||||||
|
log.Debug("Error binding JSON: ", err)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "error_binding_json",
|
"error": "error_binding_json",
|
||||||
"error_description": err.Error(),
|
"error_description": err.Error(),
|
||||||
|
@ -26,6 +29,7 @@ func RevokeHandler() gin.HandlerFunc {
|
||||||
clientID := strings.TrimSpace(reqBody["client_id"])
|
clientID := strings.TrimSpace(reqBody["client_id"])
|
||||||
|
|
||||||
if clientID == "" {
|
if clientID == "" {
|
||||||
|
log.Debug("Client ID is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "client_id_required",
|
"error": "client_id_required",
|
||||||
"error_description": "The client id is required",
|
"error_description": "The client id is required",
|
||||||
|
@ -34,6 +38,7 @@ func RevokeHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
||||||
|
log.Debug("Client ID is invalid: ", clientID)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_client_id",
|
"error": "invalid_client_id",
|
||||||
"error_description": "The client id is invalid",
|
"error_description": "The client id is invalid",
|
||||||
|
|
|
@ -7,13 +7,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"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/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TokenHandler to handle /oauth/token requests
|
// TokenHandler to handle /oauth/token requests
|
||||||
|
@ -22,6 +24,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return func(gc *gin.Context) {
|
return func(gc *gin.Context) {
|
||||||
var reqBody map[string]string
|
var reqBody map[string]string
|
||||||
if err := gc.BindJSON(&reqBody); err != nil {
|
if err := gc.BindJSON(&reqBody); err != nil {
|
||||||
|
log.Debug("Error binding JSON: ", err)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "error_binding_json",
|
"error": "error_binding_json",
|
||||||
"error_description": err.Error(),
|
"error_description": err.Error(),
|
||||||
|
@ -43,6 +46,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
isAuthorizationCodeGrant := grantType == "authorization_code"
|
isAuthorizationCodeGrant := grantType == "authorization_code"
|
||||||
|
|
||||||
if !isRefreshTokenGrant && !isAuthorizationCodeGrant {
|
if !isRefreshTokenGrant && !isAuthorizationCodeGrant {
|
||||||
|
log.Debug("Invalid grant type: ", grantType)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_grant_type",
|
"error": "invalid_grant_type",
|
||||||
"error_description": "grant_type is invalid",
|
"error_description": "grant_type is invalid",
|
||||||
|
@ -50,6 +54,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientID == "" {
|
if clientID == "" {
|
||||||
|
log.Debug("Client ID is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "client_id_required",
|
"error": "client_id_required",
|
||||||
"error_description": "The client id is required",
|
"error_description": "The client id is required",
|
||||||
|
@ -58,6 +63,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
|
||||||
|
log.Debug("Client ID is invalid: ", clientID)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_client_id",
|
"error": "invalid_client_id",
|
||||||
"error_description": "The client id is invalid",
|
"error_description": "The client id is invalid",
|
||||||
|
@ -70,6 +76,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
if isAuthorizationCodeGrant {
|
if isAuthorizationCodeGrant {
|
||||||
|
|
||||||
if codeVerifier == "" {
|
if codeVerifier == "" {
|
||||||
|
log.Debug("Code verifier is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code_verifier",
|
"error": "invalid_code_verifier",
|
||||||
"error_description": "The code verifier is required",
|
"error_description": "The code verifier is required",
|
||||||
|
@ -78,6 +85,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if code == "" {
|
if code == "" {
|
||||||
|
log.Debug("Code is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code",
|
"error": "invalid_code",
|
||||||
"error_description": "The code is required",
|
"error_description": "The code is required",
|
||||||
|
@ -92,6 +100,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
|
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
|
||||||
sessionData := sessionstore.GetState(encryptedCode)
|
sessionData := sessionstore.GetState(encryptedCode)
|
||||||
if sessionData == "" {
|
if sessionData == "" {
|
||||||
|
log.Debug("Session data is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code_verifier",
|
"error": "invalid_code_verifier",
|
||||||
"error_description": "The code verifier is invalid",
|
"error_description": "The code verifier is invalid",
|
||||||
|
@ -104,6 +113,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
sessionDataSplit := strings.Split(sessionData, "@")
|
sessionDataSplit := strings.Split(sessionData, "@")
|
||||||
|
|
||||||
if sessionDataSplit[0] != code {
|
if sessionDataSplit[0] != code {
|
||||||
|
log.Debug("Invalid code verifier. Unable to split session data")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code_verifier",
|
"error": "invalid_code_verifier",
|
||||||
"error_description": "The code verifier is invalid",
|
"error_description": "The code verifier is invalid",
|
||||||
|
@ -114,6 +124,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
// validate session
|
// validate session
|
||||||
claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
|
claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error validating session: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": "unauthorized",
|
"error": "unauthorized",
|
||||||
"error_description": "Invalid session data",
|
"error_description": "Invalid session data",
|
||||||
|
@ -128,6 +139,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
} else {
|
} else {
|
||||||
// validate refresh token
|
// validate refresh token
|
||||||
if refreshToken == "" {
|
if refreshToken == "" {
|
||||||
|
log.Debug("Refresh token is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_refresh_token",
|
"error": "invalid_refresh_token",
|
||||||
"error_description": "The refresh token is invalid",
|
"error_description": "The refresh token is invalid",
|
||||||
|
@ -136,6 +148,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
claims, err := token.ValidateRefreshToken(gc, refreshToken)
|
claims, err := token.ValidateRefreshToken(gc, refreshToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error validating refresh token: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": "unauthorized",
|
"error": "unauthorized",
|
||||||
"error_description": err.Error(),
|
"error_description": err.Error(),
|
||||||
|
@ -156,6 +169,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting user: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": "unauthorized",
|
"error": "unauthorized",
|
||||||
"error_description": "User not found",
|
"error_description": "User not found",
|
||||||
|
@ -165,6 +179,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error creating auth token: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": "unauthorized",
|
"error": "unauthorized",
|
||||||
"error_description": "User not found",
|
"error_description": "User not found",
|
||||||
|
|
|
@ -3,15 +3,18 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func UserInfoHandler() gin.HandlerFunc {
|
func UserInfoHandler() gin.HandlerFunc {
|
||||||
return func(gc *gin.Context) {
|
return func(gc *gin.Context) {
|
||||||
accessToken, err := token.GetAccessToken(gc)
|
accessToken, err := token.GetAccessToken(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting access token: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
@ -20,6 +23,7 @@ func UserInfoHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
claims, err := token.ValidateAccessToken(gc, accessToken)
|
claims, err := token.ValidateAccessToken(gc, accessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error validating access token: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
@ -29,6 +33,7 @@ func UserInfoHandler() gin.HandlerFunc {
|
||||||
userID := claims["sub"].(string)
|
userID := claims["sub"].(string)
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting user: ", err)
|
||||||
gc.JSON(http.StatusUnauthorized, gin.H{
|
gc.JSON(http.StatusUnauthorized, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,13 +6,15 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/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"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// VerifyEmailHandler handles the verify email route.
|
// VerifyEmailHandler handles the verify email route.
|
||||||
|
@ -24,12 +26,14 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
tokenInQuery := c.Query("token")
|
tokenInQuery := c.Query("token")
|
||||||
if tokenInQuery == "" {
|
if tokenInQuery == "" {
|
||||||
|
log.Debug("Token is empty")
|
||||||
c.JSON(400, errorRes)
|
c.JSON(400, errorRes)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByToken(tokenInQuery)
|
verificationRequest, err := db.Provider.GetVerificationRequestByToken(tokenInQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting verification request: ", err)
|
||||||
errorRes["error_description"] = err.Error()
|
errorRes["error_description"] = err.Error()
|
||||||
c.JSON(400, errorRes)
|
c.JSON(400, errorRes)
|
||||||
return
|
return
|
||||||
|
@ -39,6 +43,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
hostname := utils.GetHost(c)
|
hostname := utils.GetHost(c)
|
||||||
claim, err := token.ParseJWTToken(tokenInQuery, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
claim, err := token.ParseJWTToken(tokenInQuery, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error parsing token: ", err)
|
||||||
errorRes["error_description"] = err.Error()
|
errorRes["error_description"] = err.Error()
|
||||||
c.JSON(400, errorRes)
|
c.JSON(400, errorRes)
|
||||||
return
|
return
|
||||||
|
@ -46,6 +51,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByEmail(claim["sub"].(string))
|
user, err := db.Provider.GetUserByEmail(claim["sub"].(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting user: ", err)
|
||||||
errorRes["error_description"] = err.Error()
|
errorRes["error_description"] = err.Error()
|
||||||
c.JSON(400, errorRes)
|
c.JSON(400, errorRes)
|
||||||
return
|
return
|
||||||
|
@ -79,6 +85,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
authToken, err := token.CreateAuthToken(c, user, roles, scope)
|
authToken, err := token.CreateAuthToken(c, user, roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error creating auth token: ", err)
|
||||||
errorRes["error_description"] = err.Error()
|
errorRes["error_description"] = err.Error()
|
||||||
c.JSON(500, errorRes)
|
c.JSON(500, errorRes)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,7 +2,9 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
@ -15,13 +17,51 @@ import (
|
||||||
|
|
||||||
var VERSION string
|
var VERSION string
|
||||||
|
|
||||||
|
type LogUTCFormatter struct {
|
||||||
|
log.Formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
|
||||||
|
e.Time = e.Time.UTC()
|
||||||
|
return u.Formatter.Format(e)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
envstore.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
envstore.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
||||||
envstore.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
envstore.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
||||||
envstore.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
envstore.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
||||||
|
envstore.ARG_LOG_LEVEL = flag.String("log_level", "info", "Log level, possible values are debug,info,warn,error,fatal,panic")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.Println("=> version:", VERSION)
|
// global log level
|
||||||
|
logrus.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
|
||||||
|
logrus.SetReportCaller(true)
|
||||||
|
|
||||||
|
// log instance for gin server
|
||||||
|
log := logrus.New()
|
||||||
|
log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
|
||||||
|
log.SetReportCaller(true)
|
||||||
|
|
||||||
|
var logLevel logrus.Level
|
||||||
|
switch *envstore.ARG_LOG_LEVEL {
|
||||||
|
case "debug":
|
||||||
|
logLevel = logrus.DebugLevel
|
||||||
|
case "info":
|
||||||
|
logLevel = logrus.InfoLevel
|
||||||
|
case "warn":
|
||||||
|
logLevel = logrus.WarnLevel
|
||||||
|
case "error":
|
||||||
|
logLevel = logrus.ErrorLevel
|
||||||
|
case "fatal":
|
||||||
|
logLevel = logrus.FatalLevel
|
||||||
|
case "panic":
|
||||||
|
logLevel = logrus.PanicLevel
|
||||||
|
default:
|
||||||
|
logLevel = logrus.InfoLevel
|
||||||
|
}
|
||||||
|
logrus.SetLevel(logLevel)
|
||||||
|
log.SetLevel(logLevel)
|
||||||
|
|
||||||
constants.VERSION = VERSION
|
constants.VERSION = VERSION
|
||||||
|
|
||||||
// initialize required envs (mainly db & env file path)
|
// initialize required envs (mainly db & env file path)
|
||||||
|
@ -61,6 +101,7 @@ func main() {
|
||||||
log.Fatalln("Error while initializing oauth: ", err)
|
log.Fatalln("Error while initializing oauth: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
router := routes.InitRouter()
|
router := routes.InitRouter(log)
|
||||||
|
log.Info("Starting Authorizer: ", VERSION)
|
||||||
router.Run(":" + envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyPort))
|
router.Run(":" + envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyPort))
|
||||||
}
|
}
|
||||||
|
|
78
server/middlewares/log.go
Normal file
78
server/middlewares/log.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package middlewares
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var timeFormat = "02/Jan/2006:15:04:05 -0700"
|
||||||
|
|
||||||
|
// Logger is the logrus logger handler
|
||||||
|
func Logger(logger logrus.FieldLogger, notLogged ...string) gin.HandlerFunc {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
hostname = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
var skip map[string]struct{}
|
||||||
|
|
||||||
|
if length := len(notLogged); length > 0 {
|
||||||
|
skip = make(map[string]struct{}, length)
|
||||||
|
|
||||||
|
for _, p := range notLogged {
|
||||||
|
skip[p] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
// other handler can change c.Path so:
|
||||||
|
path := c.Request.URL.Path
|
||||||
|
start := time.Now()
|
||||||
|
c.Next()
|
||||||
|
stop := time.Since(start)
|
||||||
|
latency := int(math.Ceil(float64(stop.Nanoseconds()) / 1000000.0))
|
||||||
|
statusCode := c.Writer.Status()
|
||||||
|
clientIP := c.ClientIP()
|
||||||
|
clientUserAgent := c.Request.UserAgent()
|
||||||
|
referer := c.Request.Referer()
|
||||||
|
dataLength := c.Writer.Size()
|
||||||
|
if dataLength < 0 {
|
||||||
|
dataLength = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := skip[path]; ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := logger.WithFields(logrus.Fields{
|
||||||
|
"hostname": hostname,
|
||||||
|
"statusCode": statusCode,
|
||||||
|
"latency": latency, // time to process
|
||||||
|
"clientIP": clientIP,
|
||||||
|
"method": c.Request.Method,
|
||||||
|
"path": path,
|
||||||
|
"referer": referer,
|
||||||
|
"dataLength": dataLength,
|
||||||
|
"userAgent": clientUserAgent,
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(c.Errors) > 0 {
|
||||||
|
entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
|
||||||
|
} else {
|
||||||
|
msg := fmt.Sprintf("%s - %s [%s] \"%s %s\" %d %d \"%s\" \"%s\" (%dms)", clientIP, hostname, time.Now().Format(timeFormat), c.Request.Method, path, statusCode, dataLength, referer, clientUserAgent, latency)
|
||||||
|
if statusCode >= http.StatusInternalServerError {
|
||||||
|
entry.Error(msg)
|
||||||
|
} else if statusCode >= http.StatusBadRequest {
|
||||||
|
entry.Warn(msg)
|
||||||
|
} else {
|
||||||
|
entry.Info(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,13 @@ package oauth
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"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"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OAuthProviders is a struct that contains reference all the OAuth providers
|
// OAuthProviders is a struct that contains reference all the OAuth providers
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -14,15 +16,17 @@ import (
|
||||||
|
|
||||||
// AdminLoginResolver is a resolver for admin login mutation
|
// 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)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
if params.AdminSecret != adminSecret {
|
if params.AdminSecret != adminSecret {
|
||||||
|
log.Debug("Admin secret is not correct")
|
||||||
return res, fmt.Errorf(`invalid admin secret`)
|
return res, fmt.Errorf(`invalid admin secret`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
@ -12,14 +14,16 @@ import (
|
||||||
|
|
||||||
// AdminLogoutResolver is a resolver for admin logout mutation
|
// AdminLogoutResolver is a resolver for admin logout mutation
|
||||||
func AdminLogoutResolver(ctx context.Context) (*model.Response, error) {
|
func AdminLogoutResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Admin is not logged in")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -15,19 +17,22 @@ import (
|
||||||
|
|
||||||
// AdminSessionResolver is a resolver for admin session query
|
// AdminSessionResolver is a resolver for admin session query
|
||||||
func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
|
func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to encrypt key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
cookie.SetAdminCookie(gc, hashedKey)
|
cookie.SetAdminCookie(gc, hashedKey)
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -17,19 +19,22 @@ import (
|
||||||
|
|
||||||
// AdminSignupResolver is a resolver for admin signup mutation
|
// 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)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(params.AdminSecret) == "" {
|
if strings.TrimSpace(params.AdminSecret) == "" {
|
||||||
|
log.Debug("Admin secret is empty")
|
||||||
err = fmt.Errorf("please select secure admin secret")
|
err = fmt.Errorf("please select secure admin secret")
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(params.AdminSecret) < 6 {
|
if len(params.AdminSecret) < 6 {
|
||||||
|
log.Debug("Admin secret is too short")
|
||||||
err = fmt.Errorf("admin secret must be at least 6 characters")
|
err = fmt.Errorf("admin secret must be at least 6 characters")
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -37,6 +42,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
|
||||||
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
|
|
||||||
if adminSecret != "" {
|
if adminSecret != "" {
|
||||||
|
log.Debug("Admin secret is already set")
|
||||||
err = fmt.Errorf("admin sign up already completed")
|
err = fmt.Errorf("admin sign up already completed")
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -47,30 +53,36 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(envstore.EnvStoreObj.GetEnvStoreClone())
|
jsonBytes, err := json.Marshal(envstore.EnvStoreObj.GetEnvStoreClone())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to marshal envstore: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(jsonBytes, &storeData); err != nil {
|
if err := json.Unmarshal(jsonBytes, &storeData); err != nil {
|
||||||
|
log.Debug("Failed to unmarshal envstore: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
env, err := db.Provider.GetEnv()
|
env, err := db.Provider.GetEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get env: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
envData, err := crypto.EncryptEnvData(storeData)
|
envData, err := crypto.EncryptEnvData(storeData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to encrypt envstore: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
env.EnvData = envData
|
env.EnvData = envData
|
||||||
if _, err := db.Provider.UpdateEnv(env); err != nil {
|
if _, err := db.Provider.UpdateEnv(env); err != nil {
|
||||||
|
log.Debug("Failed to update env: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedKey, err := crypto.EncryptPassword(params.AdminSecret)
|
hashedKey, err := crypto.EncryptPassword(params.AdminSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to encrypt admin session key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
cookie.SetAdminCookie(gc, hashedKey)
|
cookie.SetAdminCookie(gc, hashedKey)
|
||||||
|
|
|
@ -3,7 +3,8 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -14,18 +15,26 @@ import (
|
||||||
|
|
||||||
// DeleteUserResolver is a resolver for delete user mutation
|
// DeleteUserResolver is a resolver for delete user mutation
|
||||||
func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": params.Email,
|
||||||
|
})
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByEmail(params.Email)
|
user, err := db.Provider.GetUserByEmail(params.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user from DB: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +42,7 @@ func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*mod
|
||||||
|
|
||||||
err = db.Provider.DeleteUser(user)
|
err = db.Provider.DeleteUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting user:", err)
|
log.Debug("Failed to delete user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -13,18 +14,26 @@ import (
|
||||||
|
|
||||||
// EnableAccessResolver is a resolver for enabling user access
|
// EnableAccessResolver is a resolver for enabling user access
|
||||||
func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
|
func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin.")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": params.UserID,
|
||||||
|
})
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByID(params.UserID)
|
user, err := db.Provider.GetUserByID(params.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user from DB: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +41,7 @@ func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (
|
||||||
|
|
||||||
user, err = db.Provider.UpdateUser(user)
|
user, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
log.Debug("Failed to update user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -14,14 +16,16 @@ import (
|
||||||
// EnvResolver is a resolver for config query
|
// EnvResolver is a resolver for config query
|
||||||
// This is admin only query
|
// This is admin only query
|
||||||
func EnvResolver(ctx context.Context) (*model.Env, error) {
|
func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Env
|
var res *model.Env
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin.")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"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/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -19,28 +20,38 @@ import (
|
||||||
|
|
||||||
// ForgotPasswordResolver is a resolver for forgot password mutation
|
// ForgotPasswordResolver is a resolver for forgot password mutation
|
||||||
func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
||||||
|
log.Debug("Basic authentication is disabled")
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
log.Debug("Invalid email address: ", params.Email)
|
||||||
return res, fmt.Errorf("invalid email")
|
return res, fmt.Errorf("invalid email")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": params.Email,
|
||||||
|
})
|
||||||
_, err = db.Provider.GetUserByEmail(params.Email)
|
_, err = db.Provider.GetUserByEmail(params.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("User not found: ", err)
|
||||||
return res, fmt.Errorf(`user with this email not found`)
|
return res, fmt.Errorf(`user with this email not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname := utils.GetHost(gc)
|
hostname := utils.GetHost(gc)
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
redirectURL := utils.GetAppURL(gc) + "/reset-password"
|
redirectURL := utils.GetAppURL(gc) + "/reset-password"
|
||||||
|
@ -50,9 +61,10 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||||
|
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token", err)
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
Identifier: constants.VerificationTypeForgotPassword,
|
Identifier: constants.VerificationTypeForgotPassword,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
@ -60,6 +72,10 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||||
Nonce: nonceHash,
|
Nonce: nonceHash,
|
||||||
RedirectURI: redirectURL,
|
RedirectURI: redirectURL,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// 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 email.SendForgotPasswordMail(params.Email, verificationToken, hostname)
|
go email.SendForgotPasswordMail(params.Email, verificationToken, hostname)
|
||||||
|
|
|
@ -10,16 +10,19 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerateJWTKeysResolver mutation to generate new jwt keys
|
// GenerateJWTKeysResolver mutation to generate new jwt keys
|
||||||
func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
|
func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +30,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
|
||||||
if crypto.IsHMACA(params.Type) {
|
if crypto.IsHMACA(params.Type) {
|
||||||
secret, _, err := crypto.NewHMACKey(params.Type, clientID)
|
secret, _, err := crypto.NewHMACKey(params.Type, clientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate new HMAC key: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &model.GenerateJWTKeysResponse{
|
return &model.GenerateJWTKeysResponse{
|
||||||
|
@ -37,6 +41,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
|
||||||
if crypto.IsRSA(params.Type) {
|
if crypto.IsRSA(params.Type) {
|
||||||
_, privateKey, publicKey, _, err := crypto.NewRSAKey(params.Type, clientID)
|
_, privateKey, publicKey, _, err := crypto.NewRSAKey(params.Type, clientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate new RSA key: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &model.GenerateJWTKeysResponse{
|
return &model.GenerateJWTKeysResponse{
|
||||||
|
@ -48,6 +53,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
|
||||||
if crypto.IsECDSA(params.Type) {
|
if crypto.IsECDSA(params.Type) {
|
||||||
_, privateKey, publicKey, _, err := crypto.NewECDSAKey(params.Type, clientID)
|
_, privateKey, publicKey, _, err := crypto.NewECDSAKey(params.Type, clientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate new ECDSA key: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &model.GenerateJWTKeysResponse{
|
return &model.GenerateJWTKeysResponse{
|
||||||
|
@ -56,5 +62,6 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("Invalid algorithm: ", params.Type)
|
||||||
return nil, fmt.Errorf("invalid algorithm")
|
return nil, fmt.Errorf("invalid algorithm")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"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/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -22,19 +23,23 @@ import (
|
||||||
func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
|
func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin.")
|
||||||
return nil, errors.New("unauthorized")
|
return nil, errors.New("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
// this feature is only allowed if email server is configured
|
// this feature is only allowed if email server is configured
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
||||||
|
log.Debug("Email server is not configured")
|
||||||
return nil, errors.New("email sending is disabled")
|
return nil, errors.New("email sending is disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) && envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) && envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
||||||
|
log.Debug("Basic authentication and Magic link login is disabled.")
|
||||||
return nil, errors.New("either basic authentication or magic link login is required")
|
return nil, errors.New("either basic authentication or magic link login is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +52,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(emails) == 0 {
|
if len(emails) == 0 {
|
||||||
|
log.Debug("No valid email addresses")
|
||||||
return nil, errors.New("no valid emails found")
|
return nil, errors.New("no valid emails found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,14 +62,15 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
|
||||||
for _, email := range emails {
|
for _, email := range emails {
|
||||||
_, err := db.Provider.GetUserByEmail(email)
|
_, err := db.Provider.GetUserByEmail(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s user not found. inviting user.", email)
|
log.Debugf("User with %s email not found, so inviting user", email)
|
||||||
newEmails = append(newEmails, email)
|
newEmails = append(newEmails, email)
|
||||||
} else {
|
} else {
|
||||||
log.Println("%s user already exists. skipping.", email)
|
log.Debugf("User with %s email already exists, so not inviting user", email)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(newEmails) == 0 {
|
if len(newEmails) == 0 {
|
||||||
|
log.Debug("No new emails found.")
|
||||||
return nil, errors.New("all emails already exist")
|
return nil, errors.New("all emails already exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +97,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
|
||||||
|
|
||||||
verificationToken, err := token.CreateVerificationToken(email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest := models.VerificationRequest{
|
verificationRequest := models.VerificationRequest{
|
||||||
|
@ -116,13 +123,13 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
|
||||||
|
|
||||||
user, err = db.Provider.AddUser(user)
|
user, err = db.Provider.AddUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error inviting user: %s, err: %v", email, err)
|
log.Debugf("Error adding user: %s, err: %v", email, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Provider.AddVerificationRequest(verificationRequest)
|
_, err = db.Provider.AddVerificationRequest(verificationRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error inviting user: %s, err: %v", email, err)
|
log.Debugf("Error adding verification request: %s, err: %v", email, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"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"
|
||||||
|
@ -16,49 +18,59 @@ import (
|
||||||
"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"
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoginResolver is a resolver for login mutation
|
// LoginResolver is a resolver for login mutation
|
||||||
func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
||||||
|
log.Debug("Basic authentication is disabled.")
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": params.Email,
|
||||||
|
})
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
user, err := db.Provider.GetUserByEmail(params.Email)
|
user, err := db.Provider.GetUserByEmail(params.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user by email: ", err)
|
||||||
return res, fmt.Errorf(`user with this email not found`)
|
return res, fmt.Errorf(`user with this email not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.RevokedTimestamp != nil {
|
if user.RevokedTimestamp != nil {
|
||||||
|
log.Debug("User access is revoked")
|
||||||
return res, fmt.Errorf(`user access has been revoked`)
|
return res, fmt.Errorf(`user access has been revoked`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(user.SignupMethods, constants.SignupMethodBasicAuth) {
|
if !strings.Contains(user.SignupMethods, constants.SignupMethodBasicAuth) {
|
||||||
|
log.Debug("User signup method is not basic auth")
|
||||||
return res, fmt.Errorf(`user has not signed up email & password`)
|
return res, fmt.Errorf(`user has not signed up email & password`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.EmailVerifiedAt == nil {
|
if user.EmailVerifiedAt == nil {
|
||||||
|
log.Debug("User email is not verified")
|
||||||
return res, fmt.Errorf(`email not verified`)
|
return res, fmt.Errorf(`email not verified`)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
|
err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("compare password error:", err)
|
log.Debug("Failed to compare password: ", err)
|
||||||
return res, fmt.Errorf(`invalid password`)
|
return res, fmt.Errorf(`invalid password`)
|
||||||
}
|
}
|
||||||
roles := envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles)
|
roles := envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles)
|
||||||
currentRoles := strings.Split(user.Roles, ",")
|
currentRoles := strings.Split(user.Roles, ",")
|
||||||
if len(params.Roles) > 0 {
|
if len(params.Roles) > 0 {
|
||||||
if !utils.IsValidRoles(params.Roles, currentRoles) {
|
if !utils.IsValidRoles(params.Roles, currentRoles) {
|
||||||
|
log.Debug("Invalid roles: ", params.Roles)
|
||||||
return res, fmt.Errorf(`invalid roles`)
|
return res, fmt.Errorf(`invalid roles`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +84,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create auth token", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -12,20 +14,24 @@ import (
|
||||||
|
|
||||||
// LogoutResolver is a resolver for logout mutation
|
// LogoutResolver is a resolver for logout mutation
|
||||||
func LogoutResolver(ctx context.Context) (*model.Response, error) {
|
func LogoutResolver(ctx context.Context) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get fingerprint hash
|
// get fingerprint hash
|
||||||
fingerprintHash, err := cookie.GetSession(gc)
|
fingerprintHash, err := cookie.GetSession(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get fingerprint hash: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
|
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to decrypt fingerprint hash: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"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/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -20,21 +21,29 @@ import (
|
||||||
// MagicLinkLoginResolver is a resolver for magic link login mutation
|
// MagicLinkLoginResolver is a resolver for magic link login mutation
|
||||||
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
||||||
|
log.Debug("Magic link login is disabled.")
|
||||||
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
log.Debug("Invalid email")
|
||||||
return res, fmt.Errorf(`invalid email address`)
|
return res, fmt.Errorf(`invalid email address`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": params.Email,
|
||||||
|
})
|
||||||
|
|
||||||
inputRoles := []string{}
|
inputRoles := []string{}
|
||||||
|
|
||||||
user := models.User{
|
user := models.User{
|
||||||
|
@ -45,6 +54,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
existingUser, err := db.Provider.GetUserByEmail(params.Email)
|
existingUser, err := db.Provider.GetUserByEmail(params.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
||||||
|
log.Debug("Signup is disabled.")
|
||||||
return res, fmt.Errorf(`signup is disabled for this instance`)
|
return res, fmt.Errorf(`signup is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +63,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
if len(params.Roles) > 0 {
|
if len(params.Roles) > 0 {
|
||||||
// check if roles exists
|
// check if roles exists
|
||||||
if !utils.IsValidRoles(params.Roles, envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles)) {
|
if !utils.IsValidRoles(params.Roles, envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles)) {
|
||||||
|
log.Debug("Invalid roles: ", params.Roles)
|
||||||
return res, fmt.Errorf(`invalid roles`)
|
return res, fmt.Errorf(`invalid roles`)
|
||||||
} else {
|
} else {
|
||||||
inputRoles = params.Roles
|
inputRoles = params.Roles
|
||||||
|
@ -71,6 +82,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
// Need to modify roles in this case
|
// Need to modify roles in this case
|
||||||
|
|
||||||
if user.RevokedTimestamp != nil {
|
if user.RevokedTimestamp != nil {
|
||||||
|
log.Debug("User access is revoked at: ", user.RevokedTimestamp)
|
||||||
return res, fmt.Errorf(`user access has been revoked`)
|
return res, fmt.Errorf(`user access has been revoked`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +108,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasProtectedRole {
|
if hasProtectedRole {
|
||||||
|
log.Debug("User is not assigned one of the protected roles", unasignedRoles)
|
||||||
return res, fmt.Errorf(`invalid roles`)
|
return res, fmt.Errorf(`invalid roles`)
|
||||||
} else {
|
} else {
|
||||||
user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
|
user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
|
||||||
|
@ -112,7 +125,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
user.SignupMethods = signupMethod
|
user.SignupMethods = signupMethod
|
||||||
user, _ = db.Provider.UpdateUser(user)
|
user, _ = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
log.Debug("Failed to update user: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +134,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
// insert verification request
|
// insert verification request
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
redirectURLParams := "&roles=" + strings.Join(inputRoles, ",")
|
redirectURLParams := "&roles=" + strings.Join(inputRoles, ",")
|
||||||
|
@ -144,7 +158,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
verificationType := constants.VerificationTypeMagicLinkLogin
|
verificationType := constants.VerificationTypeMagicLinkLogin
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token: ", err)
|
||||||
}
|
}
|
||||||
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
|
@ -155,6 +169,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
RedirectURI: redirectURL,
|
RedirectURI: redirectURL,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request in db: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
@ -11,25 +13,34 @@ import (
|
||||||
|
|
||||||
// ProfileResolver is a resolver for profile query
|
// ProfileResolver is a resolver for profile query
|
||||||
func ProfileResolver(ctx context.Context) (*model.User, error) {
|
func ProfileResolver(ctx context.Context) (*model.User, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.User
|
var res *model.User
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accessToken, err := token.GetAccessToken(gc)
|
accessToken, err := token.GetAccessToken(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get access token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, err := token.ValidateAccessToken(gc, accessToken)
|
claims, err := token.ValidateAccessToken(gc, accessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to validate access token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := claims["sub"].(string)
|
userID := claims["sub"].(string)
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": userID,
|
||||||
|
})
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/email"
|
"github.com/authorizerdev/authorizer/server/email"
|
||||||
|
@ -18,42 +19,48 @@ import (
|
||||||
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
|
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
|
||||||
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
log.Debug("Invalid email: ", params.Email)
|
||||||
return res, fmt.Errorf("invalid email")
|
return res, fmt.Errorf("invalid email")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidVerificationIdentifier(params.Identifier) {
|
if !utils.IsValidVerificationIdentifier(params.Identifier) {
|
||||||
|
log.Debug("Invalid verification identifier: ", params.Identifier)
|
||||||
return res, fmt.Errorf("invalid identifier")
|
return res, fmt.Errorf("invalid identifier")
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(params.Email, params.Identifier)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(params.Email, params.Identifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get verification request: ", err)
|
||||||
return res, fmt.Errorf(`verification request not found`)
|
return res, fmt.Errorf(`verification request not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete current verification and create new one
|
// delete current verification and create new one
|
||||||
err = db.Provider.DeleteVerificationRequest(verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(verificationRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting verification request:", err)
|
log.Debug("Failed to delete verification request: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hostname := utils.GetHost(gc)
|
hostname := utils.GetHost(gc)
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier, hostname, nonceHash, verificationRequest.RedirectURI)
|
verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier, hostname, nonceHash, verificationRequest.RedirectURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token: ", err)
|
||||||
}
|
}
|
||||||
db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
Identifier: params.Identifier,
|
Identifier: params.Identifier,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
@ -61,6 +68,9 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
|
||||||
Nonce: nonceHash,
|
Nonce: nonceHash,
|
||||||
RedirectURI: verificationRequest.RedirectURI,
|
RedirectURI: verificationRequest.RedirectURI,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 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 email.SendVerificationMail(params.Email, verificationToken, hostname)
|
go email.SendVerificationMail(params.Email, verificationToken, hostname)
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
@ -18,24 +20,30 @@ import (
|
||||||
// ResetPasswordResolver is a resolver for reset password mutation
|
// ResetPasswordResolver is a resolver for reset password mutation
|
||||||
func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
||||||
|
log.Debug("Basic authentication is disabled")
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
|
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get verification request: ", err)
|
||||||
return res, fmt.Errorf(`invalid token`)
|
return res, fmt.Errorf(`invalid token`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Password != params.ConfirmPassword {
|
if params.Password != params.ConfirmPassword {
|
||||||
|
log.Debug("Passwords do not match")
|
||||||
return res, fmt.Errorf(`passwords don't match`)
|
return res, fmt.Errorf(`passwords don't match`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidPassword(params.Password) {
|
if !utils.IsValidPassword(params.Password) {
|
||||||
|
log.Debug("Invalid password")
|
||||||
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
|
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +51,17 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
|
||||||
hostname := utils.GetHost(gc)
|
hostname := utils.GetHost(gc)
|
||||||
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to parse token: ", err)
|
||||||
return res, fmt.Errorf(`invalid token`)
|
return res, fmt.Errorf(`invalid token`)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByEmail(claim["sub"].(string))
|
email := claim["sub"].(string)
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": email,
|
||||||
|
})
|
||||||
|
user, err := db.Provider.GetUserByEmail(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +81,17 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete from verification table
|
// delete from verification table
|
||||||
db.Provider.DeleteVerificationRequest(verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(verificationRequest)
|
||||||
db.Provider.UpdateUser(user)
|
if err != nil {
|
||||||
|
log.Debug("Failed to delete verification request: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Provider.UpdateUser(user)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to update user: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
Message: `Password updated successfully.`,
|
Message: `Password updated successfully.`,
|
||||||
|
|
|
@ -3,9 +3,10 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
|
@ -15,18 +16,25 @@ import (
|
||||||
|
|
||||||
// RevokeAccessResolver is a resolver for revoking user access
|
// RevokeAccessResolver is a resolver for revoking user access
|
||||||
func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
|
func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": params.UserID,
|
||||||
|
})
|
||||||
user, err := db.Provider.GetUserByID(params.UserID)
|
user, err := db.Provider.GetUserByID(params.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user by ID: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +43,7 @@ func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (
|
||||||
|
|
||||||
user, err = db.Provider.UpdateUser(user)
|
user, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
log.Debug("Failed to update user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -22,22 +23,28 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
|
||||||
|
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionToken, err := cookie.GetSession(gc)
|
sessionToken, err := cookie.GetSession(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting session token:", err)
|
log.Debug("Failed to get session token", err)
|
||||||
return res, errors.New("unauthorized")
|
return res, errors.New("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
// get session from cookie
|
// get session from cookie
|
||||||
claims, err := token.ValidateBrowserSession(gc, sessionToken)
|
claims, err := token.ValidateBrowserSession(gc, sessionToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("session validation failed:", err)
|
log.Debug("Failed to validate session token", err)
|
||||||
return res, errors.New("unauthorized")
|
return res, errors.New("unauthorized")
|
||||||
}
|
}
|
||||||
userID := claims.Subject
|
userID := claims.Subject
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": userID,
|
||||||
|
})
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
@ -46,13 +53,12 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
|
||||||
// refresh token has "roles" as claim
|
// refresh token has "roles" as claim
|
||||||
claimRoleInterface := claims.Roles
|
claimRoleInterface := claims.Roles
|
||||||
claimRoles := []string{}
|
claimRoles := []string{}
|
||||||
for _, v := range claimRoleInterface {
|
claimRoles = append(claimRoles, claimRoleInterface...)
|
||||||
claimRoles = append(claimRoles, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
if params != nil && params.Roles != nil && len(params.Roles) > 0 {
|
if params != nil && params.Roles != nil && len(params.Roles) > 0 {
|
||||||
for _, v := range params.Roles {
|
for _, v := range params.Roles {
|
||||||
if !utils.StringSliceContains(claimRoles, v) {
|
if !utils.StringSliceContains(claimRoles, v) {
|
||||||
|
log.Debug("User does not have required role: ", claimRoles, v)
|
||||||
return res, fmt.Errorf(`unauthorized`)
|
return res, fmt.Errorf(`unauthorized`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +71,7 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, claimRoles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, claimRoles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create auth token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -22,44 +23,56 @@ import (
|
||||||
|
|
||||||
// SignupResolver is a resolver for signup mutation
|
// SignupResolver is a resolver for signup mutation
|
||||||
func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
|
||||||
|
log.Debug("Signup is disabled")
|
||||||
return res, fmt.Errorf(`signup is disabled for this instance`)
|
return res, fmt.Errorf(`signup is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
||||||
|
log.Debug("Basic authentication is disabled")
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.ConfirmPassword != params.Password {
|
if params.ConfirmPassword != params.Password {
|
||||||
|
log.Debug("Passwords do not match")
|
||||||
return res, fmt.Errorf(`password and confirm password does not match`)
|
return res, fmt.Errorf(`password and confirm password does not match`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidPassword(params.Password) {
|
if !utils.IsValidPassword(params.Password) {
|
||||||
|
log.Debug("Invalid password")
|
||||||
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
|
return res, fmt.Errorf(`password is not valid. It needs to be at least 6 characters long and contain at least one number, one uppercase letter, one lowercase letter and one special character`)
|
||||||
}
|
}
|
||||||
|
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
log.Debug("Invalid email: ", params.Email)
|
||||||
return res, fmt.Errorf(`invalid email address`)
|
return res, fmt.Errorf(`invalid email address`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": params.Email,
|
||||||
|
})
|
||||||
// find user with email
|
// find user with email
|
||||||
existingUser, err := db.Provider.GetUserByEmail(params.Email)
|
existingUser, err := db.Provider.GetUserByEmail(params.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("user with email " + params.Email + " not found")
|
log.Debug("Failed to get user by email: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if existingUser.EmailVerifiedAt != nil {
|
if existingUser.EmailVerifiedAt != nil {
|
||||||
// email is verified
|
// email is verified
|
||||||
|
log.Debug("Email is already verified and signed up.")
|
||||||
return res, fmt.Errorf(`%s has already signed up`, params.Email)
|
return res, fmt.Errorf(`%s has already signed up`, params.Email)
|
||||||
} else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil {
|
} else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil {
|
||||||
|
log.Debug("Email is already signed up. Verification pending...")
|
||||||
return res, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", params.Email)
|
return res, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", params.Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +81,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
if len(params.Roles) > 0 {
|
if len(params.Roles) > 0 {
|
||||||
// check if roles exists
|
// check if roles exists
|
||||||
if !utils.IsValidRoles(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) {
|
if !utils.IsValidRoles(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) {
|
||||||
|
log.Debug("Invalid roles: ", params.Roles)
|
||||||
return res, fmt.Errorf(`invalid roles`)
|
return res, fmt.Errorf(`invalid roles`)
|
||||||
} else {
|
} else {
|
||||||
inputRoles = params.Roles
|
inputRoles = params.Roles
|
||||||
|
@ -124,6 +138,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
}
|
}
|
||||||
user, err = db.Provider.AddUser(user)
|
user, err = db.Provider.AddUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to add user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
roles := strings.Split(user.Roles, ",")
|
roles := strings.Split(user.Roles, ",")
|
||||||
|
@ -134,6 +149,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
// insert verification request
|
// insert verification request
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
verificationType := constants.VerificationTypeBasicAuthSignup
|
verificationType := constants.VerificationTypeBasicAuthSignup
|
||||||
|
@ -143,9 +159,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
}
|
}
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create verification token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
Identifier: verificationType,
|
Identifier: verificationType,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
@ -153,6 +170,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
Nonce: nonceHash,
|
Nonce: nonceHash,
|
||||||
RedirectURI: redirectURL,
|
RedirectURI: redirectURL,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// 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 email.SendVerificationMail(params.Email, verificationToken, hostname)
|
go email.SendVerificationMail(params.Email, verificationToken, hostname)
|
||||||
|
@ -169,6 +190,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create auth token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -23,14 +24,16 @@ import (
|
||||||
// UpdateEnvResolver is a resolver for update config mutation
|
// UpdateEnvResolver is a resolver for update config mutation
|
||||||
// This is admin only mutation
|
// This is admin only mutation
|
||||||
func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
|
func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +44,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
if params.JwtType != nil {
|
if params.JwtType != nil {
|
||||||
algo = *params.JwtType
|
algo = *params.JwtType
|
||||||
if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
|
if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
|
||||||
|
log.Debug("Invalid JWT type: ", algo)
|
||||||
return res, fmt.Errorf("invalid jwt type")
|
return res, fmt.Errorf("invalid jwt type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +64,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
// check if jwt secret is provided
|
// check if jwt secret is provided
|
||||||
if crypto.IsHMACA(algo) {
|
if crypto.IsHMACA(algo) {
|
||||||
if params.JwtSecret == nil {
|
if params.JwtSecret == nil {
|
||||||
|
log.Debug("JWT secret is required for HMAC")
|
||||||
return res, fmt.Errorf("jwt secret is required for HMAC algorithm")
|
return res, fmt.Errorf("jwt secret is required for HMAC algorithm")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +75,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
|
|
||||||
if crypto.IsRSA(algo) {
|
if crypto.IsRSA(algo) {
|
||||||
if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
|
if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
|
||||||
|
log.Debug("JWT private key and public key are required for RSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
|
||||||
return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
|
return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,17 +83,20 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
params.JwtSecret = &defaultSecret
|
params.JwtSecret = &defaultSecret
|
||||||
_, err = crypto.ParseRsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
|
_, err = crypto.ParseRsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Invalid JWT private key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := crypto.ParseRsaPublicKeyFromPemStr(*params.JwtPublicKey)
|
_, err := crypto.ParseRsaPublicKeyFromPemStr(*params.JwtPublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Invalid JWT public key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if crypto.IsECDSA(algo) {
|
if crypto.IsECDSA(algo) {
|
||||||
if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
|
if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
|
||||||
|
log.Debug("JWT private key and public key are required for ECDSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
|
||||||
return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
|
return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +104,13 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
params.JwtSecret = &defaultSecret
|
params.JwtSecret = &defaultSecret
|
||||||
_, err = crypto.ParseEcdsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
|
_, err = crypto.ParseEcdsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Invalid JWT private key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := crypto.ParseEcdsaPublicKeyFromPemStr(*params.JwtPublicKey)
|
_, err := crypto.ParseEcdsaPublicKeyFromPemStr(*params.JwtPublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Invalid JWT public key: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,25 +120,30 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
var data map[string]interface{}
|
var data map[string]interface{}
|
||||||
byteData, err := json.Marshal(params)
|
byteData, err := json.Marshal(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to marshal update env input: ", err)
|
||||||
return res, fmt.Errorf("error marshalling params: %t", err)
|
return res, fmt.Errorf("error marshalling params: %t", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(byteData, &data)
|
err = json.Unmarshal(byteData, &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to unmarshal update env input: ", err)
|
||||||
return res, fmt.Errorf("error un-marshalling params: %t", err)
|
return res, fmt.Errorf("error un-marshalling params: %t", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
if params.OldAdminSecret == nil {
|
if params.OldAdminSecret == nil {
|
||||||
|
log.Debug("Old admin secret is required for admin secret update")
|
||||||
return res, errors.New("admin secret and old admin secret are required for secret change")
|
return res, errors.New("admin secret and old admin secret are required for secret change")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *params.OldAdminSecret != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) {
|
if *params.OldAdminSecret != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret) {
|
||||||
|
log.Debug("Old admin secret is invalid")
|
||||||
return res, errors.New("old admin secret is not correct")
|
return res, errors.New("old admin secret is not correct")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*params.AdminSecret) < 6 {
|
if len(*params.AdminSecret) < 6 {
|
||||||
|
log.Debug("Admin secret is too short")
|
||||||
err = fmt.Errorf("admin secret must be at least 6 characters")
|
err = fmt.Errorf("admin secret must be at least 6 characters")
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -173,6 +189,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
// should be subset of roles
|
// should be subset of roles
|
||||||
for _, role := range params.DefaultRoles {
|
for _, role := range params.DefaultRoles {
|
||||||
if !utils.StringSliceContains(params.Roles, role) {
|
if !utils.StringSliceContains(params.Roles, role) {
|
||||||
|
log.Debug("Default roles should be subset of roles")
|
||||||
return res, fmt.Errorf("default role %s is not in roles", role)
|
return res, fmt.Errorf("default role %s is not in roles", role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,6 +199,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
if len(params.ProtectedRoles) > 0 {
|
if len(params.ProtectedRoles) > 0 {
|
||||||
for _, role := range params.ProtectedRoles {
|
for _, role := range params.ProtectedRoles {
|
||||||
if utils.StringSliceContains(params.Roles, role) || utils.StringSliceContains(params.DefaultRoles, role) {
|
if utils.StringSliceContains(params.Roles, role) || utils.StringSliceContains(params.DefaultRoles, role) {
|
||||||
|
log.Debug("Protected roles should not be in roles or default roles")
|
||||||
return res, fmt.Errorf("protected role %s found roles or default roles", role)
|
return res, fmt.Errorf("protected role %s found roles or default roles", role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,12 +209,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
envstore.EnvStoreObj.UpdateEnvStore(updatedData)
|
envstore.EnvStoreObj.UpdateEnvStore(updatedData)
|
||||||
jwk, err := crypto.GenerateJWKBasedOnEnv()
|
jwk, err := crypto.GenerateJWKBasedOnEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate JWK: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
// updating jwk
|
// updating jwk
|
||||||
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk)
|
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk)
|
||||||
err = sessionstore.InitSession()
|
err = sessionstore.InitSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to init session store: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
err = oauth.InitOAuth()
|
err = oauth.InitOAuth()
|
||||||
|
@ -207,12 +227,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
// Fetch the current db store and update it
|
// Fetch the current db store and update it
|
||||||
env, err := db.Provider.GetEnv()
|
env, err := db.Provider.GetEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get env: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.AdminSecret != nil {
|
if params.AdminSecret != nil {
|
||||||
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to encrypt admin secret: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
cookie.SetAdminCookie(gc, hashedKey)
|
cookie.SetAdminCookie(gc, hashedKey)
|
||||||
|
@ -220,13 +242,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
|
|
||||||
encryptedConfig, err := crypto.EncryptEnvData(updatedData)
|
encryptedConfig, err := crypto.EncryptEnvData(updatedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to encrypt env data: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
env.EnvData = encryptedConfig
|
env.EnvData = encryptedConfig
|
||||||
_, err = db.Provider.UpdateEnv(env)
|
_, err = db.Provider.UpdateEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating config:", err)
|
log.Debug("Failed to update env: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -23,29 +24,39 @@ import (
|
||||||
|
|
||||||
// UpdateProfileResolver is resolver for update profile mutation
|
// UpdateProfileResolver is resolver for update profile mutation
|
||||||
func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accessToken, err := token.GetAccessToken(gc)
|
accessToken, err := token.GetAccessToken(gc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get access token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
claims, err := token.ValidateAccessToken(gc, accessToken)
|
claims, err := token.ValidateAccessToken(gc, accessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to validate access token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate if all params are not empty
|
// validate if all params are not empty
|
||||||
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil {
|
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil {
|
||||||
|
log.Debug("All params are empty")
|
||||||
return res, fmt.Errorf("please enter at least one param to update")
|
return res, fmt.Errorf("please enter at least one param to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := claims["sub"].(string)
|
userID := claims["sub"].(string)
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": userID,
|
||||||
|
})
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByID(userID)
|
user, err := db.Provider.GetUserByID(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user by id: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,18 +94,22 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
|
|
||||||
if params.OldPassword != nil {
|
if params.OldPassword != nil {
|
||||||
if err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(*params.OldPassword)); err != nil {
|
if err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(*params.OldPassword)); err != nil {
|
||||||
|
log.Debug("Failed to compare hash and old password: ", err)
|
||||||
return res, fmt.Errorf("incorrect old password")
|
return res, fmt.Errorf("incorrect old password")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.NewPassword == nil {
|
if params.NewPassword == nil {
|
||||||
|
log.Debug("Failed to get new password: ")
|
||||||
return res, fmt.Errorf("new password is required")
|
return res, fmt.Errorf("new password is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.ConfirmNewPassword == nil {
|
if params.ConfirmNewPassword == nil {
|
||||||
|
log.Debug("Failed to get confirm new password: ")
|
||||||
return res, fmt.Errorf("confirm password is required")
|
return res, fmt.Errorf("confirm password is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *params.ConfirmNewPassword != *params.NewPassword {
|
if *params.ConfirmNewPassword != *params.NewPassword {
|
||||||
|
log.Debug("Failed to compare new password and confirm new password")
|
||||||
return res, fmt.Errorf(`password and confirm password does not match`)
|
return res, fmt.Errorf(`password and confirm password does not match`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,22 +123,28 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
if params.Email != nil && user.Email != *params.Email {
|
if params.Email != nil && user.Email != *params.Email {
|
||||||
// check if valid email
|
// check if valid email
|
||||||
if !utils.IsValidEmail(*params.Email) {
|
if !utils.IsValidEmail(*params.Email) {
|
||||||
|
log.Debug("Failed to validate email: ", *params.Email)
|
||||||
return res, fmt.Errorf("invalid email address")
|
return res, fmt.Errorf("invalid email address")
|
||||||
}
|
}
|
||||||
newEmail := strings.ToLower(*params.Email)
|
newEmail := strings.ToLower(*params.Email)
|
||||||
|
|
||||||
|
// check if valid email
|
||||||
|
if !utils.IsValidEmail(newEmail) {
|
||||||
|
log.Debug("Failed to validate new email: ", newEmail)
|
||||||
|
return res, fmt.Errorf("invalid new email address")
|
||||||
|
}
|
||||||
// check if user with new email exists
|
// check if user with new email exists
|
||||||
_, err := db.Provider.GetUserByEmail(newEmail)
|
_, err := db.Provider.GetUserByEmail(newEmail)
|
||||||
// err = nil means user exists
|
// err = nil means user exists
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
log.Debug("Failed to get user by email: ", newEmail)
|
||||||
return res, fmt.Errorf("user with this email address already exists")
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO figure out how to delete all user sessions
|
|
||||||
go sessionstore.DeleteAllUserSession(user.ID)
|
go sessionstore.DeleteAllUserSession(user.ID)
|
||||||
|
go cookie.DeleteSession(gc)
|
||||||
|
|
||||||
cookie.DeleteSession(gc)
|
|
||||||
user.Email = newEmail
|
user.Email = newEmail
|
||||||
|
|
||||||
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
||||||
hostname := utils.GetHost(gc)
|
hostname := utils.GetHost(gc)
|
||||||
user.EmailVerifiedAt = nil
|
user.EmailVerifiedAt = nil
|
||||||
|
@ -131,15 +152,17 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
// insert verification request
|
// insert verification request
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
verificationType := constants.VerificationTypeUpdateEmail
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
redirectURL := utils.GetAppURL(gc)
|
redirectURL := utils.GetAppURL(gc)
|
||||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token: ", err)
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
Identifier: verificationType,
|
Identifier: verificationType,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
@ -147,6 +170,10 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
Nonce: nonceHash,
|
Nonce: nonceHash,
|
||||||
RedirectURI: redirectURL,
|
RedirectURI: redirectURL,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// 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 email.SendVerificationMail(newEmail, verificationToken, hostname)
|
go email.SendVerificationMail(newEmail, verificationToken, hostname)
|
||||||
|
@ -155,7 +182,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
}
|
}
|
||||||
_, err = db.Provider.UpdateUser(user)
|
_, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
log.Debug("Failed to update user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
message := `Profile details updated successfully.`
|
message := `Profile details updated successfully.`
|
||||||
|
|
|
@ -3,10 +3,11 @@ package resolvers
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"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/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -21,22 +22,36 @@ import (
|
||||||
// UpdateUserResolver is a resolver for update user mutation
|
// UpdateUserResolver is a resolver for update user mutation
|
||||||
// This is admin only mutation
|
// This is admin only mutation
|
||||||
func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.User
|
var res *model.User
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return res, fmt.Errorf("unauthorized")
|
return res, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.ID == "" {
|
||||||
|
log.Debug("UserID is empty")
|
||||||
|
return res, fmt.Errorf("User ID is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"user_id": params.ID,
|
||||||
|
})
|
||||||
|
|
||||||
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.Roles == nil {
|
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.Roles == nil {
|
||||||
|
log.Debug("No params to update")
|
||||||
return res, fmt.Errorf("please enter atleast one param to update")
|
return res, fmt.Errorf("please enter atleast one param to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByID(params.ID)
|
user, err := db.Provider.GetUserByID(params.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user by id: ", err)
|
||||||
return res, fmt.Errorf(`User not found`)
|
return res, fmt.Errorf(`User not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +99,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
if params.Email != nil && user.Email != *params.Email {
|
if params.Email != nil && user.Email != *params.Email {
|
||||||
// check if valid email
|
// check if valid email
|
||||||
if !utils.IsValidEmail(*params.Email) {
|
if !utils.IsValidEmail(*params.Email) {
|
||||||
|
log.Debug("Invalid email: ", *params.Email)
|
||||||
return res, fmt.Errorf("invalid email address")
|
return res, fmt.Errorf("invalid email address")
|
||||||
}
|
}
|
||||||
newEmail := strings.ToLower(*params.Email)
|
newEmail := strings.ToLower(*params.Email)
|
||||||
|
@ -91,6 +107,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
_, err = db.Provider.GetUserByEmail(newEmail)
|
_, err = db.Provider.GetUserByEmail(newEmail)
|
||||||
// err = nil means user exists
|
// err = nil means user exists
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
log.Debug("User with email already exists: ", newEmail)
|
||||||
return res, fmt.Errorf("user with this email address already exists")
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,15 +120,16 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
// insert verification request
|
// insert verification request
|
||||||
_, nonceHash, err := utils.GenerateNonce()
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
verificationType := constants.VerificationTypeUpdateEmail
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
redirectURL := utils.GetAppURL(gc)
|
redirectURL := utils.GetAppURL(gc)
|
||||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Debug("Failed to create verification token: ", err)
|
||||||
}
|
}
|
||||||
db.Provider.AddVerificationRequest(models.VerificationRequest{
|
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
|
||||||
Token: verificationToken,
|
Token: verificationToken,
|
||||||
Identifier: verificationType,
|
Identifier: verificationType,
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
@ -119,6 +137,10 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
Nonce: nonceHash,
|
Nonce: nonceHash,
|
||||||
RedirectURI: redirectURL,
|
RedirectURI: redirectURL,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// 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 email.SendVerificationMail(newEmail, verificationToken, hostname)
|
go email.SendVerificationMail(newEmail, verificationToken, hostname)
|
||||||
|
@ -134,6 +156,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidRoles(inputRoles, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) {
|
if !utils.IsValidRoles(inputRoles, append([]string{}, append(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) {
|
||||||
|
log.Debug("Invalid roles: ", params.Roles)
|
||||||
return res, fmt.Errorf("invalid list of roles")
|
return res, fmt.Errorf("invalid list of roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +173,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
|
|
||||||
user, err = db.Provider.UpdateUser(user)
|
user, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating user:", err)
|
log.Debug("Failed to update user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
@ -15,10 +17,12 @@ import (
|
||||||
func UsersResolver(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
|
func UsersResolver(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin.")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +30,7 @@ func UsersResolver(ctx context.Context, params *model.PaginatedInput) (*model.Us
|
||||||
|
|
||||||
res, err := db.Provider.ListUsers(pagination)
|
res, err := db.Provider.ListUsers(pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get users: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/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"
|
||||||
"github.com/golang-jwt/jwt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidateJwtTokenResolver is used to validate a jwt token without its rotation
|
// ValidateJwtTokenResolver is used to validate a jwt token without its rotation
|
||||||
|
@ -22,11 +24,13 @@ import (
|
||||||
func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error) {
|
func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenType := params.TokenType
|
tokenType := params.TokenType
|
||||||
if tokenType != "access_token" && tokenType != "refresh_token" && tokenType != "id_token" {
|
if tokenType != "access_token" && tokenType != "refresh_token" && tokenType != "id_token" {
|
||||||
|
log.Debug("Invalid token type: ", tokenType)
|
||||||
return nil, errors.New("invalid token type")
|
return nil, errors.New("invalid token type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +57,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
|
||||||
if userID != "" && nonce != "" {
|
if userID != "" && nonce != "" {
|
||||||
claims, err = token.ParseJWTToken(params.Token, hostname, nonce, userID)
|
claims, err = token.ParseJWTToken(params.Token, hostname, nonce, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to parse jwt token: ", err)
|
||||||
return &model.ValidateJWTTokenResponse{
|
return &model.ValidateJWTTokenResponse{
|
||||||
IsValid: false,
|
IsValid: false,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -60,6 +65,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
|
||||||
} else {
|
} else {
|
||||||
claims, err = token.ParseJWTTokenWithoutNonce(params.Token, hostname)
|
claims, err = token.ParseJWTTokenWithoutNonce(params.Token, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to parse jwt token without nonce: ", err)
|
||||||
return &model.ValidateJWTTokenResponse{
|
return &model.ValidateJWTTokenResponse{
|
||||||
IsValid: false,
|
IsValid: false,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -76,6 +82,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
|
||||||
if params.Roles != nil && len(params.Roles) > 0 {
|
if params.Roles != nil && len(params.Roles) > 0 {
|
||||||
for _, v := range params.Roles {
|
for _, v := range params.Roles {
|
||||||
if !utils.StringSliceContains(claimRoles, v) {
|
if !utils.StringSliceContains(claimRoles, v) {
|
||||||
|
log.Debug("Token does not have required role: ", v)
|
||||||
return nil, fmt.Errorf(`unauthorized`)
|
return nil, fmt.Errorf(`unauthorized`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
@ -15,10 +17,12 @@ import (
|
||||||
func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) {
|
func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +30,7 @@ func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedIn
|
||||||
|
|
||||||
res, err := db.Provider.ListVerificationRequests(pagination)
|
res, err := db.Provider.ListVerificationRequests(pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get verification requests: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -17,14 +19,17 @@ import (
|
||||||
|
|
||||||
// VerifyEmailResolver is a resolver for verify email mutation
|
// VerifyEmailResolver is a resolver for verify email mutation
|
||||||
func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
||||||
gc, err := utils.GinContextFromContext(ctx)
|
|
||||||
var res *model.AuthResponse
|
var res *model.AuthResponse
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
|
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get verification request by token: ", err)
|
||||||
return res, fmt.Errorf(`invalid token: %s`, err.Error())
|
return res, fmt.Errorf(`invalid token: %s`, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +37,17 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
|
||||||
hostname := utils.GetHost(gc)
|
hostname := utils.GetHost(gc)
|
||||||
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to parse token: ", err)
|
||||||
return res, fmt.Errorf(`invalid token: %s`, err.Error())
|
return res, fmt.Errorf(`invalid token: %s`, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := db.Provider.GetUserByEmail(claim["sub"].(string))
|
email := claim["sub"].(string)
|
||||||
|
log := log.WithFields(log.Fields{
|
||||||
|
"email": email,
|
||||||
|
})
|
||||||
|
user, err := db.Provider.GetUserByEmail(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to get user by email: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +56,13 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
|
||||||
user.EmailVerifiedAt = &now
|
user.EmailVerifiedAt = &now
|
||||||
user, err = db.Provider.UpdateUser(user)
|
user, err = db.Provider.UpdateUser(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to update user: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
// delete from verification table
|
// delete from verification table
|
||||||
err = db.Provider.DeleteVerificationRequest(verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(verificationRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to delete verification request: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +70,7 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
|
||||||
scope := []string{"openid", "email", "profile"}
|
scope := []string{"openid", "email", "profile"}
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Failed to create auth token: ", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"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/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitRouter initializes gin router
|
// InitRouter initializes gin router
|
||||||
func InitRouter() *gin.Engine {
|
func InitRouter(log *logrus.Logger) *gin.Engine {
|
||||||
router := gin.Default()
|
gin.SetMode(gin.ReleaseMode)
|
||||||
// router.Use(location.Default())
|
router := gin.New()
|
||||||
|
|
||||||
|
router.Use(middlewares.Logger(log), gin.Recovery())
|
||||||
router.Use(middlewares.GinContextToContextMiddleware())
|
router.Use(middlewares.GinContextToContextMiddleware())
|
||||||
router.Use(middlewares.CORSMiddleware())
|
router.Use(middlewares.CORSMiddleware())
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ package sessionstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RedisStore struct {
|
type RedisStore struct {
|
||||||
|
@ -15,7 +16,7 @@ type RedisStore struct {
|
||||||
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 {
|
||||||
log.Fatalln("Error clearing redis store:", err)
|
log.Debug("Error clearing redis store: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ func (c *RedisStore) ClearStore() {
|
||||||
func (c *RedisStore) GetUserSessions(userID string) map[string]string {
|
func (c *RedisStore) GetUserSessions(userID string) map[string]string {
|
||||||
data, err := c.store.HGetAll(c.ctx, "*").Result()
|
data, err := c.store.HGetAll(c.ctx, "*").Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting token from redis store:", err)
|
log.Debug("error getting token from redis store: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := map[string]string{}
|
res := map[string]string{}
|
||||||
|
@ -44,7 +45,7 @@ func (c *RedisStore) DeleteAllUserSession(userId string) {
|
||||||
if k == "token" {
|
if k == "token" {
|
||||||
err := c.store.Del(c.ctx, v)
|
err := c.store.Del(c.ctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error deleting redis token:", err)
|
log.Debug("Error deleting redis token: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +55,7 @@ func (c *RedisStore) DeleteAllUserSession(userId string) {
|
||||||
func (c *RedisStore) SetState(key, value string) {
|
func (c *RedisStore) SetState(key, value string) {
|
||||||
err := c.store.Set(c.ctx, "authorizer_"+key, value, 0).Err()
|
err := c.store.Set(c.ctx, "authorizer_"+key, value, 0).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Error saving redis token:", err)
|
log.Debug("Error saving redis token: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ func (c *RedisStore) GetState(key string) string {
|
||||||
state := ""
|
state := ""
|
||||||
state, err := c.store.Get(c.ctx, "authorizer_"+key).Result()
|
state, err := c.store.Get(c.ctx, "authorizer_"+key).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting token from redis store:", err)
|
log.Debug("error getting token from redis store: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
|
@ -2,9 +2,10 @@ package sessionstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
|
@ -89,7 +90,7 @@ func RemoveState(key string) {
|
||||||
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
|
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
|
||||||
func InitSession() error {
|
func InitSession() error {
|
||||||
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" {
|
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" {
|
||||||
log.Println("using redis store to save sessions")
|
log.Info("using redis store to save sessions")
|
||||||
|
|
||||||
redisURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)
|
redisURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)
|
||||||
redisURLHostPortsList := strings.Split(redisURL, ",")
|
redisURLHostPortsList := strings.Split(redisURL, ",")
|
||||||
|
@ -97,6 +98,7 @@ func InitSession() error {
|
||||||
if len(redisURLHostPortsList) > 1 {
|
if len(redisURLHostPortsList) > 1 {
|
||||||
opt, err := redis.ParseURL(redisURLHostPortsList[0])
|
opt, err := redis.ParseURL(redisURLHostPortsList[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("error parsing redis url: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
urls := []string{opt.Addr}
|
urls := []string{opt.Addr}
|
||||||
|
@ -108,6 +110,7 @@ func InitSession() error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
_, err = rdb.Ping(ctx).Result()
|
_, err = rdb.Ping(ctx).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("error connecting to redis: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
|
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
|
||||||
|
@ -121,6 +124,7 @@ func InitSession() error {
|
||||||
|
|
||||||
opt, err := redis.ParseURL(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
|
opt, err := redis.ParseURL(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("error parsing redis url: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +132,7 @@ func InitSession() error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
_, err = rdb.Ping(ctx).Result()
|
_, err = rdb.Ping(ctx).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("error connecting to redis: ", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +145,7 @@ func InitSession() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Info("using in memory store to save sessions")
|
||||||
// if redis url is not set use in memory store
|
// if redis url is not set use in memory store
|
||||||
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
|
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
|
||||||
sessionStore: map[string]map[string]string{},
|
sessionStore: map[string]map[string]string{},
|
||||||
|
|
|
@ -3,10 +3,11 @@ package token
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -330,14 +331,13 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st
|
||||||
`, string(userBytes), string(claimBytes), accessTokenScript))
|
`, string(userBytes), string(claimBytes), accessTokenScript))
|
||||||
|
|
||||||
val, err := vm.Get("functionRes")
|
val, err := vm.Get("functionRes")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting custom access token script:", err)
|
log.Debug("error getting custom access token script: ", err)
|
||||||
} else {
|
} else {
|
||||||
extraPayload := make(map[string]interface{})
|
extraPayload := make(map[string]interface{})
|
||||||
err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
|
err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error converting accessTokenScript response to map:", err)
|
log.Debug("error converting accessTokenScript response to map: ", err)
|
||||||
} else {
|
} else {
|
||||||
for k, v := range extraPayload {
|
for k, v := range extraPayload {
|
||||||
customClaims[k] = v
|
customClaims[k] = v
|
||||||
|
|
Loading…
Reference in New Issue
Block a user