diff --git a/filed/config/filed.toml.example b/filed/config/filed.toml.example index 9c73491..dd3d161 100644 --- a/filed/config/filed.toml.example +++ b/filed/config/filed.toml.example @@ -21,6 +21,11 @@ allow_pass_protection=true # This is shown only if allow_uploads = false # upload_disable_reason="File uploads were disabled because of an ongoing attack." +# If you want to restrict the uploads +# To only the people who have a password, +# uncomment this field +# upload_pass=super_secret_pass + # Timeout for deleting a user uploaded file file_del_timeout=1800 diff --git a/filed/docs/file_api.swagger.yml b/filed/docs/file_api.swagger.yml index 4cdab6c..8f0818d 100644 --- a/filed/docs/file_api.swagger.yml +++ b/filed/docs/file_api.swagger.yml @@ -111,6 +111,10 @@ paths: type: string example: binary file data description: binary file data + instance_pass: + type: string + example: super_secret_pass + description: Instance-specific password needed to upload files metadata: type: object description: file info diff --git a/filed/src/config/types.rs b/filed/src/config/types.rs index dbe8bd4..878230d 100644 --- a/filed/src/config/types.rs +++ b/filed/src/config/types.rs @@ -22,6 +22,10 @@ pub struct FilesPolicy { #[serde(default)] pub upload_disable_reason: Option, + /// Upload password + #[serde(default)] + pub upload_pass: Option, + /// Default time for file to be deleted #[serde(default)] pub file_del_timeout: usize, @@ -42,6 +46,7 @@ impl Default for FilesPolicy { allow_custom_names: true, allow_pass_protection: true, upload_disable_reason: None, + upload_pass: None, file_del_timeout: 1800, type_whitelist: None, type_blacklist: None, diff --git a/filed/src/web/forms.rs b/filed/src/web/forms.rs index 9748aef..e1560b6 100644 --- a/filed/src/web/forms.rs +++ b/filed/src/web/forms.rs @@ -59,6 +59,7 @@ impl FormElement { struct UploadFormData { filename: Option, password: Option, + instancepass: Option, lookup_kind: LookupKind, delmode: DeleteMode, file: Vec, @@ -71,6 +72,7 @@ impl Default for UploadFormData { UploadFormData { filename: None, password: None, + instancepass: None, lookup_kind: LookupKind::ByHash, delmode: DeleteMode::Time, file: vec![], @@ -125,6 +127,16 @@ impl UploadFormData { } } + match data.get("instancepass") { + Some(val) => { + let val = val.data.clone(); + if let Ok(pass) = String::from_utf8(val) { + out.instancepass = Some(pass); + } + }, + None => () + }; + let file = data.get("file")?; out.file = file.data.clone(); out.mime = file.mime.clone(); @@ -199,6 +211,47 @@ pub async fn upload(form: FormData, ip: Option, state: SharedState) -> R ) } + if let Some(upload_pass) = state.config.files.upload_pass.clone() { + + if let Some(pass) = formdata.instancepass { + if upload_pass != pass { + let error = ErrorPage { + env: state.env.clone(), + conf: state.config.clone(), + error_text: "Password is invalid".into(), + link: Some("/".into()), + link_text: Some("Go back".into()) + }; + + return Ok( + Box::new( + html( + error.render() + .map_err(|x| HttpReject::AskamaError(x))? + ) + ) + ) + } + } else { + let error = ErrorPage { + env: state.env.clone(), + conf: state.config.clone(), + error_text: "Password is not available".into(), + link: Some("/".into()), + link_text: Some("Go back".into()) + }; + + return Ok( + Box::new( + html( + error.render() + .map_err(|x| HttpReject::AskamaError(x))? + ) + ) + ) + } + } + let file = File::create( formdata.file, formdata.mime, diff --git a/filed/static/assets/alert.css b/filed/static/assets/alert.css index 6228e95..55bc69d 100644 --- a/filed/static/assets/alert.css +++ b/filed/static/assets/alert.css @@ -20,4 +20,8 @@ .alert.danger .alert-title { background: #602020; +} + +.alert.blue .alert-title { + background: #203050; } \ No newline at end of file diff --git a/filed/templates/index.html b/filed/templates/index.html index 794e74f..359ecbb 100644 --- a/filed/templates/index.html +++ b/filed/templates/index.html @@ -9,6 +9,31 @@ {% endblock %} +{% block scripts %} + +{%- if conf.files.upload_pass.is_some() -%} + + {#- Script to disable button when password is not entered -#} +{#- -#} + +{%- endif -%} + +{% endblock %} + {% block body %}
@@ -114,6 +139,24 @@

{%- else -%} + + {%- if let Some(pass) = conf.files.upload_pass -%} +
+

+ Upload password +

+
+

This instance requires a password to upload a file.

+

+ +

+
+
+ {%- endif -%} +

-