diff --git a/Cargo.lock b/Cargo.lock index 9ae02623..f6102d10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,7 +650,7 @@ checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "celeste" -version = "0.8.1" +version = "0.8.3" dependencies = [ "base64 0.20.0", "blocking", diff --git a/src/login/login_util.rs b/src/login/login_util.rs index 44e3ed49..f7902259 100644 --- a/src/login/login_util.rs +++ b/src/login/login_util.rs @@ -10,6 +10,11 @@ use adw::{ use regex::Regex; use url::Url; +/// Generic input +pub fn generic_str_input(name: &str) -> EntryRow { + EntryRow::builder().title(&tr::tr!(name)).build() +} + /// Get the input for the server name. pub fn server_name_input() -> EntryRow { let input = EntryRow::builder().title(&tr::tr!("Name")).build(); diff --git a/src/login/mod.rs b/src/login/mod.rs index 3ff954ec..e57f703b 100644 --- a/src/login/mod.rs +++ b/src/login/mod.rs @@ -14,6 +14,7 @@ mod nextcloud; mod owncloud; mod pcloud; mod proton_drive; +mod s3; mod webdav; use adw::{ @@ -28,6 +29,7 @@ use nextcloud::NextcloudConfig; use owncloud::OwncloudConfig; use pcloud::PCloudConfig; use proton_drive::ProtonDriveConfig; +use s3::S3Config; use std::{cell::RefCell, rc::Rc}; use webdav::WebDavConfig; @@ -52,6 +54,7 @@ pub enum ServerType { PCloud(pcloud::PCloudConfig), ProtonDrive(proton_drive::ProtonDriveConfig), WebDav(webdav::WebDavConfig), + S3(s3::S3Config), } impl ToString for ServerType { @@ -64,6 +67,7 @@ impl ToString for ServerType { Self::PCloud(_) => "pCloud", Self::ProtonDrive(_) => "Proton Drive", Self::WebDav(_) => "WebDAV", + Self::S3(_) => "S3", } .to_string() } @@ -119,6 +123,7 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option let pcloud_name = ServerType::PCloud(Default::default()).to_string(); let proton_drive_name = ServerType::ProtonDrive(Default::default()).to_string(); let webdav_name = ServerType::WebDav(Default::default()).to_string(); + let s3_name = ServerType::S3(Default::default()).to_string(); // The dropdown for selecting the server type. let server_type_dropdown = ComboRow::builder().title(&tr::tr!("Server Type")).build(); @@ -130,6 +135,7 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option pcloud_name.as_str(), proton_drive_name.as_str(), webdav_name.as_str(), + s3_name.as_str(), ]; let server_types = StringList::new(&server_types_array); server_type_dropdown.set_model(Some(&server_types)); @@ -155,7 +161,8 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option let owncloud_items = OwncloudConfig::get_sections(&window, sender.clone()); let pcloud_items = PCloudConfig::get_sections(&window, sender.clone()); let proton_drive_items = ProtonDriveConfig::get_sections(&window, sender.clone()); - let webdav_items = WebDavConfig::get_sections(&window, sender); + let webdav_items = WebDavConfig::get_sections(&window, sender.clone()); + let s3_items = S3Config::get_sections(&window, sender); // Store the active items. let active_items: Rc, Button)>> = @@ -174,6 +181,7 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option "pcloud" => pcloud_items.clone(), "proton drive" => proton_drive_items.clone(), "webdav" => webdav_items.clone(), + "s3" => s3_items.clone(), _ => unreachable!() }; @@ -226,6 +234,7 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option ServerType::PCloud(config) => config.server_name.clone(), ServerType::ProtonDrive(config) => config.server_name.clone(), ServerType::WebDav(config) => config.server_name.clone(), + ServerType::S3(config) => config.server_name.clone(), }; let config_query = match &server { @@ -313,6 +322,19 @@ pub fn login(app: &Application, db: &DatabaseConnection) -> Option "obscure": true } }), + ServerType::S3(config) => json!({ + "name": config_name, + "parameters": { + "endpoint": config.endpoint, + "region": config.region, + "access_key_id": config.access_key_id, + "secret_access_key": config.secret_access_key, + "provider": config.provider, + "acl": config.acl, + "bucket_acl": config.bucket_acl, + }, + "type": "s3", + }), }; util::run_in_background(move || { diff --git a/src/login/s3.rs b/src/login/s3.rs new file mode 100644 index 00000000..0e999293 --- /dev/null +++ b/src/login/s3.rs @@ -0,0 +1,68 @@ +//! The data for a S3 Rclone config. +use super::{login_util, ServerType}; +use crate::mpsc::Sender; +use adw::{ + gtk::{glib, Button}, + prelude::*, + ApplicationWindow, EntryRow, +}; + +#[derive(Clone, Debug, Default)] +pub struct S3Config { + pub server_name: String, + pub endpoint: String, + pub region: String, + pub access_key_id: String, + pub secret_access_key: String, + pub provider: String, + pub acl: String, + pub bucket_acl: String, +} +impl super::LoginTrait for S3Config { + fn get_sections( + _window: &ApplicationWindow, + sender: Sender>, + ) -> (Vec, Button) { + let mut sections: Vec = vec![]; + + let server_name = login_util::server_name_input(); + let endpoint = login_util::generic_str_input("Endpoint"); + let region = login_util::generic_str_input("Region"); + let access_key_id = login_util::generic_str_input("Login ID"); + let secret_access_key = login_util::generic_str_input("Secret key"); + + let submit_button = login_util::submit_button(); + + sections.push(server_name.clone()); + sections.push(endpoint.clone()); + sections.push(region.clone()); + sections.push(access_key_id.clone()); + sections.push(secret_access_key.clone()); + + submit_button.connect_clicked( + glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key => move |_| { + + let server_type = ServerType::S3(S3Config { + server_name: server_name.text().to_string(), + endpoint: endpoint.text().to_string(), + region: region.text().to_string(), + access_key_id: access_key_id.text().to_string(), + secret_access_key: secret_access_key.text().to_string(), + // TODO handle these hardcoded values + provider: "Other".to_string(), + acl: "private".to_string(), + bucket_acl: "private".to_string(), + }); + sender.send(Some(server_type)); + }), + ); + + server_name.connect_changed(glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key, @weak submit_button => move |_| login_util::check_responses(&[&server_name, &endpoint, ®ion, &access_key_id, &secret_access_key], &submit_button))); + endpoint.connect_changed(glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key, @weak submit_button => move |_| login_util::check_responses(&[&server_name, &endpoint, ®ion, &access_key_id, &secret_access_key], &submit_button))); + region.connect_changed(glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key, @weak submit_button => move |_| login_util::check_responses(&[&server_name, &endpoint, ®ion, &access_key_id, &secret_access_key], &submit_button))); + access_key_id.connect_changed(glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key, @weak submit_button => move |_| login_util::check_responses(&[&server_name, &endpoint, ®ion, &access_key_id, &secret_access_key], &submit_button))); + secret_access_key.connect_changed(glib::clone!(@weak server_name, @weak endpoint, @weak region, @weak access_key_id, @weak secret_access_key, @weak submit_button => move |_| login_util::check_responses(&[&server_name, &endpoint, ®ion, &access_key_id, &secret_access_key], &submit_button))); + + (sections, submit_button) + } +} diff --git a/src/rclone.rs b/src/rclone.rs index c16365a9..e9479de5 100644 --- a/src/rclone.rs +++ b/src/rclone.rs @@ -53,6 +53,14 @@ pub fn get_remote(remote: T) -> Option { vendor, })) } + "s3" => Some(Remote::S3(S3Remote { + remote_name: remote, + provider: config["provider"].clone(), + access_key_id: config["access_key_id"].clone(), + secret_access_key: config["secret_access_key"].clone(), + region: config["region"].clone(), + endpoint: config["endpoint"].clone(), + })), _ => None, } } @@ -84,6 +92,7 @@ pub enum Remote { PCloud(PCloudRemote), ProtonDrive(ProtonDriveRemote), WebDav(WebDavRemote), + S3(S3Remote), } impl Remote { @@ -94,6 +103,7 @@ impl Remote { Remote::PCloud(remote) => remote.remote_name.clone(), Remote::ProtonDrive(remote) => remote.remote_name.clone(), Remote::WebDav(remote) => remote.remote_name.clone(), + Remote::S3(remote) => remote.remote_name.clone(), } } } @@ -140,6 +150,23 @@ pub struct ProtonDriveRemote { pub username: String, } +// The S3 remote type +#[derive(Clone, Debug)] +pub struct S3Remote { + /// The name of the remote. + pub remote_name: String, + /// The provider of the remote + pub provider: String, + /// The access key for the remote + pub access_key_id: String, + /// The scret key for the remote + pub secret_access_key: String, + /// The region of the remote + pub region: String, + /// The address to connect to + pub endpoint: String, +} + // The WebDav remote type. #[derive(Clone, Debug)] pub struct WebDavRemote {