Skip to content

Commit

Permalink
feat(station): add metadata to external canisters (#418)
Browse files Browse the repository at this point in the history
  • Loading branch information
olaszakos authored Nov 15, 2024
1 parent 5ed14d8 commit 06131e9
Show file tree
Hide file tree
Showing 18 changed files with 457 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ const { submit, edited, initialModel, additionalFieldErrors, submitting, valid,
name: [],
description: [],
labels: [],
change_metadata: [],
state: [],
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
return station.service.editExternalCanisterSettings(props.canisterId, {
description: [],
labels: [],
change_metadata: [],
name: [],
state: [],
permissions: [
Expand Down
211 changes: 153 additions & 58 deletions apps/wallet/src/generated/internet-identity/internet_identity.did
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,33 @@ type RateLimitConfig = record {
max_tokens: nat64;
};

// Captcha configuration
// Default:
// - max_unsolved_captchas: 500
// - captcha_trigger: Static, CaptchaEnabled
type CaptchaConfig = record {
// Maximum number of unsolved captchas.
max_unsolved_captchas : nat64;
// Configuration for when captcha protection should kick in.
captcha_trigger: variant {
// Based on the rate of registrations compared to some reference time frame and allowing some leeway.
Dynamic: record {
// Percentage of increased registration rate observed in the current rate sampling interval (compared to
// reference rate) at which II will enable captcha for new registrations.
threshold_pct: nat16;
// Length of the interval in seconds used to sample the current rate of registrations.
current_rate_sampling_interval_s: nat64;
// Length of the interval in seconds used to sample the reference rate of registrations.
reference_rate_sampling_interval_s: nat64;
};
// Statically enable / disable captcha
Static: variant {
CaptchaEnabled;
CaptchaDisabled;
}
};
};

// Init arguments of II which can be supplied on install and upgrade.
// Setting a value to null keeps the previous value.
type InternetIdentityInit = record {
Expand All @@ -228,9 +255,8 @@ type InternetIdentityInit = record {
canister_creation_cycles_cost : opt nat64;
// Rate limit for the `register` call.
register_rate_limit : opt RateLimitConfig;
// Maximum number of inflight captchas.
// Default: 500
max_inflight_captchas: opt nat64;
// Configuration of the captcha in the registration flow.
captcha_config: opt CaptchaConfig;
};

type ChallengeKey = text;
Expand Down Expand Up @@ -403,23 +429,12 @@ type IdentityInfo = record {
};

type IdentityInfoError = variant {
/// The principal is not authorized to call this method with the given arguments.
// The principal is not authorized to call this method with the given arguments.
Unauthorized: principal;
/// Internal canister error. See the error message for details.
// Internal canister error. See the error message for details.
InternalCanisterError: text;
};



type IdentityRegisterError = variant {
// No more registrations are possible in this instance of the II service canister.
CanisterFull;
// The captcha check was not successful.
BadCaptcha;
// The metadata of the provided authentication method contains invalid entries.
InvalidMetadata: text;
};

type AuthnMethodAddError = variant {
InvalidMetadata: text;
};
Expand All @@ -432,51 +447,51 @@ type AuthnMethodReplaceError = variant {

type AuthnMethodMetadataReplaceError = variant {
InvalidMetadata: text;
/// No authentication method found with the given public key.
// No authentication method found with the given public key.
AuthnMethodNotFound;
};

type AuthnMethodSecuritySettingsReplaceError = variant {
/// No authentication method found with the given public key.
// No authentication method found with the given public key.
AuthnMethodNotFound;
};

type IdentityMetadataReplaceError = variant {
/// The principal is not authorized to call this method with the given arguments.
// The principal is not authorized to call this method with the given arguments.
Unauthorized: principal;
/// The identity including the new metadata exceeds the maximum allowed size.
// The identity including the new metadata exceeds the maximum allowed size.
StorageSpaceExceeded: record {space_available: nat64; space_required: nat64};
/// Internal canister error. See the error message for details.
// Internal canister error. See the error message for details.
InternalCanisterError: text;
};

type PrepareIdAliasRequest = record {
/// Origin of the issuer in the attribute sharing flow.
// Origin of the issuer in the attribute sharing flow.
issuer : FrontendHostname;
/// Origin of the relying party in the attribute sharing flow.
// Origin of the relying party in the attribute sharing flow.
relying_party : FrontendHostname;
/// Identity for which the IdAlias should be generated.
// Identity for which the IdAlias should be generated.
identity_number : IdentityNumber;
};

type PrepareIdAliasError = variant {
/// The principal is not authorized to call this method with the given arguments.
// The principal is not authorized to call this method with the given arguments.
Unauthorized: principal;
/// Internal canister error. See the error message for details.
// Internal canister error. See the error message for details.
InternalCanisterError: text;
};

/// The prepared id alias contains two (still unsigned) credentials in JWT format,
/// certifying the id alias for the issuer resp. the relying party.
// The prepared id alias contains two (still unsigned) credentials in JWT format,
// certifying the id alias for the issuer resp. the relying party.
type PreparedIdAlias = record {
rp_id_alias_jwt : text;
issuer_id_alias_jwt : text;
canister_sig_pk_der : PublicKey;
};

/// The request to retrieve the actual signed id alias credentials.
/// The field values should be equal to the values of corresponding
/// fields from the preceding `PrepareIdAliasRequest` and `PrepareIdAliasResponse`.
// The request to retrieve the actual signed id alias credentials.
// The field values should be equal to the values of corresponding
// fields from the preceding `PrepareIdAliasRequest` and `PrepareIdAliasResponse`.
type GetIdAliasRequest = record {
rp_id_alias_jwt : text;
issuer : FrontendHostname;
Expand All @@ -486,15 +501,15 @@ type GetIdAliasRequest = record {
};

type GetIdAliasError = variant {
/// The principal is not authorized to call this method with the given arguments.
// The principal is not authorized to call this method with the given arguments.
Unauthorized: principal;
/// The credential(s) are not available: may be expired or not prepared yet (call prepare_id_alias to prepare).
// The credential(s) are not available: may be expired or not prepared yet (call prepare_id_alias to prepare).
NoSuchCredentials : text;
/// Internal canister error. See the error message for details.
// Internal canister error. See the error message for details.
InternalCanisterError: text;
};

/// The signed id alias credentials for each involved party.
// The signed id alias credentials for each involved party.
type IdAliasCredentials = record {
rp_id_alias_credential : SignedIdAlias;
issuer_id_alias_credential : SignedIdAlias;
Expand All @@ -506,8 +521,76 @@ type SignedIdAlias = record {
id_dapp : principal;
};

type IdRegNextStepResult = record {
// The next step in the registration flow
next_step: RegistrationFlowNextStep;
};

type IdRegStartError = variant {
// The method was called anonymously, which is not supported.
InvalidCaller;
// Too many registrations. Please try again later.
RateLimitExceeded;
// A registration flow is already in progress.
AlreadyInProgress;
};

// The next step in the registration flow:
// - CheckCaptcha: supply the solution to the captcha using `check_captcha`
// - Finish: finish the registration using `identity_registration_finish`
type RegistrationFlowNextStep = variant {
// Supply the captcha solution using check_captcha
CheckCaptcha: record {
captcha_png_base64: text;
};
// Finish the registration using identity_registration_finish
Finish;
};

type CheckCaptchaArg = record {
solution : text;
};

type CheckCaptchaError = variant {
// The supplied solution was wrong. Try again with the new captcha.
WrongSolution: record {
new_captcha_png_base64: text;
};
// This call is unexpected, see next_step.
UnexpectedCall: record {
next_step: RegistrationFlowNextStep;
};
// No registration flow ongoing for the caller.
NoRegistrationFlow;
};

type IdRegFinishArg = record {
authn_method: AuthnMethodData;
};

type IdRegFinishResult = record {
identity_number: nat64;
};

type IdRegFinishError = variant {
// The configured maximum number of identities has been reached.
IdentityLimitReached;
// This call is unexpected, see next_step.
UnexpectedCall: record {
next_step: RegistrationFlowNextStep;
};
// No registration flow ongoing for the caller.
NoRegistrationFlow;
// The supplied authn_method is not valid.
InvalidAuthnMethod: text;
// Error while persisting the new identity.
StorageError: text;
};

service : (opt InternetIdentityInit) -> {
init_salt: () -> ();
// Legacy identity management API
// ==============================

create_challenge : () -> (Challenge);
register : (DeviceData, ChallengeResult, opt principal) -> (RegisterResponse);
add : (UserNumber, DeviceData) -> ();
Expand All @@ -522,37 +605,25 @@ service : (opt InternetIdentityInit) -> {
get_anchor_credentials : (UserNumber) -> (AnchorCredentials) query;
get_anchor_info : (UserNumber) -> (IdentityAnchorInfo);
get_principal : (UserNumber, FrontendHostname) -> (principal) query;
stats : () -> (InternetIdentityStats) query;

enter_device_registration_mode : (UserNumber) -> (Timestamp);
exit_device_registration_mode : (UserNumber) -> ();
add_tentative_device : (UserNumber, DeviceData) -> (AddTentativeDeviceResponse);
verify_tentative_device : (UserNumber, verification_code: text) -> (VerifyTentativeDeviceResponse);

prepare_delegation : (UserNumber, FrontendHostname, SessionKey, maxTimeToLive : opt nat64) -> (UserKey, Timestamp);
get_delegation: (UserNumber, FrontendHostname, SessionKey, Timestamp) -> (GetDelegationResponse) query;

http_request: (request: HttpRequest) -> (HttpResponse) query;
http_request_update: (request: HttpRequest) -> (HttpResponse);

deploy_archive: (wasm: blob) -> (DeployArchiveResult);
// Returns a batch of entries _sorted by sequence number_ to be archived.
// This is an update call because the archive information _must_ be certified.
// Only callable by this IIs archive canister.
fetch_entries: () -> (vec BufferedArchiveEntry);
acknowledge_entries: (sequence_number: nat64) -> ();
// V2 Identity Management API
// ==========================
// WARNING: The following methods are experimental and may ch 0ange in the future.

// V2 API
// WARNING: The following methods are experimental and may change in the future.
// Starts the identity registration flow to create a new identity.
identity_registration_start: () -> (variant {Ok: IdRegNextStepResult; Err: IdRegStartError;});

// Creates a new captcha. The solution needs to be submitted using the
// `identity_register` call.
captcha_create: () -> (variant {Ok: Challenge; Err;});
// Check the captcha challenge
// If successful, the registration can be finished with `identity_registration_finish`.
check_captcha: (CheckCaptchaArg) -> (variant {Ok: IdRegNextStepResult; Err: CheckCaptchaError;});

// Registers a new identity with the given authn_method.
// A valid captcha solution to a previously generated captcha (using create_captcha) must be provided.
// The sender needs to match the supplied authn_method.
identity_register: (AuthnMethodData, CaptchaResult, opt principal) -> (variant {Ok: IdentityNumber; Err: IdentityRegisterError;});
// Starts the identity registration flow to create a new identity.
identity_registration_finish: (IdRegFinishArg) -> (variant {Ok: IdRegFinishResult; Err: IdRegFinishError;});

// Returns information about the authentication methods of the identity with the given number.
// Only returns the minimal information required for authentication without exposing any metadata such as aliases.
Expand Down Expand Up @@ -611,8 +682,32 @@ service : (opt InternetIdentityInit) -> {
// Requires authentication.
authn_method_confirm: (IdentityNumber, confirmation_code: text) -> (variant {Ok; Err: AuthnMethodConfirmationError;});

// Authentication protocol
// =======================
prepare_delegation : (UserNumber, FrontendHostname, SessionKey, maxTimeToLive : opt nat64) -> (UserKey, Timestamp);
get_delegation: (UserNumber, FrontendHostname, SessionKey, Timestamp) -> (GetDelegationResponse) query;

// Attribute Sharing MVP API
// =========================
// The methods below are used to generate ID-alias credentials during attribute sharing flow.
prepare_id_alias : (PrepareIdAliasRequest) -> (variant {Ok: PreparedIdAlias; Err: PrepareIdAliasError;});
get_id_alias : (GetIdAliasRequest) -> (variant {Ok: IdAliasCredentials; Err: GetIdAliasError;}) query;

// HTTP Gateway protocol
// =====================
http_request: (request: HttpRequest) -> (HttpResponse) query;
http_request_update: (request: HttpRequest) -> (HttpResponse);

// Internal Methods
// ================
init_salt: () -> ();
stats : () -> (InternetIdentityStats) query;
config : () -> (InternetIdentityInit) query;

deploy_archive: (wasm: blob) -> (DeployArchiveResult);
// Returns a batch of entries _sorted by sequence number_ to be archived.
// This is an update call because the archive information _must_ be certified.
// Only callable by this IIs archive canister.
fetch_entries: () -> (vec BufferedArchiveEntry);
acknowledge_entries: (sequence_number: nat64) -> ();
}
Loading

0 comments on commit 06131e9

Please sign in to comment.