From 538e390efae6eb336559e3dc7cf4d6eaf453c64f Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sun, 6 Jan 2019 14:56:58 +0100 Subject: [PATCH] models: Moved functionality out of sub-packages. --- models/session.go | 33 +++++++++++++++++++++++++ models/sessions/open.go | 53 ---------------------------------------- models/user.go | 25 +++++++++++++++++++ models/users/login.go | 21 ---------------- models/users/register.go | 25 ------------------- 5 files changed, 58 insertions(+), 99 deletions(-) delete mode 100644 models/sessions/open.go delete mode 100644 models/users/login.go delete mode 100644 models/users/register.go diff --git a/models/session.go b/models/session.go index 8b1b18f..8fb780a 100644 --- a/models/session.go +++ b/models/session.go @@ -1,6 +1,9 @@ package models import ( + "crypto/rand" + "encoding/binary" + "strconv" "time" ) @@ -11,6 +14,36 @@ type Session struct { Expires time.Time } +// GenerateID generates a unique ID for the session that's 64 base36 digits long. +func (session *Session) GenerateID() error { + result := "" + offset := 0 + data := make([]byte, 128) + + _, err := rand.Read(data) + if err != nil { + return err + } + + for len(result) < 64 { + result += strconv.FormatUint(binary.LittleEndian.Uint64(data[offset:]), 36) + offset += 8 + + if offset >= 128 { + _, err = rand.Read(data) + if err != nil { + return err + } + + offset = 0 + } + } + + session.ID = result[:64] + + return nil +} + // SessionRepository is an interface for all database operations // the user model makes. type SessionRepository interface { diff --git a/models/sessions/open.go b/models/sessions/open.go deleted file mode 100644 index 0f9cc3d..0000000 --- a/models/sessions/open.go +++ /dev/null @@ -1,53 +0,0 @@ -package sessions - -import ( - "crypto/rand" - "encoding/binary" - "strconv" - "time" - - "git.aiterp.net/lucifer/lucifer/models" -) - -func Open(repo models.SessionRepository, user models.User) (models.Session, error) { - id, err := generateID() - if err != nil { - return models.Session{}, err - } - - session := models.Session{ID: id, Expires: time.Now().Add(time.Hour * 72), UserID: user.ID} - - err = repo.InsertSession(session) - if err != nil { - return models.Session{}, err - } - - return session, nil -} - -func generateID() (string, error) { - result := "S" - offset := 0 - data := make([]byte, 32) - - _, err := rand.Read(data) - if err != nil { - return "", err - } - - for len(result) < 64 { - result += strconv.FormatUint(binary.LittleEndian.Uint64(data[offset:]), 36) - offset += 8 - - if offset >= 32 { - _, err = rand.Read(data) - if err != nil { - return "", err - } - - offset = 0 - } - } - - return result[:64], nil -} diff --git a/models/user.go b/models/user.go index df7c60b..47e73e0 100644 --- a/models/user.go +++ b/models/user.go @@ -1,5 +1,9 @@ package models +import ( + "golang.org/x/crypto/bcrypt" +) + // The User model represents a registered user. type User struct { ID int @@ -7,6 +11,27 @@ type User struct { PassHash []byte } +// SetPassword sets the user's password +func (user *User) SetPassword(password string) error { + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return err + } + + user.PassHash = hash + return nil +} + +// CheckPassword checks the user's password against the hash. +func (user *User) CheckPassword(attempt string) error { + err := bcrypt.CompareHashAndPassword(user.PassHash, []byte(attempt)) + if err != nil { + return err + } + + return nil +} + // UserRepository is an interface for all database operations // the user model makes. type UserRepository interface { diff --git a/models/users/login.go b/models/users/login.go deleted file mode 100644 index 09c7a9b..0000000 --- a/models/users/login.go +++ /dev/null @@ -1,21 +0,0 @@ -package users - -import ( - "git.aiterp.net/lucifer/lucifer/models" - "golang.org/x/crypto/bcrypt" -) - -// Login gets a user and compares the password. It does not open a session. -func Login(repo models.UserRepository, name, password string) (models.User, error) { - user, err := repo.FindUserByName(name) - if err != nil { - return models.User{}, err - } - - err = bcrypt.CompareHashAndPassword(user.PassHash, []byte(password)) - if err != nil { - return models.User{}, err - } - - return user, nil -} diff --git a/models/users/register.go b/models/users/register.go deleted file mode 100644 index bec5ea8..0000000 --- a/models/users/register.go +++ /dev/null @@ -1,25 +0,0 @@ -package users - -import ( - "git.aiterp.net/lucifer/lucifer/models" - "golang.org/x/crypto/bcrypt" -) - -// Register registers a user -func Register(repo models.UserRepository, name, password string) (models.User, error) { - hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) - if err != nil { - return models.User{}, err - } - - user := models.User{ID: -1, Name: name, PassHash: hash} - - id, err := repo.InsertUser(user) - if err != nil { - return models.User{}, err - } - - user.ID = id - - return user, nil -}