Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change registration on API v2 to flow with 3 steps #2629

Merged
merged 3 commits into from
Sep 27, 2024

Conversation

frederikrothenberger
Copy link
Member

@frederikrothenberger frederikrothenberger commented Sep 26, 2024

The registration for new identities using API v2 is now split into 3 different steps:

  1. start a flow, providing a principal to track progress on that flow
  2. solve captcha
  3. submit authn_method to tie the identity to

This PR is a preparation to making the step 2 dynamically remove step 2 on low load.

The registration for new identities using API v2 is now split into 3
different steps:
1. start a flow, providing a principal to track progress on that flow
2. solve captcha
3. submit authn_method to tie the identity to

This PR is a preparation to making the step 2 dynamically remove step 2
on low load.
@frederikrothenberger frederikrothenberger requested a review from a team as a code owner September 26, 2024 12:53
const FLOW_EXPIRATION_NS: u64 = 5 * MINUTE_NS;

#[derive(Default)]
pub struct FlowStates {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmuntaner: Ultimately, I decided against mixing flow states with temp_keys. I feel this is cleaner in terms of separation.
But it means that the "expiration logic" here and temp_keys is duplicated. I don't think it is big enough to warrant extracting that, but up to you.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now the temp keys won't be used to track the registration flow, right?

Do we need the enum for the TempKeyId still?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I will revert #2618. I'll do that after this is merged.

/// * Once the flow expires
/// * The Internet Identity canister is upgraded
///
/// The total number of flow states is limited by the registration rate limit.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the captcha is now tied to the flow_state and the number of flow_states is limited by the registration rate limit, the max_unsolved_captchas config option in the captcha config only has an effect on the legacy registration flow.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that depend on what comes furst, the registration rate limit or the max_unsolved_captchas?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, max_unsolved_captchas is not used at all in the context of the V2 registration flow, as we store the captcha with the flow state.

Copy link
Collaborator

@lmuntaner lmuntaner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy because after our conversation I was able to follow this PR pretty well. Thanks!

Minor comments, already approving.

@@ -955,8 +955,23 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-didc
- name: 'Get latest release'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this needs to be done every time we introduce a breaking change?

Do you have a script or how do you remember how to do it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually pull it out again from git history whenever I need it. My hope was that it would not be worth it improving the infrastructure to do that, as we would eventually stop making breaking changes (as APIv2 would be finished)...

@@ -532,6 +521,72 @@ type SignedIdAlias = record {
id_dapp : principal;
};

type IdRegNextStepResult = record {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not IdRegStartResult?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reuse this result for _start and check_captcha. It is essentially a result to indicate a step has been completed correctly and what the next step is.

So if there are more / different steps in the flow in the future, they can also use this.

})
}

async fn captcha_flow_state(flow_created_timestamp_ns: u64) -> (Base64, RegistrationFlowState) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you add that this returns Option<Base64> afterwards?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean, once the captcha might be skipped? No, I think I will identity_registration_start with some logic to decide whether this function should be called or if the next step is Finish.

}

fn create_identity(arg: &IdRegFinishArg) -> Result<IdentityNumber, IdRegFinishError> {
let Some(mut identity) = state::storage_borrow_mut(|s| s.allocate_anchor()) else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a thing we will need to change to allow creating the identity number at the beginning of the flow instead of the end?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there will definitely be changes here. But there need to be many more. Maybe its best we have a separate discussion about it.

/// * Once the flow expires
/// * The Internet Identity canister is upgraded
///
/// The total number of flow states is limited by the registration rate limit.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that depend on what comes furst, the registration rate limit or the max_unsolved_captchas?

src/internet_identity/src/state/flow_states.rs Outdated Show resolved Hide resolved
self.registration_flows.remove(principal);
}

pub fn registration_flow_state(&self, principal: &Principal) -> Option<RegistrationFlowState> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also prune here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary, as we explicitly check expiration before returning anything.
IMHO it is more natural to prune alongside other modifications, rather than on read.

src/internet_identity/src/state/flow_states.rs Outdated Show resolved Hide resolved
@@ -37,6 +38,40 @@ fn should_register_multiple_identities() {
assert_ne!(identity_number_1, identity_number_2);
}

#[test]
fn should_transition_flow_principal_to_temp_key() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this name for this test?

It's to make sure that the temp_key is expired after the required time, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is there for two things:

  1. the principal used in the flow can still be used after the registration (e.g. to add additional devices / get a delegation, etc.)
  2. the principal used in the flow expires after the expected amount of time

@frederikrothenberger frederikrothenberger added this pull request to the merge queue Sep 27, 2024
Merged via the queue into main with commit efc7537 Sep 27, 2024
66 checks passed
@frederikrothenberger frederikrothenberger deleted the frederik/refactor-register-flow branch September 27, 2024 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants