Update dependencies
This commit is contained in:
parent
ede41e5715
commit
0bd49c092d
1603
Cargo.lock
generated
1603
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
31
Cargo.toml
31
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aira"
|
name = "aira"
|
||||||
version = "0.0.3"
|
version = "0.1.1"
|
||||||
authors = ["Hardcore Sushi <hardcore.sushi@disroot.org>"]
|
authors = ["Hardcore Sushi <hardcore.sushi@disroot.org>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
exclude = ["src/frontend"]
|
exclude = ["src/frontend"]
|
||||||
@ -12,31 +12,32 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "net", "
|
|||||||
async-psec = { version = "0.4", features = ["split"] }
|
async-psec = { version = "0.4", features = ["split"] }
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
socket2 = "0.4"
|
socket2 = "0.4"
|
||||||
rusqlite = { version = "0.25.1", features = ["bundled"] }
|
rusqlite = { version = "0.27", features = ["bundled"] }
|
||||||
ed25519-dalek = "1" #for singatures
|
ed25519-dalek = "1" #for singatures
|
||||||
sha2 = "0.9"
|
sha2 = "0.10"
|
||||||
aes-gcm = "0.9"
|
aes-gcm = "0.9"
|
||||||
aes-gcm-siv = "0.10" #database encryption
|
aes-gcm-siv = "0.10" #database encryption
|
||||||
hkdf = "0.11"
|
hkdf = "0.12"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
actix-web = "3"
|
actix-web = "4"
|
||||||
actix-multipart = "0.3"
|
env_logger = "0.9"
|
||||||
time = "0.2" #needed for actix cookies
|
actix-multipart = "0.4"
|
||||||
|
time = "0.3" #needed for actix cookies
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
tungstenite = "0.15" #websocket
|
tungstenite = "0.17" #websocket
|
||||||
serde = "1.0" #serialization
|
serde = { version = "1.0", features = ["derive"] } #serialization
|
||||||
html-escape = "0.2"
|
html-escape = "0.2"
|
||||||
sanitize-filename = "0.3"
|
sanitize-filename = "0.3"
|
||||||
platform-dirs = "0.3"
|
platform-dirs = "0.3"
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "1.0", features = ["v4"] }
|
||||||
webbrowser = "0.5"
|
webbrowser = "0.7"
|
||||||
libmdns = "0.6" #mDNS advertiser
|
libmdns = "0.6" #mDNS advertiser
|
||||||
multicast_dns = "0.5" #mDNS browser
|
multicast_dns = "0.5" #mDNS browser
|
||||||
if-addrs = "0.6"
|
if-addrs = "0.7"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
scrypt = "0.7"
|
scrypt = "0.10"
|
||||||
zeroize = "1.2"
|
zeroize = "1.5"
|
||||||
image = "0.23"
|
image = "0.24"
|
||||||
yaml-rust = "0.4" #only in debug mode
|
yaml-rust = "0.4" #only in debug mode
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
43
src/main.rs
43
src/main.rs
@ -8,11 +8,11 @@ mod ui_interface;
|
|||||||
mod constants;
|
mod constants;
|
||||||
mod discovery;
|
mod discovery;
|
||||||
|
|
||||||
use std::{env, fs, io, net::SocketAddr, str::{FromStr, from_utf8}, sync::{Arc, RwLock}, cmp::Ordering};
|
use std::{env, fs, io::{self, Cursor}, net::SocketAddr, str::{FromStr, from_utf8}, sync::{Arc, RwLock}, cmp::Ordering};
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use tokio::{net::TcpListener, runtime::Handle, sync::mpsc, task::JoinError};
|
use tokio::{net::TcpListener, runtime::Handle, sync::mpsc, task::JoinError};
|
||||||
use tungstenite::Message;
|
use tungstenite::Message;
|
||||||
use actix_web::{App, HttpMessage, HttpRequest, HttpResponse, HttpServer, http::{header, CookieBuilder}, web, web::Data};
|
use actix_web::{App, HttpRequest, HttpResponse, HttpServer, http::header, cookie::CookieBuilder, web, web::Data};
|
||||||
use actix_multipart::Multipart;
|
use actix_multipart::Multipart;
|
||||||
use futures::{StreamExt, TryStreamExt};
|
use futures::{StreamExt, TryStreamExt};
|
||||||
use rand::{RngCore, rngs::OsRng};
|
use rand::{RngCore, rngs::OsRng};
|
||||||
@ -321,7 +321,7 @@ fn is_authenticated(req: &HttpRequest) -> bool {
|
|||||||
|
|
||||||
async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse {
|
async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse {
|
||||||
if let Ok(Some(mut field)) = payload.try_next().await {
|
if let Ok(Some(mut field)) = payload.try_next().await {
|
||||||
let content_disposition = field.content_disposition().unwrap();
|
let content_disposition = field.content_disposition();
|
||||||
if let Some(name) = content_disposition.get_name() {
|
if let Some(name) = content_disposition.get_name() {
|
||||||
if name == "avatar" {
|
if name == "avatar" {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
@ -339,9 +339,9 @@ async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResp
|
|||||||
Ordering::Equal => image,
|
Ordering::Equal => image,
|
||||||
};
|
};
|
||||||
let mut avatar = Vec::new();
|
let mut avatar = Vec::new();
|
||||||
image.write_to(&mut avatar, format).unwrap();
|
image.write_to(&mut Cursor::new(&mut avatar), format).unwrap();
|
||||||
let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap();
|
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
||||||
let session_manager = &global_vars.read().unwrap().session_manager;
|
let session_manager = &global_vars.session_manager;
|
||||||
let is_authenticated = is_authenticated(&req);
|
let is_authenticated = is_authenticated(&req);
|
||||||
let is_running = session_manager.is_identity_loaded();
|
let is_running = session_manager.is_identity_loaded();
|
||||||
if is_authenticated || !is_running {
|
if is_authenticated || !is_running {
|
||||||
@ -386,7 +386,7 @@ fn reply_with_avatar(avatar: Option<Vec<u8>>, name: Option<&str>) -> HttpRespons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_avatar(req: HttpRequest) -> HttpResponse {
|
async fn handle_avatar(req: HttpRequest) -> HttpResponse {
|
||||||
let splits: Vec<&str> = req.path()[1..].split('/').collect();
|
let splits: Vec<&str> = req.path()[1..].split('/').collect();
|
||||||
if splits.len() == 2 {
|
if splits.len() == 2 {
|
||||||
if splits[1] == "self" {
|
if splits[1] == "self" {
|
||||||
@ -406,13 +406,13 @@ struct FileInfo {
|
|||||||
uuid: String,
|
uuid: String,
|
||||||
file_name: String,
|
file_name: String,
|
||||||
}
|
}
|
||||||
fn handle_load_file(req: HttpRequest, file_info: web::Query<FileInfo>) -> HttpResponse {
|
async fn handle_load_file(req: HttpRequest, file_info: web::Query<FileInfo>) -> HttpResponse {
|
||||||
if is_authenticated(&req) {
|
if is_authenticated(&req) {
|
||||||
match Uuid::from_str(&file_info.uuid) {
|
match Uuid::from_str(&file_info.uuid) {
|
||||||
Ok(uuid) => {
|
Ok(uuid) => {
|
||||||
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
||||||
if let Some(buffer) = global_vars.session_manager.identity.read().unwrap().as_ref().unwrap().load_file(uuid) {
|
if let Some(buffer) = global_vars.session_manager.identity.read().unwrap().as_ref().unwrap().load_file(uuid) {
|
||||||
return HttpResponse::Ok().header("Content-Disposition", format!("attachment; filename=\"{}\"", escape_double_quote(html_escape::decode_html_entities(&file_info.file_name).to_string()))).content_type("application/octet-stream").body(buffer);
|
return HttpResponse::Ok().append_header(("Content-Disposition", format!("attachment; filename=\"{}\"", escape_double_quote(html_escape::decode_html_entities(&file_info.file_name).to_string())))).content_type("application/octet-stream").body(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => print_error!(e)
|
Err(e) => print_error!(e)
|
||||||
@ -425,14 +425,14 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
|
|||||||
if is_authenticated(&req) {
|
if is_authenticated(&req) {
|
||||||
let mut session_id: Option<usize> = None;
|
let mut session_id: Option<usize> = None;
|
||||||
while let Ok(Some(mut field)) = payload.try_next().await {
|
while let Ok(Some(mut field)) = payload.try_next().await {
|
||||||
let content_disposition = field.content_disposition().unwrap();
|
let content_disposition = field.content_disposition();
|
||||||
if let Some(name) = content_disposition.get_name() {
|
if let Some(name) = content_disposition.get_name() {
|
||||||
if name == "session_id" {
|
if name == "session_id" {
|
||||||
if let Some(Ok(raw_id)) = field.next().await {
|
if let Some(Ok(raw_id)) = field.next().await {
|
||||||
session_id = Some(from_utf8(&raw_id).unwrap().parse().unwrap());
|
session_id = Some(from_utf8(&raw_id).unwrap().parse().unwrap());
|
||||||
}
|
}
|
||||||
} else if session_id.is_some() {
|
} else if session_id.is_some() {
|
||||||
let filename = content_disposition.get_filename().unwrap();
|
let filename = content_disposition.get_filename().unwrap().to_owned();
|
||||||
let session_id = session_id.unwrap();
|
let session_id = session_id.unwrap();
|
||||||
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
||||||
if req.path() == "/send_file" {
|
if req.path() == "/send_file" {
|
||||||
@ -440,7 +440,7 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
|
|||||||
while let Some(Ok(chunk)) = field.next().await {
|
while let Some(Ok(chunk)) = field.next().await {
|
||||||
buffer.extend(chunk);
|
buffer.extend(chunk);
|
||||||
}
|
}
|
||||||
if let Ok(sent) = global_vars.session_manager.send_or_add_to_pending(&session_id, protocol::file(filename, &buffer)).await {
|
if let Ok(sent) = global_vars.session_manager.send_or_add_to_pending(&session_id, protocol::file(&filename, &buffer)).await {
|
||||||
return if sent {
|
return if sent {
|
||||||
HttpResponse::Ok().finish()
|
HttpResponse::Ok().finish()
|
||||||
} else {
|
} else {
|
||||||
@ -512,7 +512,7 @@ async fn handle_logout(req: HttpRequest) -> HttpResponse {
|
|||||||
global_vars.session_manager.stop().await;
|
global_vars.session_manager.stop().await;
|
||||||
}
|
}
|
||||||
if Identity::is_protected().unwrap_or(true) {
|
if Identity::is_protected().unwrap_or(true) {
|
||||||
HttpResponse::Found().header(header::LOCATION, "/").finish()
|
HttpResponse::Found().append_header((header::LOCATION, "/")).finish()
|
||||||
} else {
|
} else {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let html = fs::read_to_string("src/frontend/logout.html").unwrap();
|
let html = fs::read_to_string("src/frontend/logout.html").unwrap();
|
||||||
@ -541,8 +541,8 @@ fn login(identity: Identity, global_vars: &GlobalVars) -> HttpResponse {
|
|||||||
*global_vars.ui_auth_token.write().unwrap() = Some(cookie_value.clone());
|
*global_vars.ui_auth_token.write().unwrap() = Some(cookie_value.clone());
|
||||||
let cookie = CookieBuilder::new(constants::HTTP_COOKIE_NAME, cookie_value).max_age(time::Duration::hours(4)).finish();
|
let cookie = CookieBuilder::new(constants::HTTP_COOKIE_NAME, cookie_value).max_age(time::Duration::hours(4)).finish();
|
||||||
HttpResponse::Found()
|
HttpResponse::Found()
|
||||||
.header(header::LOCATION, "/")
|
.append_header((header::LOCATION, "/"))
|
||||||
.set_header(header::SET_COOKIE, cookie.to_string())
|
.insert_header((header::SET_COOKIE, cookie.to_string()))
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ fn on_identity_loaded(identity: Identity, global_vars: &Arc<GlobalVars>) -> Http
|
|||||||
struct LoginParams {
|
struct LoginParams {
|
||||||
password: String,
|
password: String,
|
||||||
}
|
}
|
||||||
fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse {
|
async fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse {
|
||||||
let response = match Identity::load_identity(Some(params.password.as_bytes())) {
|
let response = match Identity::load_identity(Some(params.password.as_bytes())) {
|
||||||
Ok(identity) => {
|
Ok(identity) => {
|
||||||
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
let global_vars = req.app_data::<Data<GlobalVars>>().unwrap();
|
||||||
@ -683,7 +683,7 @@ fn replace_fields(file_path: &str) -> String {
|
|||||||
content
|
content
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_static(req: HttpRequest) -> HttpResponse {
|
async fn handle_static(req: HttpRequest) -> HttpResponse {
|
||||||
let splits: Vec<&str> = req.path()[1..].split('/').collect();
|
let splits: Vec<&str> = req.path()[1..].split('/').collect();
|
||||||
if splits[0] == "static" {
|
if splits[0] == "static" {
|
||||||
let mut response_builder = HttpResponse::Ok();
|
let mut response_builder = HttpResponse::Ok();
|
||||||
@ -780,7 +780,6 @@ fn handle_static(req: HttpRequest) -> HttpResponse {
|
|||||||
HttpResponse::NotFound().finish()
|
HttpResponse::NotFound().finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
|
||||||
async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
|
async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
|
||||||
let http_addr = env::var("AIRA_HTTP_ADDR").unwrap_or_else(|_| "127.0.0.1".to_owned()).parse().expect("AIRA_HTTP_ADDR invalid");
|
let http_addr = env::var("AIRA_HTTP_ADDR").unwrap_or_else(|_| "127.0.0.1".to_owned()).parse().expect("AIRA_HTTP_ADDR invalid");
|
||||||
let http_port = match env::var("AIRA_HTTP_PORT") {
|
let http_port = match env::var("AIRA_HTTP_PORT") {
|
||||||
@ -789,7 +788,7 @@ async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
|
|||||||
};
|
};
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.data(global_vars.clone())
|
.app_data(Data::new(global_vars.clone()))
|
||||||
.service(web::resource("/")
|
.service(web::resource("/")
|
||||||
.route(web::get().to(handle_index))
|
.route(web::get().to(handle_index))
|
||||||
.route(web::post().to(handle_create))
|
.route(web::post().to(handle_create))
|
||||||
@ -799,8 +798,8 @@ async fn start_http_server(global_vars: GlobalVars) -> io::Result<()> {
|
|||||||
.route("/send_large_file", web::post().to(handle_send_file))
|
.route("/send_large_file", web::post().to(handle_send_file))
|
||||||
.route("/load_file", web::get().to(handle_load_file))
|
.route("/load_file", web::get().to(handle_load_file))
|
||||||
.route("/set_avatar", web::post().to(handle_set_avatar))
|
.route("/set_avatar", web::post().to(handle_set_avatar))
|
||||||
.route("/avatar/*", web::get().to(handle_avatar))
|
.route("/avatar/{_}*", web::get().to(handle_avatar))
|
||||||
.route("/static/.*", web::get().to(handle_static))
|
.route("/static/{_}*", web::get().to(handle_static))
|
||||||
.route("/logout", web::get().to(handle_logout))
|
.route("/logout", web::get().to(handle_logout))
|
||||||
}
|
}
|
||||||
).bind(SocketAddr::new(http_addr, http_port))?;
|
).bind(SocketAddr::new(http_addr, http_port))?;
|
||||||
@ -835,5 +834,5 @@ async fn main() {
|
|||||||
websocket_port,
|
websocket_port,
|
||||||
ui_auth_token,
|
ui_auth_token,
|
||||||
tokio_handle: Handle::current(),
|
tokio_handle: Handle::current(),
|
||||||
}).unwrap();
|
}).await.unwrap();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user