Add "moonfire-nvr login username" command

This should be useful when creating sessions for robot users without
ever having to set a password for them.
This commit is contained in:
Scott Lamb
2019-06-19 22:54:46 -07:00
parent 004aa5d6ce
commit 49a8e5c5a1
5 changed files with 221 additions and 15 deletions

View File

@@ -210,7 +210,7 @@ pub enum RevocationReason {
pub struct Session {
user_id: i32,
flags: i32, // bitmask of SessionFlags enum values
domain: Vec<u8>,
domain: Option<Vec<u8>>,
description: Option<String>,
seed: Seed,
@@ -490,14 +490,18 @@ impl State {
Ok(())
}
pub fn get_user(&self, username: &str) -> Option<&User> {
self.users_by_name
.get(username)
.map(|id| self.users_by_id.get(id).expect("users_by_name implies users_by_id"))
}
pub fn login_by_password(&mut self, conn: &Connection, req: Request, username: &str,
password: String, domain: Vec<u8>, session_flags: i32)
password: String, domain: Option<Vec<u8>>, session_flags: i32)
-> Result<(RawSessionId, &Session), Error> {
let id = match self.users_by_name.get(username) {
None => bail!("no such user {:?}", username),
Some(&id) => id,
};
let u = self.users_by_id.get_mut(&id).expect("users_by_name implies users_by_id");
let id = self.users_by_name.get(username)
.ok_or_else(|| format_err!("no such user {:?}", username))?;
let u = self.users_by_id.get_mut(id).expect("users_by_name implies users_by_id");
if u.disabled() {
bail!("user {:?} is disabled", username);
}
@@ -521,15 +525,27 @@ impl State {
u.dirty = true;
}
let password_id = u.password_id;
State::make_session(conn, req, u, domain, Some(password_id), session_flags,
State::make_session_int(conn, req, u, domain, Some(password_id), session_flags,
&mut self.sessions, u.permissions.clone())
}
fn make_session<'s>(conn: &Connection, creation: Request, user: &mut User, domain: Vec<u8>,
creation_password_id: Option<i32>, flags: i32,
sessions: &'s mut FnvHashMap<SessionHash, Session>,
permissions: Permissions)
-> Result<(RawSessionId, &'s Session), Error> {
/// Makes a session directly (no password required).
pub fn make_session<'s>(&'s mut self, conn: &Connection, creation: Request, uid: i32,
domain: Option<Vec<u8>>, flags: i32, permissions: Permissions)
-> Result<(RawSessionId, &'s Session), Error> {
let u = self.users_by_id.get_mut(&uid).ok_or_else(|| format_err!("no such uid {:?}", uid))?;
if u.disabled() {
bail!("user is disabled");
}
State::make_session_int(conn, creation, u, domain, None, flags, &mut self.sessions,
permissions)
}
fn make_session_int<'s>(conn: &Connection, creation: Request, user: &mut User,
domain: Option<Vec<u8>>, creation_password_id: Option<i32>, flags: i32,
sessions: &'s mut FnvHashMap<SessionHash, Session>,
permissions: Permissions)
-> Result<(RawSessionId, &'s Session), Error> {
let mut session_id = RawSessionId::new();
::openssl::rand::rand_bytes(&mut session_id.0).unwrap();
let mut seed = [0u8; 32];

View File

@@ -1774,12 +1774,22 @@ impl LockedDatabase {
self.auth.delete_user(&mut self.conn, id)
}
pub fn get_user(&self, username: &str) -> Option<&User> {
self.auth.get_user(username)
}
pub fn login_by_password(&mut self, req: auth::Request, username: &str, password: String,
domain: Vec<u8>, session_flags: i32)
domain: Option<Vec<u8>>, session_flags: i32)
-> Result<(RawSessionId, &Session), Error> {
self.auth.login_by_password(&self.conn, req, username, password, domain, session_flags)
}
pub fn make_session(&mut self, creation: Request, uid: i32,
domain: Option<Vec<u8>>, flags: i32, permissions: schema::Permissions)
-> Result<(RawSessionId, &Session), Error> {
self.auth.make_session(&self.conn, creation, uid, domain, flags, permissions)
}
pub fn authenticate_session(&mut self, req: auth::Request, sid: &auth::SessionHash)
-> Result<(&auth::Session, &User), Error> {
self.auth.authenticate_session(&self.conn, req, sid)