/* * Copyright (C) 2023 Jonni Liljamo * * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for * more information. */ package db import ( "database/sql" "errors" "github.com/matthewhartstonge/argon2" "github.com/oklog/ulid/v2" ) func CreateUser(email string, pwd string) error { argon := argon2.DefaultConfig() encoded, err := argon.HashEncoded([]byte(pwd)) if err != nil { return err } ulid := ulid.Make().String() _, err = DBConn.Exec(`INSERT INTO users(ulid, email, pwd) VALUES ($1, $2, $3)`, ulid, email, string(encoded)) if err != nil { return err } return nil } func CreateAdmin(email string, pwd string) error { argon := argon2.DefaultConfig() encoded, err := argon.HashEncoded([]byte(pwd)) if err != nil { return err } ulid := ulid.Make().String() _, err = DBConn.Exec(`INSERT INTO users(ulid, email, pwd, is_admin) VALUES ($1, $2, $3, TRUE)`, ulid, email, string(encoded)) if err != nil { return err } return nil } type User struct { Ulid string Email string } func FetchUser(email string, pwd string) (*User, error) { user := User{ Email: email } var encodedPwd string err := DBConn.QueryRow(`SELECT ulid, pwd FROM users WHERE email = $1`, email).Scan(&user.Ulid, &encodedPwd) if err == sql.ErrNoRows { return nil, errors.New("User not found") } if err != nil { return nil, errors.New("User query failed") } ok, err := argon2.VerifyEncoded([]byte(pwd), []byte(encodedPwd)) if err != nil { return nil, errors.New("User not found") } if !ok { return nil, errors.New("User not found") } return &user, nil }