Compare commits
9 Commits
1.1.28-rc.
...
1.1.28-rc.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6ddaf88e3f | ||
![]() |
f8bcd0fe51 | ||
![]() |
16c4b8ab76 | ||
![]() |
0788c5ff5e | ||
![]() |
2d5d38de02 | ||
![]() |
0dd06d9afd | ||
![]() |
d2f472a9cf | ||
![]() |
4678193300 | ||
![]() |
67be8ae285 |
@@ -25,7 +25,7 @@ type User struct {
|
|||||||
Nickname *string `json:"nickname" bson:"nickname" cql:"nickname" dynamo:"nickname"`
|
Nickname *string `json:"nickname" bson:"nickname" cql:"nickname" dynamo:"nickname"`
|
||||||
Gender *string `json:"gender" bson:"gender" cql:"gender" dynamo:"gender"`
|
Gender *string `json:"gender" bson:"gender" cql:"gender" dynamo:"gender"`
|
||||||
Birthdate *string `json:"birthdate" bson:"birthdate" cql:"birthdate" dynamo:"birthdate"`
|
Birthdate *string `json:"birthdate" bson:"birthdate" cql:"birthdate" dynamo:"birthdate"`
|
||||||
PhoneNumber *string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"`
|
PhoneNumber *string `gorm:"index" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"`
|
||||||
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at" cql:"phone_number_verified_at" dynamo:"phone_number_verified_at"`
|
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at" cql:"phone_number_verified_at" dynamo:"phone_number_verified_at"`
|
||||||
Picture *string `json:"picture" bson:"picture" cql:"picture" dynamo:"picture"`
|
Picture *string `json:"picture" bson:"picture" cql:"picture" dynamo:"picture"`
|
||||||
Roles string `json:"roles" bson:"roles" cql:"roles" dynamo:"roles"`
|
Roles string `json:"roles" bson:"roles" cql:"roles" dynamo:"roles"`
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
"github.com/glebarez/sqlite"
|
"github.com/glebarez/sqlite"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/driver/sqlserver"
|
"gorm.io/driver/sqlserver"
|
||||||
@@ -37,12 +35,12 @@ func NewProvider() (*provider, error) {
|
|||||||
var sqlDB *gorm.DB
|
var sqlDB *gorm.DB
|
||||||
var err error
|
var err error
|
||||||
customLogger := logger.New(
|
customLogger := logger.New(
|
||||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
logrus.StandardLogger(),
|
||||||
logger.Config{
|
logger.Config{
|
||||||
SlowThreshold: time.Second, // Slow SQL threshold
|
SlowThreshold: time.Second, // Slow SQL threshold
|
||||||
LogLevel: logger.Silent, // Log level
|
LogLevel: logger.Error, // Log level
|
||||||
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
|
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
|
||||||
Colorful: false, // Disable color
|
Colorful: false, // Disable color
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -72,35 +70,43 @@ func NewProvider() (*provider, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For sqlserver, handle uniqueness of phone_number manually via extra db call
|
||||||
|
// during create and update mutation.
|
||||||
|
if sqlDB.Migrator().HasConstraint(&models.User{}, "authorizer_users_phone_number_key") {
|
||||||
|
err = sqlDB.Migrator().DropConstraint(&models.User{}, "authorizer_users_phone_number_key")
|
||||||
|
logrus.Debug("Failed to drop phone number constraint:", err)
|
||||||
|
}
|
||||||
|
|
||||||
err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{})
|
err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IMPACT: Request user to manually delete: UQ_phone_number constraint
|
||||||
// unique constraint on phone number does not work with multiple null values for sqlserver
|
// unique constraint on phone number does not work with multiple null values for sqlserver
|
||||||
// for more information check https://stackoverflow.com/a/767702
|
// for more information check https://stackoverflow.com/a/767702
|
||||||
if dbType == constants.DbTypeSqlserver {
|
// if dbType == constants.DbTypeSqlserver {
|
||||||
var indexInfos []indexInfo
|
// var indexInfos []indexInfo
|
||||||
// remove index on phone number if present with different name
|
// // remove index on phone number if present with different name
|
||||||
res := sqlDB.Raw("SELECT i.name AS index_name, i.type_desc AS index_algorithm, CASE i.is_unique WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_unique, ac.Name AS column_name FROM sys.tables AS t INNER JOIN sys.indexes AS i ON t.object_id = i.object_id INNER JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id INNER JOIN sys.all_columns AS ac ON ic.object_id = ac.object_id AND ic.column_id = ac.column_id WHERE t.name = 'authorizer_users' AND SCHEMA_NAME(t.schema_id) = 'dbo';").Scan(&indexInfos)
|
// res := sqlDB.Raw("SELECT i.name AS index_name, i.type_desc AS index_algorithm, CASE i.is_unique WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_unique, ac.Name AS column_name FROM sys.tables AS t INNER JOIN sys.indexes AS i ON t.object_id = i.object_id INNER JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id INNER JOIN sys.all_columns AS ac ON ic.object_id = ac.object_id AND ic.column_id = ac.column_id WHERE t.name = 'authorizer_users' AND SCHEMA_NAME(t.schema_id) = 'dbo';").Scan(&indexInfos)
|
||||||
if res.Error != nil {
|
// if res.Error != nil {
|
||||||
return nil, res.Error
|
// return nil, res.Error
|
||||||
}
|
// }
|
||||||
|
|
||||||
for _, val := range indexInfos {
|
// for _, val := range indexInfos {
|
||||||
if val.ColumnName == phoneNumberColumnName && val.IndexName != phoneNumberIndexName {
|
// if val.ColumnName == phoneNumberColumnName && val.IndexName != phoneNumberIndexName {
|
||||||
// drop index & create new
|
// // drop index & create new
|
||||||
if res := sqlDB.Exec(fmt.Sprintf(`ALTER TABLE authorizer_users DROP CONSTRAINT "%s";`, val.IndexName)); res.Error != nil {
|
// if res := sqlDB.Exec(fmt.Sprintf(`ALTER TABLE authorizer_users DROP CONSTRAINT "%s";`, val.IndexName)); res.Error != nil {
|
||||||
return nil, res.Error
|
// return nil, res.Error
|
||||||
}
|
// }
|
||||||
|
|
||||||
// create index
|
// // create index
|
||||||
if res := sqlDB.Exec(fmt.Sprintf("CREATE UNIQUE NONCLUSTERED INDEX %s ON authorizer_users(phone_number) WHERE phone_number IS NOT NULL;", phoneNumberIndexName)); res.Error != nil {
|
// if res := sqlDB.Exec(fmt.Sprintf("CREATE UNIQUE NONCLUSTERED INDEX %s ON authorizer_users(phone_number) WHERE phone_number IS NOT NULL;", phoneNumberIndexName)); res.Error != nil {
|
||||||
return nil, res.Error
|
// return nil, res.Error
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return &provider{
|
return &provider{
|
||||||
db: sqlDB,
|
db: sqlDB,
|
||||||
|
@@ -2,12 +2,15 @@ package sql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
@@ -27,6 +30,12 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
|
|||||||
user.Roles = defaultRoles
|
user.Roles = defaultRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
|
||||||
|
if u, _ := p.GetUserByPhone(ctx, refs.StringValue(user.PhoneNumber)); u != nil {
|
||||||
|
return user, fmt.Errorf("user with given phone number already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user.CreatedAt = time.Now().Unix()
|
user.CreatedAt = time.Now().Unix()
|
||||||
user.UpdatedAt = time.Now().Unix()
|
user.UpdatedAt = time.Now().Unix()
|
||||||
user.Key = user.ID
|
user.Key = user.ID
|
||||||
@@ -47,6 +56,12 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
|
|||||||
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
|
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
|
||||||
user.UpdatedAt = time.Now().Unix()
|
user.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
|
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
|
||||||
|
if u, _ := p.GetUserByPhone(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
|
||||||
|
return user, fmt.Errorf("user with given phone number already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result := p.db.Save(&user)
|
result := p.db.Save(&user)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
@@ -141,3 +156,14 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *provider) GetUserByPhone(ctx context.Context, phoneNumber string) (*models.User, error) {
|
||||||
|
var user *models.User
|
||||||
|
result := p.db.Where("phone_number = ?", phoneNumber).First(&user)
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return user, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
@@ -25,10 +25,8 @@ require (
|
|||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
github.com/vektah/gqlparser/v2 v2.5.1
|
github.com/vektah/gqlparser/v2 v2.5.1
|
||||||
go.mongodb.org/mongo-driver v1.8.1
|
go.mongodb.org/mongo-driver v1.8.1
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
|
golang.org/x/crypto v0.3.0
|
||||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b // indirect
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
|
@@ -449,6 +449,8 @@ golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0
|
|||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||||
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -524,6 +526,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b h1:uKO3Js8lXGjpjdc4J3rqs0/Ex5yDKUGfk43tTYWVLas=
|
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b h1:uKO3Js8lXGjpjdc4J3rqs0/Ex5yDKUGfk43tTYWVLas=
|
||||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||||
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -598,10 +602,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -612,6 +619,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||||
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@@ -64,6 +64,12 @@ func TokenHandler() gin.HandlerFunc {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if clientID & clientSecret are present as part of
|
||||||
|
// authorization header with basic auth
|
||||||
|
if clientID == "" && clientSecret == "" {
|
||||||
|
clientID, clientSecret, _ = gc.Request.BasicAuth()
|
||||||
|
}
|
||||||
|
|
||||||
if clientID == "" {
|
if clientID == "" {
|
||||||
log.Debug("Client ID is empty")
|
log.Debug("Client ID is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
61
server/logs/logs.go
Normal file
61
server/logs/logs.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package logs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LogUTCFormatter hels in setting UTC time format for the logs
|
||||||
|
type LogUTCFormatter struct {
|
||||||
|
log.Formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format helps fomratting time to UTC
|
||||||
|
func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
|
||||||
|
e.Time = e.Time.UTC()
|
||||||
|
return u.Formatter.Format(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitLog(cliLogLevel string) *log.Logger {
|
||||||
|
|
||||||
|
// log instance for gin server
|
||||||
|
log := logrus.New()
|
||||||
|
log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
|
||||||
|
|
||||||
|
if cliLogLevel == "" {
|
||||||
|
cliLogLevel = os.Getenv("LOG_LEVEL")
|
||||||
|
}
|
||||||
|
|
||||||
|
var logLevel logrus.Level
|
||||||
|
switch cliLogLevel {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
// set log level globally
|
||||||
|
logrus.SetLevel(logLevel)
|
||||||
|
|
||||||
|
// set log level for go-gin middleware
|
||||||
|
log.SetLevel(logLevel)
|
||||||
|
|
||||||
|
// show file path in log for debug or other log levels.
|
||||||
|
if logLevel != logrus.InfoLevel {
|
||||||
|
logrus.SetReportCaller(true)
|
||||||
|
log.SetReportCaller(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return log
|
||||||
|
}
|
@@ -3,84 +3,42 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/cli"
|
"github.com/authorizerdev/authorizer/server/cli"
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/env"
|
"github.com/authorizerdev/authorizer/server/env"
|
||||||
|
"github.com/authorizerdev/authorizer/server/logs"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
"github.com/authorizerdev/authorizer/server/oauth"
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/routes"
|
"github.com/authorizerdev/authorizer/server/routes"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VERSION is used to define the version of authorizer from build tags
|
// VERSION is used to define the version of authorizer from build tags
|
||||||
var VERSION string
|
var VERSION string
|
||||||
|
|
||||||
// LogUTCFormatter hels in setting UTC time format for the logs
|
|
||||||
type LogUTCFormatter struct {
|
|
||||||
log.Formatter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format helps fomratting time to UTC
|
|
||||||
func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
|
|
||||||
e.Time = e.Time.UTC()
|
|
||||||
return u.Formatter.Format(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cli.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
cli.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
|
||||||
cli.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
cli.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
|
||||||
cli.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
cli.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
|
||||||
cli.ARG_LOG_LEVEL = flag.String("log_level", "info", "Log level, possible values are debug,info,warn,error,fatal,panic")
|
cli.ARG_LOG_LEVEL = flag.String("log_level", "", "Log level, possible values are debug,info,warn,error,fatal,panic")
|
||||||
cli.ARG_REDIS_URL = flag.String("redis_url", "", "Redis connection string")
|
cli.ARG_REDIS_URL = flag.String("redis_url", "", "Redis connection string")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// global log level
|
// global log level
|
||||||
logrus.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
|
logrus.SetFormatter(logs.LogUTCFormatter{&logrus.JSONFormatter{}})
|
||||||
|
|
||||||
// log instance for gin server
|
|
||||||
log := logrus.New()
|
|
||||||
log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
|
|
||||||
|
|
||||||
var logLevel logrus.Level
|
|
||||||
switch *cli.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
|
|
||||||
}
|
|
||||||
// set log level globally
|
|
||||||
logrus.SetLevel(logLevel)
|
|
||||||
|
|
||||||
// set log level for go-gin middleware
|
|
||||||
log.SetLevel(logLevel)
|
|
||||||
|
|
||||||
// show file path in log for debug or other log levels.
|
|
||||||
if logLevel != logrus.InfoLevel {
|
|
||||||
logrus.SetReportCaller(true)
|
|
||||||
log.SetReportCaller(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
constants.VERSION = VERSION
|
constants.VERSION = VERSION
|
||||||
|
|
||||||
// initialize required envs (mainly db, env file path and redis)
|
// initialize required envs (mainly db, env file path and redis)
|
||||||
err := memorystore.InitRequiredEnv()
|
err := memorystore.InitRequiredEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error while initializing required envs: ", err)
|
logrus.Fatal("Error while initializing required envs: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := logs.InitLog(refs.StringValue(cli.ARG_LOG_LEVEL))
|
||||||
|
|
||||||
// initialize memory store
|
// initialize memory store
|
||||||
err = memorystore.InitMemStore()
|
err = memorystore.InitMemStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -51,8 +51,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
|
|||||||
assert.Nil(t, emailTemplate)
|
assert.Nil(t, emailTemplate)
|
||||||
})
|
})
|
||||||
|
|
||||||
var design string
|
design := ""
|
||||||
design = ""
|
|
||||||
|
|
||||||
for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
|
for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
|
||||||
t.Run("should add email template with empty design for "+eventType, func(t *testing.T) {
|
t.Run("should add email template with empty design for "+eventType, func(t *testing.T) {
|
||||||
@@ -70,29 +69,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, et.EventName, eventType)
|
assert.Equal(t, et.EventName, eventType)
|
||||||
assert.Equal(t, "Test email", et.Subject)
|
assert.Equal(t, "Test email", et.Subject)
|
||||||
assert.Equal(t, "Test design", et.Design)
|
assert.Equal(t, "", et.Design)
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
design = "Test design"
|
|
||||||
|
|
||||||
for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
|
|
||||||
t.Run("should add email template for "+eventType, func(t *testing.T) {
|
|
||||||
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
|
|
||||||
EventName: eventType,
|
|
||||||
Template: "Test email",
|
|
||||||
Subject: "Test email",
|
|
||||||
Design: &design,
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NotNil(t, emailTemplate)
|
|
||||||
assert.NotEmpty(t, emailTemplate.Message)
|
|
||||||
|
|
||||||
et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, et.EventName, eventType)
|
|
||||||
assert.Equal(t, "Test email", et.Subject)
|
|
||||||
assert.Equal(t, "Test design", et.Design)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user