diff --git a/peach-lib/src/sbot.rs b/peach-lib/src/sbot.rs index b4ca2e0..c930e19 100644 --- a/peach-lib/src/sbot.rs +++ b/peach-lib/src/sbot.rs @@ -155,21 +155,17 @@ impl SbotStatus { pub struct Config { // TODO: maybe define as a Path type? /// Directory path for the log and indexes. - pub repo: String, - /// Directory path for writing debug output. - pub debugdir: String, + pub database_directory: String, /// Secret-handshake app-key (aka. network key). pub shscap: String, /// HMAC hash used to sign messages. pub hmac: String, /// Replication hops (1: friends, 2: friends of friends). - pub hops: u8, + pub replication_hops: u8, + /// Ip address of pub + pub ip: String, /// Address to listen on. - pub lis: String, - /// Address to listen on for WebSocket connections. - pub wslis: String, - /// Address to for metrics and pprof HTTP server. - pub debuglis: String, + pub ssb_port: String, /// Enable sending local UDP broadcasts. pub localadv: bool, /// Enable listening for UDP broadcasts and connecting. @@ -182,48 +178,41 @@ pub struct Config { pub promisc: bool, /// Disable the UNIX socket RPC interface. pub nounixsock: bool, - /// Attempt to repair the filesystem before starting. - pub repair: bool, } // TODO: make this real #[derive(Debug, Deserialize, Serialize)] #[serde(default)] pub struct SbotConfig { - pub repo: String, - pub debugdir: String, + pub database_directory: String, pub shscap: String, pub hmac: String, - pub hops: i8, - pub lis: String, - pub wslis: String, - pub debuglis: String, + pub replication_hops: i8, + pub ip: String, + pub ssb_port: String, + // TODO: below settings have not been configured with tilde pub localadv: bool, pub localdiscov: bool, pub enable_ebt: bool, pub promisc: bool, pub nounixsock: bool, - pub repair: bool, } /// Default configuration values for solar-sbot. impl Default for SbotConfig { fn default() -> Self { Self { - repo: ".ssb-go".to_string(), - debugdir: "".to_string(), + database_directory: "~/.local/share/tildefriends".to_string(), shscap: "1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s=".to_string(), hmac: "".to_string(), - hops: 1, - lis: ":8008".to_string(), - wslis: ":8989".to_string(), - debuglis: "localhost:6078".to_string(), + replication_hops: 1, + ip: "".to_string(), + ssb_port: "8008".to_string(), localadv: false, localdiscov: false, enable_ebt: false, promisc: false, nounixsock: false, - repair: false, } } } @@ -233,7 +222,7 @@ impl SbotConfig { pub fn read() -> Result { // determine path of user's solar-sbot config.toml let config_path = format!( - "{}/config.toml", + "{}/sbot-config.toml", config_manager::get_config_value("TILDE_SBOT_DATADIR")? ); @@ -244,16 +233,16 @@ impl SbotConfig { Ok(config) } - /// Write the given `SbotConfig` to the solar-sbot `config.toml` file. + /// Write the given `SbotConfig` to the tilde-sbot `sbot-config.toml` file. pub fn write(config: SbotConfig) -> Result<(), PeachError> { - let repo_comment = "# For details about solar-sbot configuration, please visit the repo: https://github.com/cryptoscope/ssb\n".to_string(); + let repo_comment = "# For details about tilde-sbot configuration, please visit tilde friends documentation\n".to_string(); // convert the provided `SbotConfig` instance to a string let config_string = toml::to_string(&config)?; // determine path of user's solar-sbot config.toml let config_path = format!( - "{}/config.toml", + "{}/sbot-config.toml", config_manager::get_config_value("TILDE_SBOT_DATADIR")? ); @@ -272,20 +261,17 @@ impl SbotConfig { /// Initialise an sbot client pub async fn init_sbot() -> Result { - // read sbot config from config.toml - let sbot_config = SbotConfig::read().ok(); + + // read sbot config + let sbot_config = match SbotConfig::read() { + Ok(config) => config, + // build default config if an error is returned from the read attempt + Err(_) => SbotConfig::default(), + }; debug!("Initialising an sbot client with configuration parameters"); - // initialise sbot connection with ip:port and shscap from config file - let key_path = format!( - "{}/secret", - config_manager::get_config_value("TILDE_SBOT_DATADIR")? - ); - // TODO: read this from config - const SERVER_ADDR: &str = "http://127.0.0.1:3030"; let sbot_client = TildeClient { - name: "name".to_string(), - port: "8009".to_string(), + port: sbot_config.ssb_port, binary_path: config_manager::get_config_value("TILDE_BINARY_PATH")? }; Ok(sbot_client) diff --git a/peach-web/src/public_router.rs b/peach-web/src/public_router.rs index fd433f3..b0a63fd 100644 --- a/peach-web/src/public_router.rs +++ b/peach-web/src/public_router.rs @@ -26,7 +26,7 @@ pub fn handle_route(request: &Request, session_data: &mut Option) - } // set the `.ssb-go` path in order to mount the blob fileserver - let ssb_path = sbot::get_go_ssb_path().expect("define ssb-go dir path"); + let ssb_path = sbot::get_tilde_ssb_path().expect("define ssb-go dir path"); let blobstore = format!("{}/blobs/sha256", ssb_path); // blobstore file server diff --git a/peach-web/src/routes/settings/scuttlebutt/configure.rs b/peach-web/src/routes/settings/scuttlebutt/configure.rs index 5eb249b..715a0d6 100644 --- a/peach-web/src/routes/settings/scuttlebutt/configure.rs +++ b/peach-web/src/routes/settings/scuttlebutt/configure.rs @@ -33,16 +33,8 @@ fn read_status_and_config() -> (String, SbotConfig, String, String) { Err(_) => SbotConfig::default(), }; - // split the listen address into ip and port - let (ip, port) = match sbot_config.lis.find(':') { - Some(index) => { - let (ip, port) = sbot_config.lis.split_at(index); - // remove the : from the port - (ip.to_string(), port.replace(':', "")) - } - // if no ':' separator is found, assume an ip has been configured (without port) - None => (sbot_config.lis.to_string(), String::new()), - }; + let ip = sbot_config.ip.clone(); + let port = sbot_config.ssb_port.clone(); (run_on_startup, sbot_config, ip, port) } @@ -52,7 +44,7 @@ pub fn build_template(request: &Request) -> PreEscaped { // check for flash cookies; will be (None, None) if no flash cookies are found let (flash_name, flash_msg) = request.retrieve_flash(); - let (run_on_startup, sbot_config, ip, port) = read_status_and_config(); + let (run_on_startup, sbot_config, ip, ssb_port) = read_status_and_config(); let menu_template = html! { (PreEscaped("")) @@ -62,42 +54,42 @@ pub fn build_template(request: &Request) -> PreEscaped { label for="hops" class="label-small font-gray" { "HOPS" } div id="hops" style="display: flex; justify-content: space-evenly;" { div { - @if sbot_config.hops == 0 { - input type="radio" id="hops_0" name="hops" value="0" checked; + @if sbot_config.replication_hops == 0 { + input type="radio" id="hops_0" name="replication_hops" value="0" checked; } @else { - input type="radio" id="hops_0" name="hops" value="0"; + input type="radio" id="hops_0" name="replication_hops" value="0"; } label class="font-normal" for="hops_0" { "0" } } div { - @if sbot_config.hops == 1 { - input type="radio" id="hops_1" name="hops" value="1" checked; + @if sbot_config.replication_hops == 1 { + input type="radio" id="hops_1" name="replication_hops" value="1" checked; } @else { - input type="radio" id="hops_1" name="hops" value="1"; + input type="radio" id="hops_1" name="replication_hops" value="1"; } label class="font-normal" for="hops_1" { "1" } } div { - @if sbot_config.hops == 2 { - input type="radio" id="hops_2" name="hops" value="2" checked; + @if sbot_config.replication_hops == 2 { + input type="radio" id="hops_2" name="replication_hops" value="2" checked; } @else { - input type="radio" id="hops_2" name="hops" value="2"; + input type="radio" id="hops_2" name="replication_hops" value="2"; } label class="font-normal" for="hops_2" { "2" } } div { - @if sbot_config.hops == 3 { - input type="radio" id="hops_3" name="hops" value="3" checked; + @if sbot_config.replication_hops == 3 { + input type="radio" id="hops_3" name="replication_hops" value="3" checked; } @else { - input type="radio" id="hops_3" name="hops" value="3"; + input type="radio" id="hops_3" name="replication_hops" value="3"; } label class="font-normal" for="hops_3" { "3" } } div { - @if sbot_config.hops == 4 { - input type="radio" id="hops_4" name="hops" value="4" checked; + @if sbot_config.replication_hops == 4 { + input type="radio" id="hops_4" name="replication_hops" value="4" checked; } @else { - input type="radio" id="hops_4" name="hops" value="4"; + input type="radio" id="hops_4" name="replication_hops" value="4"; } label class="font-normal" for="hops_4" { "4" } } @@ -106,11 +98,11 @@ pub fn build_template(request: &Request) -> PreEscaped { div class="center" style="display: flex; justify-content: space-between;" { div style="display: flex; flex-direction: column; width: 60%; margin-bottom: 2rem;" title="IP address on which the sbot runs" { label for="ip" class="label-small font-gray" { "IP ADDRESS" } - input type="text" id="ip" name="lis_ip" value=(ip); + input type="text" id="ip" name="ip" value=(ip); } div style="display: flex; flex-direction: column; width: 20%; margin-bottom: 2rem;" title="Port on which the sbot runs" { label for="port" class="label-small font-gray" { "PORT" } - input type="text" id="port" name="lis_port" value=(port); + input type="text" id="port" name="ssb_port" value=(ssb_port); } } div class="center" style="display: flex; flex-direction: column; margin-bottom: 2rem;" title="Network key (aka 'caps key') to define the Scuttleverse in which the sbot operates in" { @@ -119,34 +111,35 @@ pub fn build_template(request: &Request) -> PreEscaped { } div class="center" style="display: flex; flex-direction: column; margin-bottom: 2rem;" title="Directory in which the sbot database is saved" { label for="database_dir" class="label-small font-gray" { "DATABASE DIRECTORY" } - input type="text" id="database_dir" name="repo" value=(sbot_config.repo); + input type="text" id="database_dir" name="database_directory" value=(sbot_config.database_directory); } + // TODO: re-add these checkboxes, if tilde adds them div class="center" { - @if sbot_config.enable_ebt { - input type="checkbox" id="ebtReplication" style="margin-bottom: 1rem;" name="enable_ebt" checked; - } @else { - input type="checkbox" id="ebtReplication" style="margin-bottom: 1rem;" name="enable_ebt"; - } - label class="font-normal" for="ebtReplication" title="Enable Epidemic Broadcast Tree (EBT) replication instead of legacy replication" { - "Enable EBT Replication" - } - br; - @if sbot_config.localadv { - input type="checkbox" id="lanBroadcast" style="margin-bottom: 1rem;" name="localadv" checked; - } @else { - input type="checkbox" id="lanBroadcast" style="margin-bottom: 1rem;" name="localadv"; - } - label class="font-normal" for="lanBroadcast" title="Broadcast the IP and port of this sbot instance so that local peers can discovery it and attempt to connect" { - "Enable LAN Broadcasting" - } - br; - @if sbot_config.localdiscov { - input type="checkbox" id="lanDiscovery" style="margin-bottom: 1rem;" name="localdiscov" checked; - } @else { - input type="checkbox" id="lanDiscovery" style="margin-bottom: 1rem;" name="localdiscov"; - } - label class="font-normal" for="lanDiscovery" title="Listen for the presence of local peers and attempt to connect if found" { "Enable LAN Discovery" } - br; + // @if sbot_config.enable_ebt { + // input type="checkbox" id="ebtReplication" style="margin-bottom: 1rem;" name="enable_ebt" checked; + // } @else { + // input type="checkbox" id="ebtReplication" style="margin-bottom: 1rem;" name="enable_ebt"; + // } + // label class="font-normal" for="ebtReplication" title="Enable Epidemic Broadcast Tree (EBT) replication instead of legacy replication" { + // "Enable EBT Replication" + // } + // br; + // @if sbot_config.localadv { + // input type="checkbox" id="lanBroadcast" style="margin-bottom: 1rem;" name="localadv" checked; + // } @else { + // input type="checkbox" id="lanBroadcast" style="margin-bottom: 1rem;" name="localadv"; + // } + // label class="font-normal" for="lanBroadcast" title="Broadcast the IP and port of this sbot instance so that local peers can discovery it and attempt to connect" { + // "Enable LAN Broadcasting" + // } + // br; + // @if sbot_config.localdiscov { + // input type="checkbox" id="lanDiscovery" style="margin-bottom: 1rem;" name="localdiscov" checked; + // } @else { + // input type="checkbox" id="lanDiscovery" style="margin-bottom: 1rem;" name="localdiscov"; + // } + // label class="font-normal" for="lanDiscovery" title="Listen for the presence of local peers and attempt to connect if found" { "Enable LAN Discovery" } + // br; @if run_on_startup == "enabled" { input type="checkbox" id="startup" style="margin-bottom: 1rem;" name="startup" checked; } @else { @@ -154,18 +147,9 @@ pub fn build_template(request: &Request) -> PreEscaped { } label class="font-normal" for="startup" title="Run the pub automatically on system startup" { "Run pub when computer starts" } br; - @if sbot_config.repair { - input type="checkbox" id="repair" name="repair" checked; - } @else { - input type="checkbox" id="repair" name="repair"; - } - label class="font-normal" for="repair" title="Attempt to repair the filesystem when starting the pub" { "Attempt filesystem repair when pub starts" } } (PreEscaped("")) - input type="hidden" id="debugdir" name="debugdir" value=(sbot_config.debugdir); input type="hidden" id="hmac" name="hmac" value=(sbot_config.hmac); - input type="hidden" id="wslis" name="wslis" value=(sbot_config.wslis); - input type="hidden" id="debuglis" name="debuglis" value=(sbot_config.debuglis); input type="hidden" id="promisc" name="promisc" value=(sbot_config.promisc); input type="hidden" id="nounixsock" name="nounixsock" value=(sbot_config.nounixsock); (PreEscaped("")) @@ -196,61 +180,56 @@ pub fn build_template(request: &Request) -> PreEscaped { templates::base::build_template(body, theme) } +// use std::io::Read; /// Parse the sbot configuration values and write to file. pub fn handle_form(request: &Request, restart: bool) -> Response { + // query the request body for form data // return a 400 error if the admin_id field is missing let data = try_or_400!(post_input!(request, { - repo: String, - debugdir: String, + database_directory: String, shscap: String, hmac: String, - hops: i8, - lis_ip: String, - lis_port: String, - wslis: String, - debuglis: String, + replication_hops: i8, + ip: String, + ssb_port: String, localadv: bool, localdiscov: bool, enable_ebt: bool, promisc: bool, nounixsock: bool, startup: bool, - repair: bool, })); // concat the ip and port for listen address - let lis = format!("{}:{}", data.lis_ip, data.lis_port); + let lis = format!("{}:{}", data.ip, data.ssb_port); // instantiate `SbotConfig` from form data let config = SbotConfig { - lis, - hops: data.hops, - repo: data.repo, - debugdir: data.debugdir, + ip: data.ip, + ssb_port: data.ssb_port, + replication_hops: data.replication_hops, + database_directory: data.database_directory, shscap: data.shscap, localadv: data.localadv, localdiscov: data.localdiscov, hmac: data.hmac, - wslis: data.wslis, - debuglis: data.debuglis, enable_ebt: data.enable_ebt, promisc: data.promisc, nounixsock: data.nounixsock, - repair: data.repair, }; match data.startup { true => { - debug!("Enabling go-sbot.service"); + debug!("Enabling tilde-sbot.service"); if let Err(e) = sbot::systemctl_sbot_cmd("enable") { - warn!("Failed to enable go-sbot.service: {}", e) + warn!("Failed to enable tilde-sbot.service: {}", e) } } false => { - debug!("Disabling go-sbot.service"); + debug!("Disabling tilde-sbot.service"); if let Err(e) = sbot::systemctl_sbot_cmd("disable") { - warn!("Failed to disable go-sbot.service: {}", e) + warn!("Failed to disable tilde-sbot.service: {}", e) } } }; diff --git a/peach-web/src/routes/status/scuttlebutt.rs b/peach-web/src/routes/status/scuttlebutt.rs index fd8ca8d..087d982 100644 --- a/peach-web/src/routes/status/scuttlebutt.rs +++ b/peach-web/src/routes/status/scuttlebutt.rs @@ -102,7 +102,7 @@ fn memory_element(memory: Option) -> Markup { fn hops_element() -> Markup { // retrieve go-sbot systemd process status let hops = match SbotConfig::read() { - Ok(conf) => conf.hops, + Ok(conf) => conf.replication_hops, _ => 0, }; diff --git a/peach-web/src/utils/sbot.rs b/peach-web/src/utils/sbot.rs index 29700b4..810a98d 100644 --- a/peach-web/src/utils/sbot.rs +++ b/peach-web/src/utils/sbot.rs @@ -66,11 +66,6 @@ pub fn restart_sbot_process() -> (String, String) { /// Initialise an sbot client with the given configuration parameters. pub async fn init_sbot_client() -> Result { debug!("Initialising an sbot client with configuration parameters"); - // initialise sbot connection with ip:port and shscap from config file - let key_path = format!( - "{}/secret.toml", - config_manager::get_config_value("TILDE_SBOT_DATADIR")? - ); let sbot_client = init_sbot().await?; Ok(sbot_client) } @@ -154,12 +149,11 @@ pub fn create_invite(uses: u16) -> Result { debug!("Generating Scuttlebutt invite code"); let mut invite_code = sbot_client.create_invite(uses as i32).await?; - // // TODO: insert domain into invite if one is configured - // let domain = config_manager::get_config_value("EXTERNAL_DOMAIN")?; - // if !domain.is_empty() { - // invite_code = domain + &invite_code[4..]; - // } - // + let domain = config_manager::get_config_value("EXTERNAL_DOMAIN")?; + if !domain.is_empty() { + invite_code = domain + &invite_code[4..]; + } + Ok(invite_code) }) } @@ -596,16 +590,16 @@ pub fn publish_private_msg(text: String, recipients: Vec) -> Result Result { - let go_ssb_path = match SbotConfig::read() { - Ok(conf) => conf.repo, +/// Return the path of the tilde-sbot directory. +pub fn get_tilde_ssb_path() -> Result { + let tilde_ssb_path = match SbotConfig::read() { + Ok(conf) => conf.database_directory, // return the default path if unable to read `config.toml` Err(_) => { // determine the home directory let mut home_path = dirs::home_dir().ok_or(PeachWebError::HomeDir)?; - // add the go-ssb subdirectory - home_path.push(".ssb-go"); + // add the .ssb-tilde subdirectory + home_path.push(".ssb-tilde"); // convert the PathBuf to a String home_path .into_os_string() @@ -613,12 +607,12 @@ pub fn get_go_ssb_path() -> Result { .map_err(|_| PeachWebError::OsString)? } }; - Ok(go_ssb_path) + Ok(tilde_ssb_path) } /// Check whether a blob is in the blobstore. pub async fn blob_is_stored_locally(blob_path: &str) -> Result { - let go_ssb_path = get_go_ssb_path()?; + let go_ssb_path = get_tilde_ssb_path()?; let complete_path = format!("{}/blobs/sha256/{}", go_ssb_path, blob_path); let blob_exists_locally = Path::new(&complete_path).exists(); Ok(blob_exists_locally) diff --git a/run-tilde-sbot.sh b/run-tilde-sbot.sh new file mode 100755 index 0000000..ba06b57 --- /dev/null +++ b/run-tilde-sbot.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +CONFIG_FILE="/home/notplants/.local/share/tildefriends/sbot-config.toml" + +# Extract network_key (if it exists) +NETWORK_KEY=$(grep -v '^\s*#' "$CONFIG_FILE" | grep -E '^\s*network_key\s*=' | sed -E 's/.*=\s*"?(.*?)"?\s*/\1/') +DATABASE_DIRECTORY=$(grep -v '^\s*#' "$CONFIG_FILE" \ + | grep -E '^\s*database_directory\s*=' \ + | sed -E 's/.*=\s*"([^"]*)"\s*/\1/') + +# Extract all other key-value pairs except network_key +ARGS=$(grep -v '^\s*#' "$CONFIG_FILE" \ + | grep -E '^\s*[a-zA-Z0-9_.-]+\s*=' \ + | grep -v '^\s*network_key\s*=' \ + | sed -E 's/\s*=\s*/=/' \ + | tr -d '"' \ + | paste -sd, -) + +echo "ARGS: $ARGS" +[ -n "$NETWORK_KEY" ] && echo "NETWORK_KEY: $NETWORK_KEY" +[ -n "$DATABASE_DIRECTORY" ] && echo "DATABASE_DIRECTORY: $DATABASE_DIRECTORY" + +CMD="/home/notplants/computer/projects/peachpub/tilde/tildefriends/out/release/tildefriends.standalone run" +[ -n "$ARGS" ] && CMD="$CMD -a \"$ARGS\"" +[ -n "$NETWORK_KEY" ] && CMD="$CMD -k \"$NETWORK_KEY\"" +[ -n "$DATABASE_DIRECTORY" ] && CMD="$CMD -d \"$DATABASE_DIRECTORY/db.sql\"" + +echo "Running command:" +echo "$CMD" + +# Execute the command +eval $CMD diff --git a/tilde-client/src/lib.rs b/tilde-client/src/lib.rs index 81b319b..2950025 100644 --- a/tilde-client/src/lib.rs +++ b/tilde-client/src/lib.rs @@ -9,7 +9,6 @@ use std::process::{Command, exit}; mod error; pub struct TildeClient { - pub name: String, pub port: String, pub binary_path: String, } @@ -131,7 +130,6 @@ impl TildeClient { } pub async fn create_invite(&self, num_uses: i32) -> Result { - // TODO: look up ip/domain from config let key = self.whoami().await?; self.run_tilde_command(vec!["create_invite", "-u", &num_uses.to_string(), "-i", &key, "-p", &self.port, "-a", "127.0.0.1", "-e", "-1"]) }