]>
Commit | Line | Data |
---|---|---|
85545aba | 1 | package api |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | "time" | |
6 | ||
7 | "github.com/dchest/passwordreset" | |
8 | "immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/db" | |
9 | ) | |
10 | ||
11 | var PASSWORD_RESET_SECRET []byte | |
12 | ||
13 | type PasswordResetQuery struct { | |
14 | In struct { | |
15 | Email string | |
16 | } | |
17 | } | |
18 | ||
19 | func (q PasswordResetQuery) ValidateParams() *Error { | |
20 | if q.In.Email == "" { | |
21 | return &Error{InvalidEmail, "invalid email", fmt.Errorf("invalid email")} | |
22 | } | |
23 | ||
24 | return nil | |
25 | } | |
26 | ||
27 | func (q PasswordResetQuery) Run() (interface{}, *Error) { | |
28 | user, err := db.GetUserByEmail(q.In.Email) | |
29 | if err != nil { | |
30 | return nil, NewInternalError(err) | |
31 | } | |
32 | ||
33 | if user == nil { | |
34 | return nil, &Error{NotFound, "account not found", fmt.Errorf("'%v' is not registered", q.In.Email)} | |
35 | } | |
36 | ||
37 | token := passwordreset.NewToken(q.In.Email, time.Hour*24*1, []byte(user.PasswordHash), PASSWORD_RESET_SECRET) | |
38 | if CONFIG.FreeSMSUser != "" { | |
39 | err := SendSMS(CONFIG.FreeSMSUser, CONFIG.FreeSMSPass, fmt.Sprintf("'%v' request a password reset. Token '/change-password?token=%v'", q.In.Email, token)) | |
40 | if err != nil { | |
41 | return nil, NewInternalError(err) | |
42 | } | |
43 | } | |
44 | ||
45 | return "OK", nil | |
46 | } | |
47 | ||
48 | type ChangePasswordQuery struct { | |
49 | In struct { | |
50 | Token string | |
51 | Password string | |
52 | } | |
53 | } | |
54 | ||
55 | func (q ChangePasswordQuery) ValidateParams() *Error { | |
56 | if q.In.Password == "" { | |
57 | return &Error{InvalidPassword, "invalid password", fmt.Errorf("invalid password")} | |
58 | } | |
59 | ||
60 | if q.In.Token == "" { | |
61 | return &Error{BadRequest, "invalid token", fmt.Errorf("invalid token")} | |
62 | } | |
63 | ||
64 | return nil | |
65 | } | |
66 | ||
67 | func (q ChangePasswordQuery) Run() (interface{}, *Error) { | |
68 | var user *db.User | |
69 | ||
70 | email, err := passwordreset.VerifyToken(q.In.Token, func(email string) ([]byte, error) { | |
71 | var err error | |
72 | user, err = db.GetUserByEmail(email) | |
73 | if err != nil { | |
74 | return nil, err | |
75 | } | |
76 | ||
77 | if user == nil { | |
78 | return nil, fmt.Errorf("'%v' is not registered", email) | |
79 | } | |
80 | ||
81 | return []byte(user.PasswordHash), nil | |
82 | ||
83 | }, PASSWORD_RESET_SECRET) | |
84 | ||
85 | if err != nil && (err == passwordreset.ErrExpiredToken) { | |
86 | return nil, &Error{BadRequest, "expired token", fmt.Errorf("expired token")} | |
87 | } else if err != nil && (err == passwordreset.ErrMalformedToken || err == passwordreset.ErrWrongSignature) { | |
88 | return nil, &Error{BadRequest, "wrong token", fmt.Errorf("wrong token")} | |
89 | } else if err != nil { | |
90 | return nil, NewInternalError(err) | |
91 | } | |
92 | ||
93 | if user == nil { | |
94 | return nil, &Error{BadRequest, "bad request", fmt.Errorf("no user found for email '%v'", email)} | |
95 | } | |
96 | ||
97 | err = db.SetPassword(user, q.In.Password) | |
98 | if err != nil { | |
99 | return nil, NewInternalError(err) | |
100 | } | |
101 | ||
102 | return "OK", nil | |
103 | } |