Merge pull request #173 from authorizerdev/feat/logging

feat: add logging system
This commit is contained in:
Lakhan Samani 2022-05-25 15:07:28 +05:30 committed by GitHub
commit d722fe258d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 679 additions and 207 deletions

View File

@ -1,6 +1,8 @@
package db
import (
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/providers"
"github.com/authorizerdev/authorizer/server/db/providers/arangodb"
@ -22,29 +24,37 @@ func InitDB() error {
isCassandra := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType) == constants.DbTypeCassandraDB
if isSQL {
log.Info("Initializing SQL Driver for: ", envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseType))
Provider, err = sql.NewProvider()
if err != nil {
log.Fatal("Failed to initialize SQL driver: ", err)
return err
}
}
if isArangoDB {
log.Info("Initializing ArangoDB Driver")
Provider, err = arangodb.NewProvider()
if err != nil {
log.Fatal("Failed to initialize ArangoDB driver: ", err)
return err
}
}
if isMongoDB {
log.Info("Initializing MongoDB Driver")
Provider, err = mongodb.NewProvider()
if err != nil {
log.Fatal("Failed to initialize MongoDB driver: ", err)
return err
}
}
if isCassandra {
log.Info("Initializing CassandraDB Driver")
Provider, err = cassandradb.NewProvider()
if err != nil {
log.Fatal("Failed to initialize CassandraDB driver: ", err)
return err
}
}

View File

@ -2,7 +2,6 @@ package arangodb
import (
"fmt"
"log"
"time"
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)
meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(nil), env)
if err != nil {
log.Println("error adding config:", err)
return env, err
}
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)
meta, err := collection.UpdateDocument(nil, env.Key, env)
if err != nil {
log.Println("error updating config:", err)
return env, err
}

View File

@ -2,7 +2,6 @@ package arangodb
import (
"context"
"log"
"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))
if arangodb_exists {
log.Println(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName) + " db exists already")
arangodb, err = arangoClient.Database(nil, envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseName))
if err != nil {
return nil, err
@ -55,12 +53,10 @@ func NewProvider() (*provider, error) {
}
userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User)
if userCollectionExists {
log.Println(models.Collections.User + " collection exists already")
} else {
if !userCollectionExists {
_, err = arangodb.CreateCollection(ctx, models.Collections.User, nil)
if err != nil {
log.Println("error creating collection("+models.Collections.User+"):", err)
return nil, err
}
}
userCollection, _ := arangodb.Collection(nil, models.Collections.User)
@ -74,12 +70,10 @@ func NewProvider() (*provider, error) {
})
verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.VerificationRequest)
if verificationRequestCollectionExists {
log.Println(models.Collections.VerificationRequest + " collection exists already")
} else {
if !verificationRequestCollectionExists {
_, err = arangodb.CreateCollection(ctx, models.Collections.VerificationRequest, 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)
if sessionCollectionExists {
log.Println(models.Collections.Session + " collection exists already")
} else {
if !sessionCollectionExists {
_, err = arangodb.CreateCollection(ctx, models.Collections.Session, 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)
if configCollectionExists {
log.Println(models.Collections.Env + " collection exists already")
} else {
if !configCollectionExists {
_, err = arangodb.CreateCollection(ctx, models.Collections.Env, nil)
if err != nil {
log.Println("error creating collection("+models.Collections.Env+"):", err)
return nil, err
}
}

View File

@ -2,7 +2,6 @@ package arangodb
import (
"fmt"
"log"
"time"
"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)
_, err := sessionCollection.CreateDocument(nil, session)
if err != nil {
log.Println(`error saving session`, err)
return err
}
return nil

View File

@ -3,7 +3,6 @@ package arangodb
import (
"context"
"fmt"
"log"
"strings"
"time"
@ -31,7 +30,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
userCollection, _ := p.db.Collection(nil, models.Collections.User)
meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(nil), user)
if err != nil {
log.Println("error adding user:", err)
return user, err
}
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)
meta, err := collection.UpdateDocument(nil, user.Key, user)
if err != nil {
log.Println("error updating 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)
_, err := collection.RemoveDocument(nil, user.Key)
if err != nil {
log.Println(`error deleting user:`, err)
return err
}

View File

@ -3,7 +3,6 @@ package arangodb
import (
"context"
"fmt"
"log"
"time"
"github.com/arangodb/go-driver"
@ -23,7 +22,6 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
verificationRequestRequestCollection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
meta, err := verificationRequestRequestCollection.CreateDocument(nil, verificationRequest)
if err != nil {
log.Println("error saving verificationRequest record:", err)
return verificationRequest, err
}
verificationRequest.Key = meta.Key
@ -136,7 +134,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
collection, _ := p.db.Collection(nil, models.Collections.VerificationRequest)
_, err := collection.RemoveDocument(nil, verificationRequest.Key)
if err != nil {
log.Println(`error deleting verification request:`, err)
return err
}
return nil

View File

@ -4,7 +4,6 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"strings"
"github.com/authorizerdev/authorizer/server/constants"
@ -88,7 +87,6 @@ func NewProvider() (*provider, error) {
session, err := cassandraClient.CreateSession()
if err != nil {
log.Println("Error while creating connection to cassandra db", err)
return nil, err
}
@ -101,7 +99,6 @@ func NewProvider() (*provider, error) {
var keySpace string
err := scanner.Scan(&keySpace)
if err != nil {
log.Println("Error while getting keyspace information", err)
return nil, err
}
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)
err = session.Query(createKeySpaceQuery).Exec()
if err != nil {
log.Println("Error while creating keyspace", err)
return nil, err
}
}
@ -124,27 +120,23 @@ func NewProvider() (*provider, error) {
KeySpace, models.Collections.Env)
err = session.Query(envCollectionQuery).Exec()
if err != nil {
log.Println("Unable to create env collection:", 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)
err = session.Query(sessionCollectionQuery).Exec()
if err != nil {
log.Println("Unable to create session collection:", 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)
err = session.Query(userCollectionQuery).Exec()
if err != nil {
log.Println("Unable to create user collection:", err)
return nil, err
}
userIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_email ON %s.%s (email)", KeySpace, models.Collections.User)
err = session.Query(userIndexQuery).Exec()
if err != nil {
log.Println("Unable to create user index:", 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)
err = session.Query(verificationRequestCollectionQuery).Exec()
if err != nil {
log.Println("Unable to create verification request collection:", err)
return nil, err
}
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()
if err != nil {
log.Println("Unable to create verification_requests index:", err)
return nil, err
}
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()
if err != nil {
log.Println("Unable to create verification_requests index:", 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)
err = session.Query(verificationRequestIndexQuery).Exec()
if err != nil {
log.Println("Unable to create verification_requests index:", err)
return nil, err
}

View File

@ -2,7 +2,6 @@ package cassandradb
import (
"fmt"
"log"
"time"
"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)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
log.Println("Error while quering verification request", err)
return nil, err
}
@ -77,7 +75,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
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)
if err != nil {
log.Println("Error while parsing verification request", err)
return nil, err
}
verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())

View File

@ -2,7 +2,6 @@ package mongodb
import (
"fmt"
"log"
"time"
"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())
_, err := configCollection.InsertOne(nil, env)
if err != nil {
log.Println("error adding config:", err)
return env, err
}
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())
_, err := configCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions())
if err != nil {
log.Println("error updating config:", err)
return env, err
}
return env, nil

View File

@ -1,7 +1,6 @@
package mongodb
import (
"log"
"time"
"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())
_, err := sessionCollection.InsertOne(nil, session)
if err != nil {
log.Println(`error saving session`, err)
return err
}
return nil
@ -33,7 +31,6 @@ func (p *provider) DeleteSession(userId string) error {
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
_, err := sessionCollection.DeleteMany(nil, bson.M{"user_id": userId}, options.Delete())
if err != nil {
log.Println("error deleting session:", err)
return err
}
return nil

View File

@ -1,7 +1,6 @@
package mongodb
import (
"log"
"strings"
"time"
@ -29,7 +28,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
userCollection := p.db.Collection(models.Collections.User, options.Collection())
_, err := userCollection.InsertOne(nil, user)
if err != nil {
log.Println("error adding 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())
_, err := userCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions())
if err != nil {
log.Println("error updating user:", err)
return user, err
}
return user, nil
@ -53,7 +50,6 @@ func (p *provider) DeleteUser(user models.User) error {
userCollection := p.db.Collection(models.Collections.User, options.Collection())
_, err := userCollection.DeleteOne(nil, bson.M{"_id": user.ID}, options.Delete())
if err != nil {
log.Println("error deleting user:", 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())
count, err := userCollection.CountDocuments(nil, bson.M{}, options.Count())
if err != nil {
log.Println("error getting total users:", 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)
if err != nil {
log.Println("error getting users:", err)
return nil, err
}
defer cursor.Close(nil)

View File

@ -1,7 +1,6 @@
package mongodb
import (
"log"
"time"
"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())
_, err := verificationRequestCollection.InsertOne(nil, verificationRequest)
if err != nil {
log.Println("error saving verification record:", err)
return verificationRequest, err
}
}
@ -73,7 +71,6 @@ func (p *provider) ListVerificationRequests(pagination model.Pagination) (*model
cursor, err := verificationRequestCollection.Find(nil, bson.M{}, opts)
if err != nil {
log.Println("error getting verification requests:", err)
return nil, err
}
defer cursor.Close(nil)
@ -98,7 +95,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
_, err := verificationRequestCollection.DeleteOne(nil, bson.M{"_id": verificationRequest.ID}, options.Delete())
if err != nil {
log.Println("error deleting verification request::", err)
return err
}

View File

@ -1,7 +1,6 @@
package sql
import (
"log"
"time"
"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)
if result.Error != nil {
log.Println("error adding config:", result.Error)
return env, result.Error
}
return env, nil
@ -32,7 +30,6 @@ func (p *provider) UpdateEnv(env models.Env) (models.Env, error) {
result := p.db.Save(&env)
if result.Error != nil {
log.Println("error updating config:", result.Error)
return env, result.Error
}
return env, nil

View File

@ -1,7 +1,6 @@
package sql
import (
"log"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
@ -23,7 +22,6 @@ func (p *provider) AddSession(session models.Session) error {
DoNothing: true,
}).Create(&session)
if res.Error != nil {
log.Println(`error saving session`, res.Error)
return res.Error
}
return nil
@ -34,7 +32,6 @@ func (p *provider) DeleteSession(userId string) error {
result := p.db.Where("user_id = ?", userId).Delete(&models.Session{})
if result.Error != nil {
log.Println(`error deleting session:`, result.Error)
return result.Error
}
return nil

View File

@ -1,7 +1,6 @@
package sql
import (
"log"
"strings"
"time"
@ -33,7 +32,6 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
}).Create(&user)
if result.Error != nil {
log.Println("error adding 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)
if result.Error != nil {
log.Println("error updating user:", result.Error)
return user, result.Error
}
@ -59,7 +56,6 @@ func (p *provider) DeleteUser(user models.User) error {
result := p.db.Delete(&user)
if result.Error != nil {
log.Println(`error deleting user:`, result.Error)
return result.Error
}
@ -71,7 +67,6 @@ func (p *provider) ListUsers(pagination model.Pagination) (*model.Users, error)
var users []models.User
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users)
if result.Error != nil {
log.Println("error getting users:", result.Error)
return nil, result.Error
}

View File

@ -1,7 +1,6 @@
package sql
import (
"log"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
@ -25,7 +24,6 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
}).Create(&verificationRequest)
if result.Error != nil {
log.Println(`error saving verification request record`, 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)
if result.Error != nil {
log.Println(`error getting verification request:`, 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)
if result.Error != nil {
log.Println(`error getting verification token:`, 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)
if result.Error != nil {
log.Println("error getting verification requests:", result.Error)
return nil, result.Error
}
@ -94,7 +89,6 @@ func (p *provider) DeleteVerificationRequest(verificationRequest models.Verifica
result := p.db.Delete(&verificationRequest)
if result.Error != nil {
log.Println(`error deleting verification request:`, result.Error)
return result.Error
}

View File

@ -4,13 +4,14 @@ import (
"bytes"
"crypto/tls"
"encoding/json"
"log"
"strconv"
"text/template"
log "github.com/sirupsen/logrus"
gomail "gopkg.in/mail.v2"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
gomail "gopkg.in/mail.v2"
)
// 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}
}
if err := d.DialAndSend(m); err != nil {
log.Printf("smtp error: %s", err)
log.Debug("SMTP Failed: ", err)
return err
}
return nil

View File

@ -1,7 +1,7 @@
package email
import (
"log"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
@ -107,7 +107,7 @@ func InviteEmail(toEmail, token, verificationURL, redirectURI string) error {
err := SendMail(Receiver, Subject, message)
if err != nil {
log.Println("error sending email:", err)
log.Warn("error sending email: ", err)
}
return err
}

View File

@ -1,7 +1,7 @@
package email
import (
"log"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
@ -107,7 +107,7 @@ func SendVerificationMail(toEmail, token, hostname string) error {
err := SendMail(Receiver, Subject, message)
if err != nil {
log.Println("error sending email:", err)
log.Warn("error sending email: ", err)
}
return err
}

18
server/env/env.go vendored
View File

@ -2,17 +2,17 @@ package env
import (
"errors"
"log"
"os"
"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/crypto"
"github.com/authorizerdev/authorizer/server/envstore"
"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
@ -29,10 +29,11 @@ func InitRequiredEnv() error {
if envstore.ARG_ENV_FILE != nil && *envstore.ARG_ENV_FILE != "" {
envPath = *envstore.ARG_ENV_FILE
}
log.Info("env path: ", envPath)
err := godotenv.Load(envPath)
if err != nil {
log.Printf("using OS env instead of %s file", envPath)
log.Info("using OS env instead of %s file", envPath)
}
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
@ -52,6 +53,7 @@ func InitRequiredEnv() error {
}
if dbType == "" {
log.Debug("DATABASE_TYPE is not set")
return errors.New("invalid database type. DATABASE_TYPE is empty")
}
}
@ -62,6 +64,7 @@ func InitRequiredEnv() error {
}
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
log.Debug("DATABASE_URL is not set")
return errors.New("invalid database url. DATABASE_URL is required")
}
}
@ -91,7 +94,7 @@ func InitRequiredEnv() error {
func InitAllEnv() error {
envData, err := GetEnvData()
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
envData = envstore.EnvStoreObj.GetEnvStoreClone()
}
@ -118,7 +121,6 @@ func InitAllEnv() error {
if envData.StringEnv[constants.EnvKeyEnv] == "production" {
envData.BoolEnv[constants.EnvKeyIsProd] = true
gin.SetMode(gin.ReleaseMode)
} else {
envData.BoolEnv[constants.EnvKeyIsProd] = false
}
@ -179,6 +181,7 @@ func InitAllEnv() error {
} else {
algo = envData.StringEnv[constants.EnvKeyJwtType]
if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
log.Debug("Invalid JWT Algorithm")
return errors.New("invalid JWT_TYPE")
}
}
@ -384,6 +387,7 @@ func InitAllEnv() error {
}
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`)
}

View File

@ -2,12 +2,12 @@ package env
import (
"encoding/json"
"log"
"os"
"strconv"
"strings"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/crypto"
@ -23,12 +23,14 @@ func GetEnvData() (envstore.Store, error) {
env, err := db.Provider.GetEnv()
// config not found in db
if err != nil {
log.Debug("Error while getting env data from db: ", err)
return result, err
}
encryptionKey := env.Hash
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
if err != nil {
log.Debug("Error while decrypting encryption key: ", err)
return result, err
}
@ -36,16 +38,19 @@ func GetEnvData() (envstore.Store, error) {
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
if err != nil {
log.Debug("Error while decrypting env data from B64: ", err)
return result, err
}
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
if err != nil {
log.Debug("Error while decrypting env data from AES: ", err)
return result, err
}
err = json.Unmarshal(decryptedConfigs, &result)
if err != nil {
log.Debug("Error while unmarshalling env data: ", err)
return result, err
}
@ -64,6 +69,7 @@ func PersistEnv() error {
encryptedConfig, err := crypto.EncryptEnvData(envstore.EnvStoreObj.GetEnvStoreClone())
if err != nil {
log.Debug("Error while encrypting env data: ", err)
return err
}
@ -74,6 +80,7 @@ func PersistEnv() error {
env, err = db.Provider.AddEnv(env)
if err != nil {
log.Debug("Error while persisting env data to db: ", err)
return err
}
} else {
@ -82,6 +89,7 @@ func PersistEnv() error {
encryptionKey := env.Hash
decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
if err != nil {
log.Debug("Error while decrypting encryption key: ", err)
return err
}
@ -89,11 +97,13 @@ func PersistEnv() error {
b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
if err != nil {
log.Debug("Error while decrypting env data from B64: ", err)
return err
}
decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
if err != nil {
log.Debug("Error while decrypting env data from AES: ", err)
return err
}
@ -102,6 +112,7 @@ func PersistEnv() error {
err = json.Unmarshal(decryptedConfigs, &storeData)
if err != nil {
log.Debug("Error while unmarshalling env data: ", err)
return err
}
@ -169,6 +180,7 @@ func PersistEnv() error {
envstore.EnvStoreObj.UpdateEnvStore(storeData)
jwk, err := crypto.GenerateJWKBasedOnEnv()
if err != nil {
log.Debug("Error while generating JWK: ", err)
return err
}
// updating jwk
@ -177,13 +189,14 @@ func PersistEnv() error {
if hasChanged {
encryptedConfig, err := crypto.EncryptEnvData(storeData)
if err != nil {
log.Debug("Error while encrypting env data: ", err)
return err
}
env.EnvData = encryptedConfig
_, err = db.Provider.UpdateEnv(env)
if err != nil {
log.Println("error updating config:", err)
log.Debug("Failed to Update Config: ", err)
return err
}
}

View File

@ -13,6 +13,8 @@ var (
ARG_DB_TYPE *string
// ARG_ENV_FILE is the cli arg variable for the env file
ARG_ENV_FILE *string
// ARG_LOG_LEVEL is the cli arg variable for the log level
ARG_LOG_LEVEL *string
)
// Store data structure

View File

@ -20,6 +20,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
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/ugorji/go v1.2.6 // indirect
github.com/vektah/gqlparser/v2 v2.2.0

View File

@ -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/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.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.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=

View File

@ -1,14 +1,15 @@
package handlers
import (
"log"
"net/http"
"strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/gin-gonic/gin"
)
// State is the struct that holds authorizer url and redirect url
@ -23,6 +24,7 @@ func AppHandler() gin.HandlerFunc {
return func(c *gin.Context) {
hostname := utils.GetHost(c)
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
log.Debug("Login page is disabled")
c.JSON(400, gin.H{"error": "login page is not enabled"})
return
}
@ -43,6 +45,7 @@ func AppHandler() gin.HandlerFunc {
} else {
// validate redirect url with allowed origins
if !utils.IsValidOrigin(redirect_uri) {
log.Debug("Invalid redirect_uri")
c.JSON(400, gin.H{"error": "invalid redirect url"})
return
}
@ -52,7 +55,7 @@ func AppHandler() gin.HandlerFunc {
if pusher := c.Writer.Pusher(); pusher != nil {
// use pusher.Push() to do server push
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{

View File

@ -6,14 +6,16 @@ import (
"strings"
"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/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// AuthorizeHandler is the handler for the /authorize route
@ -48,6 +50,7 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseMode != "query" && responseMode != "web_message" {
log.Debug("Invalid response_mode: ", responseMode)
gc.JSON(400, gin.H{"error": "invalid response mode"})
}
@ -63,6 +66,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if isQuery {
gc.Redirect(http.StatusFound, loginURL)
} else {
log.Debug("Failed to get client_id: ", clientID)
gc.HTML(http.StatusOK, template, gin.H{
"target_origin": redirectURI,
"authorization_response": map[string]interface{}{
@ -80,6 +84,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if isQuery {
gc.Redirect(http.StatusFound, loginURL)
} else {
log.Debug("Invalid client_id: ", clientID)
gc.HTML(http.StatusOK, template, gin.H{
"target_origin": redirectURI,
"authorization_response": map[string]interface{}{
@ -97,6 +102,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if isQuery {
gc.Redirect(http.StatusFound, loginURL)
} else {
log.Debug("Failed to get state: ", state)
gc.HTML(http.StatusOK, template, gin.H{
"target_origin": redirectURI,
"authorization_response": map[string]interface{}{
@ -121,6 +127,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if isQuery {
gc.Redirect(http.StatusFound, loginURL)
} else {
log.Debug("Invalid response_type: ", responseType)
gc.HTML(http.StatusOK, template, gin.H{
"target_origin": redirectURI,
"authorization_response": map[string]interface{}{
@ -139,6 +146,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if isQuery {
gc.Redirect(http.StatusFound, loginURL)
} else {
log.Debug("Failed to get code_challenge: ", codeChallenge)
gc.HTML(http.StatusBadRequest, template, gin.H{
"target_origin": redirectURI,
"authorization_response": map[string]interface{}{

View File

@ -3,9 +3,11 @@ package handlers
import (
"encoding/json"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/gin-gonic/gin"
)
func JWKsHandler() gin.HandlerFunc {
@ -14,6 +16,7 @@ func JWKsHandler() gin.HandlerFunc {
jwk := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJWK)
err := json.Unmarshal([]byte(jwk), &data)
if err != nil {
log.Debug("Failed to parse JWK: ", err)
c.JSON(500, gin.H{
"error": err.Error(),
})

View File

@ -4,10 +4,12 @@ import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/gin-gonic/gin"
)
// Handler to logout user
@ -17,6 +19,7 @@ func LogoutHandler() gin.HandlerFunc {
// get fingerprint hash
fingerprintHash, err := cookie.GetSession(gc)
if err != nil {
log.Debug("Failed to get session: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@ -25,6 +28,7 @@ func LogoutHandler() gin.HandlerFunc {
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
if err != nil {
log.Debug("Failed to decrypt fingerprint: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})

View File

@ -5,12 +5,16 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
"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/cookie"
"github.com/authorizerdev/authorizer/server/db"
@ -20,9 +24,6 @@ import (
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"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
@ -33,6 +34,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
sessionState := sessionstore.GetState(state)
if sessionState == "" {
log.Debug("Invalid oauth state: ", state)
c.JSON(400, gin.H{"error": "invalid oauth state"})
}
sessionstore.GetState(state)
@ -40,6 +42,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
sessionSplit := strings.Split(state, "___")
if len(sessionSplit) < 3 {
log.Debug("Unable to get redirect url from state: ", state)
c.JSON(400, gin.H{"error": "invalid redirect url"})
return
}
@ -60,18 +63,22 @@ func OAuthCallbackHandler() gin.HandlerFunc {
case constants.SignupMethodFacebook:
user, err = processFacebookUserInfo(code)
default:
log.Info("Invalid oauth provider")
err = fmt.Errorf(`invalid oauth provider`)
}
if err != nil {
log.Debug("Failed to process user info: ", err)
c.JSON(400, gin.H{"error": err.Error()})
return
}
existingUser, err := db.Provider.GetUserByEmail(user.Email)
log := log.WithField("user", user.Email)
if err != nil {
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"})
return
}
@ -86,6 +93,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
}
if hasProtectedRole {
log.Debug("Signup is not allowed with protected roles:", inputRoles)
c.JSON(400, gin.H{"error": "invalid role"})
return
}
@ -96,6 +104,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
user, _ = db.Provider.AddUser(user)
} else {
if user.RevokedTimestamp != nil {
log.Debug("User access revoked at: ", user.RevokedTimestamp)
c.JSON(400, gin.H{"error": "user access has been revoked"})
}
@ -137,6 +146,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
}
if hasProtectedRole {
log.Debug("Invalid role. User is using protected unassigned role")
c.JSON(400, gin.H{"error": "invalid role"})
return
} else {
@ -148,6 +158,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
user, err = db.Provider.UpdateUser(user)
if err != nil {
log.Debug("Failed to update user: ", err)
c.JSON(500, gin.H{"error": err.Error()})
return
}
@ -155,6 +166,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
authToken, err := token.CreateAuthToken(c, user, inputRoles, scopes)
if err != nil {
log.Debug("Failed to create auth token: ", err)
c.JSON(500, gin.H{"error": err.Error()})
}
@ -194,6 +206,7 @@ func processGoogleUserInfo(code string) (models.User, error) {
ctx := context.Background()
oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
if err != nil {
log.Debug("Failed to exchange code for token: ", err)
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.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
log.Debug("Failed to extract ID Token from OAuth2 token")
return user, fmt.Errorf("unable to extract id_token")
}
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
log.Debug("Failed to verify ID Token: ", err)
return user, fmt.Errorf("unable to verify id_token: %s", err.Error())
}
if err := idToken.Claims(&user); err != nil {
log.Debug("Failed to parse ID Token claims: ", err)
return user, fmt.Errorf("unable to extract claims")
}
@ -222,11 +238,13 @@ func processGithubUserInfo(code string) (models.User, error) {
user := models.User{}
token, err := oauth.OAuthProviders.GithubConfig.Exchange(oauth2.NoContext, code)
if err != nil {
log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid github exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.GithubUserInfoURL, 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())
}
req.Header = http.Header{
@ -235,12 +253,14 @@ func processGithubUserInfo(code string) (models.User, error) {
response, err := client.Do(req)
if err != nil {
log.Debug("Failed to request github user info: ", err)
return user, err
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
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())
}
@ -273,23 +293,26 @@ func processFacebookUserInfo(code string) (models.User, error) {
user := models.User{}
token, err := oauth.OAuthProviders.FacebookConfig.Exchange(oauth2.NoContext, code)
if err != nil {
log.Debug("Invalid facebook exchange code: ", err)
return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.FacebookUserInfoURL+token.AccessToken, 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())
}
response, err := client.Do(req)
if err != nil {
log.Println("error processing facebook user info:", err)
log.Debug("Failed to process facebook user: ", err)
return user, err
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Debug("Failed to read facebook response: ", err)
return user, fmt.Errorf("failed to read facebook response body: %s", err.Error())
}

View File

@ -4,12 +4,14 @@ import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/oauth"
"github.com/authorizerdev/authorizer/server/sessionstore"
"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
@ -26,6 +28,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
scopeString := strings.TrimSpace(c.Query("scope"))
if redirectURI == "" {
log.Debug("redirect_uri is empty")
c.JSON(400, gin.H{
"error": "invalid redirect uri",
})
@ -33,6 +36,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
}
if state == "" {
log.Debug("state is empty")
c.JSON(400, gin.H{
"error": "invalid state",
})
@ -53,6 +57,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
// use protected roles verification for admin login only.
// 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)...)...)) {
log.Debug("Invalid roles: ", roles)
c.JSON(400, gin.H{
"error": "invalid role",
})
@ -69,6 +74,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
switch provider {
case constants.SignupMethodGoogle:
if oauth.OAuthProviders.GoogleConfig == nil {
log.Debug("Google OAuth provider is not configured")
isProviderConfigured = false
break
}
@ -79,6 +85,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
c.Redirect(http.StatusTemporaryRedirect, url)
case constants.SignupMethodGithub:
if oauth.OAuthProviders.GithubConfig == nil {
log.Debug("Github OAuth provider is not configured")
isProviderConfigured = false
break
}
@ -88,6 +95,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
c.Redirect(http.StatusTemporaryRedirect, url)
case constants.SignupMethodFacebook:
if oauth.OAuthProviders.FacebookConfig == nil {
log.Debug("Facebook OAuth provider is not configured")
isProviderConfigured = false
break
}
@ -96,6 +104,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url)
default:
log.Debug("Invalid oauth provider: ", provider)
c.JSON(422, gin.H{
"message": "Invalid oauth provider",
})

View File

@ -4,10 +4,12 @@ import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/gin-gonic/gin"
)
// Revoke handler to revoke refresh token
@ -15,6 +17,7 @@ func RevokeHandler() gin.HandlerFunc {
return func(gc *gin.Context) {
var reqBody map[string]string
if err := gc.BindJSON(&reqBody); err != nil {
log.Debug("Error binding JSON: ", err)
gc.JSON(http.StatusBadRequest, gin.H{
"error": "error_binding_json",
"error_description": err.Error(),
@ -26,6 +29,7 @@ func RevokeHandler() gin.HandlerFunc {
clientID := strings.TrimSpace(reqBody["client_id"])
if clientID == "" {
log.Debug("Client ID is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "client_id_required",
"error_description": "The client id is required",
@ -34,6 +38,7 @@ func RevokeHandler() gin.HandlerFunc {
}
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
log.Debug("Client ID is invalid: ", clientID)
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id",
"error_description": "The client id is invalid",

View File

@ -7,13 +7,15 @@ import (
"strings"
"time"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/gin-gonic/gin"
)
// TokenHandler to handle /oauth/token requests
@ -22,6 +24,7 @@ func TokenHandler() gin.HandlerFunc {
return func(gc *gin.Context) {
var reqBody map[string]string
if err := gc.BindJSON(&reqBody); err != nil {
log.Debug("Error binding JSON: ", err)
gc.JSON(http.StatusBadRequest, gin.H{
"error": "error_binding_json",
"error_description": err.Error(),
@ -43,6 +46,7 @@ func TokenHandler() gin.HandlerFunc {
isAuthorizationCodeGrant := grantType == "authorization_code"
if !isRefreshTokenGrant && !isAuthorizationCodeGrant {
log.Debug("Invalid grant type: ", grantType)
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_grant_type",
"error_description": "grant_type is invalid",
@ -50,6 +54,7 @@ func TokenHandler() gin.HandlerFunc {
}
if clientID == "" {
log.Debug("Client ID is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "client_id_required",
"error_description": "The client id is required",
@ -58,6 +63,7 @@ func TokenHandler() gin.HandlerFunc {
}
if clientID != envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyClientID) {
log.Debug("Client ID is invalid: ", clientID)
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id",
"error_description": "The client id is invalid",
@ -70,6 +76,7 @@ func TokenHandler() gin.HandlerFunc {
if isAuthorizationCodeGrant {
if codeVerifier == "" {
log.Debug("Code verifier is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code_verifier",
"error_description": "The code verifier is required",
@ -78,6 +85,7 @@ func TokenHandler() gin.HandlerFunc {
}
if code == "" {
log.Debug("Code is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code",
"error_description": "The code is required",
@ -92,6 +100,7 @@ func TokenHandler() gin.HandlerFunc {
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
sessionData := sessionstore.GetState(encryptedCode)
if sessionData == "" {
log.Debug("Session data is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code_verifier",
"error_description": "The code verifier is invalid",
@ -104,6 +113,7 @@ func TokenHandler() gin.HandlerFunc {
sessionDataSplit := strings.Split(sessionData, "@")
if sessionDataSplit[0] != code {
log.Debug("Invalid code verifier. Unable to split session data")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code_verifier",
"error_description": "The code verifier is invalid",
@ -114,6 +124,7 @@ func TokenHandler() gin.HandlerFunc {
// validate session
claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
if err != nil {
log.Debug("Error validating session: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "Invalid session data",
@ -128,6 +139,7 @@ func TokenHandler() gin.HandlerFunc {
} else {
// validate refresh token
if refreshToken == "" {
log.Debug("Refresh token is empty")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_refresh_token",
"error_description": "The refresh token is invalid",
@ -136,6 +148,7 @@ func TokenHandler() gin.HandlerFunc {
claims, err := token.ValidateRefreshToken(gc, refreshToken)
if err != nil {
log.Debug("Error validating refresh token: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": err.Error(),
@ -156,6 +169,7 @@ func TokenHandler() gin.HandlerFunc {
user, err := db.Provider.GetUserByID(userID)
if err != nil {
log.Debug("Error getting user: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "User not found",
@ -165,6 +179,7 @@ func TokenHandler() gin.HandlerFunc {
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
if err != nil {
log.Debug("Error creating auth token: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "User not found",

View File

@ -3,15 +3,18 @@ package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/token"
"github.com/gin-gonic/gin"
)
func UserInfoHandler() gin.HandlerFunc {
return func(gc *gin.Context) {
accessToken, err := token.GetAccessToken(gc)
if err != nil {
log.Debug("Error getting access token: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@ -20,6 +23,7 @@ func UserInfoHandler() gin.HandlerFunc {
claims, err := token.ValidateAccessToken(gc, accessToken)
if err != nil {
log.Debug("Error validating access token: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@ -29,6 +33,7 @@ func UserInfoHandler() gin.HandlerFunc {
userID := claims["sub"].(string)
user, err := db.Provider.GetUserByID(userID)
if err != nil {
log.Debug("Error getting user: ", err)
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})

View File

@ -6,13 +6,15 @@ import (
"strings"
"time"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/gin-gonic/gin"
)
// VerifyEmailHandler handles the verify email route.
@ -24,12 +26,14 @@ func VerifyEmailHandler() gin.HandlerFunc {
}
tokenInQuery := c.Query("token")
if tokenInQuery == "" {
log.Debug("Token is empty")
c.JSON(400, errorRes)
return
}
verificationRequest, err := db.Provider.GetVerificationRequestByToken(tokenInQuery)
if err != nil {
log.Debug("Error getting verification request: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
return
@ -39,6 +43,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
hostname := utils.GetHost(c)
claim, err := token.ParseJWTToken(tokenInQuery, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil {
log.Debug("Error parsing token: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
return
@ -46,6 +51,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
user, err := db.Provider.GetUserByEmail(claim["sub"].(string))
if err != nil {
log.Debug("Error getting user: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
return
@ -79,6 +85,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
}
authToken, err := token.CreateAuthToken(c, user, roles, scope)
if err != nil {
log.Debug("Error creating auth token: ", err)
errorRes["error_description"] = err.Error()
c.JSON(500, errorRes)
return

View File

@ -2,7 +2,9 @@ package main
import (
"flag"
"log"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
@ -15,13 +17,51 @@ import (
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() {
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_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()
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
// initialize required envs (mainly db & env file path)
@ -61,6 +101,7 @@ func main() {
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))
}

78
server/middlewares/log.go Normal file
View 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)
}
}
}
}

View File

@ -3,12 +3,13 @@ package oauth
import (
"context"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
facebookOAuth2 "golang.org/x/oauth2/facebook"
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

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -14,15 +16,17 @@ import (
// AdminLoginResolver is a resolver for admin login mutation
func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if params.AdminSecret != adminSecret {
log.Debug("Admin secret is not correct")
return res, fmt.Errorf(`invalid admin secret`)
}

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/token"
@ -12,14 +14,16 @@ import (
// AdminLogoutResolver is a resolver for admin logout mutation
func AdminLogoutResolver(ctx context.Context) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Admin is not logged in")
return res, fmt.Errorf("unauthorized")
}

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -15,19 +17,22 @@ import (
// AdminSessionResolver is a resolver for admin session query
func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return res, fmt.Errorf("unauthorized")
}
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
if err != nil {
log.Debug("Failed to encrypt key: ", err)
return res, err
}
cookie.SetAdminCookie(gc, hashedKey)

View File

@ -6,6 +6,8 @@ import (
"fmt"
"strings"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -17,19 +19,22 @@ import (
// AdminSignupResolver is a resolver for admin signup mutation
func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if strings.TrimSpace(params.AdminSecret) == "" {
log.Debug("Admin secret is empty")
err = fmt.Errorf("please select secure admin secret")
return res, err
}
if len(params.AdminSecret) < 6 {
log.Debug("Admin secret is too short")
err = fmt.Errorf("admin secret must be at least 6 characters")
return res, err
}
@ -37,6 +42,7 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
adminSecret := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
if adminSecret != "" {
log.Debug("Admin secret is already set")
err = fmt.Errorf("admin sign up already completed")
return res, err
}
@ -47,30 +53,36 @@ func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*m
jsonBytes, err := json.Marshal(envstore.EnvStoreObj.GetEnvStoreClone())
if err != nil {
log.Debug("Failed to marshal envstore: ", err)
return res, err
}
if err := json.Unmarshal(jsonBytes, &storeData); err != nil {
log.Debug("Failed to unmarshal envstore: ", err)
return res, err
}
env, err := db.Provider.GetEnv()
if err != nil {
log.Debug("Failed to get env: ", err)
return res, err
}
envData, err := crypto.EncryptEnvData(storeData)
if err != nil {
log.Debug("Failed to encrypt envstore: ", err)
return res, err
}
env.EnvData = envData
if _, err := db.Provider.UpdateEnv(env); err != nil {
log.Debug("Failed to update env: ", err)
return res, err
}
hashedKey, err := crypto.EncryptPassword(params.AdminSecret)
if err != nil {
log.Debug("Failed to encrypt admin session key: ", err)
return res, err
}
cookie.SetAdminCookie(gc, hashedKey)

View File

@ -3,7 +3,8 @@ package resolvers
import (
"context"
"fmt"
"log"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
@ -14,18 +15,26 @@ import (
// DeleteUserResolver is a resolver for delete user mutation
func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return res, fmt.Errorf("unauthorized")
}
log := log.WithFields(log.Fields{
"email": params.Email,
})
user, err := db.Provider.GetUserByEmail(params.Email)
if err != nil {
log.Debug("Failed to get user from DB: ", err)
return res, err
}
@ -33,7 +42,7 @@ func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*mod
err = db.Provider.DeleteUser(user)
if err != nil {
log.Println("error deleting user:", err)
log.Debug("Failed to delete user: ", err)
return res, err
}

View File

@ -3,7 +3,8 @@ package resolvers
import (
"context"
"fmt"
"log"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
@ -13,18 +14,26 @@ import (
// EnableAccessResolver is a resolver for enabling user access
func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.")
return res, fmt.Errorf("unauthorized")
}
log := log.WithFields(log.Fields{
"user_id": params.UserID,
})
user, err := db.Provider.GetUserByID(params.UserID)
if err != nil {
log.Debug("Failed to get user from DB: ", err)
return res, err
}
@ -32,7 +41,7 @@ func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (
user, err = db.Provider.UpdateUser(user)
if err != nil {
log.Println("error updating user:", err)
log.Debug("Failed to update user: ", err)
return res, err
}

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/authorizerdev/authorizer/server/graph/model"
@ -14,14 +16,16 @@ import (
// EnvResolver is a resolver for config query
// This is admin only query
func EnvResolver(ctx context.Context) (*model.Env, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Env
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.")
return res, fmt.Errorf("unauthorized")
}

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@ -19,28 +20,38 @@ import (
// ForgotPasswordResolver is a resolver for forgot password mutation
func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
}
params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) {
log.Debug("Invalid email address: ", params.Email)
return res, fmt.Errorf("invalid email")
}
log := log.WithFields(log.Fields{
"email": params.Email,
})
_, err = db.Provider.GetUserByEmail(params.Email)
if err != nil {
log.Debug("User not found: ", err)
return res, fmt.Errorf(`user with this email not found`)
}
hostname := utils.GetHost(gc)
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
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)
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,
Identifier: constants.VerificationTypeForgotPassword,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@ -60,6 +72,10 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
Nonce: nonceHash,
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
go email.SendForgotPasswordMail(params.Email, verificationToken, hostname)

View File

@ -10,16 +10,19 @@ import (
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
log "github.com/sirupsen/logrus"
)
// GenerateJWTKeysResolver mutation to generate new jwt keys
func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return nil, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
@ -27,6 +30,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
if crypto.IsHMACA(params.Type) {
secret, _, err := crypto.NewHMACKey(params.Type, clientID)
if err != nil {
log.Debug("Failed to generate new HMAC key: ", err)
return nil, err
}
return &model.GenerateJWTKeysResponse{
@ -37,6 +41,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
if crypto.IsRSA(params.Type) {
_, privateKey, publicKey, _, err := crypto.NewRSAKey(params.Type, clientID)
if err != nil {
log.Debug("Failed to generate new RSA key: ", err)
return nil, err
}
return &model.GenerateJWTKeysResponse{
@ -48,6 +53,7 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
if crypto.IsECDSA(params.Type) {
_, privateKey, publicKey, _, err := crypto.NewECDSAKey(params.Type, clientID)
if err != nil {
log.Debug("Failed to generate new ECDSA key: ", err)
return nil, err
}
return &model.GenerateJWTKeysResponse{
@ -56,5 +62,6 @@ func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysIn
}, nil
}
log.Debug("Invalid algorithm: ", params.Type)
return nil, fmt.Errorf("invalid algorithm")
}

View File

@ -4,10 +4,11 @@ import (
"context"
"errors"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@ -22,19 +23,23 @@ import (
func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return nil, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.")
return nil, errors.New("unauthorized")
}
// this feature is only allowed if email server is configured
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
log.Debug("Email server is not configured")
return nil, errors.New("email sending is disabled")
}
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")
}
@ -47,6 +52,7 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
}
if len(emails) == 0 {
log.Debug("No valid email addresses")
return nil, errors.New("no valid emails found")
}
@ -56,14 +62,15 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
for _, email := range emails {
_, err := db.Provider.GetUserByEmail(email)
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)
} 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 {
log.Debug("No new emails found.")
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)
if err != nil {
log.Println(`error generating token`, err)
log.Debug("Failed to create verification token: ", err)
}
verificationRequest := models.VerificationRequest{
@ -116,13 +123,13 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
user, err = db.Provider.AddUser(user)
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
}
_, err = db.Provider.AddVerificationRequest(verificationRequest)
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
}

View File

@ -3,10 +3,12 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/bcrypt"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
@ -16,49 +18,59 @@ import (
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
"golang.org/x/crypto/bcrypt"
)
// LoginResolver is a resolver for login mutation
func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.AuthResponse
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
log.Debug("Basic authentication is disabled.")
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)
user, err := db.Provider.GetUserByEmail(params.Email)
if err != nil {
log.Debug("Failed to get user by email: ", err)
return res, fmt.Errorf(`user with this email not found`)
}
if user.RevokedTimestamp != nil {
log.Debug("User access is revoked")
return res, fmt.Errorf(`user access has been revoked`)
}
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`)
}
if user.EmailVerifiedAt == nil {
log.Debug("User email is not verified")
return res, fmt.Errorf(`email not verified`)
}
err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
if err != nil {
log.Println("compare password error:", err)
log.Debug("Failed to compare password: ", err)
return res, fmt.Errorf(`invalid password`)
}
roles := envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles)
currentRoles := strings.Split(user.Roles, ",")
if len(params.Roles) > 0 {
if !utils.IsValidRoles(params.Roles, currentRoles) {
log.Debug("Invalid roles: ", params.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)
if err != nil {
log.Debug("Failed to create auth token", err)
return res, err
}

View File

@ -3,6 +3,8 @@ package resolvers
import (
"context"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/graph/model"
@ -12,20 +14,24 @@ import (
// LogoutResolver is a resolver for logout mutation
func LogoutResolver(ctx context.Context) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
// get fingerprint hash
fingerprintHash, err := cookie.GetSession(gc)
if err != nil {
log.Debug("Failed to get fingerprint hash: ", err)
return res, err
}
decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
if err != nil {
log.Debug("Failed to decrypt fingerprint hash: ", err)
return res, err
}

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@ -20,21 +21,29 @@ import (
// MagicLinkLoginResolver is a resolver for magic link login mutation
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
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`)
}
params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) {
log.Debug("Invalid email")
return res, fmt.Errorf(`invalid email address`)
}
log := log.WithFields(log.Fields{
"email": params.Email,
})
inputRoles := []string{}
user := models.User{
@ -45,6 +54,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
existingUser, err := db.Provider.GetUserByEmail(params.Email)
if err != nil {
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
log.Debug("Signup is disabled.")
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 {
// check if roles exists
if !utils.IsValidRoles(params.Roles, envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles)) {
log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf(`invalid roles`)
} else {
inputRoles = params.Roles
@ -71,6 +82,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
// Need to modify roles in this case
if user.RevokedTimestamp != nil {
log.Debug("User access is revoked at: ", user.RevokedTimestamp)
return res, fmt.Errorf(`user access has been revoked`)
}
@ -96,6 +108,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
}
if hasProtectedRole {
log.Debug("User is not assigned one of the protected roles", unasignedRoles)
return res, fmt.Errorf(`invalid roles`)
} else {
user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
@ -112,7 +125,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
user.SignupMethods = signupMethod
user, _ = db.Provider.UpdateUser(user)
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
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
redirectURLParams := "&roles=" + strings.Join(inputRoles, ",")
@ -144,7 +158,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
verificationType := constants.VerificationTypeMagicLinkLogin
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
if err != nil {
log.Println(`error generating token`, err)
log.Debug("Failed to create verification token: ", err)
}
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
Token: verificationToken,
@ -155,6 +169,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
RedirectURI: redirectURL,
})
if err != nil {
log.Debug("Failed to add verification request in db: ", err)
return res, err
}

View File

@ -3,6 +3,8 @@ package resolvers
import (
"context"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/token"
@ -11,25 +13,34 @@ import (
// ProfileResolver is a resolver for profile query
func ProfileResolver(ctx context.Context) (*model.User, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.User
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
accessToken, err := token.GetAccessToken(gc)
if err != nil {
log.Debug("Failed to get access token: ", err)
return res, err
}
claims, err := token.ValidateAccessToken(gc, accessToken)
if err != nil {
log.Debug("Failed to validate access token: ", err)
return res, err
}
userID := claims["sub"].(string)
log := log.WithFields(log.Fields{
"user_id": userID,
})
user, err := db.Provider.GetUserByID(userID)
if err != nil {
log.Debug("Failed to get user: ", err)
return res, err
}

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/email"
@ -18,42 +19,48 @@ import (
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) {
log.Debug("Invalid email: ", params.Email)
return res, fmt.Errorf("invalid email")
}
if !utils.IsValidVerificationIdentifier(params.Identifier) {
log.Debug("Invalid verification identifier: ", params.Identifier)
return res, fmt.Errorf("invalid identifier")
}
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(params.Email, params.Identifier)
if err != nil {
log.Debug("Failed to get verification request: ", err)
return res, fmt.Errorf(`verification request not found`)
}
// delete current verification and create new one
err = db.Provider.DeleteVerificationRequest(verificationRequest)
if err != nil {
log.Println("error deleting verification request:", err)
log.Debug("Failed to delete verification request: ", err)
}
hostname := utils.GetHost(gc)
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier, hostname, nonceHash, verificationRequest.RedirectURI)
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,
Identifier: params.Identifier,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@ -61,6 +68,9 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
Nonce: nonceHash,
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
go email.SendVerificationMail(params.Email, verificationToken, hostname)

View File

@ -6,6 +6,8 @@ import (
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/db"
@ -18,24 +20,30 @@ import (
// ResetPasswordResolver is a resolver for reset password mutation
func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
}
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
if err != nil {
log.Debug("Failed to get verification request: ", err)
return res, fmt.Errorf(`invalid token`)
}
if params.Password != params.ConfirmPassword {
log.Debug("Passwords do not match")
return res, fmt.Errorf(`passwords don't match`)
}
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`)
}
@ -43,11 +51,17 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
hostname := utils.GetHost(gc)
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil {
log.Debug("Failed to parse token: ", err)
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 {
log.Debug("Failed to get user: ", err)
return res, err
}
@ -67,8 +81,17 @@ func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput)
}
// delete from verification table
db.Provider.DeleteVerificationRequest(verificationRequest)
db.Provider.UpdateUser(user)
err = db.Provider.DeleteVerificationRequest(verificationRequest)
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{
Message: `Password updated successfully.`,

View File

@ -3,9 +3,10 @@ package resolvers
import (
"context"
"fmt"
"log"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore"
@ -15,18 +16,25 @@ import (
// RevokeAccessResolver is a resolver for revoking user access
func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return res, fmt.Errorf("unauthorized")
}
log := log.WithFields(log.Fields{
"user_id": params.UserID,
})
user, err := db.Provider.GetUserByID(params.UserID)
if err != nil {
log.Debug("Failed to get user by ID: ", err)
return res, err
}
@ -35,7 +43,7 @@ func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (
user, err = db.Provider.UpdateUser(user)
if err != nil {
log.Println("error updating user:", err)
log.Debug("Failed to update user: ", err)
return res, err
}

View File

@ -4,9 +4,10 @@ import (
"context"
"errors"
"fmt"
"log"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"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)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
sessionToken, err := cookie.GetSession(gc)
if err != nil {
log.Println("error getting session token:", err)
log.Debug("Failed to get session token", err)
return res, errors.New("unauthorized")
}
// get session from cookie
claims, err := token.ValidateBrowserSession(gc, sessionToken)
if err != nil {
log.Println("session validation failed:", err)
log.Debug("Failed to validate session token", err)
return res, errors.New("unauthorized")
}
userID := claims.Subject
log := log.WithFields(log.Fields{
"user_id": userID,
})
user, err := db.Provider.GetUserByID(userID)
if err != nil {
return res, err
@ -46,13 +53,12 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
// refresh token has "roles" as claim
claimRoleInterface := claims.Roles
claimRoles := []string{}
for _, v := range claimRoleInterface {
claimRoles = append(claimRoles, v)
}
claimRoles = append(claimRoles, claimRoleInterface...)
if params != nil && params.Roles != nil && len(params.Roles) > 0 {
for _, v := range params.Roles {
if !utils.StringSliceContains(claimRoles, v) {
log.Debug("User does not have required role: ", claimRoles, v)
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)
if err != nil {
log.Debug("Failed to create auth token: ", err)
return res, err
}

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -22,44 +23,56 @@ import (
// SignupResolver is a resolver for signup mutation
func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.AuthResponse
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) {
log.Debug("Signup is disabled")
return res, fmt.Errorf(`signup is disabled for this instance`)
}
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
log.Debug("Basic authentication is disabled")
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
}
if params.ConfirmPassword != params.Password {
log.Debug("Passwords do not match")
return res, fmt.Errorf(`password and confirm password does not match`)
}
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`)
}
params.Email = strings.ToLower(params.Email)
if !utils.IsValidEmail(params.Email) {
log.Debug("Invalid email: ", params.Email)
return res, fmt.Errorf(`invalid email address`)
}
log := log.WithFields(log.Fields{
"email": params.Email,
})
// find user with email
existingUser, err := db.Provider.GetUserByEmail(params.Email)
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 {
// email is verified
log.Debug("Email is already verified and signed up.")
return res, fmt.Errorf(`%s has already signed up`, params.Email)
} 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)
}
@ -68,6 +81,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
if len(params.Roles) > 0 {
// check if roles exists
if !utils.IsValidRoles(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), params.Roles) {
log.Debug("Invalid roles: ", params.Roles)
return res, fmt.Errorf(`invalid roles`)
} else {
inputRoles = params.Roles
@ -124,6 +138,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
}
user, err = db.Provider.AddUser(user)
if err != nil {
log.Debug("Failed to add user: ", err)
return res, err
}
roles := strings.Split(user.Roles, ",")
@ -134,6 +149,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
// insert verification request
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
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)
if err != nil {
log.Debug("Failed to create verification token: ", err)
return res, err
}
db.Provider.AddVerificationRequest(models.VerificationRequest{
_, err = db.Provider.AddVerificationRequest(models.VerificationRequest{
Token: verificationToken,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@ -153,6 +170,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
Nonce: nonceHash,
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
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)
if err != nil {
log.Debug("Failed to create auth token: ", err)
return res, err
}

View File

@ -5,9 +5,10 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"reflect"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -23,14 +24,16 @@ import (
// UpdateEnvResolver is a resolver for update config mutation
// This is admin only mutation
func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return res, fmt.Errorf("unauthorized")
}
@ -41,6 +44,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
if params.JwtType != nil {
algo = *params.JwtType
if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
log.Debug("Invalid JWT type: ", algo)
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
if crypto.IsHMACA(algo) {
if params.JwtSecret == nil {
log.Debug("JWT secret is required for HMAC")
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 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")
}
@ -77,17 +83,20 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
params.JwtSecret = &defaultSecret
_, err = crypto.ParseRsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
if err != nil {
log.Debug("Invalid JWT private key: ", err)
return res, err
}
_, err := crypto.ParseRsaPublicKeyFromPemStr(*params.JwtPublicKey)
if err != nil {
log.Debug("Invalid JWT public key: ", err)
return res, err
}
}
if crypto.IsECDSA(algo) {
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")
}
@ -95,11 +104,13 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
params.JwtSecret = &defaultSecret
_, err = crypto.ParseEcdsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
if err != nil {
log.Debug("Invalid JWT private key: ", err)
return res, err
}
_, err := crypto.ParseEcdsaPublicKeyFromPemStr(*params.JwtPublicKey)
if err != nil {
log.Debug("Invalid JWT public key: ", err)
return res, err
}
}
@ -109,25 +120,30 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
var data map[string]interface{}
byteData, err := json.Marshal(params)
if err != nil {
log.Debug("Failed to marshal update env input: ", err)
return res, fmt.Errorf("error marshalling params: %t", err)
}
err = json.Unmarshal(byteData, &data)
if err != nil {
log.Debug("Failed to unmarshal update env input: ", err)
return res, fmt.Errorf("error un-marshalling params: %t", err)
}
// in case of admin secret change update the cookie with new hash
if params.AdminSecret != 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")
}
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")
}
if len(*params.AdminSecret) < 6 {
log.Debug("Admin secret is too short")
err = fmt.Errorf("admin secret must be at least 6 characters")
return res, err
}
@ -173,6 +189,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
// should be subset of roles
for _, role := range params.DefaultRoles {
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)
}
}
@ -182,6 +199,7 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
if len(params.ProtectedRoles) > 0 {
for _, role := range params.ProtectedRoles {
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)
}
}
@ -191,12 +209,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
envstore.EnvStoreObj.UpdateEnvStore(updatedData)
jwk, err := crypto.GenerateJWKBasedOnEnv()
if err != nil {
log.Debug("Failed to generate JWK: ", err)
return res, err
}
// updating jwk
envstore.EnvStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyJWK, jwk)
err = sessionstore.InitSession()
if err != nil {
log.Debug("Failed to init session store: ", err)
return res, err
}
err = oauth.InitOAuth()
@ -207,12 +227,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
// Fetch the current db store and update it
env, err := db.Provider.GetEnv()
if err != nil {
log.Debug("Failed to get env: ", err)
return res, err
}
if params.AdminSecret != nil {
hashedKey, err := crypto.EncryptPassword(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret))
if err != nil {
log.Debug("Failed to encrypt admin secret: ", err)
return res, err
}
cookie.SetAdminCookie(gc, hashedKey)
@ -220,13 +242,14 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
encryptedConfig, err := crypto.EncryptEnvData(updatedData)
if err != nil {
log.Debug("Failed to encrypt env data: ", err)
return res, err
}
env.EnvData = encryptedConfig
_, err = db.Provider.UpdateEnv(env)
if err != nil {
log.Println("error updating config:", err)
log.Debug("Failed to update env: ", err)
return res, err
}

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/crypto"
@ -23,29 +24,39 @@ import (
// UpdateProfileResolver is resolver for update profile mutation
func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
accessToken, err := token.GetAccessToken(gc)
if err != nil {
log.Debug("Failed to get access token: ", err)
return res, err
}
claims, err := token.ValidateAccessToken(gc, accessToken)
if err != nil {
log.Debug("Failed to validate access token: ", err)
return res, err
}
// 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 {
log.Debug("All params are empty")
return res, fmt.Errorf("please enter at least one param to update")
}
userID := claims["sub"].(string)
log := log.WithFields(log.Fields{
"user_id": userID,
})
user, err := db.Provider.GetUserByID(userID)
if err != nil {
log.Debug("Failed to get user by id: ", err)
return res, err
}
@ -83,18 +94,22 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.OldPassword != 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")
}
if params.NewPassword == nil {
log.Debug("Failed to get new password: ")
return res, fmt.Errorf("new password is required")
}
if params.ConfirmNewPassword == nil {
log.Debug("Failed to get confirm new password: ")
return res, fmt.Errorf("confirm password is required")
}
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`)
}
@ -108,22 +123,28 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.Email != nil && user.Email != *params.Email {
// check if valid email
if !utils.IsValidEmail(*params.Email) {
log.Debug("Failed to validate email: ", *params.Email)
return res, fmt.Errorf("invalid email address")
}
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
_, err := db.Provider.GetUserByEmail(newEmail)
// err = nil means user exists
if err == nil {
log.Debug("Failed to get user by email: ", newEmail)
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 cookie.DeleteSession(gc)
cookie.DeleteSession(gc)
user.Email = newEmail
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
hostname := utils.GetHost(gc)
user.EmailVerifiedAt = nil
@ -131,15 +152,17 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
// insert verification request
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
verificationType := constants.VerificationTypeUpdateEmail
redirectURL := utils.GetAppURL(gc)
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
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,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@ -147,6 +170,10 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
Nonce: nonceHash,
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
go email.SendVerificationMail(newEmail, verificationToken, hostname)
@ -155,7 +182,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
}
_, err = db.Provider.UpdateUser(user)
if err != nil {
log.Println("error updating user:", err)
log.Debug("Failed to update user: ", err)
return res, err
}
message := `Profile details updated successfully.`

View File

@ -3,10 +3,11 @@ package resolvers
import (
"context"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@ -21,22 +22,36 @@ import (
// UpdateUserResolver is a resolver for update user mutation
// This is admin only mutation
func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.User
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
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 {
log.Debug("No params to update")
return res, fmt.Errorf("please enter atleast one param to update")
}
user, err := db.Provider.GetUserByID(params.ID)
if err != nil {
log.Debug("Failed to get user by id: ", err)
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 {
// check if valid email
if !utils.IsValidEmail(*params.Email) {
log.Debug("Invalid email: ", *params.Email)
return res, fmt.Errorf("invalid email address")
}
newEmail := strings.ToLower(*params.Email)
@ -91,6 +107,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
_, err = db.Provider.GetUserByEmail(newEmail)
// err = nil means user exists
if err == nil {
log.Debug("User with email already exists: ", newEmail)
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
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
log.Debug("Failed to generate nonce: ", err)
return res, err
}
verificationType := constants.VerificationTypeUpdateEmail
redirectURL := utils.GetAppURL(gc)
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
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,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@ -119,6 +137,10 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
Nonce: nonceHash,
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
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)...)...)) {
log.Debug("Invalid roles: ", params.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)
if err != nil {
log.Println("error updating user:", err)
log.Debug("Failed to update user: ", err)
return res, err
}

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/token"
@ -15,10 +17,12 @@ import (
func UsersResolver(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return nil, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.")
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)
if err != nil {
log.Debug("Failed to get users: ", err)
return nil, err
}

View File

@ -6,11 +6,13 @@ import (
"fmt"
"strings"
"github.com/golang-jwt/jwt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/sessionstore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/golang-jwt/jwt"
)
// 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) {
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return nil, err
}
tokenType := params.TokenType
if tokenType != "access_token" && tokenType != "refresh_token" && tokenType != "id_token" {
log.Debug("Invalid token type: ", tokenType)
return nil, errors.New("invalid token type")
}
@ -53,6 +57,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
if userID != "" && nonce != "" {
claims, err = token.ParseJWTToken(params.Token, hostname, nonce, userID)
if err != nil {
log.Debug("Failed to parse jwt token: ", err)
return &model.ValidateJWTTokenResponse{
IsValid: false,
}, nil
@ -60,6 +65,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
} else {
claims, err = token.ParseJWTTokenWithoutNonce(params.Token, hostname)
if err != nil {
log.Debug("Failed to parse jwt token without nonce: ", err)
return &model.ValidateJWTTokenResponse{
IsValid: false,
}, nil
@ -76,6 +82,7 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
if params.Roles != nil && len(params.Roles) > 0 {
for _, v := range params.Roles {
if !utils.StringSliceContains(claimRoles, v) {
log.Debug("Token does not have required role: ", v)
return nil, fmt.Errorf(`unauthorized`)
}
}

View File

@ -4,6 +4,8 @@ import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/token"
@ -15,10 +17,12 @@ import (
func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) {
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return nil, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
@ -26,6 +30,7 @@ func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedIn
res, err := db.Provider.ListVerificationRequests(pagination)
if err != nil {
log.Debug("Failed to get verification requests: ", err)
return nil, err
}

View File

@ -6,6 +6,8 @@ import (
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/cookie"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
@ -17,14 +19,17 @@ import (
// VerifyEmailResolver is a resolver for verify email mutation
func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
gc, err := utils.GinContextFromContext(ctx)
var res *model.AuthResponse
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
verificationRequest, err := db.Provider.GetVerificationRequestByToken(params.Token)
if err != nil {
log.Debug("Failed to get verification request by token: ", err)
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)
claim, err := token.ParseJWTToken(params.Token, hostname, verificationRequest.Nonce, verificationRequest.Email)
if err != nil {
log.Debug("Failed to parse token: ", err)
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 {
log.Debug("Failed to get user by email: ", err)
return res, err
}
@ -45,11 +56,13 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
user.EmailVerifiedAt = &now
user, err = db.Provider.UpdateUser(user)
if err != nil {
log.Debug("Failed to update user: ", err)
return res, err
}
// delete from verification table
err = db.Provider.DeleteVerificationRequest(verificationRequest)
if err != nil {
log.Debug("Failed to delete verification request: ", err)
return res, err
}
@ -57,6 +70,7 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
scope := []string{"openid", "email", "profile"}
authToken, err := token.CreateAuthToken(gc, user, roles, scope)
if err != nil {
log.Debug("Failed to create auth token: ", err)
return res, err
}

View File

@ -1,15 +1,19 @@
package routes
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/handlers"
"github.com/authorizerdev/authorizer/server/middlewares"
"github.com/gin-gonic/gin"
)
// InitRouter initializes gin router
func InitRouter() *gin.Engine {
router := gin.Default()
// router.Use(location.Default())
func InitRouter(log *logrus.Logger) *gin.Engine {
gin.SetMode(gin.ReleaseMode)
router := gin.New()
router.Use(middlewares.Logger(log), gin.Recovery())
router.Use(middlewares.GinContextToContextMiddleware())
router.Use(middlewares.CORSMiddleware())

View File

@ -2,8 +2,9 @@ package sessionstore
import (
"context"
"log"
"strings"
log "github.com/sirupsen/logrus"
)
type RedisStore struct {
@ -15,7 +16,7 @@ type RedisStore struct {
func (c *RedisStore) ClearStore() {
err := c.store.Del(c.ctx, "authorizer_*").Err()
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 {
data, err := c.store.HGetAll(c.ctx, "*").Result()
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{}
@ -44,7 +45,7 @@ func (c *RedisStore) DeleteAllUserSession(userId string) {
if k == "token" {
err := c.store.Del(c.ctx, v)
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) {
err := c.store.Set(c.ctx, "authorizer_"+key, value, 0).Err()
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, err := c.store.Get(c.ctx, "authorizer_"+key).Result()
if err != nil {
log.Println("error getting token from redis store:", err)
log.Debug("error getting token from redis store: ", err)
}
return state

View File

@ -2,9 +2,10 @@ package sessionstore
import (
"context"
"log"
"strings"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/go-redis/redis/v8"
@ -89,7 +90,7 @@ func RemoveState(key string) {
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
func InitSession() error {
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)
redisURLHostPortsList := strings.Split(redisURL, ",")
@ -97,6 +98,7 @@ func InitSession() error {
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
urls := []string{opt.Addr}
@ -108,6 +110,7 @@ func InitSession() error {
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
@ -121,6 +124,7 @@ func InitSession() error {
opt, err := redis.ParseURL(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
@ -128,6 +132,7 @@ func InitSession() error {
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
@ -140,6 +145,7 @@ func InitSession() error {
return nil
}
log.Info("using in memory store to save sessions")
// if redis url is not set use in memory store
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
sessionStore: map[string]map[string]string{},

View File

@ -3,10 +3,11 @@ package token
import (
"encoding/json"
"fmt"
"log"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"github.com/google/uuid"
@ -330,14 +331,13 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce string) (st
`, string(userBytes), string(claimBytes), accessTokenScript))
val, err := vm.Get("functionRes")
if err != nil {
log.Println("error getting custom access token script:", err)
log.Debug("error getting custom access token script: ", err)
} else {
extraPayload := make(map[string]interface{})
err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
if err != nil {
log.Println("error converting accessTokenScript response to map:", err)
log.Debug("error converting accessTokenScript response to map: ", err)
} else {
for k, v := range extraPayload {
customClaims[k] = v