2022-10-09 18:54:14 +00:00
package couchbase
import (
"context"
2022-11-02 17:30:03 +00:00
"fmt"
"log"
"reflect"
2022-10-09 18:54:14 +00:00
"time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
2022-11-02 17:30:03 +00:00
"github.com/couchbase/gocb/v2"
2022-10-09 18:54:14 +00:00
"github.com/google/uuid"
)
// AddUser to save user information in database
func ( p * provider ) AddUser ( ctx context . Context , user models . User ) ( models . User , error ) {
if user . ID == "" {
user . ID = uuid . New ( ) . String ( )
}
if user . Roles == "" {
defaultRoles , err := memorystore . Provider . GetStringStoreEnvVariable ( constants . EnvKeyDefaultRoles )
if err != nil {
return user , err
}
user . Roles = defaultRoles
}
user . CreatedAt = time . Now ( ) . Unix ( )
user . UpdatedAt = time . Now ( ) . Unix ( )
2022-11-02 17:30:03 +00:00
insertOpt := gocb . InsertOptions {
Context : ctx ,
}
_ , err := p . db . Collection ( models . Collections . User ) . Insert ( user . ID , user , & insertOpt )
if err != nil {
return user , err
}
2022-10-09 18:54:14 +00:00
return user , nil
}
// UpdateUser to update user information in database
func ( p * provider ) UpdateUser ( ctx context . Context , user models . User ) ( models . User , error ) {
user . UpdatedAt = time . Now ( ) . Unix ( )
2022-11-02 17:30:03 +00:00
unsertOpt := gocb . UpsertOptions {
Context : ctx ,
}
_ , err := p . db . Collection ( models . Collections . User ) . Upsert ( user . ID , user , & unsertOpt )
if err != nil {
return user , err
}
2022-10-09 18:54:14 +00:00
return user , nil
}
// DeleteUser to delete user information from database
func ( p * provider ) DeleteUser ( ctx context . Context , user models . User ) error {
2022-11-02 17:30:03 +00:00
removeOpt := gocb . RemoveOptions {
Context : ctx ,
}
2022-11-26 12:13:39 +00:00
2022-11-02 17:30:03 +00:00
_ , 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)
// sessionCollection := p.db.Collection(models.Collections.Session).Queue()
// _, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete())
// if err != nil {
// return err
// }
if err != nil {
return err
}
2022-10-09 18:54:14 +00:00
return nil
}
// ListUsers to get list of users from database
func ( p * provider ) ListUsers ( ctx context . Context , pagination model . Pagination ) ( * model . Users , error ) {
2022-11-02 17:30:03 +00:00
users := [ ] * model . User { }
// r := p.db.Collection(models.Collections.User).
paginationClone := pagination
inventoryScope := p . db . Scope ( "_default" )
userQuery := fmt . Sprintf ( "SELECT * FROM auth._default.%s ORDER BY id OFFSET %d LIMIT %d" , models . Collections . User , paginationClone . Offset , paginationClone . Limit )
queryResult , err := inventoryScope . Query ( userQuery , & gocb . QueryOptions { } )
if err != nil {
return nil , err
}
for queryResult . Next ( ) {
var user models . User
err := queryResult . Row ( & user )
if err != nil {
log . Fatal ( err )
}
users = append ( users , user . AsAPIUser ( ) )
}
if err := queryResult . Err ( ) ; err != nil {
return nil , err
}
return & model . Users {
Pagination : & paginationClone ,
Users : users ,
} , nil
2022-10-09 18:54:14 +00:00
}
// GetUserByEmail to get user information from database using email address
func ( p * provider ) GetUserByEmail ( ctx context . Context , email string ) ( models . User , error ) {
2022-11-26 12:13:39 +00:00
user := models . User { }
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 email = '%s' LIMIT 1" , models . Collections . User , email )
q , err := scope . Query ( query , & gocb . QueryOptions { } )
2022-11-02 17:30:03 +00:00
if err != nil {
return user , err
}
2022-11-26 12:13:39 +00:00
err = q . One ( & user )
2022-11-02 17:30:03 +00:00
if err != nil {
return user , err
}
2022-10-09 18:54:14 +00:00
return user , nil
}
// GetUserByID to get user information from database using user ID
func ( p * provider ) GetUserByID ( ctx context . Context , id string ) ( models . User , error ) {
2022-11-26 12:13:39 +00:00
user := models . User { }
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 { } )
2022-11-02 17:30:03 +00:00
if err != nil {
return user , err
}
2022-11-26 12:13:39 +00:00
err = q . One ( & user )
2022-11-02 17:30:03 +00:00
if err != nil {
return user , err
}
2022-11-26 12:13:39 +00:00
2022-10-09 18:54:14 +00:00
return user , nil
}
// UpdateUsers to update multiple users, with parameters of user IDs slice
// If ids set to nil / empty all the users will be updated
func ( p * provider ) UpdateUsers ( ctx context . Context , data map [ string ] interface { } , ids [ ] string ) error {
// set updated_at time for all users
data [ "updated_at" ] = time . Now ( ) . Unix ( )
2022-11-02 17:30:03 +00:00
inventoryScope := p . db . Scope ( "_default" )
updateFields := ""
for key , value := range data {
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 )
}
}
if ids != nil && len ( ids ) > 0 {
for _ , v := range ids {
2022-11-02 17:36:05 +00:00
userQuery := fmt . Sprintf ( "UPDATE auth._default.%s SET %s WHERE id = '%s'" , models . Collections . User , updateFields , v )
2022-11-26 12:13:39 +00:00
2022-11-02 17:30:03 +00:00
_ , err := inventoryScope . Query ( userQuery , & gocb . QueryOptions { } )
if err != nil {
return err
}
}
} else {
2022-11-02 17:36:05 +00:00
userQuery := fmt . Sprintf ( "UPDATE auth._default.%s SET %s WHERE id IS NOT NULL" , models . Collections . User , updateFields )
2022-11-02 17:30:03 +00:00
_ , err := inventoryScope . Query ( userQuery , & gocb . QueryOptions { } )
if err != nil {
return err
}
}
2022-10-09 18:54:14 +00:00
return nil
}