Skip to content

Commit

Permalink
docs: add main authorization flow with registartion in Client
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeysova committed Jan 30, 2021
1 parent 79ab9db commit b0f9131
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 53 deletions.
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,36 +54,37 @@ Configs in repository's root should be prefixed with dot (ex.: `.config-producti
## Development

- Use [`just`](https://github.com/casey/just) to run commands from [`justfile`](./justfile)
- `just run` — to build and start `api-public` crate (aliased to `just run public`)

## Flows
- `just` — to build and start `api-internal` crate (aliased to `just internal`)
- `just public` — to build and run `api-public`

## Glossary

It's implements simplified OAuth 2.0 flow ([example](https://itnext.io/an-oauth-2-0-introduction-for-beginners-6e386b19f7a9))

- Application — OAuth Client App
- User — the person who wants to be authenticated, to access protected information.
- Accesso — Authorization server

### Authorization flow

Client side:

1. User wants to login. Open https://application/login
2. Application (redirects|opens a window) to https://accesso/session?application_id&redirect_uri&state
3. Accesso checks application request (application_id matches redirect_uri)
4. Accesso shows login form
5. User inserts credentials
6. Accesso checks credentials
7. Accesso sends authorization_code to redirect_uri

Server side:

8. Application sends authorization_code, application_id and secret_key to Accesso
9. Accesso checks authorization_code (application_id matches secret_key, matches authorization_code)
10. Accesso sends access_token back to Application

11. Application makes request using access_token to Accesso to get info about session
12. Accesso checks access_token
13. Accesso returns info about session back to Application
- **Client** — OAuth 2.0 Client App.
- **User — the person who wants to be authenticated, to access protected information.
- **Accesso** — Authorization server.
- **Registration Request** — When User registers on Accesso, server send code of request to his email.
- **Authorization Code** — When user authorizes in Client through OAuth 2.0 authorization code flow, he needs to exchange code to access token.
- **Access Token** — Token that exchanged from authorization code, used to send requests from Client server to Accesso server on behalf of User.
- **Session Token** — Token used to authenticate user on Accesso Frontend, it writes to cookies.

## Authorization code flow

> `accesso.server` is an alias for domain of an Accesso instance
1. On the Client side, user presses "Login with Accesso" button.
1. Client redirects to `accesso.server/oauth/authorize` with Client ID, redirect URI and state.
1. Accesso Frontend shows pages and checks User authentication.
1. If User not authenticated, redirect to login, then redirect back to `/oauth/authorize` with all parameters.
1. Accesso Frontend sends `oauthAuthorize` to Accesso Internal API.
1. Accesso Internal API validates Client ID and parameters.
1. [?] Accesso Internal API checks if User already registered in the Client.
1. [?] If User not registered in the Client, Accesso Internal API returns need_confirmation to Accesso Frontend.
1. [?] Accesso Frontend shows a confirmation window to User.
1. [?] When User clicks "Register" in the confirmation window, Accesso Frontend sends _`oauthRegister` (?)_ to Accesso Internal API with all parameters.
1. [?] Accesso Internal API creates Authorization Code and returns it to Accesso Frontend.
1. Accesso Frontend redirects to redirect URI passed from Client with Authorization Code.
1. Client Server send `oauthToken` to Accesso Public API with authorization code, Client ID and secret to exchange it to Access Token.
1. Accesso Public API validates parameters and returns a new Accesso Token.
1. Client Server send any request to Accesso Public API with Access Token.
7 changes: 7 additions & 0 deletions core/src/app/oauth/authorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ where
.client_find_by_id(form.client_id)?
.ok_or(RequestAuthCodeFailed::InvalidRequest)?;

// TODO: register or login?
// If user already registered in application, just transaprently check
// If user not registered, show confirmation dialog

// TODO: check `client.allowed_registrations` when user registers
// If not allowed reject authorization request

if !client.is_allowed_redirect(&form.redirect_uri) {
return Err(RequestAuthCodeFailed::InvalidRequest);
}
Expand Down
51 changes: 26 additions & 25 deletions core/src/app/registrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,31 +110,32 @@ where

let code = form.confirmation_code.clone();

if let Some(request) = self.db.register_request_get_by_code(code)? {
let password_hash = self.generator.password_hash(form.password);

let created_user = self.db.user_register(UserRegisterForm {
id: uuid::Uuid::new_v4(),
email: request.email,
password_hash,
first_name: form.first_name,
last_name: form.last_name,
})?;

self.emailer.send(
created_user.email.clone(),
EmailMessage::RegisterFinished {
first_name: created_user.first_name,
last_name: created_user.last_name,
},
);

self.db
.register_requests_delete_all_for_email(created_user.email)?;

Ok(())
} else {
Err(RegisterConfirmError::CodeNotFound)
match self.db.register_request_get_by_code(code)? {
Some(request) => {
let password_hash = self.generator.password_hash(form.password);

let created_user = self.db.user_register(UserRegisterForm {
id: uuid::Uuid::new_v4(),
email: request.email,
password_hash,
first_name: form.first_name,
last_name: form.last_name,
})?;

self.emailer.send(
created_user.email.clone(),
EmailMessage::RegisterFinished {
first_name: created_user.first_name,
last_name: created_user.last_name,
},
);

self.db
.register_requests_delete_all_for_email(created_user.email)?;

Ok(())
}
None => Err(RegisterConfirmError::CodeNotFound),
}
}
}
Expand Down

0 comments on commit b0f9131

Please sign in to comment.