Skip to content

Commit 08d257e

Browse files
committed
password encrypting
1 parent 43c3bde commit 08d257e

File tree

8 files changed

+120
-46
lines changed

8 files changed

+120
-46
lines changed

controllers/book.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (c BookController) GetBook() http.HandlerFunc {
3232
id, err := strconv.ParseInt(params["id"], 10, 0)
3333

3434
if err != nil {
35-
utils.SendError(w, http.StatusNotFound, models.Error{Message: "id must be int convertible"})
35+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "id must be int convertible"})
3636
return
3737
}
3838

@@ -50,15 +50,27 @@ func (c BookController) GetBook() http.HandlerFunc {
5050

5151
func (c BookController) AddBook() http.HandlerFunc {
5252
return func(w http.ResponseWriter, r *http.Request) {
53-
w.Header().Set("Content-Type", "application/json")
5453
var newBookMap map[string]string
5554
err := json.NewDecoder(r.Body).Decode(&newBookMap)
5655

5756
if err != nil {
58-
utils.SendError(w, http.StatusNotFound, models.Error{Message: "all values must be strings"})
57+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "all values must be strings"})
5958
return
6059
}
6160

61+
if newBookMap["title"] == "" || len(newBookMap["title"]) < 3 {
62+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "title is mandatory"})
63+
}
64+
65+
if newBookMap["author"] == "" || len(newBookMap["author"]) < 3 {
66+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "author is mandatory"})
67+
}
68+
69+
if newBookMap["utils"] == "" || len(newBookMap["year"]) < 4 {
70+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "year is mandatory"})
71+
72+
}
73+
6274
newBookYear, _ := strconv.ParseInt(newBookMap["year"], 10, 0)
6375
newBook := models.Book{
6476
Title: newBookMap["title"],
@@ -79,7 +91,6 @@ func (c BookController) AddBook() http.HandlerFunc {
7991

8092
func (c BookController) UpdateBook() http.HandlerFunc {
8193
return func(w http.ResponseWriter, r *http.Request) {
82-
w.Header().Set("Content-Type", "application/json")
8394
var updateData map[string]string
8495
err := json.NewDecoder(r.Body).Decode(&updateData)
8596

@@ -89,26 +100,38 @@ func (c BookController) UpdateBook() http.HandlerFunc {
89100
}
90101

91102
bookId, errr := strconv.ParseInt(mux.Vars(r)["id"], 10, 0)
92-
bookToUpdate := models.Book{ID: bookId}
93103

94104
if errr != nil {
95105
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "impossible to parse id"})
96106
}
97107

98-
if updateData["title"] != "" {
108+
bookToUpdate := models.Book{ID: bookId}
109+
110+
if len(updateData["title"]) > 3 {
99111
bookToUpdate.Title = updateData["title"]
112+
} else {
113+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "title minimum length is 4"})
114+
return
100115
}
101116

102-
if updateData["author"] != "" {
117+
if len(updateData["author"]) > 3 {
103118
bookToUpdate.Author = updateData["author"]
119+
} else {
120+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "author minimum length is 4"})
121+
return
104122
}
105123

106-
if updateData["year"] != "" {
124+
if len(updateData["year"]) > 4 {
107125
newBookYear, err := strconv.ParseInt(updateData["year"], 10, 0)
126+
108127
if err != nil {
109128
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "impossible to parse year"})
110129
}
130+
111131
bookToUpdate.Year = newBookYear
132+
} else {
133+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "year minimum length is 4"})
134+
return
112135
}
113136

114137
booksDao := daos.BookDAO{}
@@ -128,7 +151,7 @@ func (c BookController) RemoveBook() http.HandlerFunc {
128151
idToRemove, err := strconv.ParseInt(mux.Vars(r)["id"], 10, 0)
129152

130153
if err != nil {
131-
utils.SendError(w, 400, models.Error{Message: "impossible to parse id"})
154+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "impossible to parse id"})
132155
return
133156
}
134157

controllers/user.go

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,49 @@ type ResponseOutput struct {
1717

1818
func (u UserController) SignupUser() http.HandlerFunc {
1919
return func(w http.ResponseWriter, r *http.Request) {
20-
User := models.User{}
21-
json.NewDecoder(r.Body).Decode(&User)
20+
user := models.User{}
21+
json.NewDecoder(r.Body).Decode(&user)
2222

23-
if len(User.Name) < 3 {
23+
if len(user.Name) < 3 {
2424
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Name should be at least 3 characters long!"})
2525
return
2626
}
2727

28-
if len(User.Username) < 3 {
28+
if len(user.Username) < 3 {
2929
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Username should be at least 3 characters long!"})
3030
return
3131
}
3232

33-
if len(User.Email) < 3 {
33+
if len(user.Email) < 3 {
3434
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Email should be at least 3 characters long!"})
3535
return
3636
}
3737

38-
if len(User.Password) < 3 {
38+
if len(user.Password) < 3 {
3939
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Password should be at least 3 characters long!"})
4040
return
4141
}
4242

43-
userDao := daos.UsersDao{}
43+
hashedPass, err := utils.HashPassword(user.Password)
44+
45+
if err != nil {
46+
utils.SendError(w, http.StatusInternalServerError, models.Error{Message: "Couldn't hash password."})
47+
return
48+
}
4449

45-
_, err := userDao.CreateUser(User)
50+
user.Password = hashedPass
51+
userDao := daos.UsersDao{}
52+
_, err = userDao.CreateUser(user)
4653

4754
if err != nil {
48-
utils.SendError(w, http.StatusInternalServerError, models.Error{Message: "Failed To Add new User in database!"})
55+
utils.SendError(w, http.StatusInternalServerError, models.Error{Message: "Failed To Add new user in database!"})
4956
return
5057
}
5158

5259
payload := utils.Payload{
53-
Username: User.Username,
54-
Email: User.Email,
55-
Id: User.ID,
60+
Username: user.Username,
61+
Email: user.Email,
62+
Id: user.ID,
5663
}
5764

5865
token, err := utils.GenerateJwtToken(payload)
@@ -63,7 +70,7 @@ func (u UserController) SignupUser() http.HandlerFunc {
6370

6471
utils.SendSuccess(w, ResponseOutput{
6572
Token: token,
66-
User: User,
73+
User: user,
6774
})
6875
}
6976
}
@@ -82,15 +89,19 @@ func (u UserController) LoginUser() http.HandlerFunc {
8289
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Invalid Password!"})
8390
return
8491
}
92+
8593
userDao := daos.UsersDao{}
8694
user, err := userDao.GetUser(credentials)
95+
8796
if err != nil {
8897
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Invalid Username/Email, Please Signup!"})
8998
return
9099
}
91100

92-
if user.Password != credentials["password"] {
93-
utils.SendError(w, http.StatusNotFound, models.Error{Message: "Invalid Credentials!"})
101+
isCorrectPass := utils.CheckPasswordHash(credentials["password"], user.Password)
102+
103+
if !isCorrectPass {
104+
utils.SendError(w, http.StatusBadRequest, models.Error{Message: "Invalid Credentials!"})
94105
return
95106
}
96107

@@ -101,11 +112,14 @@ func (u UserController) LoginUser() http.HandlerFunc {
101112
}
102113

103114
token, err := utils.GenerateJwtToken(payload)
115+
104116
if err != nil {
105117
utils.SendError(w, http.StatusInternalServerError, models.Error{Message: "Failed To Generate New JWT Token!"})
106118
return
107119
}
108120

121+
user.Password = ""
122+
109123
utils.SendSuccess(w, ResponseOutput{
110124
Token: token,
111125
User: user,

database/db.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,19 @@ func CreateTablesAndPrePopulate() {
3131
}
3232

3333
books := []models.Book{
34-
{Title: "Book1", Author: "Author1", Year: 1990},
35-
{Title: "Book2", Author: "Author2", Year: 2022},
34+
{Title: "Book1", Author: "Author1", Year: 1983},
35+
{Title: "Book2", Author: "Author2", Year: 1990},
36+
{Title: "Book3", Author: "Author3", Year: 2000},
37+
{Title: "Book4", Author: "Author4", Year: 2010},
38+
{Title: "Book5", Author: "Author5", Year: 2020},
39+
{Title: "Book6", Author: "Author6", Year: 2022},
3640
}
3741

38-
Db.NewInsert().Model(&books).Exec(DbContext)
42+
_, err = Db.NewInsert().Model(&books).Exec(DbContext)
43+
44+
if err != nil {
45+
fmt.Println("Could not create sample books on database table 'books', please check...")
46+
return
47+
}
3948

4049
}

main.go

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,12 @@ import (
66
"github.com/subosito/gotenv"
77
"log"
88
"net/http"
9-
"rest/controllers"
109
"rest/database"
11-
"rest/middlewares"
10+
"rest/routes"
1211
)
1312

1413
func main() {
15-
router, userController, booksController := start()
16-
17-
router.HandleFunc("/auth/login", userController.LoginUser()).Methods(http.MethodPost)
18-
router.HandleFunc("/auth/signup", userController.SignupUser()).Methods(http.MethodPost)
19-
20-
router.HandleFunc("/books", middlewares.CheckAuth(booksController.GetBooks())).Methods(http.MethodGet)
21-
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.GetBook())).Methods(http.MethodGet)
22-
router.HandleFunc("/books", middlewares.CheckAuth(booksController.AddBook())).Methods(http.MethodPost)
23-
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.UpdateBook())).Methods(http.MethodPut)
24-
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.RemoveBook())).Methods(http.MethodDelete)
14+
router := initialSetupAndGetRouter()
2515

2616
log.Println("Server started at port 8000...")
2717
log.Fatal(http.ListenAndServe(":8000", handlers.CORS(
@@ -30,17 +20,15 @@ func main() {
3020
handlers.AllowedOrigins([]string{"*"}))(router)))
3121
}
3222

33-
func start() (*mux.Router, controllers.UserController, controllers.BookController) {
23+
func initialSetupAndGetRouter() *mux.Router {
3424
err := gotenv.Load()
3525

3626
if err != nil {
37-
panic("Could not load env vars, exiting.")
27+
log.Fatal("Could not load env vars, exiting.")
3828
}
3929

4030
database.CreateTablesAndPrePopulate()
41-
router := mux.NewRouter()
42-
booksController := controllers.BookController{}
43-
userController := controllers.UserController{}
31+
router := routes.GetRouter()
4432

45-
return router, userController, booksController
33+
return router
4634
}

routes/routes.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package routes
2+
3+
import (
4+
"github.com/gorilla/mux"
5+
"net/http"
6+
"rest/controllers"
7+
"rest/middlewares"
8+
)
9+
10+
func GetRouter() *mux.Router {
11+
booksController := controllers.BookController{}
12+
userController := controllers.UserController{}
13+
router := mux.NewRouter()
14+
15+
router.HandleFunc("/auth/login", userController.LoginUser()).Methods(http.MethodPost)
16+
router.HandleFunc("/auth/signup", userController.SignupUser()).Methods(http.MethodPost)
17+
18+
router.HandleFunc("/books", middlewares.CheckAuth(booksController.GetBooks())).Methods(http.MethodGet)
19+
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.GetBook())).Methods(http.MethodGet)
20+
router.HandleFunc("/books", middlewares.CheckAuth(booksController.AddBook())).Methods(http.MethodPost)
21+
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.UpdateBook())).Methods(http.MethodPut)
22+
router.HandleFunc("/books/{id}", middlewares.CheckAuth(booksController.RemoveBook())).Methods(http.MethodDelete)
23+
24+
return router
25+
}

utils/jwt.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var JWT_SECRET string
2626

2727
func GenerateJwtToken(payload Payload) (string, error) {
2828
if JWT_SECRET = os.Getenv("JWT_SECRET"); JWT_SECRET == "" {
29-
log.Fatal("[ ERROR ] JWT_SECRET environment variable not provided!\n")
29+
log.Fatal("JWT_SECRET environment variable not provided")
3030
}
3131

3232
key := []byte(JWT_SECRET)

utils/passwords.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package utils
2+
3+
import (
4+
"golang.org/x/crypto/bcrypt"
5+
)
6+
7+
func HashPassword(password string) (string, error) {
8+
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
9+
return string(bytes), err
10+
}
11+
12+
func CheckPasswordHash(password, hash string) bool {
13+
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
14+
return err == nil
15+
}
File renamed without changes.

0 commit comments

Comments
 (0)