arimelody.me/controller/account.go
2025-01-20 15:08:01 +00:00

125 lines
3.1 KiB
Go

package controller
import (
"arimelody-web/global"
"arimelody-web/model"
"errors"
"fmt"
"math/rand"
"net/http"
"strings"
"github.com/jmoiron/sqlx"
)
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 {
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 {
return nil, err
}
return &account, nil
}
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 {
if err.Error() == "sql: no rows in result set" {
return nil, nil
}
return nil, err
}
return &account, nil
}
func GetAccountByRequest(db *sqlx.DB, r *http.Request) (*model.Account, error) {
tokenStr := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
if tokenStr == "" {
cookie, err := r.Cookie(global.COOKIE_TOKEN)
if err != nil {
// not logged in
return nil, nil
}
tokenStr = cookie.Value
}
token, err := GetToken(db, tokenStr)
if err != nil {
if strings.HasPrefix(err.Error(), "sql: no rows") {
return nil, nil
}
return nil, errors.New(fmt.Sprintf("GetToken: %s", err.Error()))
}
// 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)
}
func CreateAccount(db *sqlx.DB, account *model.Account) error {
_, err := db.Exec(
"INSERT INTO account (username, password, email, avatar_url) " +
"VALUES ($1, $2, $3, $4)",
account.Username,
account.Password,
account.Email,
account.AvatarURL)
return err
}
func UpdateAccount(db *sqlx.DB, account *model.Account) error {
_, err := db.Exec(
"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)
return err
}
func DeleteAccount(db *sqlx.DB, accountID string) error {
_, err := db.Exec("DELETE FROM account WHERE id=$1", accountID)
return err
}
var inviteChars = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
func GenerateInviteCode(length int) []byte {
code := []byte{}
for i := 0; i < length; i++ {
code = append(code, inviteChars[rand.Intn(len(inviteChars) - 1)])
}
return code
}