package controller import ( "crypto/rand" "encoding/base64" "git.tek.govt.hu/dowerx/chat/server/config" "git.tek.govt.hu/dowerx/chat/server/dao" "git.tek.govt.hu/dowerx/chat/server/dao/postgres" "git.tek.govt.hu/dowerx/chat/server/dao/valkey" "git.tek.govt.hu/dowerx/chat/server/model" "git.tek.govt.hu/dowerx/chat/server/util" "golang.org/x/crypto/bcrypt" ) type AuthController struct { UserDAO dao.IUserDAO SessionDAO dao.ISessionDAO } const ( MIN_USERNAME_LENGTH int = 3 MIN_PASSWORD_LENGTH int = 6 HASH_COST int = bcrypt.DefaultCost TOKEN_LENGTH int = 32 ) func (c AuthController) Register(username string, password string, repeatPassword string) *util.ChatError { if len(username) < MIN_USERNAME_LENGTH { return &util.ChatError{Message: "", Code: util.USERNAME_TOO_SHORT} } if len(password) < MIN_PASSWORD_LENGTH { return &util.ChatError{Message: "", Code: util.PASSWORD_TOO_SHORT} } if password != repeatPassword { return &util.ChatError{Message: "", Code: util.PASSWORDS_DONT_MATCH} } hash, err := bcrypt.GenerateFromPassword([]byte(password), HASH_COST) if err != nil { return util.MakeError(err, util.GENERAL_ERROR) } return c.UserDAO.Create(model.User{ Username: username, PasswordHash: string(hash), }) } func generateToken(length int) (string, error) { b := make([]byte, length) _, err := rand.Read(b) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(b), nil } func (c AuthController) Login(username string, password string) (string, *util.ChatError) { user, err := c.UserDAO.Read(model.User{Username: username}) if err != nil { return "", err } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil { return "", &util.ChatError{Message: "", Code: util.WRONG_PASSWORD} } token, tokenErr := generateToken(TOKEN_LENGTH) if tokenErr != nil { return "", util.MakeError(err, util.GENERAL_ERROR) } err = c.SessionDAO.DeleteAllByID(user.ID) if err != nil { return "", err } err = c.SessionDAO.Set(token, user.ID) if err != nil { return "", err } return token, nil } func (c AuthController) Logout(token string) *util.ChatError { return c.SessionDAO.Delete(token) } func (c AuthController) Bump(token string) *util.ChatError { return c.SessionDAO.Bump(token, config.GetConfig().API.TokenLife) } func MakeAuthController() (AuthController, *util.ChatError) { controller := AuthController{} userDAO := postgres.UserDAOPG{} err := userDAO.Init() if err != nil { return controller, err } sessionDAO := valkey.SessionDAOVK{} err = sessionDAO.Init() if err != nil { return controller, err } controller.UserDAO = userDAO controller.SessionDAO = sessionDAO return controller, nil }