summaryrefslogtreecommitdiff
path: root/src/db.rs
blob: 2cc81e907ffb4858a7f6119121ee200da375c289 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use rusqlite::Connection;
use std;
use auth::HashedPassword;

// TODO Replace the unwraps in this file with a custom error type.

type Result<T> = std::result::Result<T, String>;

fn is_initialized(conn: &mut Connection) -> Result<bool> {
    // We just initialize every time for now.
    Ok(false)
}

pub fn init(conn: &mut Connection) -> Result<()> {
    if !is_initialized(conn)? {
        info!("Initializing db...");
        conn.execute_batch(r#"
            BEGIN;

            CREATE TABLE IF NOT EXISTS users
              (username TEXT PRIMARY KEY, salt TEXT, passwd TEXT);

            CREATE TABLE IF NOT EXISTS acls
              (username TEXT NOT NULL,
               unit TEXT NOT NULL,
               read BOOL,
               change BOOL,
               PRIMARY KEY (username, unit));

            INSERT OR IGNORE INTO acls
              (username, unit, read, change) VALUES
              ('*', '*', 0, 0);

            COMMIT;
        "#)
            .unwrap();
    }
    Ok(())
}

pub fn insert_user(conn: &Connection, username: &str, password: &HashedPassword) -> Result<()> {
    conn.execute("INSERT INTO users (username, salt, passwd)
                  VALUES (?1, ?2, ?3)",
                 &[&username, &password.salt, &password.enc])
        .unwrap();
    Ok(())
}

pub fn lookup_user(conn: &Connection, username: &str) -> Result<Option<HashedPassword>> {
    let mut stmt = conn.prepare("SELECT salt, passwd FROM users WHERE username = ?")
        .unwrap();
    let result = stmt.query_map(&[&username], |row| {
            HashedPassword {
                salt: row.get(0),
                enc: row.get(1),
            }
        })
        .unwrap()
        .map(|v| v.unwrap())
        .next();
    Ok(result)
}