package controller import ( "crypto/rand" "encoding/base64" "errors" "git.tek.govt.hu/dowerx/chat/server/dao" "git.tek.govt.hu/dowerx/chat/server/model" "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) init() error { userDAO, err := dao.MakeUserDAO() c.userDAO = userDAO if err != nil { return err } sessionDao, err := dao.MakeSessionDAO() c.sessionDAO = sessionDao if err != nil { return err } return nil } func (c AuthController) Register(username string, password string, repeatPassword string) error { if len(username) < MIN_USERNAME_LENGTH { return errors.New("username too short") } if len(password) < MIN_PASSWORD_LENGTH { return errors.New("password too short") } if password != repeatPassword { return errors.New("passwords don't match") } hash, err := bcrypt.GenerateFromPassword([]byte(password), HASH_COST) if err != nil { return err } 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, bool, error) { user, err := c.userDAO.Read(model.User{Username: username}) if err != nil { return "", false, err } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil { return "", false, errors.New("wrong password") } token, err := generateToken(TOKEN_LENGTH) if err != nil { return "", false, err } err = c.sessionDAO.Set(token, user.ID) if err != nil { return "", false, err } return token, true, nil } func (c AuthController) Logout(token string) error { return c.sessionDAO.Delete(token) }