V3-1091 Extend Users table with IsActive functionality (#1170)
* V3-1091 Extend Users table with IsActive functionality * fixed review comments
This commit is contained in:
parent
c5047f2364
commit
19bc01c19a
@ -18,6 +18,8 @@ const (
|
||||
CreateUserMutation = "createUser"
|
||||
// UpdateAccountMutation is a mutation name for account updating
|
||||
UpdateAccountMutation = "updateAccount"
|
||||
// ActivateAccountMutation is a mutation name for account activation
|
||||
ActivateAccountMutation = "activateAccount"
|
||||
// DeleteAccountMutation is a mutation name for account deletion
|
||||
DeleteAccountMutation = "deleteAccount"
|
||||
// ChangePasswordMutation is a mutation name for password changing
|
||||
@ -97,6 +99,24 @@ func rootMutation(service *console.Service, types Types) *graphql.Object {
|
||||
return auth.User, nil
|
||||
},
|
||||
},
|
||||
ActivateAccountMutation: &graphql.Field{
|
||||
Type: graphql.String,
|
||||
Args: graphql.FieldConfigArgument{
|
||||
InputArg: &graphql.ArgumentConfig{
|
||||
Type: graphql.String,
|
||||
},
|
||||
},
|
||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||
activationToken, _ := p.Args[InputArg].(string)
|
||||
|
||||
token, err := service.ActivateAccount(p.Context, activationToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
},
|
||||
},
|
||||
ChangePasswordMutation: &graphql.Field{
|
||||
Type: types.User(),
|
||||
Args: graphql.FieldConfigArgument{
|
||||
|
@ -68,6 +68,41 @@ func TestGrapqhlMutation(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Run("Activate account mutation", func(t *testing.T) {
|
||||
activationToken, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
rootUser.ID,
|
||||
createUser.Email,
|
||||
rootUser.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
query := fmt.Sprintf("mutation {activateAccount(input:\"%s\")}", activationToken)
|
||||
|
||||
result := graphql.Do(graphql.Params{
|
||||
Schema: schema,
|
||||
Context: ctx,
|
||||
RequestString: query,
|
||||
RootObject: make(map[string]interface{}),
|
||||
})
|
||||
|
||||
for _, err := range result.Errors {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
if result.HasErrors() {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
data := result.Data.(map[string]interface{})
|
||||
token := data[consoleql.ActivateAccountMutation].(string)
|
||||
|
||||
assert.NotEqual(t, "", token)
|
||||
rootUser.Email = createUser.Email
|
||||
})
|
||||
|
||||
token, err := service.Token(ctx, createUser.Email, createUser.Password)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -122,7 +157,6 @@ func TestGrapqhlMutation(t *testing.T) {
|
||||
user, err := service.GetUser(authCtx, *uID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, newUser.Email, user.Email)
|
||||
assert.Equal(t, newUser.FirstName, user.FirstName)
|
||||
assert.Equal(t, newUser.LastName, user.LastName)
|
||||
})
|
||||
@ -336,11 +370,25 @@ func TestGrapqhlMutation(t *testing.T) {
|
||||
},
|
||||
Password: "123a123",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
|
||||
activationToken1, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
user1.ID,
|
||||
"u1@email.net",
|
||||
user1.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
_, err = service.ActivateAccount(ctx, activationToken1)
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
user1.Email = "u1@email.net"
|
||||
|
||||
user2, err := service.CreateUser(authCtx, console.CreateUser{
|
||||
UserInfo: console.UserInfo{
|
||||
FirstName: "User1",
|
||||
@ -348,10 +396,23 @@ func TestGrapqhlMutation(t *testing.T) {
|
||||
},
|
||||
Password: "123a123",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
activationToken2, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
user2.ID,
|
||||
"u2@email.net",
|
||||
user2.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
_, err = service.ActivateAccount(ctx, activationToken2)
|
||||
if err != nil {
|
||||
t.Fatal(err, project)
|
||||
}
|
||||
user2.Email = "u2@email.net"
|
||||
|
||||
t.Run("Add project members mutation", func(t *testing.T) {
|
||||
query := fmt.Sprintf(
|
||||
|
@ -66,6 +66,21 @@ func TestGraphqlQuery(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
activationToken, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
rootUser.ID,
|
||||
"mtest@email.com",
|
||||
rootUser.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = service.ActivateAccount(ctx, activationToken)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rootUser.Email = "mtest@email.com"
|
||||
|
||||
token, err := service.Token(ctx, createUser.Email, createUser.Password)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -176,10 +191,23 @@ func TestGraphqlQuery(t *testing.T) {
|
||||
},
|
||||
Password: "123a123",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
activationToken1, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
user1.ID,
|
||||
"muu1@email.com",
|
||||
user1.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = service.ActivateAccount(ctx, activationToken1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
user1.Email = "muu1@email.com"
|
||||
|
||||
user2, err := service.CreateUser(authCtx, console.CreateUser{
|
||||
UserInfo: console.UserInfo{
|
||||
@ -189,10 +217,23 @@ func TestGraphqlQuery(t *testing.T) {
|
||||
},
|
||||
Password: "123a123",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
activationToken2, err := service.GenerateActivationToken(
|
||||
ctx,
|
||||
user2.ID,
|
||||
"muu2@email.com",
|
||||
user2.CreatedAt.Add(time.Hour*24),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = service.ActivateAccount(ctx, activationToken2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
user2.Email = "muu2@email.com"
|
||||
|
||||
err = service.AddProjectMembers(authCtx, createdProject.ID, []string{
|
||||
user1.Email,
|
||||
|
@ -6,6 +6,7 @@ package console
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/skyrings/skyring-common/tools/uuid"
|
||||
@ -24,7 +25,8 @@ var (
|
||||
|
||||
const (
|
||||
// maxLimit specifies the limit for all paged queries
|
||||
maxLimit = 50
|
||||
maxLimit = 50
|
||||
tokenExpirationTime = 24 * time.Hour
|
||||
)
|
||||
|
||||
// Service is handling accounts related logic
|
||||
@ -52,28 +54,99 @@ func NewService(log *zap.Logger, signer Signer, store DB) (*Service, error) {
|
||||
return &Service{Signer: signer, store: store, log: log}, nil
|
||||
}
|
||||
|
||||
// CreateUser gets password hash value and creates new User
|
||||
// CreateUser gets password hash value and creates new inactive User
|
||||
func (s *Service) CreateUser(ctx context.Context, user CreateUser) (u *User, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
if err := user.IsValid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: store original email input in the db,
|
||||
// TODO: store original email input in the db,
|
||||
// add normalization
|
||||
email := normalizeEmail(user.Email)
|
||||
|
||||
u, err = s.store.Users().GetByEmail(ctx, email)
|
||||
if u != nil {
|
||||
return nil, errs.New(fmt.Sprintf("%s is already in use", email))
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.store.Users().Insert(ctx, &User{
|
||||
Email: email,
|
||||
u, err = s.store.Users().Insert(ctx, &User{
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
PasswordHash: hash,
|
||||
})
|
||||
|
||||
// TODO: send "finish registration email" when email service will be ready
|
||||
|
||||
//activationToken, err := s.GenerateActivationToken(ctx, u.ID, email, u.CreatedAt.Add(tokenExpirationTime))
|
||||
|
||||
return u, err
|
||||
}
|
||||
|
||||
// GenerateActivationToken - is a method for generating activation token
|
||||
func (s *Service) GenerateActivationToken(ctx context.Context, id uuid.UUID, email string, expirationDate time.Time) (activationToken string, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
claims := &consoleauth.Claims{
|
||||
ID: id,
|
||||
Email: email,
|
||||
Expiration: expirationDate,
|
||||
}
|
||||
|
||||
return s.createToken(claims)
|
||||
}
|
||||
|
||||
// ActivateAccount - is a method for activating user account after registration
|
||||
func (s *Service) ActivateAccount(ctx context.Context, activationToken string) (authToken string, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
token, err := consoleauth.FromBase64URLString(activationToken)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := s.authenticate(token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := s.store.Users().Get(ctx, claims.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
if user.Email != "" {
|
||||
return "", errs.New("account is already active")
|
||||
}
|
||||
|
||||
if now.After(user.CreatedAt.Add(tokenExpirationTime)) {
|
||||
return "", errs.New("activation token is expired")
|
||||
}
|
||||
|
||||
user.Email = normalizeEmail(claims.Email)
|
||||
err = s.store.Users().Update(ctx, user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
claims = &consoleauth.Claims{
|
||||
ID: user.ID,
|
||||
Expiration: time.Now().Add(tokenExpirationTime),
|
||||
}
|
||||
|
||||
authToken, err = s.createToken(claims)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return authToken, err
|
||||
}
|
||||
|
||||
// Token authenticates User by credentials and returns auth token
|
||||
@ -92,10 +165,9 @@ func (s *Service) Token(ctx context.Context, email, password string) (token stri
|
||||
return "", ErrUnauthorized.New("password is incorrect: %s", err.Error())
|
||||
}
|
||||
|
||||
// TODO: move expiration time to constants
|
||||
claims := consoleauth.Claims{
|
||||
ID: user.ID,
|
||||
Expiration: time.Now().Add(time.Minute * 15),
|
||||
Expiration: time.Now().Add(tokenExpirationTime),
|
||||
}
|
||||
|
||||
token, err = s.createToken(&claims)
|
||||
|
@ -13,26 +13,26 @@ import (
|
||||
|
||||
// Users exposes methods to manage User table in database.
|
||||
type Users interface {
|
||||
// Get is a method for querying user from the database by id.
|
||||
Get(ctx context.Context, id uuid.UUID) (*User, error)
|
||||
// GetByEmail is a method for querying user by email from the database.
|
||||
GetByEmail(ctx context.Context, email string) (*User, error)
|
||||
// Get is a method for querying user from the database by id
|
||||
Get(ctx context.Context, id uuid.UUID) (*User, error)
|
||||
// Insert is a method for inserting user into the database
|
||||
// Insert is a method for inserting user into the database.
|
||||
Insert(ctx context.Context, user *User) (*User, error)
|
||||
// Delete is a method for deleting user by Id from the database.
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
// Update is a method for updating user entity
|
||||
// Update is a method for updating user entity.
|
||||
Update(ctx context.Context, user *User) error
|
||||
}
|
||||
|
||||
// UserInfo holds User updatable data
|
||||
// UserInfo holds User updatable data.
|
||||
type UserInfo struct {
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// IsValid checks UserInfo validity and returns error describing whats wrong
|
||||
// IsValid checks UserInfo validity and returns error describing whats wrong.
|
||||
func (user *UserInfo) IsValid() error {
|
||||
var errs validationErrors
|
||||
|
||||
@ -48,13 +48,13 @@ func (user *UserInfo) IsValid() error {
|
||||
return errs.Combine()
|
||||
}
|
||||
|
||||
// CreateUser struct holds info for User creation
|
||||
// CreateUser struct holds info for User creation.
|
||||
type CreateUser struct {
|
||||
UserInfo
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// IsValid checks CreateUser validity and returns error describing whats wrong
|
||||
// IsValid checks CreateUser validity and returns error describing whats wrong.
|
||||
func (user *CreateUser) IsValid() error {
|
||||
var errs validationErrors
|
||||
|
||||
@ -64,12 +64,13 @@ func (user *CreateUser) IsValid() error {
|
||||
return errs.Combine()
|
||||
}
|
||||
|
||||
// User is a database object that describes User entity
|
||||
// User is a database object that describes User entity.
|
||||
type User struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
|
||||
Email string `json:"email"`
|
||||
PasswordHash []byte `json:"passwordHash"`
|
||||
|
||||
|
@ -245,13 +245,14 @@ model user (
|
||||
key id
|
||||
unique email
|
||||
|
||||
field id blob
|
||||
field first_name text ( updatable )
|
||||
field last_name text ( updatable )
|
||||
field email text ( updatable )
|
||||
field password_hash blob ( updatable )
|
||||
field id blob
|
||||
field first_name text ( updatable )
|
||||
field last_name text ( updatable )
|
||||
|
||||
field created_at timestamp ( autoinsert )
|
||||
field email text ( updatable, nullable )
|
||||
field password_hash blob ( updatable )
|
||||
|
||||
field created_at timestamp ( autoinsert )
|
||||
)
|
||||
read one (
|
||||
select user
|
||||
|
@ -364,7 +364,7 @@ CREATE TABLE users (
|
||||
id bytea NOT NULL,
|
||||
first_name text NOT NULL,
|
||||
last_name text NOT NULL,
|
||||
email text NOT NULL,
|
||||
email text,
|
||||
password_hash bytea NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
PRIMARY KEY ( id ),
|
||||
@ -546,7 +546,7 @@ CREATE TABLE users (
|
||||
id BLOB NOT NULL,
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
email TEXT,
|
||||
password_hash BLOB NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id ),
|
||||
@ -1917,13 +1917,17 @@ type User struct {
|
||||
Id []byte
|
||||
FirstName string
|
||||
LastName string
|
||||
Email string
|
||||
Email *string
|
||||
PasswordHash []byte
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (User) _Table() string { return "users" }
|
||||
|
||||
type User_Create_Fields struct {
|
||||
Email User_Email_Field
|
||||
}
|
||||
|
||||
type User_Update_Fields struct {
|
||||
FirstName User_FirstName_Field
|
||||
LastName User_LastName_Field
|
||||
@ -1991,13 +1995,26 @@ func (User_LastName_Field) _Column() string { return "last_name" }
|
||||
type User_Email_Field struct {
|
||||
_set bool
|
||||
_null bool
|
||||
_value string
|
||||
_value *string
|
||||
}
|
||||
|
||||
func User_Email(v string) User_Email_Field {
|
||||
return User_Email_Field{_set: true, _value: v}
|
||||
return User_Email_Field{_set: true, _value: &v}
|
||||
}
|
||||
|
||||
func User_Email_Raw(v *string) User_Email_Field {
|
||||
if v == nil {
|
||||
return User_Email_Null()
|
||||
}
|
||||
return User_Email(*v)
|
||||
}
|
||||
|
||||
func User_Email_Null() User_Email_Field {
|
||||
return User_Email_Field{_set: true, _null: true}
|
||||
}
|
||||
|
||||
func (f User_Email_Field) isnull() bool { return !f._set || f._null || f._value == nil }
|
||||
|
||||
func (f User_Email_Field) value() interface{} {
|
||||
if !f._set || f._null {
|
||||
return nil
|
||||
@ -2729,15 +2746,15 @@ func (obj *postgresImpl) Create_User(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
user_last_name User_LastName_Field,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
user_password_hash User_PasswordHash_Field,
|
||||
optional User_Create_Fields) (
|
||||
user *User, err error) {
|
||||
|
||||
__now := obj.db.Hooks.Now().UTC()
|
||||
__id_val := user_id.value()
|
||||
__first_name_val := user_first_name.value()
|
||||
__last_name_val := user_last_name.value()
|
||||
__email_val := user_email.value()
|
||||
__email_val := optional.Email.value()
|
||||
__password_hash_val := user_password_hash.value()
|
||||
__created_at_val := __now
|
||||
|
||||
@ -3401,10 +3418,17 @@ func (obj *postgresImpl) Get_User_By_Email(ctx context.Context,
|
||||
user_email User_Email_Field) (
|
||||
user *User, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.created_at FROM users WHERE users.email = ?")
|
||||
var __cond_0 = &__sqlbundle_Condition{Left: "users.email", Equal: true, Right: "?", Null: true}
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.created_at FROM users WHERE "), __cond_0}}
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values, user_email.value())
|
||||
__values = append(__values)
|
||||
|
||||
if !user_email.isnull() {
|
||||
__cond_0.Null = false
|
||||
__values = append(__values, user_email.value())
|
||||
}
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
@ -4876,15 +4900,15 @@ func (obj *sqlite3Impl) Create_User(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
user_last_name User_LastName_Field,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
user_password_hash User_PasswordHash_Field,
|
||||
optional User_Create_Fields) (
|
||||
user *User, err error) {
|
||||
|
||||
__now := obj.db.Hooks.Now().UTC()
|
||||
__id_val := user_id.value()
|
||||
__first_name_val := user_first_name.value()
|
||||
__last_name_val := user_last_name.value()
|
||||
__email_val := user_email.value()
|
||||
__email_val := optional.Email.value()
|
||||
__password_hash_val := user_password_hash.value()
|
||||
__created_at_val := __now
|
||||
|
||||
@ -5563,10 +5587,17 @@ func (obj *sqlite3Impl) Get_User_By_Email(ctx context.Context,
|
||||
user_email User_Email_Field) (
|
||||
user *User, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.created_at FROM users WHERE users.email = ?")
|
||||
var __cond_0 = &__sqlbundle_Condition{Left: "users.email", Equal: true, Right: "?", Null: true}
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.created_at FROM users WHERE "), __cond_0}}
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values, user_email.value())
|
||||
__values = append(__values)
|
||||
|
||||
if !user_email.isnull() {
|
||||
__cond_0.Null = false
|
||||
__values = append(__values, user_email.value())
|
||||
}
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
@ -7419,14 +7450,14 @@ func (rx *Rx) Create_User(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
user_last_name User_LastName_Field,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
user_password_hash User_PasswordHash_Field,
|
||||
optional User_Create_Fields) (
|
||||
user *User, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Create_User(ctx, user_id, user_first_name, user_last_name, user_email, user_password_hash)
|
||||
return tx.Create_User(ctx, user_id, user_first_name, user_last_name, user_password_hash, optional)
|
||||
|
||||
}
|
||||
|
||||
@ -7975,8 +8006,8 @@ type Methods interface {
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
user_last_name User_LastName_Field,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
user_password_hash User_PasswordHash_Field,
|
||||
optional User_Create_Fields) (
|
||||
user *User, err error)
|
||||
|
||||
Delete_AccountingRaw_By_Id(ctx context.Context,
|
||||
|
@ -91,7 +91,7 @@ CREATE TABLE users (
|
||||
id bytea NOT NULL,
|
||||
first_name text NOT NULL,
|
||||
last_name text NOT NULL,
|
||||
email text NOT NULL,
|
||||
email text,
|
||||
password_hash bytea NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
PRIMARY KEY ( id ),
|
||||
|
@ -91,7 +91,7 @@ CREATE TABLE users (
|
||||
id BLOB NOT NULL,
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
email TEXT,
|
||||
password_hash BLOB NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id ),
|
||||
|
@ -377,7 +377,7 @@ func (m *lockedUsers) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
return m.db.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Get is a method for querying user from the database by id
|
||||
// Get is a method for querying user from the database by id.
|
||||
func (m *lockedUsers) Get(ctx context.Context, id uuid.UUID) (*console.User, error) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
@ -391,14 +391,14 @@ func (m *lockedUsers) GetByEmail(ctx context.Context, email string) (*console.Us
|
||||
return m.db.GetByEmail(ctx, email)
|
||||
}
|
||||
|
||||
// Insert is a method for inserting user into the database
|
||||
// Insert is a method for inserting user into the database.
|
||||
func (m *lockedUsers) Insert(ctx context.Context, user *console.User) (*console.User, error) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
return m.db.Insert(ctx, user)
|
||||
}
|
||||
|
||||
// Update is a method for updating user entity
|
||||
// Update is a method for updating user entity.
|
||||
func (m *lockedUsers) Update(ctx context.Context, user *console.User) error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
@ -46,12 +46,22 @@ func (users *users) Insert(ctx context.Context, user *console.User) (*console.Us
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var email dbx.User_Email_Field
|
||||
if user.Email != "" {
|
||||
email = dbx.User_Email(user.Email)
|
||||
} else {
|
||||
email = dbx.User_Email_Null()
|
||||
}
|
||||
|
||||
createdUser, err := users.db.Create_User(ctx,
|
||||
dbx.User_Id(userID[:]),
|
||||
dbx.User_FirstName(user.FirstName),
|
||||
dbx.User_LastName(user.LastName),
|
||||
dbx.User_Email(user.Email),
|
||||
dbx.User_PasswordHash(user.PasswordHash))
|
||||
dbx.User_PasswordHash(user.PasswordHash),
|
||||
dbx.User_Create_Fields{
|
||||
Email: email,
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -105,12 +115,17 @@ func userFromDBX(user *dbx.User) (*console.User, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &console.User{
|
||||
result := console.User{
|
||||
ID: id,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
Email: user.Email,
|
||||
PasswordHash: user.PasswordHash,
|
||||
CreatedAt: user.CreatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if user.Email != nil {
|
||||
result.Email = *user.Email
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ func TestUserFromDbx(t *testing.T) {
|
||||
Id: []byte("qweqwe"),
|
||||
FirstName: "FirstName",
|
||||
LastName: "LastName",
|
||||
Email: "email@ukr.net",
|
||||
Email: nil,
|
||||
PasswordHash: []byte("ihqerfgnu238723huagsd"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user