feat/add arangodb support (#80)

*feat: add arangodb init

* fix: dao for sql + arangodb

* fix: update error logs

* fix: use db name dynamically
This commit is contained in:
Lakhan Samani 2021-12-17 21:25:07 +05:30 committed by GitHub
parent 155d2e65c2
commit f110255310
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 640 additions and 266 deletions

View File

@ -1,4 +1,4 @@
FROM golang:1.16-alpine as builder FROM golang:1.17-alpine as builder
WORKDIR /app WORKDIR /app
COPY server server COPY server server
COPY Makefile . COPY Makefile .

View File

@ -6,6 +6,7 @@ var (
VERSION = "" VERSION = ""
DATABASE_TYPE = "" DATABASE_TYPE = ""
DATABASE_URL = "" DATABASE_URL = ""
DATABASE_NAME = ""
SMTP_HOST = "" SMTP_HOST = ""
SMTP_PORT = "" SMTP_PORT = ""
SENDER_EMAIL = "" SENDER_EMAIL = ""

View File

@ -2,6 +2,7 @@ package constants
var ( var (
// Ref: https://github.com/qor/auth/blob/master/providers/google/google.go // Ref: https://github.com/qor/auth/blob/master/providers/google/google.go
// deprecated and not used. instead we follow open id approach for google login
GoogleUserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo" GoogleUserInfoURL = "https://www.googleapis.com/oauth2/v3/userinfo"
// Ref: https://github.com/qor/auth/blob/master/providers/facebook/facebook.go#L18 // Ref: https://github.com/qor/auth/blob/master/providers/facebook/facebook.go#L18
FacebookUserInfoURL = "https://graph.facebook.com/me?fields=id,first_name,last_name,name,email,picture&access_token=" FacebookUserInfoURL = "https://graph.facebook.com/me?fields=id,first_name,last_name,name,email,picture&access_token="

113
server/db/arangodb.go Normal file
View File

@ -0,0 +1,113 @@
package db
import (
"context"
"log"
"github.com/arangodb/go-driver"
arangoDriver "github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/http"
"github.com/authorizerdev/authorizer/server/constants"
)
// for this we need arangodb instance up and running
// for local testing we can use dockerized version of it
// docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=root arangodb/arangodb:3.8.4
func initArangodb() (arangoDriver.Database, error) {
ctx := context.Background()
conn, err := http.NewConnection(http.ConnectionConfig{
Endpoints: []string{constants.DATABASE_URL},
})
if err != nil {
return nil, err
}
client, err := arangoDriver.NewClient(arangoDriver.ClientConfig{
Connection: conn,
})
if err != nil {
return nil, err
}
var arangodb driver.Database
arangodb_exists, err := client.DatabaseExists(nil, constants.DATABASE_NAME)
if arangodb_exists {
log.Println(constants.DATABASE_NAME + " db exists already")
arangodb, err = client.Database(nil, constants.DATABASE_NAME)
if err != nil {
return nil, err
}
} else {
arangodb, err = client.CreateDatabase(nil, constants.DATABASE_NAME, nil)
if err != nil {
return nil, err
}
}
userCollectionExists, err := arangodb.CollectionExists(ctx, Collections.User)
if userCollectionExists {
log.Println(Collections.User + " collection exists already")
} else {
_, err = arangodb.CreateCollection(ctx, Collections.User, nil)
if err != nil {
log.Println("error creating collection("+Collections.User+"):", err)
}
}
userCollection, _ := arangodb.Collection(nil, Collections.User)
userCollection.EnsureHashIndex(ctx, []string{"id"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
userCollection.EnsureHashIndex(ctx, []string{"email"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, Collections.VerificationRequest)
if verificationRequestCollectionExists {
log.Println(Collections.VerificationRequest + " collection exists already")
} else {
_, err = arangodb.CreateCollection(ctx, Collections.VerificationRequest, nil)
if err != nil {
log.Println("error creating collection("+Collections.VerificationRequest+"):", err)
}
}
verificationRequestCollection, _ := arangodb.Collection(nil, Collections.VerificationRequest)
verificationRequestCollection.EnsureHashIndex(ctx, []string{"id"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
verificationRequestCollection.EnsureHashIndex(ctx, []string{"email", "identifier"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
verificationRequestCollection.EnsureHashIndex(ctx, []string{"token"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
sessionCollectionExists, err := arangodb.CollectionExists(ctx, Collections.Session)
if sessionCollectionExists {
log.Println(Collections.Session + " collection exists already")
} else {
_, err = arangodb.CreateCollection(ctx, Collections.Session, nil)
if err != nil {
log.Println("error creating collection("+Collections.Session+"):", err)
}
}
sessionCollection, _ := arangodb.Collection(nil, Collections.Session)
sessionCollection.EnsureHashIndex(ctx, []string{"id"}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
return arangodb, err
}

View File

@ -3,9 +3,9 @@ package db
import ( import (
"log" "log"
arangoDriver "github.com/arangodb/go-driver"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/enum" "github.com/authorizerdev/authorizer/server/enum"
"github.com/google/uuid"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
@ -14,51 +14,94 @@ import (
) )
type Manager interface { type Manager interface {
SaveUser(user User) (User, error) AddUser(user User) (User, error)
UpdateUser(user User) (User, error) UpdateUser(user User) (User, error)
DeleteUser(user User) error
GetUsers() ([]User, error) GetUsers() ([]User, error)
GetUserByEmail(email string) (User, error) GetUserByEmail(email string) (User, error)
GetUserByID(email string) (User, error) GetUserByID(email string) (User, error)
UpdateVerificationTime(verifiedAt int64, id uuid.UUID) error
AddVerification(verification VerificationRequest) (VerificationRequest, error) AddVerification(verification VerificationRequest) (VerificationRequest, error)
GetVerificationByToken(token string) (VerificationRequest, error) GetVerificationByToken(token string) (VerificationRequest, error)
DeleteToken(email string) error DeleteVerificationRequest(verificationRequest VerificationRequest) error
GetVerificationRequests() ([]VerificationRequest, error) GetVerificationRequests() ([]VerificationRequest, error)
GetVerificationByEmail(email string) (VerificationRequest, error) GetVerificationByEmail(email string) (VerificationRequest, error)
DeleteUser(email string) error AddSession(session Session) error
SaveRoles(roles []Role) error
SaveSession(session Session) error
} }
type manager struct { type manager struct {
db *gorm.DB sqlDB *gorm.DB
arangodb arangoDriver.Database
} }
var Mgr Manager // mainly used by nosql dbs
type CollectionList struct {
User string
VerificationRequest string
Session string
}
var (
IsSQL bool
IsArangoDB bool
Mgr Manager
Prefix = "authorizer_"
Collections = CollectionList{
User: Prefix + "users",
VerificationRequest: Prefix + "verification_requests",
Session: Prefix + "sessions",
}
)
func InitDB() { func InitDB() {
var db *gorm.DB var sqlDB *gorm.DB
var err error var err error
IsSQL = constants.DATABASE_TYPE != enum.Arangodb.String()
IsArangoDB = constants.DATABASE_TYPE == enum.Arangodb.String()
// sql db orm config
ormConfig := &gorm.Config{ ormConfig := &gorm.Config{
NamingStrategy: schema.NamingStrategy{ NamingStrategy: schema.NamingStrategy{
TablePrefix: "authorizer_", TablePrefix: Prefix,
}, },
} }
if constants.DATABASE_TYPE == enum.Postgres.String() {
db, err = gorm.Open(postgres.Open(constants.DATABASE_URL), ormConfig) log.Println("db type:", constants.DATABASE_TYPE)
}
if constants.DATABASE_TYPE == enum.Mysql.String() { switch constants.DATABASE_TYPE {
db, err = gorm.Open(mysql.Open(constants.DATABASE_URL), ormConfig) case enum.Postgres.String():
} sqlDB, err = gorm.Open(postgres.Open(constants.DATABASE_URL), ormConfig)
if constants.DATABASE_TYPE == enum.Sqlite.String() { break
db, err = gorm.Open(sqlite.Open(constants.DATABASE_URL), ormConfig) case enum.Sqlite.String():
sqlDB, err = gorm.Open(sqlite.Open(constants.DATABASE_URL), ormConfig)
break
case enum.Mysql.String():
sqlDB, err = gorm.Open(mysql.Open(constants.DATABASE_URL), ormConfig)
break
case enum.Arangodb.String():
arangodb, err := initArangodb()
if err != nil {
log.Fatal("error initing arangodb:", err)
}
Mgr = &manager{
sqlDB: nil,
arangodb: arangodb,
}
break
} }
if err != nil { // common for all sql dbs that are configured via gorm
log.Fatal("Failed to init db:", err) if IsSQL {
} else { if err != nil {
db.AutoMigrate(&User{}, &VerificationRequest{}, &Role{}, &Session{}) log.Fatal("Failed to init sqlDB:", err)
} else {
sqlDB.AutoMigrate(&User{}, &VerificationRequest{}, &Session{})
}
Mgr = &manager{
sqlDB: sqlDB,
arangodb: nil,
}
} }
Mgr = &manager{db: db}
} }

View File

@ -1,34 +0,0 @@
package db
import (
"log"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type Role struct {
ID uuid.UUID `gorm:"primaryKey;type:char(36)"`
Role string `gorm:"unique"`
}
func (r *Role) BeforeCreate(tx *gorm.DB) (err error) {
r.ID = uuid.New()
return
}
// SaveRoles function to save roles
func (mgr *manager) SaveRoles(roles []Role) error {
res := mgr.db.Clauses(
clause.OnConflict{
DoNothing: true,
}).Create(&roles)
if res.Error != nil {
log.Println(`Error saving roles`)
return res.Error
}
return nil
}

View File

@ -2,37 +2,62 @@ package db
import ( import (
"log" "log"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
type Session struct { type Session struct {
ID uuid.UUID `gorm:"primaryKey;type:char(36)"` Key string `json:"_key,omitempty"` // for arangodb
UserID uuid.UUID `gorm:"type:char(36)"` ObjectID string `json:"_id,omitempty"` // for arangodb & mongodb
User User ID string `gorm:"primaryKey;type:char(36)" json:"id"`
UserAgent string UserID string `gorm:"type:char(36)" json:"user_id"`
IP string User User `json:"-"`
CreatedAt int64 `gorm:"autoCreateTime"` UserAgent string `json:"user_agent"`
UpdatedAt int64 `gorm:"autoUpdateTime"` IP string `json:"ip"`
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at"`
} }
func (r *Session) BeforeCreate(tx *gorm.DB) (err error) { // AddSession function to save user sessiosn
r.ID = uuid.New() func (mgr *manager) AddSession(session Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
return if session.CreatedAt == 0 {
} session.CreatedAt = time.Now().Unix()
}
// SaveSession function to save user sessiosn if session.UpdatedAt == 0 {
func (mgr *manager) SaveSession(session Session) error { session.CreatedAt = time.Now().Unix()
res := mgr.db.Clauses( }
clause.OnConflict{
DoNothing: true, if IsSQL {
}).Create(&session) // copy id as value for fields required for mongodb & arangodb
if res.Error != nil { session.Key = session.ID
log.Println(`Error saving session`, res.Error) session.ObjectID = session.ID
return res.Error res := mgr.sqlDB.Clauses(
clause.OnConflict{
DoNothing: true,
}).Create(&session)
if res.Error != nil {
log.Println(`error saving session`, res.Error)
return res.Error
}
}
if IsArangoDB {
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
sessionCollection, _ := mgr.arangodb.Collection(nil, Collections.Session)
_, err := sessionCollection.CreateDocument(nil, session)
if err != nil {
log.Println(`error saving session`, err)
return err
}
} }
return nil return nil

View File

@ -1,45 +1,68 @@
package db package db
import ( import (
"context"
"errors"
"fmt"
"log" "log"
"time" "time"
"github.com/arangodb/go-driver"
arangoDriver "github.com/arangodb/go-driver"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
type User struct { type User struct {
ID uuid.UUID `gorm:"primaryKey;type:char(36)"` Key string `json:"_key,omitempty"` // for arangodb
FirstName string ObjectID string `json:"_id,omitempty"` // for arangodb & mongodb
LastName string ID string `gorm:"primaryKey;type:char(36)" json:"id"`
Email string `gorm:"unique"` FirstName string `json:"first_name"`
Password string `gorm:"type:text"` LastName string `json:"last_name"`
SignupMethod string Email string `gorm:"unique" json:"email"`
EmailVerifiedAt int64 Password string `gorm:"type:text" json:"password"`
CreatedAt int64 `gorm:"autoCreateTime"` SignupMethod string `json:"signup_method"`
UpdatedAt int64 `gorm:"autoUpdateTime"` EmailVerifiedAt int64 `json:"email_verified_at"`
Image string `gorm:"type:text"` CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
Roles string UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at"`
Image string `gorm:"type:text" json:"image"`
Roles string `json:"roles"`
} }
func (u *User) BeforeCreate(tx *gorm.DB) (err error) { // AddUser function to add user even with email conflict
u.ID = uuid.New() func (mgr *manager) AddUser(user User) (User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
return if IsSQL {
} // copy id as value for fields required for mongodb & arangodb
user.Key = user.ID
user.ObjectID = user.ID
result := mgr.sqlDB.Clauses(
clause.OnConflict{
UpdateAll: true,
Columns: []clause.Column{{Name: "email"}},
}).Create(&user)
// SaveUser function to add user even with email conflict if result.Error != nil {
func (mgr *manager) SaveUser(user User) (User, error) { log.Println("error adding user:", result.Error)
result := mgr.db.Clauses( return user, result.Error
clause.OnConflict{ }
UpdateAll: true, }
Columns: []clause.Column{{Name: "email"}},
}).Create(&user)
if result.Error != nil { if IsArangoDB {
log.Println(result.Error) user.CreatedAt = time.Now().Unix()
return user, result.Error user.UpdatedAt = time.Now().Unix()
ctx := context.Background()
userCollection, _ := mgr.arangodb.Collection(nil, Collections.User)
meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(ctx), user)
if err != nil {
log.Println("error adding user:", err)
return user, err
}
user.Key = meta.Key
user.ObjectID = meta.ID.String()
} }
return user, nil return user, nil
} }
@ -47,15 +70,26 @@ func (mgr *manager) SaveUser(user User) (User, error) {
// UpdateUser function to update user with ID conflict // UpdateUser function to update user with ID conflict
func (mgr *manager) UpdateUser(user User) (User, error) { func (mgr *manager) UpdateUser(user User) (User, error) {
user.UpdatedAt = time.Now().Unix() user.UpdatedAt = time.Now().Unix()
result := mgr.db.Clauses(
clause.OnConflict{
UpdateAll: true,
Columns: []clause.Column{{Name: "email"}},
}).Create(&user)
if result.Error != nil { if IsSQL {
log.Println(result.Error) result := mgr.sqlDB.Save(&user)
return user, result.Error
if result.Error != nil {
log.Println("error updating user:", result.Error)
return user, result.Error
}
}
if IsArangoDB {
collection, _ := mgr.arangodb.Collection(nil, Collections.User)
meta, err := collection.UpdateDocument(nil, user.Key, user)
if err != nil {
log.Println("error updating user:", err)
return user, err
}
user.Key = meta.Key
user.ObjectID = meta.ID.String()
} }
return user, nil return user, nil
} }
@ -63,20 +97,76 @@ func (mgr *manager) UpdateUser(user User) (User, error) {
// GetUsers function to get all users // GetUsers function to get all users
func (mgr *manager) GetUsers() ([]User, error) { func (mgr *manager) GetUsers() ([]User, error) {
var users []User var users []User
result := mgr.db.Find(&users)
if result.Error != nil { if IsSQL {
log.Println(result.Error) result := mgr.sqlDB.Find(&users)
return users, result.Error if result.Error != nil {
log.Println("error getting users:", result.Error)
return users, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s RETURN d", Collections.User)
cursor, err := mgr.arangodb.Query(nil, query, nil)
if err != nil {
return users, err
}
defer cursor.Close()
for {
var user User
meta, err := cursor.ReadDocument(nil, &user)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return users, err
}
if meta.Key != "" {
user.Key = meta.Key
user.ObjectID = meta.ID.String()
users = append(users, user)
}
}
} }
return users, nil return users, nil
} }
func (mgr *manager) GetUserByEmail(email string) (User, error) { func (mgr *manager) GetUserByEmail(email string) (User, error) {
var user User var user User
result := mgr.db.Where("email = ?", email).First(&user)
if result.Error != nil { if IsSQL {
return user, result.Error result := mgr.sqlDB.Where("email = ?", email).First(&user)
if result.Error != nil {
return user, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s FILTER d.email == @email LIMIT 1 RETURN d", Collections.User)
bindVars := map[string]interface{}{
"email": email,
}
cursor, err := mgr.arangodb.Query(nil, query, bindVars)
if err != nil {
return user, err
}
defer cursor.Close()
for {
_, err := cursor.ReadDocument(nil, &user)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return user, err
}
}
} }
return user, nil return user, nil
@ -84,35 +174,62 @@ func (mgr *manager) GetUserByEmail(email string) (User, error) {
func (mgr *manager) GetUserByID(id string) (User, error) { func (mgr *manager) GetUserByID(id string) (User, error) {
var user User var user User
result := mgr.db.Where("id = ?", id).First(&user)
if result.Error != nil { if IsSQL {
return user, result.Error result := mgr.sqlDB.Where("id = ?", id).First(&user)
if result.Error != nil {
return user, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s FILTER d.id == @id LIMIT 1 RETURN d", Collections.User)
bindVars := map[string]interface{}{
"id": id,
}
cursor, err := mgr.arangodb.Query(nil, query, bindVars)
if err != nil {
return user, err
}
defer cursor.Close()
count := cursor.Count()
if count == 0 {
return user, errors.New("user not found")
}
for {
_, err := cursor.ReadDocument(nil, &user)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return user, err
}
}
} }
return user, nil return user, nil
} }
func (mgr *manager) UpdateVerificationTime(verifiedAt int64, id uuid.UUID) error { func (mgr *manager) DeleteUser(user User) error {
user := &User{ if IsSQL {
ID: id, result := mgr.sqlDB.Delete(&user)
}
result := mgr.db.Model(&user).Where("id = ?", id).Update("email_verified_at", verifiedAt)
if result.Error != nil { if result.Error != nil {
return result.Error log.Println(`error deleting user:`, result.Error)
} return result.Error
}
return nil }
}
if IsArangoDB {
func (mgr *manager) DeleteUser(email string) error { collection, _ := mgr.arangodb.Collection(nil, Collections.User)
var user User _, err := collection.RemoveDocument(nil, user.Key)
result := mgr.db.Where("email = ?", email).Delete(&user) if err != nil {
log.Println(`error deleting user:`, err)
if result.Error != nil { return err
log.Println(`Error deleting user:`, result.Error) }
return result.Error
} }
return nil return nil

View File

@ -1,50 +1,132 @@
package db package db
import ( import (
"fmt"
"log" "log"
"github.com/arangodb/go-driver"
"github.com/google/uuid" "github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
type VerificationRequest struct { type VerificationRequest struct {
ID uuid.UUID `gorm:"primaryKey;type:char(36)"` Key string `json:"_key,omitempty"` // for arangodb
Token string `gorm:"type:text"` ObjectID string `json:"_id,omitempty"` // for arangodb & mongodb
Identifier string ID string `gorm:"primaryKey;type:char(36)" json:"id"`
ExpiresAt int64 Token string `gorm:"type:text" json:"token"`
CreatedAt int64 `gorm:"autoCreateTime"` Identifier string `gorm:"uniqueIndex:idx_email_identifier" json:"identifier"`
UpdatedAt int64 `gorm:"autoUpdateTime"` ExpiresAt int64 `json:"expires_at"`
Email string `gorm:"unique"` CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
} UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at"`
Email string `gorm:"uniqueIndex:idx_email_identifier" json:"email"`
func (v *VerificationRequest) BeforeCreate(tx *gorm.DB) (err error) {
v.ID = uuid.New()
return
} }
// AddVerification function to add verification record // AddVerification function to add verification record
func (mgr *manager) AddVerification(verification VerificationRequest) (VerificationRequest, error) { func (mgr *manager) AddVerification(verification VerificationRequest) (VerificationRequest, error) {
result := mgr.db.Clauses(clause.OnConflict{ if verification.ID == "" {
Columns: []clause.Column{{Name: "email"}}, verification.ID = uuid.New().String()
DoUpdates: clause.AssignmentColumns([]string{"token", "identifier", "expires_at"}), }
}).Create(&verification) if IsSQL {
// copy id as value for fields required for mongodb & arangodb
verification.Key = verification.ID
verification.ObjectID = verification.ID
result := mgr.sqlDB.Clauses(clause.OnConflict{
DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at"}),
}).Create(&verification)
if result.Error != nil { if result.Error != nil {
log.Println(`Error saving verification record`, result.Error) log.Println(`error saving verification record`, result.Error)
return verification, result.Error return verification, result.Error
}
}
if IsArangoDB {
verificationRequestCollection, _ := mgr.arangodb.Collection(nil, Collections.VerificationRequest)
meta, err := verificationRequestCollection.CreateDocument(nil, verification)
if err != nil {
return verification, err
}
verification.Key = meta.Key
verification.ObjectID = meta.ID.String()
} }
return verification, nil return verification, nil
} }
// GetVerificationRequests function to get all verification requests
func (mgr *manager) GetVerificationRequests() ([]VerificationRequest, error) {
var verificationRequests []VerificationRequest
if IsSQL {
result := mgr.sqlDB.Find(&verificationRequests)
if result.Error != nil {
log.Println("error getting verification requests:", result.Error)
return verificationRequests, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s RETURN d", Collections.VerificationRequest)
cursor, err := mgr.arangodb.Query(nil, query, nil)
if err != nil {
return verificationRequests, err
}
defer cursor.Close()
for {
var verificationRequest VerificationRequest
meta, err := cursor.ReadDocument(nil, &verificationRequest)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return verificationRequests, err
}
if meta.Key != "" {
verificationRequest.Key = meta.Key
verificationRequest.ObjectID = meta.ID.String()
verificationRequests = append(verificationRequests, verificationRequest)
}
}
}
return verificationRequests, nil
}
func (mgr *manager) GetVerificationByToken(token string) (VerificationRequest, error) { func (mgr *manager) GetVerificationByToken(token string) (VerificationRequest, error) {
var verification VerificationRequest var verification VerificationRequest
result := mgr.db.Where("token = ?", token).First(&verification)
if result.Error != nil { if IsSQL {
log.Println(`Error getting verification token:`, result.Error) result := mgr.sqlDB.Where("token = ?", token).First(&verification)
return verification, result.Error
if result.Error != nil {
log.Println(`error getting verification request:`, result.Error)
return verification, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", Collections.VerificationRequest)
bindVars := map[string]interface{}{
"token": token,
}
cursor, err := mgr.arangodb.Query(nil, query, bindVars)
if err != nil {
return verification, err
}
defer cursor.Close()
for {
_, err := cursor.ReadDocument(nil, &verification)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return verification, err
}
}
} }
return verification, nil return verification, nil
@ -52,35 +134,60 @@ func (mgr *manager) GetVerificationByToken(token string) (VerificationRequest, e
func (mgr *manager) GetVerificationByEmail(email string) (VerificationRequest, error) { func (mgr *manager) GetVerificationByEmail(email string) (VerificationRequest, error) {
var verification VerificationRequest var verification VerificationRequest
result := mgr.db.Where("email = ?", email).First(&verification) if IsSQL {
result := mgr.sqlDB.Where("email = ?", email).First(&verification)
if result.Error != nil { if result.Error != nil {
log.Println(`Error getting verification token:`, result.Error) log.Println(`error getting verification token:`, result.Error)
return verification, result.Error return verification, result.Error
}
}
if IsArangoDB {
query := fmt.Sprintf("FOR d in %s FILTER d.email == @email LIMIT 1 RETURN d", Collections.VerificationRequest)
bindVars := map[string]interface{}{
"email": email,
}
cursor, err := mgr.arangodb.Query(nil, query, bindVars)
if err != nil {
return verification, err
}
defer cursor.Close()
for {
_, err := cursor.ReadDocument(nil, &verification)
if driver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return verification, err
}
}
} }
return verification, nil return verification, nil
} }
func (mgr *manager) DeleteToken(email string) error { func (mgr *manager) DeleteVerificationRequest(verificationRequest VerificationRequest) error {
var verification VerificationRequest if IsSQL {
result := mgr.db.Where("email = ?", email).Delete(&verification) result := mgr.sqlDB.Delete(&verificationRequest)
if result.Error != nil { if result.Error != nil {
log.Println(`Error deleting token:`, result.Error) log.Println(`error deleting verification request:`, result.Error)
return result.Error return result.Error
}
}
if IsArangoDB {
collection, _ := mgr.arangodb.Collection(nil, Collections.VerificationRequest)
_, err := collection.RemoveDocument(nil, verificationRequest.Key)
if err != nil {
log.Println(`error deleting verification request:`, err)
return err
}
} }
return nil return nil
} }
// GetUsers function to get all users
func (mgr *manager) GetVerificationRequests() ([]VerificationRequest, error) {
var verificationRequests []VerificationRequest
result := mgr.db.Find(&verificationRequests)
if result.Error != nil {
log.Println(result.Error)
return verificationRequests, result.Error
}
return verificationRequests, nil
}

View File

@ -6,6 +6,7 @@ const (
Postgres DbType = iota Postgres DbType = iota
Sqlite Sqlite
Mysql Mysql
Arangodb
) )
func (d DbType) String() string { func (d DbType) String() string {
@ -13,5 +14,6 @@ func (d DbType) String() string {
"postgres", "postgres",
"sqlite", "sqlite",
"mysql", "mysql",
"arangodb",
}[d] }[d]
} }

View File

@ -35,7 +35,7 @@ func InitEnv() {
err := godotenv.Load(envPath) err := godotenv.Load(envPath)
if err != nil { if err != nil {
log.Println("Error loading .env file") log.Println("error loading .env file")
} }
constants.VERSION = Version constants.VERSION = Version
@ -43,6 +43,7 @@ func InitEnv() {
constants.ENV = os.Getenv("ENV") constants.ENV = os.Getenv("ENV")
constants.DATABASE_TYPE = os.Getenv("DATABASE_TYPE") constants.DATABASE_TYPE = os.Getenv("DATABASE_TYPE")
constants.DATABASE_URL = os.Getenv("DATABASE_URL") constants.DATABASE_URL = os.Getenv("DATABASE_URL")
constants.DATABASE_NAME = os.Getenv("DATABASE_NAME")
constants.SMTP_HOST = os.Getenv("SMTP_HOST") constants.SMTP_HOST = os.Getenv("SMTP_HOST")
constants.SMTP_PORT = os.Getenv("SMTP_PORT") constants.SMTP_PORT = os.Getenv("SMTP_PORT")
constants.SENDER_EMAIL = os.Getenv("SENDER_EMAIL") constants.SENDER_EMAIL = os.Getenv("SENDER_EMAIL")
@ -115,6 +116,10 @@ func InitEnv() {
panic("Database type is required") panic("Database type is required")
} }
if constants.DATABASE_NAME == "" {
constants.DATABASE_NAME = "authorizer"
}
if constants.JWT_TYPE == "" { if constants.JWT_TYPE == "" {
constants.JWT_TYPE = "HS256" constants.JWT_TYPE = "HS256"
} }
@ -137,7 +142,7 @@ func InitEnv() {
constants.DISABLE_EMAIL_VERIFICATION = "false" constants.DISABLE_EMAIL_VERIFICATION = "false"
} }
log.Println("=> disable email verification:", constants.DISABLE_EMAIL_VERIFICATION) log.Println("email verification disabled:", constants.DISABLE_EMAIL_VERIFICATION)
rolesSplit := strings.Split(os.Getenv("ROLES"), ",") rolesSplit := strings.Split(os.Getenv("ROLES"), ",")
roles := []string{} roles := []string{}

View File

@ -4,12 +4,13 @@ go 1.16
require ( require (
github.com/99designs/gqlgen v0.13.0 github.com/99designs/gqlgen v0.13.0
github.com/arangodb/go-driver v1.2.1 // indirect
github.com/coreos/go-oidc/v3 v3.1.0 // indirect github.com/coreos/go-oidc/v3 v3.1.0 // indirect
github.com/gin-contrib/location v0.0.2 // indirect github.com/gin-contrib/location v0.0.2 // indirect
github.com/gin-gonic/gin v1.7.2 github.com/gin-gonic/gin v1.7.2
github.com/go-playground/validator/v10 v10.8.0 // indirect github.com/go-playground/validator/v10 v10.8.0 // indirect
github.com/go-redis/redis/v8 v8.11.0 github.com/go-redis/redis/v8 v8.11.0
github.com/golang-jwt/jwt v3.2.1+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/jackc/pgproto3/v2 v2.1.0 // indirect github.com/jackc/pgproto3/v2 v2.1.0 // indirect

View File

@ -74,6 +74,10 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/arangodb/go-driver v1.2.1 h1:HREDHhDmzdIWxHmfkfTESbYUnRjESjPh4WUuXq7FZa8=
github.com/arangodb/go-driver v1.2.1/go.mod h1:zdDkJJnCj8DAkfbtIjIXnsTrWIiy6VhP3Vy14p+uQeY=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g=
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@ -109,6 +113,7 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/go-iptables v0.4.3/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw=
github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -123,6 +128,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
@ -278,6 +284,7 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -535,6 +542,8 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -569,6 +578,7 @@ github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@ -896,6 +906,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=

View File

@ -129,7 +129,7 @@ func processFacebookUserInfo(code string) (db.User, error) {
response, err := client.Do(req) response, err := client.Do(req)
if err != nil { if err != nil {
log.Println("err:", err) log.Println("error processing facebook user info:", err)
return user, err return user, err
} }
@ -217,6 +217,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
} }
user.Roles = strings.Join(inputRoles, ",") user.Roles = strings.Join(inputRoles, ",")
user, _ = db.Mgr.AddUser(user)
} else { } else {
// user exists in db, check if method was google // user exists in db, check if method was google
// if not append google to existing signup method and save it // if not append google to existing signup method and save it
@ -260,9 +261,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
} else { } else {
user.Roles = existingUser.Roles user.Roles = existingUser.Roles
} }
user.Key = existingUser.Key
user.ObjectID = existingUser.ObjectID
user.ID = existingUser.ID
user, err = db.Mgr.UpdateUser(user)
} }
user, _ = db.Mgr.SaveUser(user)
user, _ = db.Mgr.GetUserByEmail(user.Email) user, _ = db.Mgr.GetUserByEmail(user.Email)
userIdStr := fmt.Sprintf("%v", user.ID) userIdStr := fmt.Sprintf("%v", user.ID)
refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, inputRoles) refreshToken, _, _ := utils.CreateAuthToken(user, enum.RefreshToken, inputRoles)
@ -277,7 +281,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
IP: utils.GetIP(c.Request), IP: utils.GetIP(c.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
c.Redirect(http.StatusTemporaryRedirect, redirectURL) c.Redirect(http.StatusTemporaryRedirect, redirectURL)

View File

@ -24,7 +24,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
return return
} }
_, err := db.Mgr.GetVerificationByToken(token) verificationRequest, err := db.Mgr.GetVerificationByToken(token)
if err != nil { if err != nil {
c.JSON(400, errorRes) c.JSON(400, errorRes)
return return
@ -47,10 +47,11 @@ func VerifyEmailHandler() gin.HandlerFunc {
// update email_verified_at in users table // update email_verified_at in users table
if user.EmailVerifiedAt <= 0 { if user.EmailVerifiedAt <= 0 {
db.Mgr.UpdateVerificationTime(time.Now().Unix(), user.ID) user.EmailVerifiedAt = time.Now().Unix()
db.Mgr.UpdateUser(user)
} }
// delete from verification table // delete from verification table
db.Mgr.DeleteToken(claim.Email) db.Mgr.DeleteVerificationRequest(verificationRequest)
userIdStr := fmt.Sprintf("%v", user.ID) userIdStr := fmt.Sprintf("%v", user.ID)
roles := strings.Split(user.Roles, ",") roles := strings.Split(user.Roles, ",")
@ -66,7 +67,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
IP: utils.GetIP(c.Request), IP: utils.GetIP(c.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
utils.SetCookie(c, accessToken) utils.SetCookie(c, accessToken)
c.Redirect(http.StatusTemporaryRedirect, claim.RedirectURL) c.Redirect(http.StatusTemporaryRedirect, claim.RedirectURL)

View File

@ -19,7 +19,7 @@ func GinContextToContextMiddleware() gin.HandlerFunc {
if constants.AUTHORIZER_URL == "" { if constants.AUTHORIZER_URL == "" {
url := location.Get(c) url := location.Get(c)
constants.AUTHORIZER_URL = url.Scheme + "://" + c.Request.Host constants.AUTHORIZER_URL = url.Scheme + "://" + c.Request.Host
log.Println("=> setting url:", constants.AUTHORIZER_URL) log.Println("=> authorizer url:", constants.AUTHORIZER_URL)
} }
ctx := context.WithValue(c.Request.Context(), "GinContextKey", c) ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
c.Request = c.Request.WithContext(ctx) c.Request = c.Request.WithContext(ctx)
@ -33,7 +33,6 @@ func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
origin := c.Request.Header.Get("Origin") origin := c.Request.Header.Get("Origin")
constants.APP_URL = origin constants.APP_URL = origin
log.Println("=> APP_URL:", constants.APP_URL)
c.Writer.Header().Set("Access-Control-Allow-Origin", origin) c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")

View File

@ -69,7 +69,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
verificationType := enum.UpdateEmail.String() verificationType := enum.UpdateEmail.String()
token, err := utils.CreateVerificationToken(newEmail, verificationType) token, err := utils.CreateVerificationToken(newEmail, verificationType)
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,
@ -110,7 +110,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
user, err = db.Mgr.UpdateUser(user) user, err = db.Mgr.UpdateUser(user)
if err != nil { if err != nil {
log.Println("Error updating user:", err) log.Println("error updating user:", err)
return res, err return res, err
} }

View File

@ -29,9 +29,9 @@ func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Respo
session.DeleteUserSession(fmt.Sprintf("%x", user.ID)) session.DeleteUserSession(fmt.Sprintf("%x", user.ID))
err = db.Mgr.DeleteUser(params.Email) err = db.Mgr.DeleteUser(user)
if err != nil { if err != nil {
log.Println("Err:", err) log.Println("error deleting user:", err)
return res, err return res, err
} }

View File

@ -37,7 +37,7 @@ func ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*mod
token, err := utils.CreateVerificationToken(params.Email, enum.ForgotPassword.String()) token, err := utils.CreateVerificationToken(params.Email, enum.ForgotPassword.String())
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,

View File

@ -43,7 +43,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(params.Password)) err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(params.Password))
if err != nil { if err != nil {
log.Println("Compare password error:", err) log.Println("compare password error:", err)
return res, fmt.Errorf(`invalid password`) return res, fmt.Errorf(`invalid password`)
} }
roles := constants.DEFAULT_ROLES roles := constants.DEFAULT_ROLES
@ -68,7 +68,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
IP: utils.GetIP(gc.Request), IP: utils.GetIP(gc.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
res = &model.AuthResponse{ res = &model.AuthResponse{

View File

@ -27,7 +27,7 @@ func Logout(ctx context.Context) (*model.Response, error) {
} }
userId := fmt.Sprintf("%v", claim["id"]) userId := fmt.Sprintf("%v", claim["id"])
session.DeleteToken(userId, token) session.DeleteVerificationRequest(userId, token)
res = &model.Response{ res = &model.Response{
Message: "Logged out successfully", Message: "Logged out successfully",
} }

View File

@ -35,6 +35,7 @@ func MagicLogin(ctx context.Context, params model.MagicLoginInput) (*model.Respo
// find user with email // find user with email
existingUser, err := db.Mgr.GetUserByEmail(params.Email) existingUser, err := db.Mgr.GetUserByEmail(params.Email)
if err != nil { if err != nil {
user.SignupMethod = enum.MagicLink.String() user.SignupMethod = enum.MagicLink.String()
// define roles for new user // define roles for new user
@ -50,6 +51,7 @@ func MagicLogin(ctx context.Context, params model.MagicLoginInput) (*model.Respo
} }
user.Roles = strings.Join(inputRoles, ",") user.Roles = strings.Join(inputRoles, ",")
user, _ = db.Mgr.AddUser(user)
} else { } else {
user = existingUser user = existingUser
// There multiple scenarios with roles here in magic link login // There multiple scenarios with roles here in magic link login
@ -90,16 +92,18 @@ func MagicLogin(ctx context.Context, params model.MagicLoginInput) (*model.Respo
} }
user.SignupMethod = signupMethod user.SignupMethod = signupMethod
user, _ = db.Mgr.UpdateUser(user)
if err != nil {
log.Println("error updating user:", err)
}
} }
user, _ = db.Mgr.SaveUser(user)
if constants.DISABLE_EMAIL_VERIFICATION != "true" { if constants.DISABLE_EMAIL_VERIFICATION != "true" {
// insert verification request // insert verification request
verificationType := enum.MagicLink.String() verificationType := enum.MagicLink.String()
token, err := utils.CreateVerificationToken(params.Email, verificationType) token, err := utils.CreateVerificationToken(params.Email, verificationType)
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,

View File

@ -27,7 +27,7 @@ func ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput)
token, err := utils.CreateVerificationToken(params.Email, verificationRequest.Identifier) token, err := utils.CreateVerificationToken(params.Email, verificationRequest.Identifier)
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,

View File

@ -18,7 +18,7 @@ func ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
_, err := db.Mgr.GetVerificationByToken(params.Token) verificationRequest, err := db.Mgr.GetVerificationByToken(params.Token)
if err != nil { if err != nil {
return res, fmt.Errorf(`invalid token`) return res, fmt.Errorf(`invalid token`)
} }
@ -48,7 +48,7 @@ func ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model
user.SignupMethod = signupMethod user.SignupMethod = signupMethod
// delete from verification table // delete from verification table
db.Mgr.DeleteToken(claim.Email) db.Mgr.DeleteVerificationRequest(verificationRequest)
db.Mgr.UpdateUser(user) db.Mgr.UpdateUser(user)
res = &model.Response{ res = &model.Response{

View File

@ -51,7 +51,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
// find user with email // find user with email
existingUser, err := db.Mgr.GetUserByEmail(params.Email) existingUser, err := db.Mgr.GetUserByEmail(params.Email)
if err != nil { if err != nil {
log.Println("User with email " + params.Email + " not found") log.Println("user with email " + params.Email + " not found")
} }
if existingUser.EmailVerifiedAt > 0 { if existingUser.EmailVerifiedAt > 0 {
@ -79,7 +79,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
if constants.DISABLE_EMAIL_VERIFICATION == "true" { if constants.DISABLE_EMAIL_VERIFICATION == "true" {
user.EmailVerifiedAt = time.Now().Unix() user.EmailVerifiedAt = time.Now().Unix()
} }
user, err = db.Mgr.SaveUser(user) user, err = db.Mgr.AddUser(user)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -103,7 +103,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
verificationType := enum.BasicAuthSignup.String() verificationType := enum.BasicAuthSignup.String()
token, err := utils.CreateVerificationToken(params.Email, verificationType) token, err := utils.CreateVerificationToken(params.Email, verificationType)
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,
@ -135,7 +135,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
IP: utils.GetIP(gc.Request), IP: utils.GetIP(gc.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
res = &model.AuthResponse{ res = &model.AuthResponse{
Message: `Signed up successfully.`, Message: `Signed up successfully.`,

View File

@ -64,7 +64,7 @@ func Token(ctx context.Context, roles []string) (*model.AuthResponse, error) {
// if access token has expired and refresh/session token is valid // if access token has expired and refresh/session token is valid
// generate new accessToken // generate new accessToken
currentRefreshToken := session.GetToken(userIdStr, token) currentRefreshToken := session.GetToken(userIdStr, token)
session.DeleteToken(userIdStr, token) session.DeleteVerificationRequest(userIdStr, token)
token, expiresAt, _ = utils.CreateAuthToken(user, enum.AccessToken, claimRoles) token, expiresAt, _ = utils.CreateAuthToken(user, enum.AccessToken, claimRoles)
session.SetToken(userIdStr, token, currentRefreshToken) session.SetToken(userIdStr, token, currentRefreshToken)
go func() { go func() {
@ -74,7 +74,7 @@ func Token(ctx context.Context, roles []string) (*model.AuthResponse, error) {
IP: utils.GetIP(gc.Request), IP: utils.GetIP(gc.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
} }

View File

@ -109,7 +109,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
verificationType := enum.UpdateEmail.String() verificationType := enum.UpdateEmail.String()
token, err := utils.CreateVerificationToken(newEmail, verificationType) token, err := utils.CreateVerificationToken(newEmail, verificationType)
if err != nil { if err != nil {
log.Println(`Error generating token`, err) log.Println(`error generating token`, err)
} }
db.Mgr.AddVerification(db.VerificationRequest{ db.Mgr.AddVerification(db.VerificationRequest{
Token: token, Token: token,
@ -126,7 +126,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
_, err = db.Mgr.UpdateUser(user) _, err = db.Mgr.UpdateUser(user)
if err != nil { if err != nil {
log.Println("Error updating user:", err) log.Println("error updating user:", err)
return res, err return res, err
} }
message := `Profile details updated successfully.` message := `Profile details updated successfully.`

View File

@ -20,7 +20,7 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
return res, err return res, err
} }
_, err = db.Mgr.GetVerificationByToken(params.Token) verificationRequest, err := db.Mgr.GetVerificationByToken(params.Token)
if err != nil { if err != nil {
return res, fmt.Errorf(`invalid token`) return res, fmt.Errorf(`invalid token`)
} }
@ -37,9 +37,10 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
} }
// update email_verified_at in users table // update email_verified_at in users table
db.Mgr.UpdateVerificationTime(time.Now().Unix(), user.ID) user.EmailVerifiedAt = time.Now().Unix()
db.Mgr.UpdateUser(user)
// delete from verification table // delete from verification table
db.Mgr.DeleteToken(claim.Email) db.Mgr.DeleteVerificationRequest(verificationRequest)
userIdStr := fmt.Sprintf("%v", user.ID) userIdStr := fmt.Sprintf("%v", user.ID)
roles := strings.Split(user.Roles, ",") roles := strings.Split(user.Roles, ",")
@ -55,7 +56,7 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
IP: utils.GetIP(gc.Request), IP: utils.GetIP(gc.Request),
} }
db.Mgr.SaveSession(sessionData) db.Mgr.AddSession(sessionData)
}() }()
res = &model.AuthResponse{ res = &model.AuthResponse{

View File

@ -1,7 +1,6 @@
package session package session
import ( import (
"log"
"sync" "sync"
) )
@ -30,8 +29,6 @@ func (c *InMemoryStore) AddToken(userId, accessToken, refreshToken string) {
c.store[userId] = tempMap c.store[userId] = tempMap
} }
log.Println(c.store)
c.mu.Unlock() c.mu.Unlock()
} }
@ -41,7 +38,7 @@ func (c *InMemoryStore) DeleteUserSession(userId string) {
c.mu.Unlock() c.mu.Unlock()
} }
func (c *InMemoryStore) DeleteToken(userId, accessToken string) { func (c *InMemoryStore) DeleteVerificationRequest(userId, accessToken string) {
c.mu.Lock() c.mu.Lock()
delete(c.store[userId], accessToken) delete(c.store[userId], accessToken)
c.mu.Unlock() c.mu.Unlock()

View File

@ -29,7 +29,7 @@ func (c *RedisStore) DeleteUserSession(userId string) {
} }
} }
func (c *RedisStore) DeleteToken(userId, accessToken string) { func (c *RedisStore) DeleteVerificationRequest(userId, accessToken string) {
err := c.store.HDel(c.ctx, "authorizer_"+userId, accessToken).Err() err := c.store.HDel(c.ctx, "authorizer_"+userId, accessToken).Err()
if err != nil { if err != nil {
log.Fatalln("Error deleting redis token:", err) log.Fatalln("Error deleting redis token:", err)
@ -47,7 +47,7 @@ func (c *RedisStore) GetToken(userId, accessToken string) string {
token := "" token := ""
res, err := c.store.HMGet(c.ctx, "authorizer_"+userId, accessToken).Result() res, err := c.store.HMGet(c.ctx, "authorizer_"+userId, accessToken).Result()
if err != nil { if err != nil {
log.Println("Error getting token from redis store:", err) log.Println("error getting token from redis store:", err)
} }
if len(res) > 0 && res[0] != nil { if len(res) > 0 && res[0] != nil {
token = fmt.Sprintf("%v", res[0]) token = fmt.Sprintf("%v", res[0])
@ -66,7 +66,7 @@ func (c *RedisStore) GetSocialLoginState(key string) string {
state := "" state := ""
state, err := c.store.Get(c.ctx, key).Result() state, err := c.store.Get(c.ctx, key).Result()
if err != nil { if err != nil {
log.Println("Error getting token from redis store:", err) log.Println("error getting token from redis store:", err)
} }
return state return state

View File

@ -27,12 +27,12 @@ func SetToken(userId, accessToken, refreshToken string) {
} }
} }
func DeleteToken(userId, accessToken string) { func DeleteVerificationRequest(userId, accessToken string) {
if SessionStoreObj.RedisMemoryStoreObj != nil { if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.DeleteToken(userId, accessToken) SessionStoreObj.RedisMemoryStoreObj.DeleteVerificationRequest(userId, accessToken)
} }
if SessionStoreObj.InMemoryStoreObj != nil { if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.DeleteToken(userId, accessToken) SessionStoreObj.InMemoryStoreObj.DeleteVerificationRequest(userId, accessToken)
} }
} }
@ -96,7 +96,7 @@ func RemoveSocialLoginState(key string) {
func InitSession() { func InitSession() {
if constants.REDIS_URL != "" { if constants.REDIS_URL != "" {
log.Println("Using redis store to save sessions") log.Println("using redis store to save sessions")
opt, err := redis.ParseURL(constants.REDIS_URL) opt, err := redis.ParseURL(constants.REDIS_URL)
if err != nil { if err != nil {
log.Fatalln("Error parsing redis url:", err) log.Fatalln("Error parsing redis url:", err)
@ -114,7 +114,7 @@ func InitSession() {
} }
} else { } else {
log.Println("Using in memory store to save sessions") log.Println("using in memory store to save sessions")
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{ SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
store: map[string]map[string]string{}, store: map[string]map[string]string{},
socialLoginState: map[string]string{}, socialLoginState: map[string]string{},

View File

@ -64,12 +64,12 @@ func CreateAuthToken(user db.User, tokenType enum.TokenType, roles []string) (st
val, err := vm.Get("functionRes") val, err := vm.Get("functionRes")
if err != nil { if err != nil {
log.Println("=> err custom access token script:", err) log.Println("error getting custom access token script:", err)
} else { } else {
extraPayload := make(map[string]interface{}) extraPayload := make(map[string]interface{})
err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload) err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
if err != nil { if err != nil {
log.Println("Error converting accessTokenScript response to map:", err) log.Println("error converting accessTokenScript response to map:", err)
} else { } else {
for k, v := range extraPayload { for k, v := range extraPayload {
customClaims[k] = v customClaims[k] = v

View File

@ -1,30 +1,6 @@
package utils package utils
import (
"log"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
)
// any jobs that we want to run at start of server can be executed here // any jobs that we want to run at start of server can be executed here
// 1. create roles table and add the roles list from env to table
func InitServer() { func InitServer() {
roles := []db.Role{}
for _, val := range constants.ROLES {
roles = append(roles, db.Role{
Role: val,
})
}
for _, val := range constants.PROTECTED_ROLES {
roles = append(roles, db.Role{
Role: val,
})
}
err := db.Mgr.SaveRoles(roles)
if err != nil {
log.Println(`Error saving roles`, err)
}
} }