/
user.go
91 lines (80 loc) · 2.56 KB
/
user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package storage
import (
"time"
"github.com/google/uuid"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
_ "github.com/lib/pq"
_ "gorm.io/driver/postgres"
_ "gorm.io/gorm"
"github.com/mnadev/limestone/auth"
pb "github.com/mnadev/limestone/proto"
)
type gender string
const (
MALE gender = "MALE"
FEMALE gender = "FEMALE"
)
func (g gender) String() string {
if g == MALE {
return "MALE"
}
return "FEMALE"
}
// User represents a registered user with email/password authentication
// TODO: make username and email unique. It currently causes postgres to throw a unique constraint violation.
type User struct {
ID uuid.UUID `gorm:"primaryKey;type:char(36)"`
Email string `gorm:"type:varchar(320)"`
Username string `gorm:"type:varchar(255)"`
HashedPassword string `gorm:"type:varchar(60)"`
IsVerified bool `gorm:"default:false"`
FirstName string `gorm:"type:varchar(255)"`
LastName string `gorm:"type:varchar(255)"`
PhoneNumber string `gorm:"type:varchar(255)"`
Gender gender `gorm:"type:varchar(6);check:gender IN ('MALE', 'FEMALE')"`
CreatedAt time.Time
UpdatedAt time.Time
}
// NewUser creates a new User struct given the User proto and plaintext password
func NewUser(up *pb.User, pwd string) (*User, error) {
if len(pwd) < 8 {
return nil, status.Error(codes.InvalidArgument, "password must be at least 8 characters long")
}
hpwd, err := auth.HashPassword(pwd)
if err != nil {
// TODO: log error that occurred
return nil, status.Error(codes.Internal, "an internal error occurred")
}
// uuid generation
uuid, err := uuid.NewUUID()
if err != nil {
return nil, err
}
return &User{
ID: uuid,
Email: up.GetEmail(),
Username: up.GetUsername(),
HashedPassword: hpwd,
IsVerified: up.GetIsEmailVerified(),
FirstName: up.GetFirstName(),
LastName: up.GetLastName(),
PhoneNumber: up.GetPhoneNumber(),
Gender: gender(up.GetGender().String()),
}, status.Error(codes.OK, codes.OK.String())
}
func (u *User) ToProto() *pb.User {
return &pb.User{
UserId: u.ID.String(),
Email: u.Email,
Username: u.Username,
Gender: pb.User_Gender(pb.User_Gender_value[u.Gender.String()]),
IsEmailVerified: u.IsVerified,
FirstName: u.FirstName,
LastName: u.LastName,
PhoneNumber: u.PhoneNumber,
CreateTime: timestamppb.New(u.CreatedAt),
UpdateTime: timestamppb.New(u.UpdatedAt),
}
}