diff options
| -rw-r--r-- | docs/api/initial-setup.md | 27 | ||||
| -rw-r--r-- | src/event/handlers/stream/test/setup.rs | 7 | ||||
| -rw-r--r-- | src/setup/app.rs | 11 | ||||
| -rw-r--r-- | src/setup/handlers/setup/mod.rs | 10 | ||||
| -rw-r--r-- | src/setup/handlers/setup/test.rs | 12 |
5 files changed, 22 insertions, 45 deletions
diff --git a/docs/api/initial-setup.md b/docs/api/initial-setup.md index a3f6506..b52771f 100644 --- a/docs/api/initial-setup.md +++ b/docs/api/initial-setup.md @@ -17,8 +17,7 @@ New instances of this service require an initial setup step before they can full ## Requests before setup completed -Before the service is set up, all API endpoints, other than those specifically documented as exceptions, will return a status of -`503 Service Unavailable` to all requests. +Before the service is set up, all API endpoints, other than those specifically documented as exceptions, will return a status of `503 Service Unavailable` to all requests. Initial setup can be completed only once. @@ -64,29 +63,9 @@ The proposed `name` must be valid. The precise definition of valid is still up i <!-- This prose is duplicated from authentication.md, with small changes for context. If you edit it here, edit it there, too. --> -This endpoint will respond with a status of -`200 Okay` when successful. The body of the response will be a JSON object describing the newly-created user: +This endpoint will respond with a status of `204 No Content` when successful. -```json -{ - "id": "Uabcd1234", - "name": "Andrea" -} -``` - -The response will include the following fields: - -| Field | Type | Description | -| :----- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------- | -| `id` | string | A unique identifier for the newly-created user. This can be used to associate the user with other events, or to make API calls targeting the user. | -| `name` | string | The user's name. | - -The returned name may not be identical to the name requested, as the name will be converted to [normalization form C](http://www.unicode.org/reports/tr15/) automatically. The returned name will include this normalization; the service will use the normalized name elsewhere, and does not store the originally requested name. - -The provided password will also be converted to normalization form C. However, the normalized password is not returned to the client. - -The response will include a `Set-Cookie` header for the -`identity` cookie, providing the client with a newly-minted identity token associated with the initial user created for this request. See the [authentication](./authentication) section for details on how this cookie may be used. +The response will include a `Set-Cookie` header for the `identity` cookie, providing the client with a newly-minted identity token associated with the initial user created for this request. See the [authentication](./authentication) section for details on how this cookie may be used. The cookie will expire if it is not used regularly. diff --git a/src/event/handlers/stream/test/setup.rs b/src/event/handlers/stream/test/setup.rs index 992b962..297162e 100644 --- a/src/event/handlers/stream/test/setup.rs +++ b/src/event/handlers/stream/test/setup.rs @@ -17,11 +17,16 @@ async fn previously_completed() { // Complete initial setup let (name, password) = fixtures::user::propose(); - let (owner, _) = app + let secret = app .setup() .initial(&name, &password, &fixtures::now()) .await .expect("initial setup in an empty app succeeds"); + let (_, owner) = app + .tokens() + .validate(&secret, &fixtures::now()) + .await + .expect("secret returned by initial setup should be valid"); // Subscribe to events diff --git a/src/setup/app.rs b/src/setup/app.rs index 1210175..123cff9 100644 --- a/src/setup/app.rs +++ b/src/setup/app.rs @@ -7,10 +7,7 @@ use crate::{ name::Name, password::Password, token::{Secret, repo::Provider as _}, - user::{ - User, - create::{self, Create}, - }, + user::create::{self, Create}, }; pub struct Setup<'a> { @@ -28,7 +25,7 @@ impl<'a> Setup<'a> { name: &Name, password: &Password, created_at: &DateTime, - ) -> Result<(User, Secret), Error> { + ) -> Result<Secret, Error> { let create = Create::begin(name, password, created_at); let validated = create.validate()?; @@ -42,9 +39,9 @@ impl<'a> Setup<'a> { let secret = tx.tokens().issue(stored.user(), created_at).await?; tx.commit().await?; - let user = stored.publish(self.events); + let _ = stored.publish(self.events); - Ok((user.as_created(), secret)) + Ok(secret) } pub async fn completed(&self) -> Result<bool, sqlx::Error> { diff --git a/src/setup/handlers/setup/mod.rs b/src/setup/handlers/setup/mod.rs index 9e31282..fe24798 100644 --- a/src/setup/handlers/setup/mod.rs +++ b/src/setup/handlers/setup/mod.rs @@ -5,8 +5,8 @@ use axum::{ }; use crate::{ - app::App, clock::RequestedAt, error::Internal, name::Name, password::Password, setup::app, - token::extract::IdentityCookie, user::User, + app::App, clock::RequestedAt, empty::Empty, error::Internal, name::Name, password::Password, + setup::app, token::extract::IdentityCookie, }; #[cfg(test)] @@ -17,14 +17,14 @@ pub async fn handler( RequestedAt(setup_at): RequestedAt, identity: IdentityCookie, Json(request): Json<Request>, -) -> Result<(IdentityCookie, Json<User>), Error> { - let (user, secret) = app +) -> Result<(IdentityCookie, Empty), Error> { + let secret = app .setup() .initial(&request.name, &request.password, &setup_at) .await .map_err(Error)?; let identity = identity.set(secret); - Ok((identity, Json(user))) + Ok((identity, Empty)) } #[derive(serde::Deserialize)] diff --git a/src/setup/handlers/setup/test.rs b/src/setup/handlers/setup/test.rs index 8243ac3..69e44c2 100644 --- a/src/setup/handlers/setup/test.rs +++ b/src/setup/handlers/setup/test.rs @@ -1,6 +1,6 @@ use axum::extract::{Json, State}; -use crate::{setup::app, test::fixtures}; +use crate::{empty::Empty, setup::app, test::fixtures}; #[tokio::test] async fn fresh_instance() { @@ -15,15 +15,11 @@ async fn fresh_instance() { name: name.clone(), password: password.clone(), }; - let (identity, Json(response)) = + let (identity, Empty) = super::handler(State(app.clone()), fixtures::now(), identity, Json(request)) .await .expect("setup in a fresh app succeeds"); - // Verify the response - - assert_eq!(name, response.name); - // Verify that the issued token is valid let secret = identity @@ -34,7 +30,7 @@ async fn fresh_instance() { .validate(&secret, &fixtures::now()) .await .expect("newly-issued identity cookie is valid"); - assert_eq!(response, login); + assert_eq!(name, login.name); // Verify that the given credentials can log in @@ -43,7 +39,7 @@ async fn fresh_instance() { .login(&name, &password, &fixtures::now()) .await .expect("credentials given on signup are valid"); - assert_eq!(response, login); + assert_eq!(name, login.name); } #[tokio::test] |
