Compare commits
2 Commits
f52ad5f03a
...
de83676794
Author | SHA1 | Date | |
---|---|---|---|
de83676794 | |||
4854d926d7 |
44
api/auth.go
44
api/auth.go
@ -40,21 +40,14 @@ func register(c *gin.Context) {
|
||||
}
|
||||
|
||||
authController, err := controller.MakeAuthController()
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = authController.Register(transaction.Username, transaction.Password, transaction.RepeatPassword)
|
||||
|
||||
// TODO: handle server errors/register violations separetly
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -78,24 +71,13 @@ func login(c *gin.Context) {
|
||||
|
||||
authController, err := controller.MakeAuthController()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
token, ok, err := authController.Login(transaction.Username, transaction.Password)
|
||||
token, err := authController.Login(transaction.Username, transaction.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !ok {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"error": "bad credentials",
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -109,18 +91,14 @@ func login(c *gin.Context) {
|
||||
func logout(c *gin.Context) {
|
||||
authController, err := controller.MakeAuthController()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
token, _ := c.Get(SESSION_COOKIE) // must exist after isLoggedIn
|
||||
err = authController.Logout(token.(string))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -133,17 +111,13 @@ func logout(c *gin.Context) {
|
||||
func bump(c *gin.Context) {
|
||||
authController, err := controller.MakeAuthController()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
token, _ := c.Get(SESSION_COOKIE)
|
||||
if err = authController.Bump(token.(string)); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,10 @@ func Listen(address string, base string) error {
|
||||
auth.GET("logout", isLoggedIn, logout)
|
||||
auth.GET("bump", isLoggedIn, bump)
|
||||
|
||||
user := api.Group("user")
|
||||
user.Use(isLoggedIn)
|
||||
user.GET("info/:username", userInfo)
|
||||
|
||||
server := &http.Server{
|
||||
Addr: address,
|
||||
Handler: router,
|
||||
|
12
api/errors.go
Normal file
12
api/errors.go
Normal file
@ -0,0 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func sendError(c *gin.Context, err *util.ChatError) {
|
||||
c.JSON(err.Status(), gin.H{
|
||||
"error": err.ErrorFromCode(),
|
||||
})
|
||||
}
|
31
api/user.go
Normal file
31
api/user.go
Normal file
@ -0,0 +1,31 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/controller"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const USERNAME_PARAM string = "username"
|
||||
|
||||
func userInfo(c *gin.Context) {
|
||||
username := c.Param(USERNAME_PARAM)
|
||||
|
||||
userController, err := controller.MakeUserController()
|
||||
if err != nil {
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := userController.GetUser(username)
|
||||
if err != nil {
|
||||
sendError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "user found",
|
||||
"user": user,
|
||||
})
|
||||
}
|
@ -3,11 +3,11 @@ package controller
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/config"
|
||||
"git.tek.govt.hu/dowerx/chat/server/dao"
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
@ -23,7 +23,7 @@ const (
|
||||
TOKEN_LENGTH int = 32
|
||||
)
|
||||
|
||||
func (c *AuthController) init() error {
|
||||
func (c *AuthController) init() *util.ChatError {
|
||||
userDAO, err := dao.MakeUserDAO()
|
||||
c.userDAO = userDAO
|
||||
if err != nil {
|
||||
@ -39,22 +39,23 @@ func (c *AuthController) init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c AuthController) Register(username string, password string, repeatPassword string) error {
|
||||
func (c AuthController) Register(username string, password string, repeatPassword string) *util.ChatError {
|
||||
if len(username) < MIN_USERNAME_LENGTH {
|
||||
return errors.New("username too short")
|
||||
return &util.ChatError{Message: "", Code: util.USERNAME_TOO_SHORT}
|
||||
}
|
||||
|
||||
if len(password) < MIN_PASSWORD_LENGTH {
|
||||
return errors.New("password too short")
|
||||
return &util.ChatError{Message: "", Code: util.PASSWORD_TOO_SHORT}
|
||||
}
|
||||
|
||||
if password != repeatPassword {
|
||||
return errors.New("passwords don't match")
|
||||
return &util.ChatError{Message: "", Code: util.PASSWORDS_DONT_MATCH}
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), HASH_COST)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.GENERAL_ERROR)
|
||||
}
|
||||
|
||||
return c.userDAO.Create(model.User{
|
||||
@ -73,38 +74,38 @@ func generateToken(length int) (string, error) {
|
||||
return base64.URLEncoding.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
func (c AuthController) Login(username string, password string) (string, bool, error) {
|
||||
func (c AuthController) Login(username string, password string) (string, *util.ChatError) {
|
||||
user, err := c.userDAO.Read(model.User{Username: username})
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {
|
||||
return "", false, errors.New("wrong password")
|
||||
return "", &util.ChatError{Message: "", Code: util.WRONG_PASSWORD}
|
||||
}
|
||||
|
||||
token, err := generateToken(TOKEN_LENGTH)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
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 "", false, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = c.sessionDAO.Set(token, user.ID)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, true, nil
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (c AuthController) Logout(token string) error {
|
||||
func (c AuthController) Logout(token string) *util.ChatError {
|
||||
return c.sessionDAO.Delete(token)
|
||||
}
|
||||
|
||||
func (c AuthController) Bump(token string) error {
|
||||
func (c AuthController) Bump(token string) *util.ChatError {
|
||||
return c.sessionDAO.Bump(token, config.GetConfig().API.TokenLife)
|
||||
}
|
||||
|
@ -1,7 +1,15 @@
|
||||
package controller
|
||||
|
||||
func MakeAuthController() (AuthController, error) {
|
||||
import "git.tek.govt.hu/dowerx/chat/server/util"
|
||||
|
||||
func MakeAuthController() (AuthController, *util.ChatError) {
|
||||
authController := &AuthController{}
|
||||
err := authController.init()
|
||||
return *authController, err
|
||||
}
|
||||
|
||||
func MakeUserController() (UserController, *util.ChatError) {
|
||||
userController := &UserController{}
|
||||
err := userController.init()
|
||||
return *userController, err
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package controller
|
||||
|
||||
import "git.tek.govt.hu/dowerx/chat/server/util"
|
||||
|
||||
type IController interface {
|
||||
init() error
|
||||
init() *util.ChatError
|
||||
}
|
||||
|
25
controller/UserController.go
Normal file
25
controller/UserController.go
Normal file
@ -0,0 +1,25 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/dao"
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
userDAO dao.IUserDAO
|
||||
}
|
||||
|
||||
func (c *UserController) init() *util.ChatError {
|
||||
userDAO, err := dao.MakeUserDAO()
|
||||
c.userDAO = userDAO
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c UserController) GetUser(username string) (model.User, *util.ChatError) {
|
||||
return c.userDAO.Read(model.User{Username: username})
|
||||
}
|
@ -3,15 +3,16 @@ package dao
|
||||
import (
|
||||
"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/util"
|
||||
)
|
||||
|
||||
func MakeUserDAO() (IUserDAO, error) {
|
||||
func MakeUserDAO() (IUserDAO, *util.ChatError) {
|
||||
dao := &postgres.UserDAOPG{}
|
||||
err := dao.Init()
|
||||
return dao, err
|
||||
}
|
||||
|
||||
func MakeSessionDAO() (ISessionDAO, error) {
|
||||
func MakeSessionDAO() (ISessionDAO, *util.ChatError) {
|
||||
dao := &valkey.SessionDAOVK{}
|
||||
err := dao.Init()
|
||||
return dao, err
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dao
|
||||
|
||||
import "git.tek.govt.hu/dowerx/chat/server/util"
|
||||
|
||||
type IDAO interface {
|
||||
Init() error
|
||||
Init() *util.ChatError
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package dao
|
||||
|
||||
import "git.tek.govt.hu/dowerx/chat/server/util"
|
||||
|
||||
type ISessionDAO interface {
|
||||
Set(token string, id int) error
|
||||
Get(token string) (int, error)
|
||||
Delete(token string) error
|
||||
DeleteAllByID(id int) error
|
||||
Bump(token string, time int) error
|
||||
Set(token string, id int) *util.ChatError
|
||||
Get(token string) (int, *util.ChatError)
|
||||
Delete(token string) *util.ChatError
|
||||
DeleteAllByID(id int) *util.ChatError
|
||||
Bump(token string, time int) *util.ChatError
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package dao
|
||||
|
||||
import "git.tek.govt.hu/dowerx/chat/server/model"
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
)
|
||||
|
||||
type IUserDAO interface {
|
||||
Create(user model.User) error
|
||||
Read(user model.User) (model.User, error)
|
||||
List() ([]model.User, error)
|
||||
Update(user model.User) error
|
||||
Delete(user model.User) error
|
||||
Create(user model.User) *util.ChatError
|
||||
Read(user model.User) (model.User, *util.ChatError)
|
||||
List() ([]model.User, *util.ChatError)
|
||||
Update(user model.User) *util.ChatError
|
||||
Delete(user model.User) *util.ChatError
|
||||
}
|
||||
|
@ -4,18 +4,19 @@ import (
|
||||
"fmt"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/config"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var db *sqlx.DB
|
||||
|
||||
func getDatabase() (*sqlx.DB, error) {
|
||||
func getDatabase() (*sqlx.DB, *util.ChatError) {
|
||||
if db == nil {
|
||||
cfg := config.GetConfig()
|
||||
newDB, err := sqlx.Connect("postgres", fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", cfg.Database.Host, cfg.Database.Port, cfg.Database.User, cfg.Database.Password, cfg.Database.DBname))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, util.MakeError(err, util.DATABASE_CONNECTION_FAULT)
|
||||
}
|
||||
db = newDB
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
@ -12,13 +11,13 @@ type UserDAOPG struct {
|
||||
}
|
||||
|
||||
// Create a new user
|
||||
func (d UserDAOPG) Create(user model.User) error {
|
||||
func (d UserDAOPG) Create(user model.User) *util.ChatError {
|
||||
_, err := d.db.NamedExec(`call add_user(:username, :password_hash)`, &user)
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
// Read returns a user by ID if ID != 0, else by Username
|
||||
func (d UserDAOPG) Read(user model.User) (model.User, error) {
|
||||
func (d UserDAOPG) Read(user model.User) (model.User, *util.ChatError) {
|
||||
var rows *sqlx.Rows
|
||||
var err error
|
||||
if user.ID != 0 {
|
||||
@ -28,22 +27,22 @@ func (d UserDAOPG) Read(user model.User) (model.User, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return user, err
|
||||
return user, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
if !rows.Next() {
|
||||
return user, errors.New("no such user")
|
||||
return user, &util.ChatError{Message: "", Code: util.USER_NOT_FOUND}
|
||||
}
|
||||
|
||||
err = rows.StructScan(&user)
|
||||
return user, err
|
||||
return user, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
// List all users
|
||||
func (d UserDAOPG) List() ([]model.User, error) {
|
||||
func (d UserDAOPG) List() ([]model.User, *util.ChatError) {
|
||||
rows, err := d.db.Queryx(`select * from "user" order by "username"`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
users := make([]model.User, 0)
|
||||
@ -59,17 +58,17 @@ func (d UserDAOPG) List() ([]model.User, error) {
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
return users, err
|
||||
return users, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
// Update sets all the fields of the User with the given ID
|
||||
func (d UserDAOPG) Update(user model.User) error {
|
||||
func (d UserDAOPG) Update(user model.User) *util.ChatError {
|
||||
_, err := d.db.NamedExec(`update "user" set "username" = :username, "password_hash" = :password_hash, "status" = :status, "picture" = :picture, "bio" = :bio where "id" = :id`, &user)
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
// Delete removes a user by ID if ID != 0, else by Username
|
||||
func (d UserDAOPG) Delete(user model.User) error {
|
||||
func (d UserDAOPG) Delete(user model.User) *util.ChatError {
|
||||
var err error
|
||||
if user.ID != 0 {
|
||||
_, err = d.db.NamedExec(`delete from "user" where "id" = :id`, &user)
|
||||
@ -77,5 +76,5 @@ func (d UserDAOPG) Delete(user model.User) error {
|
||||
_, err = d.db.NamedExec(`delete from "user" where "username" = :username`, &user)
|
||||
}
|
||||
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
@ -8,7 +9,7 @@ type pgDAO struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func (d *pgDAO) Init() error {
|
||||
func (d *pgDAO) Init() *util.ChatError {
|
||||
conn, err := getDatabase()
|
||||
d.db = conn
|
||||
return err
|
||||
|
@ -2,16 +2,17 @@ package valkey
|
||||
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/config"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/valkey-io/valkey-go"
|
||||
)
|
||||
|
||||
var vk valkey.Client = nil
|
||||
|
||||
func getClient() (*valkey.Client, error) {
|
||||
func getClient() (*valkey.Client, *util.ChatError) {
|
||||
if vk == nil {
|
||||
client, err := valkey.NewClient(config.GetConfig().Valkey)
|
||||
vk = client
|
||||
return &vk, err
|
||||
return &vk, util.MakeError(err, util.DATABASE_CONNECTION_FAULT)
|
||||
}
|
||||
|
||||
return &vk, nil
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/config"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
)
|
||||
|
||||
const SESSION_PREFIX string = "session:"
|
||||
@ -13,28 +14,28 @@ type SessionDAOVK struct {
|
||||
vkDAO
|
||||
}
|
||||
|
||||
func (d SessionDAOVK) Set(token string, id int) error {
|
||||
func (d SessionDAOVK) Set(token string, id int) *util.ChatError {
|
||||
cmd := (*d.vk).B().Set().Key(SESSION_PREFIX + token).Value(strconv.Itoa(id)).ExSeconds(int64(config.GetConfig().API.TokenLife)).Build()
|
||||
return (*d.vk).Do(context.Background(), cmd).Error()
|
||||
return util.MakeError((*d.vk).Do(context.Background(), cmd).Error(), util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
func (d SessionDAOVK) Get(token string) (int, error) {
|
||||
func (d SessionDAOVK) Get(token string) (int, *util.ChatError) {
|
||||
cmd := (*d.vk).B().Get().Key(SESSION_PREFIX + token).Build()
|
||||
result := (*d.vk).Do(context.Background(), cmd)
|
||||
if err := result.Error(); err != nil {
|
||||
return 0, err
|
||||
return 0, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
id, err := result.AsInt64()
|
||||
return int(id), err
|
||||
return int(id), util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
func (d SessionDAOVK) Delete(token string) error {
|
||||
func (d SessionDAOVK) Delete(token string) *util.ChatError {
|
||||
cmd := (*d.vk).B().Del().Key(SESSION_PREFIX + token).Build()
|
||||
return (*d.vk).Do(context.Background(), cmd).Error()
|
||||
return util.MakeError((*d.vk).Do(context.Background(), cmd).Error(), util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
func (d SessionDAOVK) DeleteAllByID(id int) error {
|
||||
func (d SessionDAOVK) DeleteAllByID(id int) *util.ChatError {
|
||||
// iterate all session keys
|
||||
var cursor uint64 = 0
|
||||
pattern := SESSION_PREFIX + "*"
|
||||
@ -43,12 +44,12 @@ func (d SessionDAOVK) DeleteAllByID(id int) error {
|
||||
|
||||
result := (*d.vk).Do(context.Background(), cmd)
|
||||
if err := result.Error(); err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
entry, err := result.AsScanEntry()
|
||||
if err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
for _, key := range entry.Elements {
|
||||
@ -57,12 +58,12 @@ func (d SessionDAOVK) DeleteAllByID(id int) error {
|
||||
|
||||
result := (*d.vk).Do(context.Background(), cmd)
|
||||
if err := result.Error(); err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
value, err := result.AsInt64()
|
||||
if err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
// check if the value is the same as our id
|
||||
@ -71,7 +72,7 @@ func (d SessionDAOVK) DeleteAllByID(id int) error {
|
||||
cmd = (*d.vk).B().Del().Key(key).Build()
|
||||
result := (*d.vk).Do(context.Background(), cmd)
|
||||
if err := result.Error(); err != nil {
|
||||
return err
|
||||
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,7 +84,7 @@ func (d SessionDAOVK) DeleteAllByID(id int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d SessionDAOVK) Bump(token string, time int) error {
|
||||
func (d SessionDAOVK) Bump(token string, time int) *util.ChatError {
|
||||
cmd := (*d.vk).B().Expire().Key(SESSION_PREFIX + token).Seconds(int64(time)).Build()
|
||||
return (*d.vk).Do(context.Background(), cmd).Error()
|
||||
return util.MakeError((*d.vk).Do(context.Background(), cmd).Error(), util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package valkey
|
||||
|
||||
import (
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/valkey-io/valkey-go"
|
||||
)
|
||||
|
||||
@ -8,7 +9,7 @@ type vkDAO struct {
|
||||
vk *valkey.Client
|
||||
}
|
||||
|
||||
func (d *vkDAO) Init() error {
|
||||
func (d *vkDAO) Init() *util.ChatError {
|
||||
client, err := getClient()
|
||||
d.vk = client
|
||||
return err
|
||||
|
@ -4,8 +4,8 @@ import "time"
|
||||
|
||||
type Message struct {
|
||||
ID int
|
||||
Sender User
|
||||
Channel Channel
|
||||
Sender string // username
|
||||
Channel Channel // channel.id
|
||||
Time time.Time
|
||||
Content string
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package model
|
||||
|
||||
type User struct {
|
||||
ID int `db:"id"`
|
||||
Username string `db:"username"`
|
||||
PasswordHash string `db:"password_hash"`
|
||||
Status string `db:"status"`
|
||||
Picture string `db:"picture"`
|
||||
Bio string `db:"bio"`
|
||||
ID int `db:"id" json:"-"`
|
||||
Username string `db:"username" json:"username"`
|
||||
PasswordHash string `db:"password_hash" json:"-"`
|
||||
Status string `db:"status" json:"status"`
|
||||
Picture string `db:"picture" json:"picture"`
|
||||
Bio string `db:"bio" json:"bio"`
|
||||
}
|
||||
|
83
util/errors.go
Normal file
83
util/errors.go
Normal file
@ -0,0 +1,83 @@
|
||||
package util
|
||||
|
||||
import "net/http"
|
||||
|
||||
type ChatErrorCode int
|
||||
|
||||
// List off all known error codes
|
||||
|
||||
const (
|
||||
// GENERAL_ERROR for not classified system errros
|
||||
GENERAL_ERROR ChatErrorCode = iota
|
||||
|
||||
DATABASE_CONNECTION_FAULT
|
||||
DATABASE_QUERY_FAULT
|
||||
|
||||
USER_NOT_FOUND
|
||||
WRONG_PASSWORD
|
||||
USERNAME_TOO_SHORT
|
||||
PASSWORD_TOO_SHORT
|
||||
PASSWORDS_DONT_MATCH
|
||||
)
|
||||
|
||||
var codeToMessage = map[ChatErrorCode]string{
|
||||
GENERAL_ERROR: "an unexpected error occurred",
|
||||
DATABASE_CONNECTION_FAULT: "database connection failed",
|
||||
DATABASE_QUERY_FAULT: "database query failed",
|
||||
USER_NOT_FOUND: "user not found",
|
||||
WRONG_PASSWORD: "incorrect password",
|
||||
USERNAME_TOO_SHORT: "username is too short",
|
||||
PASSWORD_TOO_SHORT: "password is too short",
|
||||
PASSWORDS_DONT_MATCH: "passwords do not match",
|
||||
}
|
||||
|
||||
type ChatError struct {
|
||||
Message string
|
||||
Code ChatErrorCode
|
||||
}
|
||||
|
||||
// Error returns the original errors message if not empty, else returns ErrorFromCode()
|
||||
func (e ChatError) Error() string {
|
||||
if e.Message != "" {
|
||||
return e.Message
|
||||
} else {
|
||||
return e.ErrorFromCode()
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorFromCode returns a string that is safe to show in API responses
|
||||
func (e *ChatError) ErrorFromCode() string {
|
||||
message, ok := codeToMessage[e.Code]
|
||||
if ok {
|
||||
return message
|
||||
} else {
|
||||
return "unknown error code"
|
||||
}
|
||||
}
|
||||
|
||||
// Status returns the http status of the error type
|
||||
func (e *ChatError) Status() int {
|
||||
switch e.Code {
|
||||
case USER_NOT_FOUND:
|
||||
fallthrough
|
||||
case WRONG_PASSWORD:
|
||||
fallthrough
|
||||
case USERNAME_TOO_SHORT:
|
||||
fallthrough
|
||||
case PASSWORD_TOO_SHORT:
|
||||
fallthrough
|
||||
case PASSWORDS_DONT_MATCH:
|
||||
return http.StatusOK
|
||||
default:
|
||||
return http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
// MakeError makes an error with the given code id err exists
|
||||
func MakeError(err error, code ChatErrorCode) *ChatError {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &ChatError{Message: err.Error(), Code: code}
|
||||
}
|
Loading…
Reference in New Issue
Block a user