linux-auth/internal/db/sqlite.go

170 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package db
import (
"database/sql"
"errors"
"fmt"
_ "github.com/mattn/go-sqlite3"
)
/**
* @brief Структура пользователя
*/
type User struct {
ID int
Username string
PasswordHash string
FailedAttempts int
Locked bool
}
var database *sql.DB
/**
* @brief Инициализация соединения с SQLite БД
* @param path Путь к файлу базы данных
* @return ошибка при неудаче
*/
func Init(path string) error {
var err error
database, err = sql.Open("sqlite3", path)
if err != nil {
return err
}
// Проверка соединения
if err = database.Ping(); err != nil {
return err
}
return createTables()
}
/**
* @brief Закрытие соединения с БД
*/
func Close() {
if database != nil {
_ = database.Close()
}
}
/**
* @brief Создание таблиц при первом запуске
*/
func createTables() error {
query := `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
failed_attempts INTEGER DEFAULT 0,
locked INTEGER DEFAULT 0
);
`
_, err := database.Exec(query)
return err
}
/**
* @brief Получить пользователя по имени
* @param username Логин пользователя
* @return структура User или ошибка
*/
func GetUser(username string) (*User, error) {
query := `
SELECT id, username, password_hash, failed_attempts, locked
FROM users
WHERE username = ?;
`
row := database.QueryRow(query, username)
var user User
var locked int
err := row.Scan(
&user.ID,
&user.Username,
&user.PasswordHash,
&user.FailedAttempts,
&locked,
)
if err == sql.ErrNoRows {
return nil, errors.New("пользователь не найден")
}
if err != nil {
return nil, err
}
user.Locked = locked != 0
return &user, nil
}
/**
* @brief Увеличить счётчик неудачных попыток входа
* @param username Логин пользователя
*/
func IncrementFail(username string) error {
query := `
UPDATE users
SET failed_attempts = failed_attempts + 1
WHERE username = ?;
`
_, err := database.Exec(query, username)
return err
}
/**
* @brief Сбросить счётчик неудачных попыток
* @param username Логин пользователя
*/
func ResetFails(username string) error {
query := `
UPDATE users
SET failed_attempts = 0
WHERE username = ?;
`
_, err := database.Exec(query, username)
return err
}
/**
* @brief Заблокировать пользователя
* @param username Логин пользователя
*/
func LockUser(username string) error {
query := `
UPDATE users
SET locked = 1
WHERE username = ?;
`
_, err := database.Exec(query)
return err
}
/**
* @brief Добавить нового пользователя (для инициализации)
* @param username Логин
* @param passwordHash Хеш пароля
*/
func CreateUser(username, passwordHash string) error {
query := `
INSERT INTO users (username, password_hash)
VALUES (?, ?);
`
_, err := database.Exec(query, username, passwordHash)
if err != nil {
return fmt.Errorf("не удалось создать пользователя: %w", err)
}
return nil
}