
Generally more explicit behavior is provided *NOTE: if this call succeeds then we have fully authenticated and subsequent calls should have acccess to "secret" in the serialized params structure, thus unwraps should be fine as they'll be proven via informal induction
54 lines
1.4 KiB
Rust
54 lines
1.4 KiB
Rust
use mysql_async::{Conn, Pool};
|
|
use mysql_async::prelude::{params, Queryable};
|
|
|
|
use crate::routes;
|
|
|
|
pub enum AuthReason {
|
|
Good, //passed regular check
|
|
OpenAuth, // route does not require auth
|
|
LimitPassed,
|
|
NoKey,
|
|
}
|
|
|
|
fn check_key_row(row: &Option<(i32, i32, u64)>) -> AuthReason {
|
|
// (limit, uses, _userid)
|
|
use self::AuthReason::*;
|
|
match row {
|
|
Some(data) => {
|
|
if data.1 > data.0 {
|
|
LimitPassed
|
|
}
|
|
else {
|
|
Good
|
|
}
|
|
},
|
|
None => NoKey
|
|
}
|
|
}
|
|
|
|
fn open_route(path: &str) -> bool {
|
|
return path == routes::INVITE_JOIN
|
|
}
|
|
|
|
pub async fn wall_entry(path: &str, pool: &Pool, params: &serde_json::Value) -> Result<AuthReason, mysql_async::error::Error> {
|
|
// Start by Checking if the api key is in our keystore
|
|
if open_route(path) {
|
|
Ok(AuthReason::OpenAuth)
|
|
}
|
|
else {
|
|
if let Some(key) = params.get("secret") {
|
|
let conn = pool.get_conn().await?;
|
|
// (id, name, secret)
|
|
let (_con, row): (Conn, Option<(i32, i32, u64)>) = conn
|
|
.first_exec(r"SELECT limit, uses, userid, FROM keys WHERE secret = :secret ", mysql_async::params!{ "secret" => key})
|
|
.await?;
|
|
|
|
// Error case should probably have some kind of error checking
|
|
Ok(check_key_row(&row))
|
|
}
|
|
else {
|
|
Ok(AuthReason::NoKey)
|
|
}
|
|
}
|
|
}
|