Free Trial¶
[!WARNING]
completion,extendandembed-tokenare undocumented.
What is it?¶
Creates an account and gives a temporary access to one small app of an instance.
How to test it?¶
Here's a list of environments where you can test it:
- On indus: https://free-trial-indus.toucantoco.guru/
- On preprod: https://free-trial-preprod.toucantoco.com/
- On prod: https://free-trial.toucantoco.com/
To trigger a free trial, you can use the following command:
curl -X POST https://free-trial-indus.toucantoco.guru/api/legacy/trial/register \
--header "Content-Type: application/json" \
-d '{"username":"example@example.com"}'
A verification email will be sent to example@example.com.
Implementation details¶
Flow¶
sequenceDiagram
participant User as User<br/>(Browser)
participant Canopee as Canopee<br/>(Auth Proxy)
participant Keycloak as Keycloak<br/>(Auth Service)
participant Laputa as Laputa Backend<br/>(API)
participant EmailService as Email Service
Note over User,EmailService: PHASE 1: Trial Registration
User->>Laputa: POST /api/trial/register<br/>TrialRegister.post()<br/>{username, firstname, ...}
Laputa->>Laputa: get_user(username)<br/>Check if user exists
alt User Already Exists
Laputa->>+EmailService: send_trial_user_exists_email()<br/>Send login/password reset link
EmailService-->>-User: Email: "Welcome back to Toucan"
else New User
Laputa->>Laputa: generate_stored_token()<br/>Create TRIAL_VERIFICATION token<br/>TokenType.TRIAL_VERIFICATION
Laputa->>+EmailService: send_trial_confirmation_email()<br/>send_notif_email_from_file()
EmailService-->>-User: Email: "Verify your email to start<br/>your free trial 🚀"
Note over User: Email contains verification link<br/>with reset password URL
end
Note over User,EmailService: PHASE 2: Email Verification (Password Reset)
User->>+Canopee: Click verification link in email<br/>Redirect to reset password<br/>with token param
Canopee-->>+Keycloak: Redirect to authorize url with token param + "&prompt=create"
Keycloak->>+Laputa: POST /api/trial/verify: Check if the trial is activated
Laputa-->>-Keycloak: OK
Keycloak-->>-User: User registration form
User->>+Keycloak: Submit credentials
Keycloak->>Keycloak: Create account
Keycloak->>+Laputa: POST /api/trial/creation with token and password, Create Account with password, Small app, ...
Laputa-->>-Keycloak: OK
Keycloak-->>-Canopee: OK
Canopee-->>-User: OK
Note over User,EmailService: PHASE 3: Post login
User->>+Canopee: Login
Canopee->>+Keycloak: Login
Keycloak->>+Laputa: GET /api/trial/infos: Check for trial expiration
Laputa-->>-Keycloak: OK
Keycloak-->-Canopee: OK
Canopee-->-User: OK
Logic on Laputa¶
/api/trial/register¶
Called by the user, or an automated system.
- Generate a unique invitation token. Store the username server-side for verification.
- Send a verification email with a link to create an account.
/api/trial/verify¶
Called by the authentication service, with the invitation token.
- Check if the invitation token is valid.
- Send the username to the authentication service.
/api/trial/creation¶
Provision the small app and permissions to the account.
/api/trial/infos¶
Used to check if the trial has expired.
Logic on Canopee¶
https://github.com/ToucanToco/canopee
/api/login?invitation_token={token}¶
Start the OAuth authorization code flow, with the invitation token and
&prompt=create as a query parameters.
This will automatically redirect the user to the registration form of Keycloak.
Logic on Keycloak¶
https://github.com/ToucanToco/keycloak-builder
TrialTokenAuthenticator¶
Set in the registration flow.
Authentication step which will send a request to /api/trial/verify to check if
the invitation token is valid.
If it is valid, it adds the username in the authentication context (server-side).
TrialTokenFormAction¶
Set in a form subflow of the registration flow.
- Prefill and disable the username field with the username from the authentication context.
- Validate any modification to the username field.
- On success, calls
/api/trial/creation.
TrialExpirationAuthenticator¶
Set in the browser flow.
Calls /api/trial/infos to check if the trial has expired.