Removed try_trait and some formatting, particularly around imports

This commit is contained in:
Daniel García 2020-07-14 18:00:09 +02:00
parent fb6f96f5c3
commit 668d5c23dc
No known key found for this signature in database
GPG key ID: FC8A7D14C3CD543A
25 changed files with 251 additions and 272 deletions

View file

@ -1,22 +1,26 @@
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde_json::Value;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde_json::Value;
use std::process::Command; use std::process::Command;
use rocket::http::{Cookie, Cookies, SameSite}; use rocket::{
use rocket::request::{self, FlashMessage, Form, FromRequest, Request}; http::{Cookie, Cookies, SameSite},
use rocket::response::{content::Html, Flash, Redirect}; request::{self, FlashMessage, Form, FromRequest, Request},
use rocket::{Outcome, Route}; response::{content::Html, Flash, Redirect},
Outcome, Route,
};
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use crate::api::{ApiResult, EmptyResult, JsonResult}; use crate::{
use crate::auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp}; api::{ApiResult, EmptyResult, JsonResult},
use crate::config::ConfigBuilder; auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp},
use crate::db::{backup_database, models::*, DbConn}; config::ConfigBuilder,
use crate::error::Error; db::{backup_database, models::*, DbConn},
use crate::mail; error::{Error, MapResult},
use crate::util::get_display_size; mail,
use crate::CONFIG; util::get_display_size,
CONFIG,
};
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
if !CONFIG.disable_admin_token() && !CONFIG.is_admin_token_set() { if !CONFIG.disable_admin_token() && !CONFIG.is_admin_token_set() {
@ -270,21 +274,13 @@ fn users_overview(_token: AdminToken, conn: DbConn) -> ApiResult<Html<String>> {
#[post("/users/<uuid>/delete")] #[post("/users/<uuid>/delete")]
fn delete_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { fn delete_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
let user = match User::find_by_uuid(&uuid, &conn) { let user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?;
Some(user) => user,
None => err!("User doesn't exist"),
};
user.delete(&conn) user.delete(&conn)
} }
#[post("/users/<uuid>/deauth")] #[post("/users/<uuid>/deauth")]
fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
let mut user = match User::find_by_uuid(&uuid, &conn) { let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?;
Some(user) => user,
None => err!("User doesn't exist"),
};
Device::delete_all_by_user(&user.uuid, &conn)?; Device::delete_all_by_user(&user.uuid, &conn)?;
user.reset_security_stamp(); user.reset_security_stamp();
@ -293,11 +289,7 @@ fn deauth_user(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
#[post("/users/<uuid>/remove-2fa")] #[post("/users/<uuid>/remove-2fa")]
fn remove_2fa(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult { fn remove_2fa(uuid: String, _token: AdminToken, conn: DbConn) -> EmptyResult {
let mut user = match User::find_by_uuid(&uuid, &conn) { let mut user = User::find_by_uuid(&uuid, &conn).map_res("User doesn't exist")?;
Some(user) => user,
None => err!("User doesn't exist"),
};
TwoFactor::delete_all_by_user(&user.uuid, &conn)?; TwoFactor::delete_all_by_user(&user.uuid, &conn)?;
user.totp_recover = None; user.totp_recover = None;
user.save(&conn) user.save(&conn)
@ -340,7 +332,7 @@ struct GitCommit {
} }
fn get_github_api<T: DeserializeOwned>(url: &str) -> Result<T, Error> { fn get_github_api<T: DeserializeOwned>(url: &str) -> Result<T, Error> {
use reqwest::{header::USER_AGENT, blocking::Client}; use reqwest::{blocking::Client, header::USER_AGENT};
use std::time::Duration; use std::time::Duration;
let github_api = Client::builder().build()?; let github_api = Client::builder().build()?;

View file

@ -1,19 +1,15 @@
use chrono::Utc; use chrono::Utc;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use crate::db::models::*; use crate::{
use crate::db::DbConn; api::{EmptyResult, JsonResult, JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType},
auth::{decode_delete, decode_invite, decode_verify_email, Headers},
crypto,
db::{models::*, DbConn},
mail, CONFIG,
};
use crate::api::{EmptyResult, JsonResult, JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType}; pub fn routes() -> Vec<rocket::Route> {
use crate::auth::{decode_delete, decode_invite, decode_verify_email, Headers};
use crate::crypto;
use crate::mail;
use crate::CONFIG;
use rocket::Route;
pub fn routes() -> Vec<Route> {
routes![ routes![
register, register,
profile, profile,

View file

@ -1,26 +1,20 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::path::Path; use std::path::Path;
use rocket::http::ContentType; use rocket::{http::ContentType, request::Form, Data, Route};
use rocket::{request::Form, Data, Route};
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use multipart::server::save::SavedData;
use multipart::server::{Multipart, SaveResult};
use data_encoding::HEXLOWER; use data_encoding::HEXLOWER;
use multipart::server::{save::SavedData, Multipart, SaveResult};
use crate::db::models::*; use crate::{
use crate::db::DbConn; api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType},
auth::Headers,
use crate::crypto; crypto,
db::{models::*, DbConn},
use crate::api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType}; CONFIG,
use crate::auth::Headers; };
use crate::CONFIG;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![ routes![
@ -617,9 +611,8 @@ fn share_cipher_by_uuid(
match data.Cipher.OrganizationId.clone() { match data.Cipher.OrganizationId.clone() {
// If we don't get an organization ID, we don't do anything // If we don't get an organization ID, we don't do anything
// No error because this is used when using the Clone functionality // No error because this is used when using the Clone functionality
None => {}, None => {}
Some(organization_uuid) => { Some(organization_uuid) => {
for uuid in &data.CollectionIds { for uuid in &data.CollectionIds {
match Collection::find_by_uuid_and_org(uuid, &organization_uuid, &conn) { match Collection::find_by_uuid_and_org(uuid, &organization_uuid, &conn) {
None => err!("Invalid collection ID provided"), None => err!("Invalid collection ID provided"),

View file

@ -1,15 +1,13 @@
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use crate::db::models::*; use crate::{
use crate::db::DbConn; api::{EmptyResult, JsonResult, JsonUpcase, Notify, UpdateType},
auth::Headers,
db::{models::*, DbConn},
};
use crate::api::{EmptyResult, JsonResult, JsonUpcase, Notify, UpdateType}; pub fn routes() -> Vec<rocket::Route> {
use crate::auth::Headers;
use rocket::Route;
pub fn routes() -> Vec<Route> {
routes![ routes![
get_folders, get_folders,
get_folder, get_folder,

View file

@ -29,14 +29,15 @@ pub fn routes() -> Vec<Route> {
// Move this somewhere else // Move this somewhere else
// //
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use crate::api::{EmptyResult, JsonResult, JsonUpcase}; use crate::{
use crate::auth::Headers; api::{EmptyResult, JsonResult, JsonUpcase},
use crate::db::DbConn; auth::Headers,
use crate::error::Error; db::DbConn,
error::Error,
};
#[put("/devices/identifier/<uuid>/clear-token")] #[put("/devices/identifier/<uuid>/clear-token")]
fn clear_device_token(uuid: String) -> EmptyResult { fn clear_device_token(uuid: String) -> EmptyResult {
@ -146,7 +147,7 @@ fn hibp_breach(username: String) -> JsonResult {
username username
); );
use reqwest::{header::USER_AGENT, blocking::Client}; use reqwest::{blocking::Client, header::USER_AGENT};
if let Some(api_key) = crate::CONFIG.hibp_api_key() { if let Some(api_key) = crate::CONFIG.hibp_api_key() {
let hibp_client = Client::builder().build()?; let hibp_client = Client::builder().build()?;

View file

@ -1,17 +1,14 @@
use rocket::request::Form; use num_traits::FromPrimitive;
use rocket::Route; use rocket::{request::Form, Route};
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use num_traits::FromPrimitive;
use crate::api::{ use crate::{
EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType, api::{EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType},
auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders},
db::{models::*, DbConn},
mail, CONFIG,
}; };
use crate::auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders};
use crate::db::models::*;
use crate::db::DbConn;
use crate::mail;
use crate::CONFIG;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![ routes![
@ -935,7 +932,7 @@ fn list_policies_token(org_id: String, token: String, conn: DbConn) -> JsonResul
if invite_org_id != org_id { if invite_org_id != org_id {
err!("Token doesn't match request organization"); err!("Token doesn't match request organization");
} }
// TODO: We receive the invite token as ?token=<>, validate it contains the org id // TODO: We receive the invite token as ?token=<>, validate it contains the org id
let policies = OrgPolicy::find_by_org(&org_id, &conn); let policies = OrgPolicy::find_by_org(&org_id, &conn);
let policies_json: Vec<Value> = policies.iter().map(OrgPolicy::to_json).collect(); let policies_json: Vec<Value> = policies.iter().map(OrgPolicy::to_json).collect();

View file

@ -2,13 +2,16 @@ use data_encoding::BASE32;
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use crate::api::core::two_factor::_generate_recover_code; use crate::{
use crate::api::{EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData}; api::{
use crate::auth::{ClientIp, Headers}; core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData,
use crate::crypto; },
use crate::db::{ auth::{ClientIp, Headers},
models::{TwoFactor, TwoFactorType}, crypto,
DbConn, db::{
models::{TwoFactor, TwoFactorType},
DbConn,
},
}; };
pub use crate::config::CONFIG; pub use crate::config::CONFIG;

View file

@ -3,16 +3,17 @@ use data_encoding::BASE64;
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use crate::api::core::two_factor::_generate_recover_code; use crate::{
use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, PasswordData}; api::{core::two_factor::_generate_recover_code, ApiResult, EmptyResult, JsonResult, JsonUpcase, PasswordData},
use crate::auth::Headers; auth::Headers,
use crate::crypto; crypto,
use crate::db::{ db::{
models::{TwoFactor, TwoFactorType, User}, models::{TwoFactor, TwoFactorType, User},
DbConn, DbConn,
},
error::MapResult,
CONFIG,
}; };
use crate::error::MapResult;
use crate::CONFIG;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![get_duo, activate_duo, activate_duo_put,] routes![get_duo, activate_duo, activate_duo_put,]
@ -186,7 +187,7 @@ fn activate_duo_put(data: JsonUpcase<EnableDuoData>, headers: Headers, conn: DbC
fn duo_api_request(method: &str, path: &str, params: &str, data: &DuoData) -> EmptyResult { fn duo_api_request(method: &str, path: &str, params: &str, data: &DuoData) -> EmptyResult {
const AGENT: &str = "bitwarden_rs:Duo/1.0 (Rust)"; const AGENT: &str = "bitwarden_rs:Duo/1.0 (Rust)";
use reqwest::{header::*, Method, blocking::Client}; use reqwest::{blocking::Client, header::*, Method};
use std::str::FromStr; use std::str::FromStr;
// https://duo.com/docs/authapi#api-details // https://duo.com/docs/authapi#api-details

View file

@ -1,20 +1,18 @@
use chrono::{Duration, NaiveDateTime, Utc};
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use crate::api::core::two_factor::_generate_recover_code; use crate::{
use crate::api::{EmptyResult, JsonResult, JsonUpcase, PasswordData}; api::{core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, PasswordData},
use crate::auth::Headers; auth::Headers,
use crate::crypto; crypto,
use crate::db::{ db::{
models::{TwoFactor, TwoFactorType}, models::{TwoFactor, TwoFactorType},
DbConn, DbConn,
},
error::{Error, MapResult},
mail, CONFIG,
}; };
use crate::error::Error;
use crate::mail;
use crate::CONFIG;
use chrono::{Duration, NaiveDateTime, Utc};
use std::ops::Add;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![get_email, send_email_login, send_email, email,] routes![get_email, send_email_login, send_email, email,]
@ -58,7 +56,7 @@ fn send_email_login(data: JsonUpcase<SendEmailLoginData>, conn: DbConn) -> Empty
/// Generate the token, save the data for later verification and send email to user /// Generate the token, save the data for later verification and send email to user
pub fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult { pub fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult {
let type_ = TwoFactorType::Email as i32; let type_ = TwoFactorType::Email as i32;
let mut twofactor = TwoFactor::find_by_user_and_type(user_uuid, type_, &conn)?; let mut twofactor = TwoFactor::find_by_user_and_type(user_uuid, type_, &conn).map_res("Two factor not found")?;
let generated_token = crypto::generate_token(CONFIG.email_token_size())?; let generated_token = crypto::generate_token(CONFIG.email_token_size())?;
@ -67,7 +65,7 @@ pub fn send_token(user_uuid: &str, conn: &DbConn) -> EmptyResult {
twofactor.data = twofactor_data.to_json(); twofactor.data = twofactor_data.to_json();
twofactor.save(&conn)?; twofactor.save(&conn)?;
mail::send_token(&twofactor_data.email, &twofactor_data.last_token?)?; mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?;
Ok(()) Ok(())
} }
@ -134,7 +132,7 @@ fn send_email(data: JsonUpcase<SendEmailData>, headers: Headers, conn: DbConn) -
); );
twofactor.save(&conn)?; twofactor.save(&conn)?;
mail::send_token(&twofactor_data.email, &twofactor_data.last_token?)?; mail::send_token(&twofactor_data.email, &twofactor_data.last_token.map_res("Token is empty")?)?;
Ok(()) Ok(())
} }
@ -158,7 +156,7 @@ fn email(data: JsonUpcase<EmailData>, headers: Headers, conn: DbConn) -> JsonRes
} }
let type_ = TwoFactorType::EmailVerificationChallenge as i32; let type_ = TwoFactorType::EmailVerificationChallenge as i32;
let mut twofactor = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn)?; let mut twofactor = TwoFactor::find_by_user_and_type(&user.uuid, type_, &conn).map_res("Two factor not found")?;
let mut email_data = EmailTokenData::from_json(&twofactor.data)?; let mut email_data = EmailTokenData::from_json(&twofactor.data)?;
@ -188,7 +186,7 @@ fn email(data: JsonUpcase<EmailData>, headers: Headers, conn: DbConn) -> JsonRes
/// Validate the email code when used as TwoFactor token mechanism /// Validate the email code when used as TwoFactor token mechanism
pub fn validate_email_code_str(user_uuid: &str, token: &str, data: &str, conn: &DbConn) -> EmptyResult { pub fn validate_email_code_str(user_uuid: &str, token: &str, data: &str, conn: &DbConn) -> EmptyResult {
let mut email_data = EmailTokenData::from_json(&data)?; let mut email_data = EmailTokenData::from_json(&data)?;
let mut twofactor = TwoFactor::find_by_user_and_type(&user_uuid, TwoFactorType::Email as i32, &conn)?; let mut twofactor = TwoFactor::find_by_user_and_type(&user_uuid, TwoFactorType::Email as i32, &conn).map_res("Two factor not found")?;
let issued_token = match &email_data.last_token { let issued_token = match &email_data.last_token {
Some(t) => t, Some(t) => t,
_ => err!("No token available"), _ => err!("No token available"),
@ -211,7 +209,7 @@ pub fn validate_email_code_str(user_uuid: &str, token: &str, data: &str, conn: &
let date = NaiveDateTime::from_timestamp(email_data.token_sent, 0); let date = NaiveDateTime::from_timestamp(email_data.token_sent, 0);
let max_time = CONFIG.email_expiration_time() as i64; let max_time = CONFIG.email_expiration_time() as i64;
if date.add(Duration::seconds(max_time)) < Utc::now().naive_utc() { if date + Duration::seconds(max_time) < Utc::now().naive_utc() {
err!("Token has expired") err!("Token has expired")
} }

View file

@ -3,12 +3,14 @@ use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use crate::api::{JsonResult, JsonUpcase, NumberOrString, PasswordData}; use crate::{
use crate::auth::Headers; api::{JsonResult, JsonUpcase, NumberOrString, PasswordData},
use crate::crypto; auth::Headers,
use crate::db::{ crypto,
models::{TwoFactor, User}, db::{
DbConn, models::{TwoFactor, User},
DbConn,
},
}; };
pub mod authenticator; pub mod authenticator;

View file

@ -2,19 +2,25 @@ use once_cell::sync::Lazy;
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use u2f::messages::{RegisterResponse, SignResponse, U2fSignRequest}; use u2f::{
use u2f::protocol::{Challenge, U2f}; messages::{RegisterResponse, SignResponse, U2fSignRequest},
use u2f::register::Registration; protocol::{Challenge, U2f},
register::Registration,
use crate::api::core::two_factor::_generate_recover_code; };
use crate::api::{ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString, PasswordData};
use crate::auth::Headers; use crate::{
use crate::db::{ api::{
models::{TwoFactor, TwoFactorType}, core::two_factor::_generate_recover_code, ApiResult, EmptyResult, JsonResult, JsonUpcase, NumberOrString,
DbConn, PasswordData,
},
auth::Headers,
db::{
models::{TwoFactor, TwoFactorType},
DbConn,
},
error::Error,
CONFIG,
}; };
use crate::error::Error;
use crate::CONFIG;
const U2F_VERSION: &str = "U2F_V2"; const U2F_VERSION: &str = "U2F_V2";

View file

@ -1,18 +1,18 @@
use rocket::Route; use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use yubico::config::Config; use yubico::{config::Config, verify};
use yubico::verify;
use crate::api::core::two_factor::_generate_recover_code; use crate::{
use crate::api::{EmptyResult, JsonResult, JsonUpcase, PasswordData}; api::{core::two_factor::_generate_recover_code, EmptyResult, JsonResult, JsonUpcase, PasswordData},
use crate::auth::Headers; auth::Headers,
use crate::db::{ db::{
models::{TwoFactor, TwoFactorType}, models::{TwoFactor, TwoFactorType},
DbConn, DbConn,
},
error::{Error, MapResult},
CONFIG,
}; };
use crate::error::{Error, MapResult};
use crate::CONFIG;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![generate_yubikey, activate_yubikey, activate_yubikey_put,] routes![generate_yubikey, activate_yubikey, activate_yubikey_put,]

View file

@ -1,23 +1,17 @@
use std::{
fs::{create_dir_all, remove_file, symlink_metadata, File},
io::prelude::*,
net::ToSocketAddrs,
time::{Duration, SystemTime},
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::fs::{create_dir_all, remove_file, symlink_metadata, File};
use std::io::prelude::*;
use std::net::ToSocketAddrs;
use std::time::{Duration, SystemTime};
use rocket::http::ContentType;
use rocket::response::Content;
use rocket::Route;
use reqwest::{Url, header::HeaderMap, blocking::Client, blocking::Response};
use rocket::http::Cookie;
use regex::Regex; use regex::Regex;
use reqwest::{blocking::Client, blocking::Response, header::HeaderMap, Url};
use rocket::{http::ContentType, http::Cookie, response::Content, Route};
use soup::prelude::*; use soup::prelude::*;
use crate::error::Error; use crate::{error::Error, util::Cached, CONFIG};
use crate::CONFIG;
use crate::util::Cached;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![icon] routes![icon]

View file

@ -1,19 +1,22 @@
use chrono::Local; use chrono::Local;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use rocket::request::{Form, FormItems, FromForm}; use rocket::{
use rocket::Route; request::{Form, FormItems, FromForm},
Route,
};
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use crate::api::core::two_factor::email::EmailTokenData; use crate::{
use crate::api::core::two_factor::{duo, email, yubikey}; api::{
use crate::api::{ApiResult, EmptyResult, JsonResult}; core::two_factor::{duo, email, email::EmailTokenData, yubikey},
use crate::auth::ClientIp; ApiResult, EmptyResult, JsonResult,
use crate::db::models::*; },
use crate::db::DbConn; auth::ClientIp,
use crate::mail; db::{models::*, DbConn},
use crate::util; error::MapResult,
use crate::CONFIG; mail, util, CONFIG,
};
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![login] routes![login]
@ -49,10 +52,7 @@ fn _refresh_login(data: ConnectData, conn: DbConn) -> JsonResult {
let token = data.refresh_token.unwrap(); let token = data.refresh_token.unwrap();
// Get device by refresh token // Get device by refresh token
let mut device = match Device::find_by_refresh_token(&token, &conn) { let mut device = Device::find_by_refresh_token(&token, &conn).map_res("Invalid refresh token")?;
Some(device) => device,
None => err!("Invalid refresh token"),
};
// COMMON // COMMON
let user = User::find_by_uuid(&device.user_uuid, &conn).unwrap(); let user = User::find_by_uuid(&device.user_uuid, &conn).unwrap();
@ -254,10 +254,7 @@ fn twofactor_auth(
} }
fn _selected_data(tf: Option<TwoFactor>) -> ApiResult<String> { fn _selected_data(tf: Option<TwoFactor>) -> ApiResult<String> {
match tf { tf.map(|t| t.data).map_res("Two factor doesn't exist")
Some(tf) => Ok(tf.data),
None => err!("Two factor doesn't exist"),
}
} }
fn _json_err_twofactor(providers: &[i32], user_uuid: &str, conn: &DbConn) -> ApiResult<Value> { fn _json_err_twofactor(providers: &[i32], user_uuid: &str, conn: &DbConn) -> ApiResult<Value> {

View file

@ -5,23 +5,25 @@ mod identity;
mod notifications; mod notifications;
mod web; mod web;
pub use self::admin::routes as admin_routes;
pub use self::core::routes as core_routes;
pub use self::icons::routes as icons_routes;
pub use self::identity::routes as identity_routes;
pub use self::notifications::routes as notifications_routes;
pub use self::notifications::{start_notification_server, Notify, UpdateType};
pub use self::web::routes as web_routes;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
pub use crate::api::{
admin::routes as admin_routes,
core::routes as core_routes,
icons::routes as icons_routes,
identity::routes as identity_routes,
notifications::routes as notifications_routes,
notifications::{start_notification_server, Notify, UpdateType},
web::routes as web_routes,
};
use crate::util;
// Type aliases for API methods results // Type aliases for API methods results
type ApiResult<T> = Result<T, crate::error::Error>; type ApiResult<T> = Result<T, crate::error::Error>;
pub type JsonResult = ApiResult<Json<Value>>; pub type JsonResult = ApiResult<Json<Value>>;
pub type EmptyResult = ApiResult<()>; pub type EmptyResult = ApiResult<()>;
use crate::util;
type JsonUpcase<T> = Json<util::UpCase<T>>; type JsonUpcase<T> = Json<util::UpCase<T>>;
type JsonUpcaseVec<T> = Json<Vec<util::UpCase<T>>>; type JsonUpcaseVec<T> = Json<Vec<util::UpCase<T>>>;

View file

@ -4,11 +4,12 @@ use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value as JsonValue; use serde_json::Value as JsonValue;
use crate::api::{EmptyResult, JsonResult}; use crate::{
use crate::auth::Headers; api::{EmptyResult, JsonResult},
use crate::db::DbConn; auth::Headers,
db::DbConn,
use crate::{Error, CONFIG}; Error, CONFIG,
};
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
routes![negotiate, websockets_err] routes![negotiate, websockets_err]
@ -163,7 +164,7 @@ impl Handler for WSHandler {
let mut id = None; let mut id = None;
let mut access_token = None; let mut access_token = None;
for val in params_iter { for val in params_iter {
if val.starts_with(ID_KEY) { if val.starts_with(ID_KEY) {
id = Some(&val[ID_KEY.len()..]); id = Some(&val[ID_KEY.len()..]);

View file

@ -1,15 +1,10 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use rocket::http::ContentType; use rocket::{http::ContentType, response::content::Content, response::NamedFile, Route};
use rocket::response::content::Content;
use rocket::response::NamedFile;
use rocket::Route;
use rocket_contrib::json::Json; use rocket_contrib::json::Json;
use serde_json::Value; use serde_json::Value;
use crate::error::Error; use crate::{error::Error, util::Cached, CONFIG};
use crate::util::Cached;
use crate::CONFIG;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {
// If addding more routes here, consider also adding them to // If addding more routes here, consider also adding them to

View file

@ -1,17 +1,19 @@
// //
// JWT Handling // JWT Handling
// //
use crate::util::read_file;
use chrono::{Duration, Utc}; use chrono::{Duration, Utc};
use once_cell::sync::Lazy;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use once_cell::sync::Lazy;
use jsonwebtoken::{self, Algorithm, Header, EncodingKey, DecodingKey}; use jsonwebtoken::{self, Algorithm, DecodingKey, EncodingKey, Header};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::ser::Serialize; use serde::ser::Serialize;
use crate::error::{Error, MapResult}; use crate::{
use crate::CONFIG; error::{Error, MapResult},
util::read_file,
CONFIG,
};
const JWT_ALGORITHM: Algorithm = Algorithm::RS256; const JWT_ALGORITHM: Algorithm = Algorithm::RS256;
@ -213,11 +215,15 @@ pub fn generate_admin_claims() -> AdminJWTClaims {
// //
// Bearer token authentication // Bearer token authentication
// //
use rocket::request::{self, FromRequest, Request}; use rocket::{
use rocket::Outcome; request::{self, FromRequest, Request},
Outcome,
};
use crate::db::models::{Device, User, UserOrgStatus, UserOrgType, UserOrganization}; use crate::db::{
use crate::db::DbConn; models::{Device, User, UserOrgStatus, UserOrgType, UserOrganization},
DbConn,
};
pub struct Headers { pub struct Headers {
pub host: String, pub host: String,
@ -366,7 +372,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders {
} }
}, },
}) })
}, }
_ => err_handler!("Error getting the organization id"), _ => err_handler!("Error getting the organization id"),
} }
} }
@ -404,14 +410,14 @@ impl<'a, 'r> FromRequest<'a, 'r> for AdminHeaders {
} }
} }
impl Into<Headers> for AdminHeaders { impl Into<Headers> for AdminHeaders {
fn into(self) -> Headers { fn into(self) -> Headers {
Headers { Headers {
host: self.host, host: self.host,
device: self.device, device: self.device,
user: self.user user: self.user,
} }
} }
} }
pub struct OwnerHeaders { pub struct OwnerHeaders {

View file

@ -1,11 +1,13 @@
use once_cell::sync::Lazy;
use std::process::exit; use std::process::exit;
use std::sync::RwLock; use std::sync::RwLock;
use once_cell::sync::Lazy;
use reqwest::Url; use reqwest::Url;
use crate::error::Error; use crate::{
use crate::util::{get_env, get_env_bool}; error::Error,
util::{get_env, get_env_bool},
};
static CONFIG_FILE: Lazy<String> = Lazy::new(|| { static CONFIG_FILE: Lazy<String> = Lazy::new(|| {
let data_folder = get_env("DATA_FOLDER").unwrap_or_else(|| String::from("data")); let data_folder = get_env("DATA_FOLDER").unwrap_or_else(|| String::from("data"));

View file

@ -1,10 +1,11 @@
// //
// PBKDF2 derivation // PBKDF2 derivation
// //
use std::num::NonZeroU32;
use ring::{digest, hmac, pbkdf2};
use crate::error::Error; use crate::error::Error;
use ring::{digest, hmac, pbkdf2};
use std::num::NonZeroU32;
static DIGEST_ALG: pbkdf2::Algorithm = pbkdf2::PBKDF2_HMAC_SHA256; static DIGEST_ALG: pbkdf2::Algorithm = pbkdf2::PBKDF2_HMAC_SHA256;
const OUTPUT_LEN: usize = digest::SHA256_OUTPUT_LEN; const OUTPUT_LEN: usize = digest::SHA256_OUTPUT_LEN;

View file

@ -1,18 +1,14 @@
use std::ops::Deref;
use diesel::r2d2;
use diesel::r2d2::ConnectionManager;
use diesel::{Connection as DieselConnection, ConnectionError};
use rocket::http::Status;
use rocket::request::{self, FromRequest};
use rocket::{Outcome, Request, State};
use crate::error::Error;
use chrono::prelude::*;
use std::process::Command; use std::process::Command;
use crate::CONFIG; use chrono::prelude::*;
use diesel::{r2d2, r2d2::ConnectionManager, Connection as DieselConnection, ConnectionError};
use rocket::{
http::Status,
request::{self, FromRequest},
Outcome, Request, State,
};
use crate::{error::Error, CONFIG};
/// An alias to the database connection used /// An alias to the database connection used
#[cfg(feature = "sqlite")] #[cfg(feature = "sqlite")]
@ -86,7 +82,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for DbConn {
} }
// For the convenience of using an &DbConn as a &Database. // For the convenience of using an &DbConn as a &Database.
impl Deref for DbConn { impl std::ops::Deref for DbConn {
type Target = Connection; type Target = Connection;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0

View file

@ -41,7 +41,6 @@ use reqwest::Error as ReqErr;
use serde_json::{Error as SerdeErr, Value}; use serde_json::{Error as SerdeErr, Value};
use std::io::Error as IOErr; use std::io::Error as IOErr;
use std::option::NoneError as NoneErr;
use std::time::SystemTimeError as TimeErr; use std::time::SystemTimeError as TimeErr;
use u2f::u2ferror::U2fError as U2fErr; use u2f::u2ferror::U2fError as U2fErr;
use yubico::yubicoerror::YubicoError as YubiErr; use yubico::yubicoerror::YubicoError as YubiErr;
@ -84,13 +83,6 @@ make_error! {
FromStrError(FromStrErr): _has_source, _api_error, FromStrError(FromStrErr): _has_source, _api_error,
} }
// This is implemented by hand because NoneError doesn't implement neither Display nor Error
impl From<NoneErr> for Error {
fn from(_: NoneErr) -> Self {
Error::from(("NoneError", String::new()))
}
}
impl std::fmt::Debug for Error { impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.source() { match self.source() {

View file

@ -1,21 +1,23 @@
use std::env; use std::{env, str::FromStr};
use std::str::FromStr;
use lettre::message::{header, Mailbox, Message, MultiPart, SinglePart};
use lettre::transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism};
use lettre::transport::smtp::extension::ClientId;
use lettre::{Address, SmtpTransport, Tls, TlsParameters, Transport};
use native_tls::{Protocol, TlsConnector};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use crate::api::EmptyResult;
use crate::auth::{encode_jwt, generate_delete_claims, generate_invite_claims, generate_verify_email_claims};
use crate::error::Error;
use crate::CONFIG;
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
use chrono_tz::Tz; use chrono_tz::Tz;
use native_tls::{Protocol, TlsConnector};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use lettre::{
message::{header, Mailbox, Message, MultiPart, SinglePart},
transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism},
transport::smtp::extension::ClientId,
Address, SmtpTransport, Tls, TlsParameters, Transport,
};
use crate::{
api::EmptyResult,
auth::{encode_jwt, generate_delete_claims, generate_invite_claims, generate_verify_email_claims},
error::Error,
CONFIG,
};
fn mailer() -> SmtpTransport { fn mailer() -> SmtpTransport {
let host = CONFIG.smtp_host().unwrap(); let host = CONFIG.smtp_host().unwrap();

View file

@ -1,5 +1,5 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
#![feature(proc_macro_hygiene, try_trait, ip)] #![feature(proc_macro_hygiene, ip)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
extern crate openssl; extern crate openssl;

View file

@ -1,12 +1,15 @@
// //
// Web Headers and caching // Web Headers and caching
// //
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::{ContentType, Header, HeaderMap, Method, Status};
use rocket::response::{self, Responder};
use rocket::{Data, Request, Response, Rocket};
use std::io::Cursor; use std::io::Cursor;
use rocket::{
fairing::{Fairing, Info, Kind},
http::{ContentType, Header, HeaderMap, Method, Status},
response::{self, Responder},
Data, Request, Response, Rocket,
};
use crate::CONFIG; use crate::CONFIG;
pub struct AppHeaders(); pub struct AppHeaders();
@ -189,9 +192,11 @@ impl Fairing for BetterLogging {
// //
// File handling // File handling
// //
use std::fs::{self, File}; use std::{
use std::io::{Read, Result as IOResult}; fs::{self, File},
use std::path::Path; io::{Read, Result as IOResult},
path::Path,
};
pub fn file_exists(path: &str) -> bool { pub fn file_exists(path: &str) -> bool {
Path::new(path).exists() Path::new(path).exists()
@ -253,7 +258,6 @@ pub fn get_uuid() -> String {
// String util methods // String util methods
// //
use std::ops::Try;
use std::str::FromStr; use std::str::FromStr;
pub fn upcase_first(s: &str) -> String { pub fn upcase_first(s: &str) -> String {
@ -264,12 +268,12 @@ pub fn upcase_first(s: &str) -> String {
} }
} }
pub fn try_parse_string<S, T, U>(string: impl Try<Ok = S, Error = U>) -> Option<T> pub fn try_parse_string<S, T>(string: Option<S>) -> Option<T>
where where
S: AsRef<str>, S: AsRef<str>,
T: FromStr, T: FromStr,
{ {
if let Ok(Ok(value)) = string.into_result().map(|s| s.as_ref().parse::<T>()) { if let Some(Ok(value)) = string.map(|s| s.as_ref().parse::<T>()) {
Some(value) Some(value)
} else { } else {
None None
@ -286,7 +290,7 @@ pub fn get_env<V>(key: &str) -> Option<V>
where where
V: FromStr, V: FromStr,
{ {
try_parse_string(env::var(key)) try_parse_string(env::var(key).ok())
} }
const TRUE_VALUES: &[&str] = &["true", "t", "yes", "y", "1"]; const TRUE_VALUES: &[&str] = &["true", "t", "yes", "y", "1"];