diff --git a/documentation/public-task-api.md b/documentation/public-task-api.md index 2aca9f6e..7936a39a 100644 --- a/documentation/public-task-api.md +++ b/documentation/public-task-api.md @@ -21,7 +21,7 @@ Accidentally modifying any of these plaintext values would make report generatio ## Proposed improvement -We add an infinitely cacheable (`Cache-Control: public, max-age=604800`) endpoint `GET {divviup-api url}/api/tasks/:task_id`. When a task is found with the provided task identifier, the divviup-api server responds with the following json: +We add an infinitely cacheable (`Cache-Control: public, max-age=604800`) endpoint `GET {divviup-api url}/tasks/:task_id`. When a task is found with the provided task identifier, the divviup-api server responds with the following json: ```json { @@ -33,7 +33,6 @@ We add an infinitely cacheable (`Cache-Control: public, max-age=604800`) endpoin "leader": "https://dap.xxqbi.example/", "helper": "https://dap.xxqbi.example/", "time_precision_seconds": 1080, - "protocol": "DAP-04" } ``` @@ -41,7 +40,7 @@ and the client can be configured like: ```js import DivviupClient from "@divviup/client"; -const client = new DivviupClient("https://api.divviup.org/api/tasks/5YXXYPFzt1a8cuo8AlKqs6oKbt3FIrkn3Q8JseJKRYs"); +const client = new DivviupClient("https://api.divviup.org/tasks/5YXXYPFzt1a8cuo8AlKqs6oKbt3FIrkn3Q8JseJKRYs"); ``` or, optionally, the following shortcut is also supported: diff --git a/src/routes.rs b/src/routes.rs index 2f646439..f28becfe 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -47,6 +47,7 @@ pub fn routes(config: &Config) -> impl Handler { redirect(config.app_url.to_string()), ), ) + .get("/tasks/:task_id", api(tasks::public_show)) .any( &[Get, Post, Delete, Patch], "/api/*", diff --git a/src/routes/tasks.rs b/src/routes/tasks.rs index 810822ef..b36cac93 100644 --- a/src/routes/tasks.rs +++ b/src/routes/tasks.rs @@ -3,6 +3,7 @@ use crate::{ Crypter, Db, Error, Permissions, PermissionsActor, }; use sea_orm::{ActiveModelTrait, EntityTrait, ModelTrait}; +use serde_json::json; use std::time::Duration; use time::OffsetDateTime; use trillium::{Conn, Handler, Status}; @@ -90,6 +91,22 @@ pub async fn show( Ok(Json(task)) } +pub async fn public_show(conn: &mut Conn, db: Db) -> Result { + let task_id = conn.param("task_id").ok_or(Error::NotFound)?; + let task = Tasks::find_by_id(task_id) + .one(&db) + .await? + .ok_or(Error::NotFound)?; + let [leader, helper] = task.aggregators(&db).await?; + Ok(Json(json!({ + "id": task.id, + "vdaf": task.vdaf, + "leader": leader.dap_url, + "helper": helper.dap_url, + "time_precision_seconds": task.time_precision_seconds, + }))) +} + pub async fn update( _: &mut Conn, (task, Json(update), db): (Task, Json, Db), diff --git a/tests/tasks.rs b/tests/tasks.rs index f9085bf8..09ee0495 100644 --- a/tests/tasks.rs +++ b/tests/tasks.rs @@ -774,3 +774,29 @@ mod collector_auth_tokens { Ok(()) } } + +mod public_show { + use divviup_api::entity::task::vdaf::{Sum, Vdaf}; + use test_support::{assert_eq, test, *}; + #[test(harness = set_up)] + async fn as_completely_unauthenticated_user(app: DivviupApi) -> TestResult { + let account = fixtures::account(&app).await; + let task = fixtures::task(&app, &account).await; + let mut task = task.into_active_model(); + task.vdaf = ActiveValue::Set(Vdaf::Sum(Sum { bits: Some(8) })); + let task = task.update(app.db()).await?; + let [leader, helper] = task.aggregators(app.db()).await?; + assert_ok!( + get(format!("/tasks/{}", task.id)).run_async(&app).await, + serde_json::to_string(&json!({ + "id": task.id, + "leader": leader.dap_url, + "helper": helper.dap_url, + "time_precision_seconds": task.time_precision_seconds, + "vdaf": { "type":"sum", "bits": 8 } + })) + .unwrap() + ); + Ok(()) + } +}