Basic JWT is now working #12

Merged
jtom38 merged 12 commits from features/jwt/maybe into main 2024-03-29 14:51:01 -07:00
4 changed files with 114 additions and 43 deletions
Showing only changes of commit 063e677869 - Show all commits

View File

@ -1,9 +1,18 @@
{ {
"cSpell.words": [ "cSpell.words": [
"echojwt",
"glebarez", "glebarez",
"gocook", "gocook",
"huandu", "huandu",
"labstack", "labstack",
"sqlbuilder" "sqlbuilder"
],
"sqltools.connections": [
{
"previewLimit": 50,
"driver": "SQLite",
"database": "${workspaceFolder:go-cook}/gocook.db",
"name": "gocook"
}
] ]
} }

105
api/services/userService.go Normal file
View File

@ -0,0 +1,105 @@
package services
import (
"database/sql"
"errors"
"go-cook/api/models"
"go-cook/api/repositories"
"strings"
"golang.org/x/crypto/bcrypt"
)
const (
ErrPasswordNotLongEnough = "password needs to be 8 character or longer"
ErrPasswordMissingSpecialCharacter = "password needs to contain one of the following: !, @, #"
ErrInvalidPassword = "invalid password"
)
// This will handle operations that are user related, but one layer higher then the repository
type UserService struct {
repo repositories.IUserTable
}
func NewUserService(conn *sql.DB) UserService {
return UserService{
repo: repositories.NewUserRepository(conn),
}
}
func (us UserService) DoesUserExist(username string) error {
_, err := us.repo.GetByName(username)
if err != nil {
return err
}
return nil
}
func (us UserService) DoesPasswordMatchHash(username, password string) error {
passwordBytes := []byte(password)
hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
if err != nil {
return err
}
model, err := us.GetUser(username)
if err != nil {
return err
}
if model.Hash != string(hash) {
return errors.New(ErrInvalidPassword)
}
return nil
}
func (us UserService) GetUser(username string) (models.UserModel, error) {
return us.repo.GetByName(username)
}
func (us UserService) CreateNewUser(name, password string) (models.UserModel, error) {
err := us.CheckPasswordForRequirements(password)
if err != nil {
return models.UserModel{}, err
}
us.repo.Create(name, password)
return models.UserModel{}, nil
}
func (us UserService) CheckPasswordForRequirements(password string) error {
err := us.checkPasswordLength(password)
if err != nil {
return err
}
err = us.checkPasswordForSpecialCharacters(password)
if err != nil {
return err
}
return nil
}
func (us UserService) checkPasswordLength(password string) error {
if len(password) <= 8 {
return errors.New(ErrPasswordNotLongEnough)
}
return nil
}
func (us UserService) checkPasswordForSpecialCharacters(password string) error {
var chars []string
chars = append(chars, "!")
chars = append(chars, "@")
chars = append(chars, "#")
for _, char := range chars {
if strings.Contains(password, char) {
return nil
}
}
return errors.New(ErrPasswordMissingSpecialCharacter)
}

View File

@ -1,43 +0,0 @@
package services
import (
"database/sql"
"errors"
"go-cook/api/models"
"go-cook/api/repositories"
)
const (
ErrPasswordNotLongEnough = "password needs to be 8 character or longer"
)
// This will handle operations that are user related, but one layer higher then the repository
type UserService struct {
repo repositories.UserRepository
}
func NewUserService(conn *sql.DB) UserService {
return UserService{
repo: repositories.NewUserRepository(conn),
}
}
func (us UserService) DoesUserExist(username string) error {
_, err := us.repo.GetByName(username)
if err != nil {
return err
}
return nil
}
func (us UserService) CreateNewUser(name, password string) (models.UserModel, error) {
us.repo.NewUser(name, password)
return models.UserModel{}, nil
}
func (us UserService) CheckPasswordForRequirements(password string) error {
if len(password) <= 8 {
return errors.New(ErrPasswordNotLongEnough)
}
return nil
}