diff --git a/server/db/providers/arangodb/user.go b/server/db/providers/arangodb/user.go new file mode 100644 index 0000000..055bd52 --- /dev/null +++ b/server/db/providers/arangodb/user.go @@ -0,0 +1,157 @@ +package arangodb + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/arangodb/go-driver" + arangoDriver "github.com/arangodb/go-driver" + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/authorizerdev/authorizer/server/envstore" + "github.com/google/uuid" +) + +// AddUser to save user information in database +func (p *provider) AddUser(user models.User) (models.User, error) { + if user.ID == "" { + user.ID = uuid.New().String() + } + + if user.Roles == "" { + user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") + } + + user.CreatedAt = time.Now().Unix() + user.UpdatedAt = time.Now().Unix() + userCollection, _ := p.db.Collection(nil, models.Collections.User) + meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(nil), user) + if err != nil { + log.Println("error adding user:", err) + return user, err + } + user.Key = meta.Key + user.ID = meta.ID.String() + + return user, nil +} + +// UpdateUser to update user information in database +func (p *provider) UpdateUser(user models.User) (models.User, error) { + user.UpdatedAt = time.Now().Unix() + collection, _ := p.db.Collection(nil, models.Collections.User) + meta, err := collection.UpdateDocument(nil, user.Key, user) + if err != nil { + log.Println("error updating user:", err) + return user, err + } + + user.Key = meta.Key + user.ID = meta.ID.String() + return user, nil +} + +// DeleteUser to delete user information from database +func (p *provider) DeleteUser(user models.User) error { + collection, _ := p.db.Collection(nil, models.Collections.User) + _, err := collection.RemoveDocument(nil, user.Key) + if err != nil { + log.Println(`error deleting user:`, err) + return err + } + + return nil +} + +// ListUsers to get list of users from database +func (p *provider) ListUsers() ([]models.User, error) { + var users []models.User + query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.User) + + cursor, err := p.db.Query(nil, query, nil) + if err != nil { + return users, err + } + defer cursor.Close() + + for { + var user models.User + meta, err := cursor.ReadDocument(nil, &user) + + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return users, err + } + + if meta.Key != "" { + users = append(users, user) + } + } + + return users, nil +} + +// GetUserByEmail to get user information from database using email address +func (p *provider) GetUserByEmail(email string) (models.User, error) { + var user models.User + + query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.User) + bindVars := map[string]interface{}{ + "email": email, + } + + cursor, err := p.db.Query(nil, query, bindVars) + if err != nil { + return user, err + } + defer cursor.Close() + + for { + if !cursor.HasMore() { + if user.Key == "" { + return user, fmt.Errorf("user not found") + } + break + } + _, err := cursor.ReadDocument(nil, &user) + if err != nil { + return user, err + } + } + + return user, nil +} + +// GetUserByID to get user information from database using user ID +func (p *provider) GetUserByID(id string) (models.User, error) { + var user models.User + + query := fmt.Sprintf("FOR d in %s FILTER d._id == @id LIMIT 1 RETURN d", models.Collections.User) + bindVars := map[string]interface{}{ + "id": id, + } + + cursor, err := p.db.Query(nil, query, bindVars) + if err != nil { + return user, err + } + defer cursor.Close() + + for { + if !cursor.HasMore() { + if user.Key == "" { + return user, fmt.Errorf("user not found") + } + break + } + _, err := cursor.ReadDocument(nil, &user) + if err != nil { + return user, err + } + } + + return user, nil +} diff --git a/server/db/providers/arangodb/verification_requests.go b/server/db/providers/arangodb/verification_requests.go new file mode 100644 index 0000000..ab7eee6 --- /dev/null +++ b/server/db/providers/arangodb/verification_requests.go @@ -0,0 +1,135 @@ +package arangodb + +import ( + "fmt" + "log" + "time" + + "github.com/arangodb/go-driver" + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/google/uuid" +) + +// AddVerification to save verification request in database +func (p *provider) AddVerificationRequest(verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { + if verificationRequest.ID == "" { + verificationRequest.ID = uuid.New().String() + } + + verificationRequest.CreatedAt = time.Now().Unix() + verificationRequest.UpdatedAt = time.Now().Unix() + verificationRequestRequestCollection, _ := p.db.Collection(nil, models.Collections.VerificationRequest) + meta, err := verificationRequestRequestCollection.CreateDocument(nil, verificationRequest) + if err != nil { + log.Println("error saving verificationRequest record:", err) + return verificationRequest, err + } + verificationRequest.Key = meta.Key + verificationRequest.ID = meta.ID.String() + + return verificationRequest, nil +} + +// GetVerificationRequestByToken to get verification request from database using token +func (p *provider) GetVerificationRequestByToken(token string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", models.Collections.VerificationRequest) + bindVars := map[string]interface{}{ + "token": token, + } + + cursor, err := p.db.Query(nil, query, bindVars) + if err != nil { + return verificationRequest, err + } + defer cursor.Close() + + for { + if !cursor.HasMore() { + if verificationRequest.Key == "" { + return verificationRequest, fmt.Errorf("verification request not found") + } + break + } + _, err := cursor.ReadDocument(nil, &verificationRequest) + if err != nil { + return verificationRequest, err + } + } + + return verificationRequest, nil +} + +// GetVerificationRequestByEmail to get verification request by email from database +func (p *provider) GetVerificationRequestByEmail(email string, identifier string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + + query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", models.Collections.VerificationRequest) + bindVars := map[string]interface{}{ + "email": email, + "identifier": identifier, + } + + cursor, err := p.db.Query(nil, query, bindVars) + if err != nil { + return verificationRequest, err + } + defer cursor.Close() + + for { + if !cursor.HasMore() { + if verificationRequest.Key == "" { + return verificationRequest, fmt.Errorf("verification request not found") + } + break + } + _, err := cursor.ReadDocument(nil, &verificationRequest) + if err != nil { + return verificationRequest, err + } + } + + return verificationRequest, nil +} + +// ListVerificationRequests to get list of verification requests from database +func (p *provider) ListVerificationRequests() ([]models.VerificationRequest, error) { + var verificationRequests []models.VerificationRequest + + query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.VerificationRequest) + + cursor, err := p.db.Query(nil, query, nil) + if err != nil { + return verificationRequests, err + } + defer cursor.Close() + + for { + var verificationRequest models.VerificationRequest + meta, err := cursor.ReadDocument(nil, &verificationRequest) + + if driver.IsNoMoreDocuments(err) { + break + } else if err != nil { + return verificationRequests, err + } + + if meta.Key != "" { + verificationRequests = append(verificationRequests, verificationRequest) + } + + } + + return verificationRequests, nil +} + +// DeleteVerificationRequest to delete verification request from database +func (p *provider) DeleteVerificationRequest(verificationRequest models.VerificationRequest) error { + collection, _ := p.db.Collection(nil, models.Collections.VerificationRequest) + _, err := collection.RemoveDocument(nil, verificationRequest.Key) + if err != nil { + log.Println(`error deleting verification request:`, err) + return err + } + return nil +} diff --git a/server/db/providers/mongodb/user.go b/server/db/providers/mongodb/user.go new file mode 100644 index 0000000..e62107e --- /dev/null +++ b/server/db/providers/mongodb/user.go @@ -0,0 +1,108 @@ +package mongodb + +import ( + "log" + "strings" + "time" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/authorizerdev/authorizer/server/envstore" + "github.com/google/uuid" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" +) + +// AddUser to save user information in database +func (p *provider) AddUser(user models.User) (models.User, error) { + if user.ID == "" { + user.ID = uuid.New().String() + } + + if user.Roles == "" { + user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") + } + user.CreatedAt = time.Now().Unix() + user.UpdatedAt = time.Now().Unix() + user.Key = user.ID + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + _, err := userCollection.InsertOne(nil, user) + if err != nil { + log.Println("error adding user:", err) + return user, err + } + + return user, nil +} + +// UpdateUser to update user information in database +func (p *provider) UpdateUser(user models.User) (models.User, error) { + user.UpdatedAt = time.Now().Unix() + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + _, err := userCollection.UpdateOne(nil, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions()) + if err != nil { + log.Println("error updating user:", err) + return user, err + } + return user, nil +} + +// DeleteUser to delete user information from database +func (p *provider) DeleteUser(user models.User) error { + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + _, err := userCollection.DeleteOne(nil, bson.M{"_id": user.ID}, options.Delete()) + if err != nil { + log.Println("error deleting user:", err) + return err + } + + return nil +} + +// ListUsers to get list of users from database +func (p *provider) ListUsers() ([]models.User, error) { + var users []models.User + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + cursor, err := userCollection.Find(nil, bson.M{}, options.Find()) + if err != nil { + log.Println("error getting users:", err) + return users, err + } + defer cursor.Close(nil) + + for cursor.Next(nil) { + var user models.User + err := cursor.Decode(&user) + if err != nil { + return users, err + } + users = append(users, user) + } + + return users, nil +} + +// GetUserByEmail to get user information from database using email address +func (p *provider) GetUserByEmail(email string) (models.User, error) { + var user models.User + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + err := userCollection.FindOne(nil, bson.M{"email": email}).Decode(&user) + if err != nil { + return user, err + } + + return user, nil +} + +// GetUserByID to get user information from database using user ID +func (p *provider) GetUserByID(id string) (models.User, error) { + var user models.User + + userCollection := p.db.Collection(models.Collections.User, options.Collection()) + err := userCollection.FindOne(nil, bson.M{"_id": id}).Decode(&user) + if err != nil { + return user, err + } + + return user, nil +} diff --git a/server/db/providers/mongodb/verification_requests.go b/server/db/providers/mongodb/verification_requests.go new file mode 100644 index 0000000..7e86745 --- /dev/null +++ b/server/db/providers/mongodb/verification_requests.go @@ -0,0 +1,91 @@ +package mongodb + +import ( + "log" + "time" + + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/google/uuid" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" +) + +// AddVerification to save verification request in database +func (p *provider) AddVerificationRequest(verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { + if verificationRequest.ID == "" { + verificationRequest.ID = uuid.New().String() + + verificationRequest.CreatedAt = time.Now().Unix() + verificationRequest.UpdatedAt = time.Now().Unix() + verificationRequest.Key = verificationRequest.ID + verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) + _, err := verificationRequestCollection.InsertOne(nil, verificationRequest) + if err != nil { + log.Println("error saving verification record:", err) + return verificationRequest, err + } + } + + return verificationRequest, nil +} + +// GetVerificationRequestByToken to get verification request from database using token +func (p *provider) GetVerificationRequestByToken(token string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + + verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) + err := verificationRequestCollection.FindOne(nil, bson.M{"token": token}).Decode(&verificationRequest) + if err != nil { + return verificationRequest, err + } + + return verificationRequest, nil +} + +// GetVerificationRequestByEmail to get verification request by email from database +func (p *provider) GetVerificationRequestByEmail(email string, identifier string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + + verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) + err := verificationRequestCollection.FindOne(nil, bson.M{"email": email, "identifier": identifier}).Decode(&verificationRequest) + if err != nil { + return verificationRequest, err + } + + return verificationRequest, nil +} + +// ListVerificationRequests to get list of verification requests from database +func (p *provider) ListVerificationRequests() ([]models.VerificationRequest, error) { + var verificationRequests []models.VerificationRequest + verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) + cursor, err := verificationRequestCollection.Find(nil, bson.M{}, options.Find()) + if err != nil { + log.Println("error getting verification requests:", err) + return verificationRequests, err + } + defer cursor.Close(nil) + + for cursor.Next(nil) { + var verificationRequest models.VerificationRequest + err := cursor.Decode(&verificationRequest) + if err != nil { + return verificationRequests, err + } + verificationRequests = append(verificationRequests, verificationRequest) + } + + return verificationRequests, nil +} + +// DeleteVerificationRequest to delete verification request from database +func (p *provider) DeleteVerificationRequest(verificationRequest models.VerificationRequest) error { + verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) + _, err := verificationRequestCollection.DeleteOne(nil, bson.M{"_id": verificationRequest.ID}, options.Delete()) + if err != nil { + log.Println("error deleting verification request::", err) + return err + } + + return nil +} diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go index 80a9395..da4e5f7 100644 --- a/server/db/providers/providers.go +++ b/server/db/providers/providers.go @@ -17,7 +17,7 @@ type Provider interface { GetUserByID(id string) (models.User, error) // AddVerification to save verification request in database - AddVerificationRequest(verification models.VerificationRequest) (models.VerificationRequest, error) + AddVerificationRequest(verificationRequest models.VerificationRequest) (models.VerificationRequest, error) // GetVerificationRequestByToken to get verification request from database using token GetVerificationRequestByToken(token string) (models.VerificationRequest, error) // GetVerificationRequestByEmail to get verification request by email from database diff --git a/server/db/providers/sql/user.go b/server/db/providers/sql/user.go new file mode 100644 index 0000000..ad91b59 --- /dev/null +++ b/server/db/providers/sql/user.go @@ -0,0 +1,101 @@ +package sql + +import ( + "log" + "strings" + "time" + + "github.com/authorizerdev/authorizer/server/constants" + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/authorizerdev/authorizer/server/envstore" + "github.com/google/uuid" + "gorm.io/gorm/clause" +) + +// AddUser to save user information in database +func (p *provider) AddUser(user models.User) (models.User, error) { + if user.ID == "" { + user.ID = uuid.New().String() + } + + if user.Roles == "" { + user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",") + } + + user.Key = user.ID + result := p.db.Clauses( + clause.OnConflict{ + UpdateAll: true, + Columns: []clause.Column{{Name: "email"}}, + }).Create(&user) + + if result.Error != nil { + log.Println("error adding user:", result.Error) + return user, result.Error + } + + return user, nil +} + +// UpdateUser to update user information in database +func (p *provider) UpdateUser(user models.User) (models.User, error) { + user.UpdatedAt = time.Now().Unix() + + result := p.db.Save(&user) + + if result.Error != nil { + log.Println("error updating user:", result.Error) + return user, result.Error + } + + return user, nil +} + +// DeleteUser to delete user information from database +func (p *provider) DeleteUser(user models.User) error { + result := p.db.Delete(&user) + + if result.Error != nil { + log.Println(`error deleting user:`, result.Error) + return result.Error + } + + return nil +} + +// ListUsers to get list of users from database +func (p *provider) ListUsers() ([]models.User, error) { + var users []models.User + result := p.db.Find(&users) + if result.Error != nil { + log.Println("error getting users:", result.Error) + return users, result.Error + } + + return users, nil +} + +// GetUserByEmail to get user information from database using email address +func (p *provider) GetUserByEmail(email string) (models.User, error) { + var user models.User + result := p.db.Where("email = ?", email).First(&user) + + if result.Error != nil { + return user, result.Error + } + + return user, nil +} + +// GetUserByID to get user information from database using user ID +func (p *provider) GetUserByID(id string) (models.User, error) { + var user models.User + + result := p.db.Where("id = ?", id).First(&user) + + if result.Error != nil { + return user, result.Error + } + + return user, nil +} diff --git a/server/db/providers/sql/verification_requests.go b/server/db/providers/sql/verification_requests.go new file mode 100644 index 0000000..df21c7c --- /dev/null +++ b/server/db/providers/sql/verification_requests.go @@ -0,0 +1,80 @@ +package sql + +import ( + "log" + + "github.com/authorizerdev/authorizer/server/db/models" + "github.com/google/uuid" + "gorm.io/gorm/clause" +) + +// AddVerification to save verification request in database +func (p *provider) AddVerificationRequest(verificationRequest models.VerificationRequest) (models.VerificationRequest, error) { + if verificationRequest.ID == "" { + verificationRequest.ID = uuid.New().String() + } + + verificationRequest.Key = verificationRequest.ID + result := p.db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "email"}, {Name: "identifier"}}, + DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at"}), + }).Create(&verificationRequest) + + if result.Error != nil { + log.Println(`error saving verification request record`, result.Error) + return verificationRequest, result.Error + } + + return verificationRequest, nil +} + +// GetVerificationRequestByToken to get verification request from database using token +func (p *provider) GetVerificationRequestByToken(token string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + result := p.db.Where("token = ?", token).First(&verificationRequest) + + if result.Error != nil { + log.Println(`error getting verification request:`, result.Error) + return verificationRequest, result.Error + } + + return verificationRequest, nil +} + +// GetVerificationRequestByEmail to get verification request by email from database +func (p *provider) GetVerificationRequestByEmail(email string, identifier string) (models.VerificationRequest, error) { + var verificationRequest models.VerificationRequest + + result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest) + + if result.Error != nil { + log.Println(`error getting verification token:`, result.Error) + return verificationRequest, result.Error + } + + return verificationRequest, nil +} + +// ListVerificationRequests to get list of verification requests from database +func (p *provider) ListVerificationRequests() ([]models.VerificationRequest, error) { + var verificationRequests []models.VerificationRequest + + result := p.db.Find(&verificationRequests) + if result.Error != nil { + log.Println("error getting verification requests:", result.Error) + return verificationRequests, result.Error + } + return verificationRequests, nil +} + +// DeleteVerificationRequest to delete verification request from database +func (p *provider) DeleteVerificationRequest(verificationRequest models.VerificationRequest) error { + result := p.db.Delete(&verificationRequest) + + if result.Error != nil { + log.Println(`error deleting verification request:`, result.Error) + return result.Error + } + + return nil +}