Skip to content

Commit

Permalink
feat(auth): user bcrypt to encrypt user password
Browse files Browse the repository at this point in the history
Signed-off-by: Gaurav Mishra <[email protected]>
  • Loading branch information
GMishx committed Jan 5, 2024
1 parent 55dbde0 commit c426332
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
53 changes: 52 additions & 1 deletion pkg/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"strings"
"time"

"golang.org/x/crypto/bcrypt"

"github.com/gin-gonic/gin"

"github.com/fossology/LicenseDb/pkg/db"
Expand Down Expand Up @@ -54,6 +56,19 @@ func CreateUser(c *gin.Context) {
Userpassword: input.Userpassword,
}

err := utils.HashPassword(&user)
if err != nil {
er := models.LicenseError{
Status: http.StatusBadRequest,
Message: "password hashing failed",
Error: err.Error(),
Path: c.Request.URL.Path,
Timestamp: time.Now().Format(time.RFC3339),
}
c.JSON(http.StatusBadRequest, er)
return
}

result := db.DB.Where(models.User{Username: user.Username}).FirstOrCreate(&user)
if result.Error != nil {
er := models.LicenseError{
Expand Down Expand Up @@ -231,8 +246,24 @@ func AuthenticationMiddleware() gin.HandlerFunc {
return
}

err = EncryptUserPassword(&user)
if err != nil {
er := models.LicenseError{
Status: http.StatusInternalServerError,
Message: "Failed to encrypt user password",
Error: err.Error(),
Path: c.Request.URL.Path,
Timestamp: time.Now().Format(time.RFC3339),
}

c.JSON(http.StatusInternalServerError, er)
c.Abort()
return
}

// Check if the password matches
if *user.Userpassword != password {
err = utils.VerifyPassword(password, *user.Userpassword)
if err != nil {
er := models.LicenseError{
Status: http.StatusUnauthorized,
Message: "Incorrect password",
Expand Down Expand Up @@ -266,3 +297,23 @@ func CORSMiddleware() gin.HandlerFunc {
c.Next()
}
}

// EncryptUserPassword checks if the password is already encrypted or not. If
// not, it encrypts the password.
func EncryptUserPassword(user *models.User) error {
_, err := bcrypt.Cost([]byte(*user.Userpassword))
if err == nil {
return nil
}

hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*user.Userpassword), bcrypt.DefaultCost)

if err != nil {
return err
}
*user.Userpassword = string(hashedPassword)

db.DB.Model(&user).Updates(user)

return nil
}
25 changes: 25 additions & 0 deletions pkg/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ package utils

import (
"fmt"
"html"
"net/http"
"strconv"
"strings"
"time"

"golang.org/x/crypto/bcrypt"

"github.com/gin-gonic/gin"

"github.com/fossology/LicenseDb/pkg/models"
Expand Down Expand Up @@ -121,3 +125,24 @@ func ParseIdToInt(c *gin.Context, id string, idType string) (int64, error) {
}
return parsedId, nil
}

// HashPassword hashes the password of the user using bcrypt. It also trims the
// username and escapes the HTML characters.
func HashPassword(user *models.User) error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*user.Userpassword), bcrypt.DefaultCost)

if err != nil {
return err
}
*user.Userpassword = string(hashedPassword)

user.Username = html.EscapeString(strings.TrimSpace(user.Username))

return nil
}

// VerifyPassword compares the input password with the password stored in the
// database. Returns nil on success, or an error on failure.
func VerifyPassword(inputPassword, dbPassword string) error {
return bcrypt.CompareHashAndPassword([]byte(dbPassword), []byte(inputPassword))
}

0 comments on commit c426332

Please sign in to comment.