1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2025-05-28 01:15:43 +02:00

Docs and minor improvements to "ntfy access"

This commit is contained in:
Philipp Heckel 2022-02-01 16:40:33 -05:00
parent e56eb0c178
commit 5cf92c55c6
7 changed files with 120 additions and 34 deletions

View file

@ -2,13 +2,16 @@ package auth
import (
"database/sql"
"errors"
"fmt"
_ "github.com/mattn/go-sqlite3" // SQLite driver
"golang.org/x/crypto/bcrypt"
"strings"
)
const (
bcryptCost = 11
bcryptCost = 11
intentionalSlowDownHash = "$2a$11$eX15DeF27FwAgXt9wqJF0uAUMz74XywJcGBH3kP93pzKYv6ATk2ka" // Cost should match bcryptCost
)
// Auther-related queries
@ -27,7 +30,7 @@ const (
write INT NOT NULL,
PRIMARY KEY (topic, user)
);
CREATE TABLE IF NOT EXISTS schema_version (
CREATE TABLE IF NOT EXISTS schemaVersion (
id INT PRIMARY KEY,
version INT NOT NULL
);
@ -61,6 +64,13 @@ const (
deleteTopicAccessQuery = `DELETE FROM access WHERE user = ? AND topic = ?`
)
// Schema management queries
const (
currentSchemaVersion = 1
insertSchemaVersion = `INSERT INTO schemaVersion VALUES (1, ?)`
selectSchemaVersionQuery = `SELECT version FROM schemaVersion WHERE id = 1`
)
// SQLiteAuth is an implementation of Auther and Manager. It stores users and access control list
// in a SQLite database.
type SQLiteAuth struct {
@ -78,7 +88,7 @@ func NewSQLiteAuth(filename string, defaultRead, defaultWrite bool) (*SQLiteAuth
if err != nil {
return nil, err
}
if err := setupNewAuthDB(db); err != nil {
if err := setupAuthDB(db); err != nil {
return nil, err
}
return &SQLiteAuth{
@ -88,14 +98,6 @@ func NewSQLiteAuth(filename string, defaultRead, defaultWrite bool) (*SQLiteAuth
}, nil
}
func setupNewAuthDB(db *sql.DB) error {
if _, err := db.Exec(createAuthTablesQueries); err != nil {
return err
}
// FIXME schema version
return nil
}
// Authenticate checks username and password and returns a user if correct. The method
// returns in constant-ish time, regardless of whether the user exists or the password is
// correct or incorrect.
@ -105,7 +107,7 @@ func (a *SQLiteAuth) Authenticate(username, password string) (*User, error) {
}
user, err := a.User(username)
if err != nil {
bcrypt.CompareHashAndPassword([]byte("$2a$11$eX15DeF27FwAgXt9wqJF0uAUMz74XywJcGBH3kP93pzKYv6ATk2ka"),
bcrypt.CompareHashAndPassword([]byte(intentionalSlowDownHash),
[]byte("intentional slow-down to avoid timing attacks"))
return nil, ErrUnauthenticated
}
@ -360,3 +362,38 @@ func toSQLWildcard(s string) string {
func fromSQLWildcard(s string) string {
return strings.ReplaceAll(s, "%", "*")
}
func setupAuthDB(db *sql.DB) error {
// If 'schemaVersion' table does not exist, this must be a new database
rowsSV, err := db.Query(selectSchemaVersionQuery)
if err != nil {
return setupNewAuthDB(db)
}
defer rowsSV.Close()
// If 'schemaVersion' table exists, read version and potentially upgrade
schemaVersion := 0
if !rowsSV.Next() {
return errors.New("cannot determine schema version: database file may be corrupt")
}
if err := rowsSV.Scan(&schemaVersion); err != nil {
return err
}
rowsSV.Close()
// Do migrations
if schemaVersion == currentSchemaVersion {
return nil
}
return fmt.Errorf("unexpected schema version found: %d", schemaVersion)
}
func setupNewAuthDB(db *sql.DB) error {
if _, err := db.Exec(createAuthTablesQueries); err != nil {
return err
}
if _, err := db.Exec(insertSchemaVersion, currentSchemaVersion); err != nil {
return err
}
return nil
}