+ Better secret generation
+ Helper function to clearly encrypt generated secrets + New test for auth::valid_secret as a sanity check ! routes::is_open is no longer retarded and behaves as expected
This commit is contained in:
parent
812d9a9615
commit
ea5162d185
@ -1,4 +1,4 @@
|
|||||||
use bcrypt;
|
use bcrypt::{self, BcryptResult};
|
||||||
use mysql_async::{Pool};
|
use mysql_async::{Pool};
|
||||||
use mysql_async::error::Error as SqlError;
|
use mysql_async::error::Error as SqlError;
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ use db::{member::Member, common::FromDB};
|
|||||||
use db::Response;
|
use db::Response;
|
||||||
|
|
||||||
// used when we create a new users for the first time
|
// used when we create a new users for the first time
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum AuthReason {
|
pub enum AuthReason {
|
||||||
Good, //passed regular check
|
Good, //passed regular check
|
||||||
OpenAuth, // route does not require auth
|
OpenAuth, // route does not require auth
|
||||||
@ -17,10 +18,15 @@ pub enum AuthReason {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn valid_user(given_pass: &str, hash: &str) -> bool {
|
fn valid_secret(given_pass: &str, hash: &str) -> bool {
|
||||||
return match bcrypt::verify(given_pass, hash) {
|
let result = bcrypt::verify(given_pass, hash);
|
||||||
|
println!("\tGiven: {} \tRaw: {}\t{:?}", given_pass, hash, result);
|
||||||
|
return match result {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(_) => return false
|
Err(e) => {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +40,32 @@ fn valid_perms(member: Member, path: &str) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_secret() -> String {
|
||||||
|
/*
|
||||||
|
* Generates a url-safe-plaintext secret for our db
|
||||||
|
* */
|
||||||
|
use getrandom::getrandom;
|
||||||
|
use base64::{encode_config, URL_SAFE};
|
||||||
|
|
||||||
|
let mut buf: Vec<u8> = vec![0;64];
|
||||||
|
getrandom(&mut buf).unwrap();
|
||||||
|
encode_config(buf,URL_SAFE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt_secret(raw: &str) -> BcryptResult<String> {
|
||||||
|
const BCRYPT_COST: u32 = 14;
|
||||||
|
return bcrypt::hash(raw, BCRYPT_COST);
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn wall_entry(path: &str, pool: &Pool, params: &serde_json::Value) -> Result<AuthReason, SqlError> {
|
pub async fn wall_entry(path: &str, pool: &Pool, params: &serde_json::Value) -> Result<AuthReason, SqlError> {
|
||||||
// Start by Checking if the api key is in our keystore
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
// Dont need to auth if it's not required
|
||||||
if routes::is_open(path) {
|
if routes::is_open(path) {
|
||||||
Ok(AuthReason::OpenAuth)
|
Ok(AuthReason::OpenAuth)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// make sure we have some legit parameter to use
|
||||||
match (params.get("id"), params.get("secret")) {
|
match (params.get("id"), params.get("secret")) {
|
||||||
/*
|
/*
|
||||||
* If we apparantly have user data then check for validity in credentials
|
* If we apparantly have user data then check for validity in credentials
|
||||||
@ -48,10 +74,9 @@ pub async fn wall_entry(path: &str, pool: &Pool, params: &serde_json::Value) ->
|
|||||||
/* unwrapping because i couldn't care less about poorly formatted request data */
|
/* unwrapping because i couldn't care less about poorly formatted request data */
|
||||||
let id = id_v.as_u64().unwrap_or(0); // basically nobody is allowed to have 0 as its supposed to be reserved
|
let id = id_v.as_u64().unwrap_or(0); // basically nobody is allowed to have 0 as its supposed to be reserved
|
||||||
let secret = secret_v.as_str().unwrap_or("");
|
let secret = secret_v.as_str().unwrap_or("");
|
||||||
use std::borrow::Cow;
|
|
||||||
return match Member::get(pool, id).await {
|
return match Member::get(pool, id).await {
|
||||||
Response::Row(user) => {
|
Response::Row(user) => {
|
||||||
if valid_user(secret, &user.secret) && valid_perms(user, path){
|
if valid_secret(secret, &user.secret) == true && valid_perms(user, path){
|
||||||
Ok(AuthReason::Good)
|
Ok(AuthReason::Good)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -70,17 +95,6 @@ pub async fn wall_entry(path: &str, pool: &Pool, params: &serde_json::Value) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_secret() -> String {
|
|
||||||
/*
|
|
||||||
* Generates a url-safe-plaintext secret for our db
|
|
||||||
* */
|
|
||||||
use getrandom::getrandom;
|
|
||||||
use base64::{encode_config, URL_SAFE};
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = vec![0;64];
|
|
||||||
getrandom(&mut buf).unwrap();
|
|
||||||
encode_config(buf,URL_SAFE)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -111,4 +125,13 @@ mod auth_tests {
|
|||||||
assert_eq!(true, result.is_ok());
|
assert_eq!(true, result.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn validity_check() {
|
||||||
|
use bcrypt::{hash, DEFAULT_COST};
|
||||||
|
let plain = super::generate_secret();
|
||||||
|
match hash(&plain, DEFAULT_COST) {
|
||||||
|
Ok(hash) => assert_eq!(super::valid_secret(&plain, &hash), true),
|
||||||
|
Err(err) => panic!("{}", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// TODO: this whole ass module bro i mean c'mon.... just just clean it
|
// TODO: this whole ass module bro i mean c'mon.... just just clean it
|
||||||
type Rstr = &'static str;
|
type Rstr = &'static str;
|
||||||
|
|
||||||
pub const SERVER_META: Rstr = "/meta"; // @returns server meta document TBD
|
|
||||||
pub const INVITE_CREATE: Rstr = "/invite/create"; // @ perms::CREATE_INVITE
|
pub const INVITE_CREATE: Rstr = "/invite/create"; // @ perms::CREATE_INVITE
|
||||||
|
|
||||||
pub const CHANNELS_LIST: Rstr = "/channels/list"; // requires none
|
pub const CHANNELS_LIST: Rstr = "/channels/list"; // requires none
|
||||||
@ -59,13 +58,6 @@ pub fn is_open(path: &str) -> bool {
|
|||||||
* Simple interface for determining if a route/base is open
|
* Simple interface for determining if a route/base is open
|
||||||
* i.e. requires authentication or not
|
* i.e. requires authentication or not
|
||||||
*/
|
*/
|
||||||
let mut ret = path == SERVER_META;
|
return path.starts_with("/join/");
|
||||||
for route in DYNAMIC_ROUTE_BASES.iter() {
|
|
||||||
if route.1 == true || ret == true{
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user