Skip to content

Commit 0fd33f2

Browse files
committed
draft: settings overhaul
1 parent 2de8181 commit 0fd33f2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3370
-800
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
/database.db
55
/.idea/
66
/config.toml
7+
/config.toml.old
78
/data.db
89
/.vscode/launch.json
10+
/config*/
11+
/config.*
12+
/local.*

.vscode/settings.json

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,50 @@
11
{
22
"cSpell.words": [
3+
"AUTOINCREMENT",
4+
"Avicora",
5+
"Azureus",
6+
"bencode",
7+
"binascii",
8+
"Bitflu",
9+
"bufs",
310
"byteorder",
11+
"canonicalize",
12+
"canonicalized",
13+
"chrono",
14+
"completei",
15+
"downloadedi",
16+
"filesd",
17+
"Freebox",
418
"hasher",
19+
"hexlify",
20+
"Hydranode",
21+
"incompletei",
22+
"intervali",
23+
"leecher",
524
"leechers",
25+
"libtorrent",
26+
"Lphant",
627
"nanos",
28+
"nocapture",
29+
"ostr",
30+
"Pando",
31+
"Rasterbar",
32+
"repr",
733
"rngs",
34+
"rusqlite",
835
"Seedable",
36+
"Shareaza",
37+
"sharktorrent",
38+
"sqllite",
39+
"Swiftbit",
940
"thiserror",
41+
"Torrentstorm",
1042
"torrust",
11-
"typenum"
43+
"typenum",
44+
"Unamed",
45+
"untuple",
46+
"Xtorrent",
47+
"Xunlei"
1248
],
1349
"[rust]": {
1450
"editor.formatOnSave": true

Cargo.lock

Lines changed: 43 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,12 @@ async-trait = "0.1"
5959

6060
aquatic_udp_protocol = "0.2"
6161
uuid = { version = "1", features = ["v4"] }
62+
serde_merge = "0.1.3"
63+
serde_yaml = "0.9.14"
64+
#taplo = "0.11.1"
65+
66+
67+
[build-dependencies]
68+
fs_extra = "1.2.0"
69+
#copy_to_output = "2"
70+
glob = "0.3"

src/api/server.rs

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,74 @@
11
use std::cmp::min;
2-
use std::collections::{HashMap, HashSet};
2+
use std::collections::{BTreeMap, HashSet};
33
use std::net::SocketAddr;
4+
use std::str::FromStr;
45
use std::sync::Arc;
56
use std::time::Duration;
67

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

10-
use crate::peer::TorrentPeer;
11+
use crate::errors::settings::ServiceSettingsError;
1112
use crate::protocol::common::*;
12-
use crate::tracker::tracker::TorrentTracker;
13+
use crate::settings::{Service, ServiceProtocol};
14+
use crate::tracker::core::TorrentTracker;
15+
use crate::tracker::peer::TorrentPeer;
16+
use crate::{check_field_is_not_empty, check_field_is_not_none};
17+
18+
pub type ApiTokens = BTreeMap<String, String>;
19+
20+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
21+
pub struct ApiServiceSettings {
22+
pub id: String,
23+
pub enabled: bool,
24+
pub display_name: String,
25+
pub socket: SocketAddr,
26+
pub access_tokens: ApiTokens,
27+
}
28+
29+
impl Default for ApiServiceSettings {
30+
fn default() -> Self {
31+
let mut access_tokens = BTreeMap::new();
32+
access_tokens.insert("admin".to_string(), "password".to_string());
33+
34+
Self {
35+
id: "default_api".to_string(),
36+
enabled: false,
37+
display_name: "HTTP API (default)".to_string(),
38+
socket: SocketAddr::from_str("127.0.0.1:1212").unwrap(),
39+
access_tokens,
40+
}
41+
}
42+
}
43+
44+
impl TryFrom<(&String, &Service)> for ApiServiceSettings {
45+
type Error = ServiceSettingsError;
46+
47+
fn try_from(value: (&String, &Service)) -> Result<Self, Self::Error> {
48+
check_field_is_not_none!(value.1 => ServiceSettingsError;
49+
enabled, service);
50+
51+
if value.1.service.unwrap() != ServiceProtocol::Api {
52+
return Err(ServiceSettingsError::WrongService {
53+
field: "service".to_string(),
54+
expected: ServiceProtocol::Api,
55+
found: value.1.service.unwrap(),
56+
data: value.1.into(),
57+
});
58+
}
59+
60+
check_field_is_not_empty!(value.1 => ServiceSettingsError;
61+
display_name: String);
62+
63+
Ok(Self {
64+
id: value.0.to_owned(),
65+
enabled: value.1.enabled.unwrap(),
66+
display_name: value.1.display_name.to_owned().unwrap(),
67+
socket: value.1.get_socket()?,
68+
access_tokens: value.1.get_api_tokens()?,
69+
})
70+
}
71+
}
1372

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

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

59-
fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
118+
fn authenticate(tokens: ApiTokens) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
60119
#[derive(Deserialize)]
61120
struct AuthToken {
62121
token: Option<String>,
@@ -87,7 +146,7 @@ fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Er
87146
.untuple_one()
88147
}
89148

90-
pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp::Future<Output = ()> {
149+
pub fn start(settings: &ApiServiceSettings, tracker: Arc<TorrentTracker>) -> impl warp::Future<Output = ()> {
91150
// GET /api/torrents?offset=:u32&limit=:u32
92151
// View torrent list
93152
let api_torrents = tracker.clone();
@@ -129,10 +188,7 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
129188
let view_stats_list = filters::method::get()
130189
.and(filters::path::path("stats"))
131190
.and(filters::path::end())
132-
.map(move || {
133-
let tracker = api_stats.clone();
134-
tracker
135-
})
191+
.map(move || api_stats.clone())
136192
.and_then(|tracker: Arc<TorrentTracker>| async move {
137193
let mut results = Stats {
138194
torrents: 0,
@@ -304,10 +360,7 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
304360
.and(filters::path::path("whitelist"))
305361
.and(filters::path::path("reload"))
306362
.and(filters::path::end())
307-
.map(move || {
308-
let tracker = t7.clone();
309-
tracker
310-
})
363+
.map(move || t7.clone())
311364
.and_then(|tracker: Arc<TorrentTracker>| async move {
312365
match tracker.load_whitelist().await {
313366
Ok(_) => Ok(warp::reply::json(&ActionStatus::Ok)),
@@ -319,15 +372,12 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
319372

320373
// GET /api/keys/reload
321374
// Reload whitelist
322-
let t8 = tracker.clone();
375+
let t8 = tracker;
323376
let reload_keys = filters::method::get()
324377
.and(filters::path::path("keys"))
325378
.and(filters::path::path("reload"))
326379
.and(filters::path::end())
327-
.map(move || {
328-
let tracker = t8.clone();
329-
tracker
330-
})
380+
.map(move || t8.clone())
331381
.and_then(|tracker: Arc<TorrentTracker>| async move {
332382
match tracker.load_keys().await {
333383
Ok(_) => Ok(warp::reply::json(&ActionStatus::Ok)),
@@ -349,9 +399,9 @@ pub fn start(socket_addr: SocketAddr, tracker: Arc<TorrentTracker>) -> impl warp
349399
.or(reload_keys),
350400
);
351401

352-
let server = api_routes.and(authenticate(tracker.config.http_api.access_tokens.clone()));
402+
let server = api_routes.and(authenticate(settings.access_tokens.to_owned()));
353403

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

0 commit comments

Comments
 (0)