Skip to content
This repository was archived by the owner on Jul 20, 2023. It is now read-only.

Commit 3063de2

Browse files
committed
stop exposing password to the public
1 parent c6296d4 commit 3063de2

File tree

8 files changed

+84
-57
lines changed

8 files changed

+84
-57
lines changed

authentication-service/app/http/controllers/controllers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func LoginHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFunc {
6363

6464
// Retrieve the user from the database
6565
databaseUser, _ := db.GetUserByUsername(connection, login.Username)
66+
databaseUser.Password = "" // trick to prevent password from leaking to client
6667

6768
// Send the token and user back
6869
data := &models.Token{

profile-service/app/http/controllers/controllers.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
// CreateUserHandler creates a new user in the database. Password is saved as a hash.
2828
func CreateUserHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFunc {
2929
return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
30-
user := &models.User{}
30+
user := &models.UserCreate{}
3131
err := util.RequestToJSON(r, user)
3232
if err != nil {
3333
util.SendBadRequest(w, errors.New("Bad json"))
@@ -64,9 +64,9 @@ func CreateUserHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFun
6464
}
6565

6666
type Token struct {
67-
Token string `json:"token"`
68-
ExpiresOn string `json:"expires_on"`
69-
User models.User `json:"user"`
67+
Token string `json:"token"`
68+
ExpiresOn string `json:"expires_on"`
69+
User models.UserResponse `json:"user"`
7070
}
7171

7272
util.SendOK(w, &Token{
@@ -98,7 +98,7 @@ func DeleteUserHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFun
9898
return
9999
}
100100

101-
user := &models.User{}
101+
user := &models.UserResponse{}
102102
err := util.RequestToJSON(r, user)
103103
if err != nil {
104104
util.SendBadRequest(w, errors.New("Bad json"))
@@ -143,7 +143,7 @@ func UpdateUserHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFun
143143
return
144144
}
145145

146-
user := &models.User{}
146+
user := &models.UserResponse{}
147147
err := util.RequestToJSON(r, user)
148148
if err != nil {
149149
util.SendBadRequest(w, errors.New("bad json"))
@@ -168,15 +168,11 @@ func UpdateUserHandler(connection *sql.DB, cnf config.Config) negroni.HandlerFun
168168
}
169169

170170
if err := user.Validate(); err == nil {
171-
if err := user.ValidatePassword(); err == nil {
172171

173-
db.UpdateUser(connection, user)
172+
db.UpdateUser(connection, user)
174173

175-
util.SendOK(w, user)
174+
util.SendOK(w, user)
176175

177-
} else {
178-
util.SendBadRequest(w, err)
179-
}
180176
} else {
181177
util.SendBadRequest(w, err)
182178
}

profile-service/app/http/controllers/controllers_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestCreateUser(t *testing.T) {
3535
cnf := config.Config{}
3636
cnf.SecretKey = "ABCDEF"
3737

38-
user := &models.User{}
38+
user := &models.UserCreate{}
3939
user.ID = 1
4040
user.Email = "username@example.com"
4141
user.Password = "password"
@@ -83,9 +83,9 @@ func TestCreateUser(t *testing.T) {
8383

8484
// Make sure response is alright
8585
type Token struct {
86-
Token string `json:"token"`
87-
ExpiresOn string `json:"expires_on"`
88-
User models.User `json:"user"`
86+
Token string `json:"token"`
87+
ExpiresOn string `json:"expires_on"`
88+
User models.UserResponse `json:"user"`
8989
}
9090

9191
response := &Token{}
@@ -141,7 +141,7 @@ func TestCreateUserWithoutUsername(t *testing.T) {
141141
cnf := config.Config{}
142142
cnf.SecretKey = "ABCDEF"
143143

144-
user := &models.User{}
144+
user := &models.UserCreate{}
145145

146146
json, _ := json.Marshal(user)
147147

@@ -173,7 +173,7 @@ func TestCreateUserWithoutPassword(t *testing.T) {
173173
cnf := config.Config{}
174174
cnf.SecretKey = "ABCDEF"
175175

176-
user := &models.User{}
176+
user := &models.UserCreate{}
177177
user.Email = "test@example.com"
178178
user.Username = "username"
179179

@@ -207,7 +207,7 @@ func TestCreateUserWithoutEmail(t *testing.T) {
207207
cnf := config.Config{}
208208
cnf.SecretKey = "ABCDEF"
209209

210-
user := &models.User{}
210+
user := &models.UserCreate{}
211211
user.Username = "username"
212212

213213
json, _ := json.Marshal(user)
@@ -250,7 +250,7 @@ func TestDeleteUser(t *testing.T) {
250250
cnf := config.Config{}
251251
cnf.SecretKey = "ABCDEF"
252252

253-
user := &models.User{}
253+
user := &models.UserCreate{}
254254
user.ID = 1
255255
user.Email = "username@example.com"
256256
user.Password = "password"
@@ -532,8 +532,8 @@ func TestTryDeleteOtherUser(t *testing.T) {
532532
}
533533
}
534534

535-
func getTestUser() *models.User {
536-
user := &models.User{}
535+
func getTestUser() *models.UserCreate {
536+
user := &models.UserCreate{}
537537
user.ID = 1
538538
user.Email = "username@example.com"
539539
user.Password = "password"
@@ -543,7 +543,7 @@ func getTestUser() *models.User {
543543
return user
544544
}
545545

546-
func getTokenString(cnf config.Config, user *models.User, t *testing.T) string {
546+
func getTokenString(cnf config.Config, user *models.UserCreate, t *testing.T) string {
547547
expiration := time.Now().Add(time.Hour * 24 * 31).Unix()
548548
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
549549
"sub": user.ID,

profile-service/app/http/routes/routes_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ func doRequest(db *sql.DB, cnf config.Config, method string, url string, body *b
263263
return res
264264
}
265265

266-
func getTestUser() *models.User {
267-
user := &models.User{}
266+
func getTestUser() *models.UserCreate {
267+
user := &models.UserCreate{}
268268
user.ID = 1
269269
user.Email = "username@example.com"
270270
user.Password = "password"
@@ -274,7 +274,7 @@ func getTestUser() *models.User {
274274
return user
275275
}
276276

277-
func getTokenString(cnf config.Config, user *models.User, t *testing.T) string {
277+
func getTokenString(cnf config.Config, user *models.UserCreate, t *testing.T) string {
278278
expiration := time.Now().Add(time.Hour * 24 * 31).Unix()
279279
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
280280
"sub": user.ID,

profile-service/app/models/user.go

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,49 @@ import (
99
// lower_case private, upper_case public
1010
// Uppercase variable is mandatory for exposing to json
1111

12-
// User model
13-
type User struct {
12+
// UserResponse model
13+
type UserResponse struct {
1414
ID int `json:"id"`
1515
Username string `json:"username"`
1616
Email string `json:"email"`
1717
CreatedAt time.Time `json:"createdAt"`
18-
Password string `json:"password,omitempty"`
18+
}
19+
20+
// UserCreate model
21+
type UserCreate struct {
22+
ID int `json:"id"`
23+
Username string `json:"username"`
24+
Email string `json:"email"`
25+
CreatedAt time.Time `json:"createdAt"`
26+
Password string `json:"password"`
1927
Hash string
2028
}
2129

2230
// GetUsername returns the username of an user
23-
func (u *User) GetUsername() string {
31+
func (u *UserCreate) GetUsername() string {
2432
return u.Username
2533
}
2634

2735
// Print method of User
28-
func (u *User) Print() string {
36+
func (u *UserCreate) Print() string {
2937
return fmt.Sprintf("%v (%v) - %v", u.Username, u.ID, u.CreatedAt)
3038
}
3139

3240
// Validate returns an error when the username or email is to short.
33-
func (u *User) Validate() error {
41+
func (u *UserCreate) Validate() error {
42+
if len(u.Username) < 1 {
43+
return ErrUsernameTooShort
44+
}
45+
46+
if len(u.Email) < 1 {
47+
return ErrEmailTooShort
48+
}
49+
50+
return nil
51+
}
52+
53+
// Validate returns an error when the username or email is to short.
54+
func (u *UserResponse) Validate() error {
3455
if len(u.Username) < 1 {
3556
return ErrUsernameTooShort
3657
}
@@ -43,7 +64,7 @@ func (u *User) Validate() error {
4364
}
4465

4566
// ValidatePassword returns an error if the password is to small.
46-
func (u *User) ValidatePassword() error {
67+
func (u *UserCreate) ValidatePassword() error {
4768
if len(u.Password) < 1 {
4869
return ErrPasswordTooShort
4970
}

profile-service/app/models/user_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"github.com/bstaijen/mariadb-for-microservices/profile-service/app/models"
99
)
1010

11-
func getSimpleUser() models.User {
12-
user := models.User{}
11+
func getSimpleUser() models.UserCreate {
12+
user := models.UserCreate{}
1313
user.ID = 1
1414
user.Username = "user"
1515
user.Email = "user@example.com"
@@ -18,7 +18,7 @@ func getSimpleUser() models.User {
1818
}
1919

2020
func TestGetUsername(t *testing.T) {
21-
user := models.User{}
21+
user := models.UserCreate{}
2222
user.Username = "user"
2323

2424
expected := "user"
@@ -58,7 +58,7 @@ func TestValidate(t *testing.T) {
5858
}
5959

6060
func TestTooShortUsername(t *testing.T) {
61-
user := models.User{}
61+
user := models.UserCreate{}
6262
user.Username = ""
6363
user.Password = "pass"
6464
err := user.Validate()
@@ -73,7 +73,7 @@ func TestTooShortUsername(t *testing.T) {
7373
}
7474

7575
func TestTooShortEMail(t *testing.T) {
76-
user := models.User{}
76+
user := models.UserCreate{}
7777
user.Username = "user"
7878
user.Email = ""
7979
err := user.Validate()
@@ -88,7 +88,7 @@ func TestTooShortEMail(t *testing.T) {
8888
}
8989

9090
func TestTooShortPassword(t *testing.T) {
91-
user := models.User{}
91+
user := models.UserCreate{}
9292
user.Username = "user"
9393
user.Password = ""
9494
err := user.ValidatePassword()

profile-service/database/db.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ func CloseConnection(db *sql.DB) {
4646
}
4747

4848
// GetUserByID returns an models.User identified by it's ID or a ErrUserNotFound error when the user cannot be found.
49-
func GetUserByID(db *sql.DB, ID int) (models.User, error) {
50-
rows, err := db.Query("SELECT id, username, createdAt, password, email FROM users WHERE id = ?", ID)
49+
func GetUserByID(db *sql.DB, ID int) (models.UserResponse, error) {
50+
rows, err := db.Query("SELECT id, username, createdAt, email FROM users WHERE id = ?", ID)
5151
if err != nil {
52-
return models.User{}, err
52+
return models.UserResponse{}, err
5353
}
5454

5555
if rows.Next() {
@@ -60,16 +60,16 @@ func GetUserByID(db *sql.DB, ID int) (models.User, error) {
6060
var email string
6161
err = rows.Scan(&id, &username, &createdAt, &password, &email)
6262
if err != nil {
63-
return models.User{}, err
63+
return models.UserResponse{}, err
6464
}
6565

66-
return models.User{ID: id, Username: username, CreatedAt: createdAt, Password: password, Email: email}, nil
66+
return models.UserResponse{ID: id, Username: username, CreatedAt: createdAt, Email: email}, nil
6767
}
68-
return models.User{}, ErrUserNotFound
68+
return models.UserResponse{}, ErrUserNotFound
6969
}
7070

7171
// CreateUser create an user in the database and returns the ID of the user being inserted. This method returns a ErrUsernameIsNotUnique or ErrEmailIsNotUnique when the username or email of an user is not unique.
72-
func CreateUser(db *sql.DB, user *models.User) (int, error) {
72+
func CreateUser(db *sql.DB, user *models.UserCreate) (int, error) {
7373
// check unique username
7474
query := "SELECT * FROM users WHERE username = ?"
7575
rows, err := db.Query(query, user.Username)
@@ -112,7 +112,7 @@ func CreateUser(db *sql.DB, user *models.User) (int, error) {
112112
}
113113

114114
// UpdateUser updates the username and email of an user. (note: this method does not check if user is authorized to update this row)
115-
func UpdateUser(db *sql.DB, user *models.User) (int, error) {
115+
func UpdateUser(db *sql.DB, user *models.UserResponse) (int, error) {
116116
_, err := db.Exec("UPDATE users SET username = ?, email = ? WHERE id = ?", user.Username, user.Email, user.ID)
117117
if err != nil {
118118
log.Errorf("Error inserting")
@@ -123,7 +123,7 @@ func UpdateUser(db *sql.DB, user *models.User) (int, error) {
123123
}
124124

125125
// DeleteUser deletes an user from the database. Method does not check if the caller is authorized to perform this action. Method returns the number of rows affected by query. (should be 1)
126-
func DeleteUser(db *sql.DB, user *models.User) (int, error) {
126+
func DeleteUser(db *sql.DB, user *models.UserResponse) (int, error) {
127127
if user.ID > 0 {
128128
res, err := db.Exec("DELETE from users WHERE id = ?", user.ID)
129129
if err != nil {
@@ -145,13 +145,13 @@ func DeleteUser(db *sql.DB, user *models.User) (int, error) {
145145
}
146146

147147
// GetUsers returns a list of all database-users. Note: Consider implementing a paging function because this method returns EVERY users at once.
148-
func GetUsers(db *sql.DB) ([]models.User, error) {
148+
func GetUsers(db *sql.DB) ([]models.UserResponse, error) {
149149

150150
rows, err := db.Query("SELECT id, username, email, createdAt FROM users")
151151
if err != nil {
152152
return nil, err
153153
}
154-
persons := make([]models.User, 0)
154+
persons := make([]models.UserResponse, 0)
155155

156156
for rows.Next() {
157157
var id int
@@ -162,7 +162,7 @@ func GetUsers(db *sql.DB) ([]models.User, error) {
162162
if err != nil {
163163
return nil, err
164164
}
165-
persons = append(persons, models.User{ID: id, Username: username, CreatedAt: createdAt})
165+
persons = append(persons, models.UserResponse{ID: id, Username: username, CreatedAt: createdAt})
166166
}
167167
return persons, nil
168168
}

0 commit comments

Comments
 (0)