Skip to content

Commit

Permalink
draft: settings overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
da2ce7 committed Nov 6, 2022
1 parent 2de8181 commit 8e5caac
Show file tree
Hide file tree
Showing 49 changed files with 3,370 additions and 800 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
/database.db
/.idea/
/config.toml
/config.toml.old
/data.db
/.vscode/launch.json
/config*/
/config.*
/local.*
38 changes: 37 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,50 @@
{
"cSpell.words": [
"AUTOINCREMENT",
"Avicora",
"Azureus",
"bencode",
"binascii",
"Bitflu",
"bufs",
"byteorder",
"canonicalize",
"canonicalized",
"chrono",
"completei",
"downloadedi",
"filesd",
"Freebox",
"hasher",
"hexlify",
"Hydranode",
"incompletei",
"intervali",
"leecher",
"leechers",
"libtorrent",
"Lphant",
"nanos",
"nocapture",
"ostr",
"Pando",
"Rasterbar",
"repr",
"rngs",
"rusqlite",
"Seedable",
"Shareaza",
"sharktorrent",
"sqllite",
"Swiftbit",
"thiserror",
"Torrentstorm",
"torrust",
"typenum"
"typenum",
"Unamed",
"untuple",
"Xtorrent",
"Xunlei"
],
"[rust]": {
"editor.formatOnSave": true
Expand Down
46 changes: 43 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,12 @@ async-trait = "0.1"

aquatic_udp_protocol = "0.2"
uuid = { version = "1", features = ["v4"] }
serde_merge = "0.1.3"
serde_yaml = "0.9.14"
#taplo = "0.11.1"


[build-dependencies]
fs_extra = "1.2.0"
#copy_to_output = "2"
glob = "0.3"
90 changes: 70 additions & 20 deletions src/api/server.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,74 @@
use std::cmp::min;
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashSet};
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;

use serde::{Deserialize, Serialize};
use warp::{filters, reply, serve, Filter};

use crate::peer::TorrentPeer;
use crate::errors::settings::ServiceSettingsError;
use crate::protocol::common::*;
use crate::tracker::tracker::TorrentTracker;
use crate::settings::{Service, ServiceProtocol};
use crate::tracker::core::TorrentTracker;
use crate::tracker::peer::TorrentPeer;
use crate::{check_field_is_not_empty, check_field_is_not_none};

pub type ApiTokens = BTreeMap<String, String>;

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct ApiServiceSettings {
pub id: String,
pub enabled: bool,
pub display_name: String,
pub socket: SocketAddr,
pub access_tokens: ApiTokens,
}

impl Default for ApiServiceSettings {
fn default() -> Self {
let mut access_tokens = BTreeMap::new();
access_tokens.insert("admin".to_string(), "password".to_string());

Self {
id: "default_api".to_string(),
enabled: false,
display_name: "HTTP API (default)".to_string(),
socket: SocketAddr::from_str("127.0.0.1:1212").unwrap(),
access_tokens,
}
}
}

impl TryFrom<(&String, &Service)> for ApiServiceSettings {
type Error = ServiceSettingsError;

fn try_from(value: (&String, &Service)) -> Result<Self, Self::Error> {
check_field_is_not_none!(value.1 => ServiceSettingsError;
enabled, service);

if value.1.service.unwrap() != ServiceProtocol::Api {
return Err(ServiceSettingsError::WrongService {
field: "service".to_string(),
expected: ServiceProtocol::Api,
found: value.1.service.unwrap(),
data: value.1.into(),
});
}

check_field_is_not_empty!(value.1 => ServiceSettingsError;
display_name: String);

Ok(Self {
id: value.0.to_owned(),
enabled: value.1.enabled.unwrap(),
display_name: value.1.display_name.to_owned().unwrap(),
socket: value.1.get_socket()?,
access_tokens: value.1.get_api_tokens()?,
})
}
}

#[derive(Deserialize, Debug)]
struct TorrentInfoQuery {
Expand Down Expand Up @@ -56,7 +115,7 @@ enum ActionStatus<'a> {

impl warp::reject::Reject for ActionStatus<'static> {}

fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
fn authenticate(tokens: ApiTokens) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
#[derive(Deserialize)]
struct AuthToken {
token: Option<String>,
Expand Down Expand Up @@ -87,7 +146,7 @@ fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Er
.untuple_one()
}

pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp::Future<Output = ()> {
pub fn start(settings: &ApiServiceSettings, tracker: Arc<TorrentTracker>) -> impl warp::Future<Output = ()> {
// GET /api/torrents?offset=:u32&limit=:u32
// View torrent list
let api_torrents = tracker.clone();
Expand Down Expand Up @@ -129,10 +188,7 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
let view_stats_list = filters::method::get()
.and(filters::path::path("stats"))
.and(filters::path::end())
.map(move || {
let tracker = api_stats.clone();
tracker
})
.map(move || api_stats.clone())
.and_then(|tracker: Arc<TorrentTracker>| async move {
let mut results = Stats {
torrents: 0,
Expand Down Expand Up @@ -304,10 +360,7 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
.and(filters::path::path("whitelist"))
.and(filters::path::path("reload"))
.and(filters::path::end())
.map(move || {
let tracker = t7.clone();
tracker
})
.map(move || t7.clone())
.and_then(|tracker: Arc<TorrentTracker>| async move {
match tracker.load_whitelist().await {
Ok(_) => Ok(warp::reply::json(&ActionStatus::Ok)),
Expand All @@ -319,15 +372,12 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp

// GET /api/keys/reload
// Reload whitelist
let t8 = tracker.clone();
let t8 = tracker;
let reload_keys = filters::method::get()
.and(filters::path::path("keys"))
.and(filters::path::path("reload"))
.and(filters::path::end())
.map(move || {
let tracker = t8.clone();
tracker
})
.map(move || t8.clone())
.and_then(|tracker: Arc<TorrentTracker>| async move {
match tracker.load_keys().await {
Ok(_) => Ok(warp::reply::json(&ActionStatus::Ok)),
Expand All @@ -349,9 +399,9 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
.or(reload_keys),
);

let server = api_routes.and(authenticate(tracker.config.http_api.access_tokens.clone()));
let server = api_routes.and(authenticate(settings.access_tokens.to_owned()));

let (_addr, api_server) = serve(server).bind_with_graceful_shutdown(socket_addr, async move {
let (_addr, api_server) = serve(server).bind_with_graceful_shutdown(settings.socket, async move {
tokio::signal::ctrl_c().await.expect("Failed to listen to shutdown signal.");
});

Expand Down
Loading

0 comments on commit 8e5caac

Please sign in to comment.