Skip to content

Commit

Permalink
Add setting for default expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
obreitwi committed Mar 27, 2021
1 parent 843ee25 commit 29a1c9c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
Previously: `asfa push --alias my-alias.txt -- my-original-file.txt`
Now: `asfa push --alias my-alias.txt my-original-file.txt`
* Check response for errors regaring `atd` not running if `--expire` specified.
* Now supports a default setting for `--expire` in the config. Same as auth,
both a global setting and host-specific settings are supported.
* `list`:
* More informative message if no files are present on remote site.
* tests:
Expand Down
4 changes: 3 additions & 1 deletion example-config/asfa/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
default_host: my-remote-site # optional, if only one host is defined, that one
# will be used. Can be overwritten by ASFA_HOST
# environment variable.
expire: 3days # optional, expire all uploads with the given duration by default
verify_via_hash: true # defaults to true
prefix_length: 32 # optional, defaults to 32, how many hex-digits of the hash
# to print
Expand All @@ -27,7 +28,8 @@ hosts: # dictionary mapping host alias to host settings
# openSSH and defaults to 22 otherwise
user: my-remote-user # defaults to current user if not set
folder: /var/www/default/asfa # target folder where to store data,
# needs to be writable
# needs to be writable
expire: 1day # host-specific setting for expiring all uploads
url: https://my-domain.eu/asfa # URL that is prefixed when URLs are
# printed, this is of no functional
# relevance right now
Expand Down
27 changes: 27 additions & 0 deletions src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ pub struct Config {
/// List of all configured hosts.
hosts: HashMap<String, Host>,

/// Expire the uploaded file after the given amount of time via `at`-scheduled remote job.
///
/// Select files newer than the given duration. Durations can be: seconds (sec, s), minutes
/// (min, m), days (d), weeks (w), months (M) or years (y).
///
/// Mininum time till expiration is a minute.
pub expire: Option<String>,

/// Length of prefix to use unless overwritten in host
pub prefix_length: u8,

Expand Down Expand Up @@ -62,6 +70,16 @@ pub struct Host {
/// Overwrite global authentication settings for this host.
pub auth: Auth,

/// Expire the uploaded file after the given amount of time via `at`-scheduled remote job.
///
/// Select files newer than the given duration. Durations can be: seconds (sec, s), minutes
/// (min, m), days (d), weeks (w), months (M) or years (y).
///
/// Mininum time till expiration is a minute.
///
/// Overrides the global setting.
pub expire: Option<String>,

/// In which folder do we store files on the host.
pub folder: PathBuf,

Expand Down Expand Up @@ -123,6 +141,7 @@ impl Default for Config {
Config {
auth: Auth::default(),
default_host: None,
expire: None,
hosts: HashMap::new(),
prefix_length: 32,
verify_via_hash: true,
Expand Down Expand Up @@ -244,6 +263,9 @@ impl Config {
std::env::var("ASFA_HOST")
.ok()
.or(get_string_from(config_yaml, "default_host")?.cloned());

config.expire = get_string_from(config_yaml, "expire")?.cloned();

config.verify_via_hash = get_bool_from(config_yaml, "verify_via_hash")?
.cloned()
.unwrap_or(config.verify_via_hash);
Expand Down Expand Up @@ -312,6 +334,10 @@ impl Host {

let user = get_string_from(dict, "user")?.cloned();

let expire = get_string_from(dict, "expire")?
.cloned()
.or_else(|| config.expire.clone());

let folder = expanduser(get_required(dict, "folder", get_string_from)?)?;

let group = get_string_from(dict, "group")?.cloned();
Expand All @@ -334,6 +360,7 @@ impl Host {
Ok(Host {
alias,
auth,
expire,
folder,
group,
hostname,
Expand Down
8 changes: 7 additions & 1 deletion src/cmd/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub struct Push {
/// (min, m), days (d), weeks (w), months (M) or years (y).
///
/// Mininum time till expiration is a minute.
///
/// Any setting specified via command line overwrites any settings from config files.
#[clap(short, long)]
expire: Option<String>,

Expand Down Expand Up @@ -90,7 +92,11 @@ impl Push {
let hash = get_hash(to_upload, prefix_length)
.with_context(|| format!("Could not read {} to compute hash.", to_upload.display()))?;

let expirer = if let Some(delay) = self.expire.as_ref() {
let expirer = if let Some(delay) = self
.expire
.as_ref()
.or_else(|| session.host.expire.as_ref())
{
Some(At::new(session, &delay)?)
} else {
None
Expand Down
11 changes: 11 additions & 0 deletions test-utils/ci-config/raw.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@ hosts:
auth:
interactive: false
use_agent: false
asfa-ci-pw-expire:
hostname: localhost:2222
folder: /var/www/default/uploads
url: https://my-domain.eu/asfa
group: "1234"
user: asfa-ci-user
password: foobar
expire: 1min
auth:
interactive: false
use_agent: false
21 changes: 13 additions & 8 deletions tests/simple-file-upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fn expiring_file_upload_begin(host: &str) -> Result<(PathBuf, Instant)> {
let hash_b64 = base64::encode_config(hex::decode(hash)?, base64::URL_SAFE);
// also test specifying alias for single file first
run_cmd(format!(
"cargo run -- --loglevel debug -H {} push --alias {} {} --expire 1min",
"cargo run -- --loglevel debug -H {} push --alias {} {}",
host,
alias,
local.display()
Expand All @@ -155,14 +155,18 @@ fn expiring_file_upload_begin(host: &str) -> Result<(PathBuf, Instant)> {
}

fn expiring_file_upload_verify(path: &Path, uploaded_at: &Instant) -> Result<()> {
let need_to_wait = Duration::from_secs(61); // wait two minutes to be sure
let already_waited = Instant::now().duration_since(*uploaded_at);
if already_waited < need_to_wait {
let need_to_wait = Duration::from_secs(121); // wait two minutes to be sure
let mut already_waited = Instant::now().duration_since(*uploaded_at);
while Path::new(path).exists() && already_waited < need_to_wait {
println!(
"Waiting for {}s to ensure upload expires.",
(need_to_wait - already_waited).as_secs()
"Waiting {}s for upload to expire.",
already_waited.as_secs()
);
std::thread::sleep(need_to_wait - already_waited);
std::thread::sleep(std::cmp::min(
need_to_wait - already_waited,
std::time::Duration::from_secs(10),
));
already_waited = Instant::now().duration_since(*uploaded_at);
}

if Path::new(path).exists() {
Expand Down Expand Up @@ -252,7 +256,8 @@ fn clean_all(host: &str) -> Result<()> {
fn run_tests() -> Result<()> {
fixture::ensure_env()?;

let (upload_to_expire, to_expire_uploaded_at) = expiring_file_upload_begin("asfa-ci-pw")?;
let (upload_to_expire, to_expire_uploaded_at) =
expiring_file_upload_begin("asfa-ci-pw-expire")?;
simple_file_upload("asfa-ci-pw")?;
simple_file_upload("asfa-ci-key")?;
upload_with_prefix_suffix("asfa-ci-key")?;
Expand Down

0 comments on commit 29a1c9c

Please sign in to comment.