2024-09-22 23:57:23 +00:00
|
|
|
package controller
|
|
|
|
|
|
|
|
import (
|
2024-11-01 21:03:08 +00:00
|
|
|
"arimelody-web/model"
|
2025-01-20 15:08:01 +00:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
2024-09-22 23:57:23 +00:00
|
|
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
)
|
|
|
|
|
2025-01-20 19:11:16 +00:00
|
|
|
func GetAllAccounts(db *sqlx.DB) ([]model.Account, error) {
|
|
|
|
var accounts = []model.Account{}
|
|
|
|
|
|
|
|
err := db.Select(&accounts, "SELECT * FROM account ORDER BY created_at ASC")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return accounts, nil
|
|
|
|
}
|
|
|
|
|
2024-09-22 23:57:23 +00:00
|
|
|
func GetAccount(db *sqlx.DB, username string) (*model.Account, error) {
|
|
|
|
var account = model.Account{}
|
|
|
|
|
|
|
|
err := db.Get(&account, "SELECT * FROM account WHERE username=$1", username)
|
|
|
|
if err != nil {
|
2025-01-20 18:54:03 +00:00
|
|
|
if strings.Contains(err.Error(), "no rows") {
|
|
|
|
return nil, nil
|
|
|
|
}
|
2024-09-22 23:57:23 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &account, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetAccountByEmail(db *sqlx.DB, email string) (*model.Account, error) {
|
|
|
|
var account = model.Account{}
|
|
|
|
|
|
|
|
err := db.Get(&account, "SELECT * FROM account WHERE email=$1", email)
|
|
|
|
if err != nil {
|
2025-01-20 18:54:03 +00:00
|
|
|
if strings.Contains(err.Error(), "no rows") {
|
|
|
|
return nil, nil
|
|
|
|
}
|
2024-09-22 23:57:23 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &account, nil
|
|
|
|
}
|
|
|
|
|
2025-01-20 15:08:01 +00:00
|
|
|
func GetAccountByToken(db *sqlx.DB, token string) (*model.Account, error) {
|
|
|
|
if token == "" { return nil, nil }
|
|
|
|
|
|
|
|
account := model.Account{}
|
|
|
|
|
|
|
|
err := db.Get(&account, "SELECT account.* FROM account JOIN token ON id=account WHERE token=$1", token)
|
|
|
|
if err != nil {
|
2025-01-20 18:54:03 +00:00
|
|
|
if strings.Contains(err.Error(), "no rows") {
|
2025-01-20 15:08:01 +00:00
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &account, nil
|
|
|
|
}
|
|
|
|
|
2025-01-20 18:54:03 +00:00
|
|
|
func GetTokenFromRequest(db *sqlx.DB, r *http.Request) string {
|
2025-01-20 15:08:01 +00:00
|
|
|
tokenStr := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
|
2025-01-20 18:54:03 +00:00
|
|
|
if len(tokenStr) > 0 {
|
|
|
|
return tokenStr
|
|
|
|
}
|
2025-01-20 15:08:01 +00:00
|
|
|
|
2025-01-21 14:53:18 +00:00
|
|
|
cookie, err := r.Cookie(model.COOKIE_TOKEN)
|
2025-01-20 18:54:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return ""
|
2025-01-20 15:08:01 +00:00
|
|
|
}
|
2025-01-20 18:54:03 +00:00
|
|
|
return cookie.Value
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetAccountByRequest(db *sqlx.DB, r *http.Request) (*model.Account, error) {
|
|
|
|
tokenStr := GetTokenFromRequest(db, r)
|
2025-01-20 15:08:01 +00:00
|
|
|
|
|
|
|
token, err := GetToken(db, tokenStr)
|
|
|
|
if err != nil {
|
2025-01-20 18:54:03 +00:00
|
|
|
if strings.Contains(err.Error(), "no rows") {
|
2025-01-20 15:08:01 +00:00
|
|
|
return nil, nil
|
|
|
|
}
|
2025-01-20 18:54:03 +00:00
|
|
|
return nil, errors.New("GetToken: " + err.Error())
|
2025-01-20 15:08:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// does user-agent match the token?
|
|
|
|
if r.UserAgent() != token.UserAgent {
|
|
|
|
// invalidate the token
|
|
|
|
DeleteToken(db, tokenStr)
|
|
|
|
fmt.Printf("WARN: Attempted use of token by unauthorised User-Agent (Expected `%s`, got `%s`)\n", token.UserAgent, r.UserAgent())
|
|
|
|
// TODO: log unauthorised activity to the user
|
|
|
|
return nil, errors.New("User agent mismatch")
|
|
|
|
}
|
|
|
|
|
|
|
|
return GetAccountByToken(db, tokenStr)
|
|
|
|
}
|
|
|
|
|
2024-09-22 23:57:23 +00:00
|
|
|
func CreateAccount(db *sqlx.DB, account *model.Account) error {
|
2025-01-20 18:54:03 +00:00
|
|
|
err := db.Get(
|
|
|
|
&account.ID,
|
|
|
|
"INSERT INTO account (username, password, email, avatar_url) " +
|
|
|
|
"VALUES ($1, $2, $3, $4) " +
|
|
|
|
"RETURNING id",
|
|
|
|
account.Username,
|
|
|
|
account.Password,
|
|
|
|
account.Email,
|
|
|
|
account.AvatarURL,
|
|
|
|
)
|
2024-09-22 23:57:23 +00:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func UpdateAccount(db *sqlx.DB, account *model.Account) error {
|
|
|
|
_, err := db.Exec(
|
2025-01-20 18:54:03 +00:00
|
|
|
"UPDATE account " +
|
|
|
|
"SET username=$2, password=$3, email=$4, avatar_url=$5) " +
|
|
|
|
"WHERE id=$1",
|
|
|
|
account.ID,
|
|
|
|
account.Username,
|
|
|
|
account.Password,
|
|
|
|
account.Email,
|
|
|
|
account.AvatarURL,
|
|
|
|
)
|
2024-09-22 23:57:23 +00:00
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2025-01-20 18:54:03 +00:00
|
|
|
func DeleteAccount(db *sqlx.DB, username string) error {
|
|
|
|
_, err := db.Exec("DELETE FROM account WHERE username=$1", username)
|
2024-09-22 23:57:23 +00:00
|
|
|
return err
|
|
|
|
}
|