Check that sync.server.origin is a URL (#3361)

This commit is contained in:
Dustin J. Mitchell
2024-04-15 22:11:55 -04:00
committed by GitHub
parent 4d9bb20bdd
commit 10cec507cb
6 changed files with 18 additions and 3 deletions

1
Cargo.lock generated
View File

@@ -2095,6 +2095,7 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"ureq", "ureq",
"url",
"uuid", "uuid",
] ]

View File

@@ -45,3 +45,4 @@ tokio = { version = "1", features = ["rt-multi-thread"] }
thiserror = "1.0" thiserror = "1.0"
ureq = { version = "^2.9.0", features = ["tls"] } ureq = { version = "^2.9.0", features = ["tls"] }
uuid = { version = "^1.8.0", features = ["serde", "v4"] } uuid = { version = "^1.8.0", features = ["serde", "v4"] }
url = { version = "2" }

View File

@@ -73,6 +73,8 @@ Configure Taskwarrior with these details:
$ task config sync.server.origin <origin> $ task config sync.server.origin <origin>
$ task config sync.server.client_id <client_id> $ task config sync.server.client_id <client_id>
Note that the origin must include the scheme, such as 'http://' or 'https://'.
.SS Google Cloud Platform .SS Google Cloud Platform
To synchronize your tasks to GCP, use the GCP Console to create a new project, To synchronize your tasks to GCP, use the GCP Console to create a new project,

View File

@@ -186,7 +186,7 @@ static void test_replica_sync_local(void) {
static void test_replica_remote_server(void) { static void test_replica_remote_server(void) {
TCString err; TCString err;
TCServer *server = tc_server_new_sync( TCServer *server = tc_server_new_sync(
tc_string_borrow("tc.freecinc.com"), tc_string_borrow("http://tc.freecinc.com"),
tc_uuid_new_v4(), tc_uuid_new_v4(),
tc_string_borrow("\xf0\x28\x8c\x28"), // NOTE: not utf-8 tc_string_borrow("\xf0\x28\x8c\x28"), // NOTE: not utf-8
&err); &err);

View File

@@ -15,7 +15,7 @@ rust-version = "1.70.0"
default = ["server-sync", "server-gcp"] default = ["server-sync", "server-gcp"]
# Support for sync to a server # Support for sync to a server
server-sync = ["encryption", "dep:ureq"] server-sync = ["encryption", "dep:ureq", "dep:url"]
# Support for sync to GCP # Support for sync to GCP
server-gcp = ["cloud", "encryption", "dep:google-cloud-storage", "dep:tokio"] server-gcp = ["cloud", "encryption", "dep:google-cloud-storage", "dep:tokio"]
# (private) Support for sync protocol encryption # (private) Support for sync protocol encryption
@@ -43,10 +43,12 @@ byteorder.workspace = true
ring.workspace = true ring.workspace = true
google-cloud-storage.workspace = true google-cloud-storage.workspace = true
tokio.workspace = true tokio.workspace = true
url.workspace = true
google-cloud-storage.optional = true google-cloud-storage.optional = true
tokio.optional = true tokio.optional = true
ureq.optional = true ureq.optional = true
url.optional = true
ring.optional = true ring.optional = true
[dev-dependencies] [dev-dependencies]

View File

@@ -4,6 +4,7 @@ use crate::server::{
VersionId, VersionId,
}; };
use std::time::Duration; use std::time::Duration;
use url::Url;
use uuid::Uuid; use uuid::Uuid;
use super::encryption::{Cryptor, Sealed, Secret, Unsealed}; use super::encryption::{Cryptor, Sealed, Secret, Unsealed};
@@ -28,8 +29,16 @@ impl SyncServer {
/// identify this client to the server. Multiple replicas synchronizing the same task history /// identify this client to the server. Multiple replicas synchronizing the same task history
/// should use the same client_id. /// should use the same client_id.
pub fn new(origin: String, client_id: Uuid, encryption_secret: Vec<u8>) -> Result<SyncServer> { pub fn new(origin: String, client_id: Uuid, encryption_secret: Vec<u8>) -> Result<SyncServer> {
let origin = Url::parse(&origin)
.map_err(|_| Error::Server(format!("Could not parse {} as a URL", origin)))?;
if origin.path() != "/" {
return Err(Error::Server(format!(
"Server origin must have an empty path; got {}",
origin
)));
}
Ok(SyncServer { Ok(SyncServer {
origin, origin: origin.to_string(),
client_id, client_id,
cryptor: Cryptor::new(client_id, &Secret(encryption_secret.to_vec()))?, cryptor: Cryptor::new(client_id, &Secret(encryption_secret.to_vec()))?,
agent: ureq::AgentBuilder::new() agent: ureq::AgentBuilder::new()