summaryrefslogtreecommitdiffstats
path: root/rust/src/endpoints.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/endpoints.rs')
-rw-r--r--rust/src/endpoints.rs250
1 files changed, 133 insertions, 117 deletions
diff --git a/rust/src/endpoints.rs b/rust/src/endpoints.rs
index 4817184f..7d6db908 100644
--- a/rust/src/endpoints.rs
+++ b/rust/src/endpoints.rs
@@ -69,11 +69,12 @@ macro_rules! wrap_entity_handlers {
// stable doesn't have a mechanism to "concat" or generate new identifiers in macros, at least
// in the context of defining new functions.
// The only stable approach I know of would be: https://github.com/dtolnay/mashup
- ($get_fn:ident, $get_resp:ident, $post_fn:ident, $post_resp:ident, $post_batch_fn:ident,
- $post_batch_handler:ident, $post_batch_resp:ident, $update_fn:ident, $update_resp:ident,
- $delete_fn:ident, $delete_resp:ident, $get_history_fn:ident, $get_history_resp:ident,
- $get_edit_fn:ident, $get_edit_resp:ident, $delete_edit_fn:ident, $delete_edit_resp:ident,
- $get_rev_fn:ident, $get_rev_resp:ident, $get_redirects_fn:ident, $get_redirects_resp:ident,
+ ($get_fn:ident, $get_resp:ident, $post_fn:ident, $post_resp:ident, $auto_batch_type:ident,
+ $post_auto_batch_fn:ident, $post_auto_batch_handler:ident, $post_auto_batch_resp:ident,
+ $update_fn:ident, $update_resp:ident, $delete_fn:ident, $delete_resp:ident,
+ $get_history_fn:ident, $get_history_resp:ident, $get_edit_fn:ident, $get_edit_resp:ident,
+ $delete_edit_fn:ident, $delete_edit_resp:ident, $get_rev_fn:ident, $get_rev_resp:ident,
+ $get_redirects_fn:ident, $get_redirects_resp:ident,
$model:ident) => {
fn $get_fn(
@@ -110,8 +111,8 @@ macro_rules! wrap_entity_handlers {
fn $post_fn(
&self,
- entity: models::$model,
editgroup_id: String,
+ entity: models::$model,
context: &Context,
) -> Box<Future<Item = $post_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
@@ -120,7 +121,7 @@ macro_rules! wrap_entity_handlers {
let auth_context = self.auth_confectionary.require_auth(&conn, &context.auth_data, Some(stringify!($post_fn)))?;
auth_context.require_role(FatcatRole::Editor)?;
auth_context.require_editgroup(&conn, editgroup_id)?;
- let edit_context = make_edit_context(&conn, auth_context.editor_id, Some(editgroup_id), false, None, None)?;
+ let edit_context = make_edit_context(auth_context.editor_id, editgroup_id, false)?;
edit_context.check(&conn)?;
entity.db_create(&conn, &edit_context)?.into_model()
}).map_err(|e| FatcatError::from(e)) {
@@ -133,54 +134,51 @@ macro_rules! wrap_entity_handlers {
Box::new(futures::done(Ok(ret)))
}
- fn $post_batch_fn(
+ fn $post_auto_batch_fn(
&self,
- entity_list: &Vec<models::$model>,
- autoaccept: Option<bool>,
- editgroup_id: Option<String>,
- description: Option<String>,
- extra: Option<String>,
+ auto_batch: $auto_batch_type,
context: &Context,
- ) -> Box<Future<Item = $post_batch_resp, Error = ApiError> + Send> {
+ ) -> Box<Future<Item = $post_auto_batch_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
let ret = match conn.transaction(|| {
- let auth_context = self.auth_confectionary.require_auth(&conn, &context.auth_data, Some(stringify!($post_batch_fn)))?;
- let autoaccept = autoaccept.unwrap_or(false);
- if autoaccept {
- auth_context.require_role(FatcatRole::Admin)?;
- } else {
- auth_context.require_role(FatcatRole::Editor)?;
- };
- let editgroup_id = if let Some(s) = editgroup_id {
- // make_edit_context() checks for "both editgroup_id and autosubmit" error case
- let eg_id = FatcatId::from_str(&s)?;
- auth_context.require_editgroup(&conn, eg_id)?;
- Some(eg_id)
- } else { None };
- let extra: Option<serde_json::Value> = match extra {
- Some(v) => serde_json::from_str(&v)?,
- None => None,
+ let auth_context = self.auth_confectionary.require_auth(&conn, &context.auth_data, Some(stringify!($post_auto_batch_fn)))?;
+ auth_context.require_role(FatcatRole::Admin)?;
+ let mut editgroup = auto_batch.editgroup.clone();
+ // TODO: this is duplicated code with create_editgroup()
+ match editgroup.editor_id.clone() {
+ Some(editor_id) => {
+ if editor_id != auth_context.editor_id.to_string()
+ && !auth_context.has_role(FatcatRole::Admin)
+ {
+ return Err(FatcatError::InsufficientPrivileges(
+ "not authorized to create editgroups in others' names".to_string()
+ ))
+ }
+ }
+ None => {
+ editgroup.editor_id = Some(auth_context.editor_id.to_string());
+ }
};
- self.$post_batch_handler(&conn, entity_list, autoaccept, auth_context.editor_id, editgroup_id, description, extra)
- }).map_err(|e| FatcatError::from(e)) {
- Ok(edits) => {
- self.metrics.count("entities.created", edits.len() as i64).ok();
- if let Some(true) = autoaccept {
- self.metrics.incr("editgroup.created").ok();
- self.metrics.incr("editgroup.accepted").ok();
- };
- $post_batch_resp::CreatedEntities(edits)
+ self.$post_auto_batch_handler(&conn, editgroup, &auto_batch.entity_list, auth_context.editor_id)
+ .map_err(|e| FatcatError::from(e))
+ }) {
+ Ok(editgroup) => {
+ // TODO: need a count helper on editgroup
+ //self.metrics.count("entities.created", count as i64).ok();
+ self.metrics.incr("editgroup.created").ok();
+ self.metrics.incr("editgroup.accepted").ok();
+ $post_auto_batch_resp::CreatedEditgroup(editgroup)
},
- Err(fe) => generic_auth_err_responses!(fe, $post_batch_resp),
+ Err(fe) => generic_auth_err_responses!(fe, $post_auto_batch_resp),
};
Box::new(futures::done(Ok(ret)))
}
fn $update_fn(
&self,
+ editgroup_id: String,
ident: String,
entity: models::$model,
- editgroup_id: String,
context: &Context,
) -> Box<Future<Item = $update_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
@@ -190,7 +188,7 @@ macro_rules! wrap_entity_handlers {
auth_context.require_role(FatcatRole::Editor)?;
let entity_id = FatcatId::from_str(&ident)?;
auth_context.require_editgroup(&conn, editgroup_id)?;
- let edit_context = make_edit_context(&conn, auth_context.editor_id, Some(editgroup_id), false, None, None)?;
+ let edit_context = make_edit_context(auth_context.editor_id, editgroup_id, false)?;
edit_context.check(&conn)?;
entity.db_update(&conn, &edit_context, entity_id)?.into_model()
}).map_err(|e| FatcatError::from(e)) {
@@ -205,8 +203,8 @@ macro_rules! wrap_entity_handlers {
fn $delete_fn(
&self,
- ident: String,
editgroup_id: String,
+ ident: String,
context: &Context,
) -> Box<Future<Item = $delete_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
@@ -216,7 +214,7 @@ macro_rules! wrap_entity_handlers {
auth_context.require_role(FatcatRole::Editor)?;
let entity_id = FatcatId::from_str(&ident)?;
auth_context.require_editgroup(&conn, editgroup_id)?;
- let edit_context = make_edit_context(&conn, auth_context.editor_id, Some(editgroup_id), false, None, None)?;
+ let edit_context = make_edit_context(auth_context.editor_id, editgroup_id, false)?;
edit_context.check(&conn)?;
$model::db_delete(&conn, &edit_context, entity_id)?.into_model()
}).map_err(|e| FatcatError::from(e)) {
@@ -300,18 +298,27 @@ macro_rules! wrap_entity_handlers {
fn $delete_edit_fn(
&self,
+ editgroup_id: String,
edit_id: String,
context: &Context,
) -> Box<Future<Item = $delete_edit_resp, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
let ret = match conn.transaction(|| {
+ let editgroup_id = FatcatId::from_str(&editgroup_id)?;
let edit_id = Uuid::from_str(&edit_id)?;
let auth_context = self.auth_confectionary.require_auth(&conn, &context.auth_data, Some(stringify!($delete_edit_fn)))?;
auth_context.require_role(FatcatRole::Editor)?;
let edit = $model::db_get_edit(&conn, edit_id)?;
- auth_context.require_editgroup(&conn, FatcatId::from_uuid(&edit.editgroup_id))?;
+ if !(edit.editgroup_id == editgroup_id.to_uuid()) {
+ return Err(FatcatError::BadRequest(
+ "editgroup_id parameter didn't match that of the edit".to_string()
+ ))
+ }
+ auth_context.require_editgroup(&conn, editgroup_id)?;
+ // check for editgroup being deleted happens in db_delete_edit()
$model::db_delete_edit(&conn, edit_id)
- }).map_err(|e| FatcatError::from(e)) {
+ .map_err(|e| FatcatError::from(e))
+ }) {
Ok(()) =>
$delete_edit_resp::DeletedEdit(Success {
success: true,
@@ -429,9 +436,10 @@ impl Api for Server {
GetContainerResponse,
create_container,
CreateContainerResponse,
- create_container_batch,
- create_container_batch_handler,
- CreateContainerBatchResponse,
+ ContainerAutoBatch,
+ create_container_auto_batch,
+ create_container_auto_batch_handler,
+ CreateContainerAutoBatchResponse,
update_container,
UpdateContainerResponse,
delete_container,
@@ -454,9 +462,10 @@ impl Api for Server {
GetCreatorResponse,
create_creator,
CreateCreatorResponse,
- create_creator_batch,
- create_creator_batch_handler,
- CreateCreatorBatchResponse,
+ CreatorAutoBatch,
+ create_creator_auto_batch,
+ create_creator_auto_batch_handler,
+ CreateCreatorAutoBatchResponse,
update_creator,
UpdateCreatorResponse,
delete_creator,
@@ -478,9 +487,10 @@ impl Api for Server {
GetFileResponse,
create_file,
CreateFileResponse,
- create_file_batch,
- create_file_batch_handler,
- CreateFileBatchResponse,
+ FileAutoBatch,
+ create_file_auto_batch,
+ create_file_auto_batch_handler,
+ CreateFileAutoBatchResponse,
update_file,
UpdateFileResponse,
delete_file,
@@ -502,9 +512,10 @@ impl Api for Server {
GetFilesetResponse,
create_fileset,
CreateFilesetResponse,
- create_fileset_batch,
- create_fileset_batch_handler,
- CreateFilesetBatchResponse,
+ FilesetAutoBatch,
+ create_fileset_auto_batch,
+ create_fileset_auto_batch_handler,
+ CreateFilesetAutoBatchResponse,
update_fileset,
UpdateFilesetResponse,
delete_fileset,
@@ -526,9 +537,10 @@ impl Api for Server {
GetWebcaptureResponse,
create_webcapture,
CreateWebcaptureResponse,
- create_webcapture_batch,
- create_webcapture_batch_handler,
- CreateWebcaptureBatchResponse,
+ WebcaptureAutoBatch,
+ create_webcapture_auto_batch,
+ create_webcapture_auto_batch_handler,
+ CreateWebcaptureAutoBatchResponse,
update_webcapture,
UpdateWebcaptureResponse,
delete_webcapture,
@@ -550,9 +562,10 @@ impl Api for Server {
GetReleaseResponse,
create_release,
CreateReleaseResponse,
- create_release_batch,
- create_release_batch_handler,
- CreateReleaseBatchResponse,
+ ReleaseAutoBatch,
+ create_release_auto_batch,
+ create_release_auto_batch_handler,
+ CreateReleaseAutoBatchResponse,
update_release,
UpdateReleaseResponse,
delete_release,
@@ -574,9 +587,10 @@ impl Api for Server {
GetWorkResponse,
create_work,
CreateWorkResponse,
- create_work_batch,
- create_work_batch_handler,
- CreateWorkBatchResponse,
+ WorkAutoBatch,
+ create_work_auto_batch,
+ create_work_auto_batch_handler,
+ CreateWorkAutoBatchResponse,
update_work,
UpdateWorkResponse,
delete_work,
@@ -941,31 +955,31 @@ impl Api for Server {
context: &Context,
) -> Box<Future<Item = CreateEditgroupResponse, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
- let ret = match conn
- .transaction(|| {
- let auth_context = self.auth_confectionary.require_auth(
- &conn,
- &context.auth_data,
- Some("create_editgroup"),
- )?;
- auth_context.require_role(FatcatRole::Editor)?;
- let mut entity = entity.clone();
- match entity.editor_id.clone() {
- Some(editor_id) => {
- if editor_id != auth_context.editor_id.to_string()
- && !auth_context.has_role(FatcatRole::Admin)
- {
- bail!("not authorized to create editgroups in others' names");
- }
- }
- None => {
- entity.editor_id = Some(auth_context.editor_id.to_string());
+ let ret = match conn.transaction(|| {
+ let auth_context = self.auth_confectionary.require_auth(
+ &conn,
+ &context.auth_data,
+ Some("create_editgroup"),
+ )?;
+ auth_context.require_role(FatcatRole::Editor)?;
+ let mut entity = entity.clone();
+ match entity.editor_id.clone() {
+ Some(editor_id) => {
+ if editor_id != auth_context.editor_id.to_string()
+ && !auth_context.has_role(FatcatRole::Admin)
+ {
+ return Err(FatcatError::InsufficientPrivileges(
+ "not authorized to create editgroups in others' names".to_string(),
+ ));
}
- };
- self.create_editgroup_handler(&conn, entity)
- })
- .map_err(|e| FatcatError::from(e))
- {
+ }
+ None => {
+ entity.editor_id = Some(auth_context.editor_id.to_string());
+ }
+ };
+ self.create_editgroup_handler(&conn, entity)
+ .map_err(|e| FatcatError::from(e))
+ }) {
Ok(eg) => {
self.metrics.incr("editgroup.created").ok();
CreateEditgroupResponse::SuccessfullyCreated(eg)
@@ -1035,33 +1049,35 @@ impl Api for Server {
context: &Context,
) -> Box<Future<Item = CreateEditgroupAnnotationResponse, Error = ApiError> + Send> {
let conn = self.db_pool.get().expect("db_pool error");
- let ret = match conn
- .transaction(|| {
- let auth_context = self.auth_confectionary.require_auth(
- &conn,
- &context.auth_data,
- Some("create_editgroup_annotation"),
- )?;
- auth_context.require_role(FatcatRole::Editor)?;
- let editgroup_id = FatcatId::from_str(&editgroup_id)?;
- let mut annotation = annotation.clone();
- annotation.editgroup_id = Some(editgroup_id.to_string());
- match annotation.editor_id.clone() {
- Some(editor_id) => {
- if editor_id != auth_context.editor_id.to_string()
- && !auth_context.has_role(FatcatRole::Superuser)
- {
- bail!("not authorized to annotate in others' names");
- }
- }
- None => {
- annotation.editor_id = Some(auth_context.editor_id.to_string());
+ let ret = match conn.transaction(|| {
+ let auth_context = self.auth_confectionary.require_auth(
+ &conn,
+ &context.auth_data,
+ Some("create_editgroup_annotation"),
+ )?;
+ auth_context.require_role(FatcatRole::Editor)?;
+ let editgroup_id = FatcatId::from_str(&editgroup_id)?;
+ let mut annotation = annotation.clone();
+ annotation.editgroup_id = Some(editgroup_id.to_string());
+ match annotation.editor_id.clone() {
+ Some(editor_id) => {
+ if editor_id != auth_context.editor_id.to_string()
+ && !auth_context.has_role(FatcatRole::Superuser)
+ {
+ return Err(FatcatError::BadRequest(
+ "not authorized to annotate in others' names".to_string(),
+ ));
}
- };
- annotation.db_create(&conn).map(|a| a.into_model())
- })
- .map_err(|e: Error| FatcatError::from(e))
- {
+ }
+ None => {
+ annotation.editor_id = Some(auth_context.editor_id.to_string());
+ }
+ };
+ annotation
+ .db_create(&conn)
+ .map(|a| a.into_model())
+ .map_err(|e: Error| FatcatError::from(e))
+ }) {
Ok(annotation) => CreateEditgroupAnnotationResponse::Created(annotation),
Err(fe) => generic_auth_err_responses!(fe, CreateEditgroupAnnotationResponse),
};