one-click registration works
parent
ebd1026903
commit
ce82f7d6a3
|
@ -123,11 +123,8 @@ async fn handle_http_request (
|
|||
|
||||
let req_method = req.method.clone ();
|
||||
|
||||
{
|
||||
let config = state.config.read ().await;
|
||||
if ! config.servers.contains_key (server_name) {
|
||||
return Err (UnknownServer);
|
||||
}
|
||||
if ! state.server_exists (server_name).await {
|
||||
return Err (UnknownServer);
|
||||
}
|
||||
|
||||
let user = get_user_name (&req);
|
||||
|
@ -643,10 +640,16 @@ async fn handle_all (
|
|||
let api_key = req.headers ().get ("X-ApiKey");
|
||||
|
||||
let api_key = match api_key {
|
||||
None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run server without an API key")?),
|
||||
None => return Ok (error_reply (StatusCode::FORBIDDEN, "Forbidden")?),
|
||||
Some (x) => x,
|
||||
};
|
||||
server_endpoint::handle_listen (state, listen_code.into (), api_key.as_bytes ()).await?
|
||||
|
||||
match check_server_api_key (state, listen_code, api_key.as_bytes ()).await {
|
||||
Ok (_) => (),
|
||||
Err (_) => return Ok (error_reply (StatusCode::FORBIDDEN, "Forbidden")?)
|
||||
}
|
||||
|
||||
server_endpoint::handle_listen (state, listen_code.into ()).await?
|
||||
},
|
||||
ServerHttpResponse {
|
||||
request_code,
|
||||
|
@ -658,39 +661,40 @@ async fn handle_all (
|
|||
Ok (response)
|
||||
}
|
||||
|
||||
async fn check_server_api_key (state: &Relay, name: &str, req: &http::request::Parts)
|
||||
async fn check_server_api_key (state: &Relay, name: &str, api_key: &[u8])
|
||||
-> Result <(), anyhow::Error>
|
||||
{
|
||||
let api_key = req.headers.get ("X-ApiKey");
|
||||
let actual_tripcode = key_validity::BlakeHashWrapper::from_key (api_key);
|
||||
|
||||
let api_key = match api_key {
|
||||
None => bail! ("Can't run server without an API key"),
|
||||
Some (x) => x,
|
||||
};
|
||||
|
||||
let actual_tripcode = blake3::hash (api_key.as_bytes ());
|
||||
|
||||
let expected_tripcode = {
|
||||
let expected_human = {
|
||||
let config = state.config.read ().await;
|
||||
|
||||
match config.servers.get (name) {
|
||||
None => {
|
||||
state.unregistered_servers.push (crate::RejectedServer {
|
||||
name: name.to_string (),
|
||||
tripcode: actual_tripcode,
|
||||
seen: Utc::now (),
|
||||
}).await;
|
||||
bail! ("Denied API request for non-existent server name {}", name);
|
||||
},
|
||||
Some (x) => *(*x).tripcode,
|
||||
}
|
||||
config.servers.get (name).map (|s| s.tripcode.clone ())
|
||||
};
|
||||
|
||||
if expected_tripcode != actual_tripcode {
|
||||
bail! ("Denied API request for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ()));
|
||||
let expected_machine = {
|
||||
let me_config = state.me_config.read ().await;
|
||||
|
||||
me_config.servers.get (name).map (|s| s.tripcode.clone ())
|
||||
};
|
||||
|
||||
if expected_machine.is_none () && expected_human.is_none () {
|
||||
state.unregistered_servers.push (crate::RejectedServer {
|
||||
name: name.to_string (),
|
||||
tripcode: *actual_tripcode,
|
||||
seen: Utc::now (),
|
||||
}).await;
|
||||
bail! ("Denied API request for non-existent server name {}", name);
|
||||
}
|
||||
|
||||
Ok (())
|
||||
if Some (actual_tripcode) == expected_human {
|
||||
return Ok (());
|
||||
}
|
||||
if Some (actual_tripcode) == expected_machine {
|
||||
return Ok (());
|
||||
}
|
||||
|
||||
bail! ("Denied API request for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ()));
|
||||
}
|
||||
|
||||
fn load_templates (asset_root: &Path)
|
||||
|
|
|
@ -182,7 +182,7 @@ impl TryFrom <Config> for Relay {
|
|||
let me_config = match machine_editable::Config::from_file (Path::new ("data/ptth_relay_me_config.toml"))
|
||||
{
|
||||
Err (e) => {
|
||||
error! ("Can't load machine-editable config: {:?}", e);
|
||||
warn! ("Can't load machine-editable config: {:?}", e);
|
||||
me_config
|
||||
},
|
||||
Ok (x) => x,
|
||||
|
@ -211,6 +211,24 @@ impl Relay {
|
|||
.collect ()
|
||||
}
|
||||
|
||||
pub async fn server_exists (&self, name: &str) -> bool {
|
||||
{
|
||||
let config = self.config.read ().await;
|
||||
if config.servers.contains_key (name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let config = self.me_config.read ().await;
|
||||
if config.servers.contains_key (name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn build () -> Builder {
|
||||
Builder::default ()
|
||||
}
|
||||
|
|
|
@ -68,20 +68,31 @@ pub async fn v1_server_list (state: &Relay)
|
|||
-> ServerList
|
||||
{
|
||||
// name --> display_name
|
||||
let display_names: HashMap <String, String> = {
|
||||
let mut display_names = HashMap::new ();
|
||||
|
||||
{
|
||||
let guard = state.config.read ().await;
|
||||
|
||||
let servers = (*guard).servers.iter ()
|
||||
.map (|(k, v)| {
|
||||
for (k, v) in &guard.servers {
|
||||
let display_name = v.display_name
|
||||
.clone ()
|
||||
.unwrap_or_else (|| k.clone ());
|
||||
|
||||
(k.clone (), display_name)
|
||||
});
|
||||
display_names.insert (k.clone (), display_name);
|
||||
}
|
||||
}
|
||||
|
||||
servers.collect ()
|
||||
};
|
||||
{
|
||||
let guard = state.me_config.read ().await;
|
||||
|
||||
for (k, v) in &guard.servers {
|
||||
let display_name = v.display_name
|
||||
.clone ()
|
||||
.unwrap_or_else (|| k.clone ());
|
||||
|
||||
display_names.insert (k.clone (), display_name);
|
||||
}
|
||||
}
|
||||
|
||||
// name --> status
|
||||
let server_statuses = {
|
||||
|
|
|
@ -45,41 +45,12 @@ use super::{
|
|||
pub async fn handle_listen (
|
||||
state: &Relay,
|
||||
watcher_code: String,
|
||||
api_key: &[u8],
|
||||
)
|
||||
-> Result <Response <Body>, RequestError>
|
||||
{
|
||||
use super::RequestRendezvous::*;
|
||||
|
||||
let trip_error = || Ok (error_reply (StatusCode::UNAUTHORIZED, "Bad X-ApiKey")?);
|
||||
|
||||
let now = Utc::now ();
|
||||
let actual_tripcode = blake3::hash (api_key);
|
||||
|
||||
let expected_tripcode = {
|
||||
let config = state.config.read ().await;
|
||||
|
||||
match config.servers.get (&watcher_code) {
|
||||
None => {
|
||||
error! ("Denied http_listen for non-existent server name {}", watcher_code);
|
||||
state.unregistered_servers.push (crate::RejectedServer {
|
||||
name: watcher_code,
|
||||
tripcode: actual_tripcode,
|
||||
seen: now,
|
||||
}).await;
|
||||
|
||||
return trip_error ();
|
||||
},
|
||||
Some (x) => *(*x).tripcode,
|
||||
}
|
||||
};
|
||||
|
||||
if expected_tripcode != actual_tripcode {
|
||||
error! ("Denied http_listen for bad tripcode {}", base64::encode (actual_tripcode.as_bytes ()));
|
||||
return trip_error ();
|
||||
}
|
||||
|
||||
// End of early returns
|
||||
|
||||
{
|
||||
// TODO: Move into relay_state.rs
|
||||
|
|
Loading…
Reference in New Issue