otp, email and other improvement added
This commit is contained in:
parent
b7828ff758
commit
3381e6d5df
|
@ -1,6 +1,10 @@
|
||||||
ENV=test
|
ENV=test
|
||||||
DATABASE_URL=test.db
|
DATABASE_TYPE=couchbase
|
||||||
DATABASE_TYPE=sqlite
|
COUCHBASE_SCOPE=_default
|
||||||
|
DATABASE_USERNAME=admin
|
||||||
|
DATABASE_PASSWORD=123456
|
||||||
|
COUCHBASE_BUCKET=auth
|
||||||
|
DATABASE_URL=couchbase://127.0.0.1
|
||||||
CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}"
|
CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}"
|
||||||
SMTP_HOST=smtp.mailtrap.io
|
SMTP_HOST=smtp.mailtrap.io
|
||||||
SMTP_PORT=2525
|
SMTP_PORT=2525
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -28,9 +28,9 @@ test-dynamodb:
|
||||||
cd server && go clean --testcache && TEST_DBS="dynamodb" go test -p 1 -v ./test
|
cd server && go clean --testcache && TEST_DBS="dynamodb" go test -p 1 -v ./test
|
||||||
docker rm -vf dynamodb-local-test
|
docker rm -vf dynamodb-local-test
|
||||||
test-couchbase:
|
test-couchbase:
|
||||||
docker run -d --name couchbase-local-test -p 8091-8097:8091-8097 -p 11210:11210 -p 11207:11207 -p 18091-18095:18091-18095 -p 18096:18096 -p 18097:18097 couchbase:latest
|
# docker run -d --name couchbase-local-test -p 8091-8097:8091-8097 -p 11210:11210 -p 11207:11207 -p 18091-18095:18091-18095 -p 18096:18096 -p 18097:18097 couchbase:latest
|
||||||
cd server && go clean --testcache && TEST_DBS="couchdb" go test -p 1 -v ./test
|
cd server && go clean --testcache && TEST_DBS="couchbase" go test -p 1 -v ./test
|
||||||
docker rm -vf couchbase-local-test
|
# docker rm -vf couchbase-local-test
|
||||||
test-all-db:
|
test-all-db:
|
||||||
rm -rf server/test/test.db && rm -rf test.db
|
rm -rf server/test/test.db && rm -rf test.db
|
||||||
docker run -d --name authorizer_scylla_db -p 9042:9042 scylladb/scylla
|
docker run -d --name authorizer_scylla_db -p 9042:9042 scylladb/scylla
|
||||||
|
|
|
@ -2,15 +2,22 @@ package couchbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"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/couchbase/gocb/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddEmailTemplate to add EmailTemplate
|
// AddEmailTemplate to add EmailTemplate
|
||||||
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
||||||
|
|
||||||
if emailTemplate.ID == "" {
|
if emailTemplate.ID == "" {
|
||||||
emailTemplate.ID = uuid.New().String()
|
emailTemplate.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
@ -18,31 +25,158 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
|
||||||
emailTemplate.Key = emailTemplate.ID
|
emailTemplate.Key = emailTemplate.ID
|
||||||
emailTemplate.CreatedAt = time.Now().Unix()
|
emailTemplate.CreatedAt = time.Now().Unix()
|
||||||
emailTemplate.UpdatedAt = time.Now().Unix()
|
emailTemplate.UpdatedAt = time.Now().Unix()
|
||||||
|
insertOpt := gocb.InsertOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := p.db.Collection(models.Collections.EmailTemplate).Insert(emailTemplate.ID, emailTemplate, &insertOpt)
|
||||||
|
if err != nil {
|
||||||
|
return emailTemplate.AsAPIEmailTemplate(), err
|
||||||
|
}
|
||||||
|
|
||||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateEmailTemplate to update EmailTemplate
|
// UpdateEmailTemplate to update EmailTemplate
|
||||||
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
||||||
emailTemplate.UpdatedAt = time.Now().Unix()
|
scope := p.db.Scope("_default")
|
||||||
|
bytes, err := json.Marshal(emailTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// use decoder instead of json.Unmarshall, because it converts int64 -> float64 after unmarshalling
|
||||||
|
decoder := json.NewDecoder(strings.NewReader(string(bytes)))
|
||||||
|
decoder.UseNumber()
|
||||||
|
emailTemplateMap := map[string]interface{}{}
|
||||||
|
err = decoder.Decode(&emailTemplateMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFields := ""
|
||||||
|
for key, value := range emailTemplateMap {
|
||||||
|
if key == "_id" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "_key" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if value == nil {
|
||||||
|
updateFields += fmt.Sprintf("%s = null,", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
valueType := reflect.TypeOf(value)
|
||||||
|
if valueType.Name() == "string" {
|
||||||
|
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
|
||||||
|
} else {
|
||||||
|
updateFields += fmt.Sprintf("%s = %v, ", key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateFields = strings.Trim(updateFields, " ")
|
||||||
|
updateFields = strings.TrimSuffix(updateFields, ",")
|
||||||
|
|
||||||
|
query := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE _id = '%s'", models.Collections.EmailTemplate, updateFields, emailTemplate.ID)
|
||||||
|
_, err = scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListEmailTemplates to list EmailTemplate
|
// ListEmailTemplates to list EmailTemplate
|
||||||
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
|
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
|
||||||
return nil, nil
|
emailTemplates := []*model.EmailTemplate{}
|
||||||
|
// r := p.db.Collection(models.Collections.User).
|
||||||
|
paginationClone := pagination
|
||||||
|
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
userQuery := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM auth._default.%s ORDER BY _id OFFSET %d LIMIT %d", models.Collections.EmailTemplate, paginationClone.Offset, paginationClone.Limit)
|
||||||
|
|
||||||
|
queryResult, err := scope.Query(userQuery, &gocb.QueryOptions{
|
||||||
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for queryResult.Next() {
|
||||||
|
emailTemplate := models.EmailTemplate{}
|
||||||
|
err := queryResult.Row(&emailTemplate)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := queryResult.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return &model.EmailTemplates{
|
||||||
|
Pagination: &paginationClone,
|
||||||
|
EmailTemplates: emailTemplates,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEmailTemplateByID to get EmailTemplate by id
|
// GetEmailTemplateByID to get EmailTemplate by id
|
||||||
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
|
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
|
||||||
return nil, nil
|
emailTemplate := models.EmailTemplate{}
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
query := fmt.Sprintf(`SELECT _id, event_name, subject, design, template, created_at, updated_at FROM auth._default.%s WHERE _id = '%s' LIMIT 1`, models.Collections.EmailTemplate, emailTemplateID)
|
||||||
|
q, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = q.One(&emailTemplate)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEmailTemplateByEventName to get EmailTemplate by event_name
|
// GetEmailTemplateByEventName to get EmailTemplate by event_name
|
||||||
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
|
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
|
||||||
return nil, nil
|
emailTemplate := models.EmailTemplate{}
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM auth._default.%s WHERE event_name=$1 LIMIT 1", models.Collections.EmailTemplate)
|
||||||
|
q, err := scope.Query(query, &gocb.QueryOptions{
|
||||||
|
Context: ctx,
|
||||||
|
PositionalParameters: []interface{}{eventName},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = q.One(&emailTemplate)
|
||||||
|
|
||||||
|
time.Sleep(20 * time.Second)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteEmailTemplate to delete EmailTemplate
|
// DeleteEmailTemplate to delete EmailTemplate
|
||||||
func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
|
func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
|
||||||
|
removeOpt := gocb.RemoveOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.EmailTemplate).Remove(emailTemplate.ID, &removeOpt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package couchbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
"github.com/couchbase/gocb/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,21 +15,48 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
|
||||||
if env.ID == "" {
|
if env.ID == "" {
|
||||||
env.ID = uuid.New().String()
|
env.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
env.CreatedAt = time.Now().Unix()
|
env.CreatedAt = time.Now().Unix()
|
||||||
env.UpdatedAt = time.Now().Unix()
|
env.UpdatedAt = time.Now().Unix()
|
||||||
|
env.Key = env.ID
|
||||||
|
|
||||||
|
insertOpt := gocb.InsertOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.Env).Insert(env.ID, env, &insertOpt)
|
||||||
|
if err != nil {
|
||||||
|
return env, err
|
||||||
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateEnv to update environment information in database
|
// UpdateEnv to update environment information in database
|
||||||
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
|
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
|
||||||
env.UpdatedAt = time.Now().Unix()
|
env.UpdatedAt = time.Now().Unix()
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
|
||||||
|
updateEnvQuery := fmt.Sprintf("UPDATE auth._default.%s SET env = '%s', updated_at = %d WHERE _id = '%s'", models.Collections.Env, env.EnvData, env.UpdatedAt, env.ID)
|
||||||
|
_, err := scope.Query(updateEnvQuery, &gocb.QueryOptions{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return env, err
|
||||||
|
}
|
||||||
|
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEnv to get environment information from database
|
// GetEnv to get environment information from database
|
||||||
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
|
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
|
||||||
var env models.Env
|
var env models.Env
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s LIMIT 1", models.Collections.Env)
|
||||||
|
q, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return env, err
|
||||||
|
}
|
||||||
|
err = q.One(&env)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return env, err
|
||||||
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,104 @@ package couchbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
"github.com/couchbase/gocb/v2"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpsertOTP to add or update otp
|
// UpsertOTP to add or update otp
|
||||||
func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error) {
|
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
|
||||||
return nil, nil
|
// otp, _ = p.GetOTPByEmail(ctx, otp.Email)
|
||||||
|
// if otp == nil {
|
||||||
|
// id := uuid.NewString()
|
||||||
|
// otp = &models.OTP{
|
||||||
|
// ID: id,
|
||||||
|
// Key: id,
|
||||||
|
// Otp: otp.Otp,
|
||||||
|
// Email: otp.Email,
|
||||||
|
// ExpiresAt: otp.ExpiresAt,
|
||||||
|
// CreatedAt: time.Now().Unix(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// otp.UpdatedAt = time.Now().Unix()
|
||||||
|
// unsertOpt := gocb.UpsertOptions{
|
||||||
|
// Context: ctx,
|
||||||
|
// }
|
||||||
|
// _, err := p.db.Collection(models.Collections.OTP).Upsert(otp.ID, otp, &unsertOpt)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return otp, nil
|
||||||
|
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
|
||||||
|
|
||||||
|
shouldCreate := false
|
||||||
|
if otp == nil {
|
||||||
|
shouldCreate = true
|
||||||
|
otp = &models.OTP{
|
||||||
|
ID: uuid.NewString(),
|
||||||
|
Otp: otpParam.Otp,
|
||||||
|
Email: otpParam.Email,
|
||||||
|
ExpiresAt: otpParam.ExpiresAt,
|
||||||
|
CreatedAt: time.Now().Unix(),
|
||||||
|
UpdatedAt: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
otp.Otp = otpParam.Otp
|
||||||
|
otp.ExpiresAt = otpParam.ExpiresAt
|
||||||
|
}
|
||||||
|
|
||||||
|
otp.UpdatedAt = time.Now().Unix()
|
||||||
|
if shouldCreate {
|
||||||
|
insertOpt := gocb.InsertOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.OTP).Insert(otp.ID, otp, &insertOpt)
|
||||||
|
if err != nil {
|
||||||
|
return otp, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
query := fmt.Sprintf(`UPDATE auth._default.%s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID)
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
_, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return otp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return otp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOTPByEmail to get otp for a given email address
|
// GetOTPByEmail to get otp for a given email address
|
||||||
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
|
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
|
||||||
return nil, nil
|
otp := models.OTP{}
|
||||||
|
query := fmt.Sprintf(`SELECT _id, email, otp, expires_at, created_at, updated_at FROM auth._default.%s WHERE email = '%s' LIMIT 1`, models.Collections.OTP, emailAddress)
|
||||||
|
q, err := p.db.Scope("_default").Query(query, &gocb.QueryOptions{
|
||||||
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = q.One(&otp)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &otp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteOTP to delete otp
|
// DeleteOTP to delete otp
|
||||||
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
|
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
|
||||||
|
removeOpt := gocb.RemoveOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.OTP).Remove(otp.ID, &removeOpt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ func NewProvider() (*provider, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket := cluster.Bucket(bucketName)
|
bucket := cluster.Bucket(bucketName)
|
||||||
|
|
||||||
v := reflect.ValueOf(models.Collections)
|
v := reflect.ValueOf(models.Collections)
|
||||||
|
@ -47,9 +46,9 @@ func NewProvider() (*provider, error) {
|
||||||
collectionOpts := gocb.CreateCollectionOptions{
|
collectionOpts := gocb.CreateCollectionOptions{
|
||||||
Context: context.TODO(),
|
Context: context.TODO(),
|
||||||
}
|
}
|
||||||
bucket.Collections().CreateCollection(user, &collectionOpts)
|
_ = bucket.Collections().CreateCollection(user, &collectionOpts)
|
||||||
}
|
}
|
||||||
// bucket.Collection(models.Collections.User).Insert()
|
|
||||||
return &provider{
|
return &provider{
|
||||||
db: bucket,
|
db: bucket,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
"github.com/couchbase/gocb/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,6 +17,14 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
|
||||||
|
|
||||||
session.CreatedAt = time.Now().Unix()
|
session.CreatedAt = time.Now().Unix()
|
||||||
session.UpdatedAt = time.Now().Unix()
|
session.UpdatedAt = time.Now().Unix()
|
||||||
|
insertOpt := gocb.InsertOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.Session).Insert(session.ID, session, &insertOpt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,9 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
|
||||||
removeOpt := gocb.RemoveOptions{
|
removeOpt := gocb.RemoveOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := p.db.Collection(models.Collections.User).Remove(user.ID, &removeOpt)
|
_, err := p.db.Collection(models.Collections.User).Remove(user.ID, &removeOpt)
|
||||||
// query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values)
|
// query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values)
|
||||||
|
|
||||||
// sessionCollection := p.db.Collection(models.Collections.Session).Queue()
|
// sessionCollection := p.db.Collection(models.Collections.Session).Queue()
|
||||||
// _, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete())
|
// _, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete())
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
@ -110,45 +110,36 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
|
||||||
|
|
||||||
// GetUserByEmail to get user information from database using email address
|
// GetUserByEmail to get user information from database using email address
|
||||||
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
|
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
|
||||||
var user models.User
|
user := models.User{}
|
||||||
// inventoryScope := p.db.Scope("_default")
|
scope := p.db.Scope("_default")
|
||||||
// userQuery := fmt.Sprintf("SELECT * FROM auth._default.%s WHERE email = '%s' LIMIT %d", models.Collections.User, email, 1)
|
query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM auth._default.%s WHERE email = '%s' LIMIT 1", models.Collections.User, email)
|
||||||
queryResult, err := p.db.Collection(models.Collections.User).Get("email:"+email, &gocb.GetOptions{})
|
q, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
if err != nil {
|
|
||||||
return user, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// queryResult, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{})
|
|
||||||
err = queryResult.Content(&user)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
err = q.One(&user)
|
||||||
// for queryResult.Next() {
|
if err != nil {
|
||||||
// var user models.User
|
return user, err
|
||||||
// err := queryResult.Row(&user)
|
}
|
||||||
// if err != nil {
|
|
||||||
// log.Fatal(err)
|
|
||||||
// }
|
|
||||||
// return user, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByID to get user information from database using user ID
|
// GetUserByID to get user information from database using user ID
|
||||||
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
|
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
|
||||||
var user models.User
|
user := models.User{}
|
||||||
queryResult, err := p.db.Collection(models.Collections.User).Get("id:"+id, &gocb.GetOptions{})
|
scope := p.db.Scope("_default")
|
||||||
|
query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM auth._default.%s WHERE _id = '%s' LIMIT 1", models.Collections.User, id)
|
||||||
|
q, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
|
err = q.One(&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = queryResult.Content(&user)
|
|
||||||
if err != nil {
|
|
||||||
return user, err
|
|
||||||
}
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +176,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
|
||||||
if ids != nil && len(ids) > 0 {
|
if ids != nil && len(ids) > 0 {
|
||||||
for _, v := range ids {
|
for _, v := range ids {
|
||||||
userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE id = '%s'", models.Collections.User, updateFields, v)
|
userQuery := fmt.Sprintf("UPDATE auth._default.%s SET %s WHERE id = '%s'", models.Collections.User, updateFields, v)
|
||||||
|
|
||||||
_, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{})
|
_, err := inventoryScope.Query(userQuery, &gocb.QueryOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,6 +18,7 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
|
||||||
verificationRequest.ID = uuid.New().String()
|
verificationRequest.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verificationRequest.Key = verificationRequest.ID
|
||||||
verificationRequest.CreatedAt = time.Now().Unix()
|
verificationRequest.CreatedAt = time.Now().Unix()
|
||||||
verificationRequest.UpdatedAt = time.Now().Unix()
|
verificationRequest.UpdatedAt = time.Now().Unix()
|
||||||
insertOpt := gocb.InsertOptions{
|
insertOpt := gocb.InsertOptions{
|
||||||
|
@ -33,15 +34,22 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
|
||||||
|
|
||||||
// GetVerificationRequestByToken to get verification request from database using token
|
// GetVerificationRequestByToken to get verification request from database using token
|
||||||
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
|
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
|
||||||
var verificationRequest models.VerificationRequest
|
verificationRequest := models.VerificationRequest{}
|
||||||
scope := p.db.Scope("_default")
|
scope := p.db.Scope("_default")
|
||||||
|
params := make(map[string]interface{}, 1)
|
||||||
|
params["token"] = token
|
||||||
|
query := fmt.Sprintf("SELECT _id, token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM auth._default.%s WHERE token=$1 LIMIT 1", models.Collections.VerificationRequest)
|
||||||
|
|
||||||
|
queryResult, err := scope.Query(query, &gocb.QueryOptions{
|
||||||
|
Context: ctx,
|
||||||
|
PositionalParameters: []interface{}{token},
|
||||||
|
})
|
||||||
|
|
||||||
query := fmt.Sprintf("SELECT _id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM auth._default.%s WHERE token = '%s' LIMIT 1", models.Collections.VerificationRequest, token)
|
|
||||||
queryResult, err := scope.Query(query, &gocb.QueryOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
err = queryResult.One(&verificationRequest)
|
err = queryResult.One(&verificationRequest)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
|
@ -50,15 +58,23 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
|
||||||
|
|
||||||
// GetVerificationRequestByEmail to get verification request by email from database
|
// GetVerificationRequestByEmail to get verification request by email from database
|
||||||
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
|
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
|
||||||
var verificationRequest models.VerificationRequest
|
|
||||||
scope := p.db.Scope("_default")
|
|
||||||
|
|
||||||
query := fmt.Sprintf("SELECT _id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM auth._default.%s WHERE email = '%s' AND identifier = '%s' LIMIT 1", models.Collections.VerificationRequest, email, identifier)
|
scope := p.db.Scope("_default")
|
||||||
queryResult, err := scope.Query(query, &gocb.QueryOptions{})
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
|
query := fmt.Sprintf("SELECT _id, identifier, token, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM auth._default.%s WHERE email=$1 AND identifier=$2 LIMIT 1", models.Collections.VerificationRequest)
|
||||||
|
queryResult, err := scope.Query(query, &gocb.QueryOptions{
|
||||||
|
Context: ctx,
|
||||||
|
PositionalParameters: []interface{}{email, identifier},
|
||||||
|
})
|
||||||
|
verificationRequest := models.VerificationRequest{}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = queryResult.One(&verificationRequest)
|
err = queryResult.One(&verificationRequest)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return verificationRequest, err
|
return verificationRequest, err
|
||||||
}
|
}
|
||||||
|
@ -101,7 +117,7 @@ func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRe
|
||||||
removeOpt := gocb.RemoveOptions{
|
removeOpt := gocb.RemoveOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
}
|
}
|
||||||
_, err := p.db.Collection(models.Collections.Webhook).Remove(verificationRequest.ID, &removeOpt)
|
_, err := p.db.Collection(models.Collections.VerificationRequest).Remove(verificationRequest.ID, &removeOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
scope := p.db.Scope("_default")
|
scope := p.db.Scope("_default")
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.Env, paginationClone.Offset, paginationClone.Limit)
|
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.Webhook, paginationClone.Offset, paginationClone.Limit)
|
||||||
queryResult, err := scope.Query(query, &gocb.QueryOptions{})
|
queryResult, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -143,6 +143,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
|
||||||
scope := p.db.Scope("_default")
|
scope := p.db.Scope("_default")
|
||||||
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM auth._default.%s WHERE event_name = '%s' LIMIT 1`, models.Collections.Webhook, eventName)
|
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM auth._default.%s WHERE event_name = '%s' LIMIT 1`, models.Collections.Webhook, eventName)
|
||||||
q, err := scope.Query(query, &gocb.QueryOptions{})
|
q, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,13 @@ package couchbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"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/couchbase/gocb/v2"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,10 +21,44 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
|
||||||
webhookLog.Key = webhookLog.ID
|
webhookLog.Key = webhookLog.ID
|
||||||
webhookLog.CreatedAt = time.Now().Unix()
|
webhookLog.CreatedAt = time.Now().Unix()
|
||||||
webhookLog.UpdatedAt = time.Now().Unix()
|
webhookLog.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
|
insertOpt := gocb.InsertOptions{
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
_, err := p.db.Collection(models.Collections.WebhookLog).Insert(webhookLog.ID, webhookLog, &insertOpt)
|
||||||
|
if err != nil {
|
||||||
|
return webhookLog.AsAPIWebhookLog(), err
|
||||||
|
}
|
||||||
|
|
||||||
return webhookLog.AsAPIWebhookLog(), nil
|
return webhookLog.AsAPIWebhookLog(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhookLogs to list webhook logs
|
// ListWebhookLogs to list webhook logs
|
||||||
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
|
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
|
||||||
return nil, nil
|
webhookLogs := []*model.WebhookLog{}
|
||||||
|
scope := p.db.Scope("_default")
|
||||||
|
paginationClone := pagination
|
||||||
|
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM auth._default.%s OFFSET %d LIMIT %d", models.Collections.Env, paginationClone.Offset, paginationClone.Limit)
|
||||||
|
queryResult, err := scope.Query(query, &gocb.QueryOptions{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for queryResult.Next() {
|
||||||
|
var webhookLog models.WebhookLog
|
||||||
|
err := queryResult.Row(&webhookLog)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := queryResult.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
return &model.WebhookLogs{
|
||||||
|
Pagination: &paginationClone,
|
||||||
|
WebhookLogs: webhookLogs,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,12 @@ import (
|
||||||
|
|
||||||
func TestResolvers(t *testing.T) {
|
func TestResolvers(t *testing.T) {
|
||||||
databases := map[string]string{
|
databases := map[string]string{
|
||||||
constants.DbTypeSqlite: "../../test.db",
|
constants.DbTypeSqlite: "../../test.db",
|
||||||
constants.DbTypeArangodb: "http://localhost:8529",
|
constants.DbTypeArangodb: "http://localhost:8529",
|
||||||
constants.DbTypeMongodb: "mongodb://localhost:27017",
|
constants.DbTypeMongodb: "mongodb://localhost:27017",
|
||||||
constants.DbTypeScyllaDB: "127.0.0.1:9042",
|
constants.DbTypeScyllaDB: "127.0.0.1:9042",
|
||||||
constants.DbTypeDynamoDB: "http://127.0.0.1:8000",
|
constants.DbTypeDynamoDB: "http://127.0.0.1:8000",
|
||||||
|
constants.DbTypeCouchbaseDB: "couchbase://127.0.0.1",
|
||||||
}
|
}
|
||||||
|
|
||||||
testDBs := strings.Split(os.Getenv("TEST_DBS"), ",")
|
testDBs := strings.Split(os.Getenv("TEST_DBS"), ",")
|
||||||
|
@ -44,6 +45,7 @@ func TestResolvers(t *testing.T) {
|
||||||
defer s.Server.Close()
|
defer s.Server.Close()
|
||||||
|
|
||||||
for dbType, dbURL := range databases {
|
for dbType, dbURL := range databases {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package test
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
@ -22,6 +23,7 @@ func revokeAccessTest(t *testing.T, s TestSetup) {
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
time.Sleep(4 * time.Second)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user