Skip to content

Add get_account_delegation functionality #3078

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

Merged
merged 102 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
80c98c2
add get_accounts_for_origin to account_management and get_accounts to…
LXIF May 13, 2025
daf7c2f
add authorization fn
LXIF May 13, 2025
5fb5bc1
clippy
LXIF May 13, 2025
c25a7bb
add tests for get and create
LXIF May 13, 2025
e5f72b3
clippy
LXIF May 13, 2025
07d0f73
add account updating endpoint and related account management function…
LXIF May 13, 2025
b98bc18
cwippy
LXIF May 13, 2025
55f85d9
add seed_from_anchor to Account
LXIF May 13, 2025
5a4c704
add seed_from_anchor to account struct
LXIF May 13, 2025
af693d0
add calculate_account_delegation_seed function
LXIF May 13, 2025
f10ac25
make get_accounts return a result
LXIF May 14, 2025
a281016
Merge branch 'andri/implement-get-accounts' into andri/implement-crea…
LXIF May 14, 2025
d75a785
add principal to GetAccountsError::Unauthorized
LXIF May 14, 2025
9110107
Merge branch 'andri/implement-get-accounts' into andri/implement-crea…
LXIF May 14, 2025
4355c14
add const
LXIF May 14, 2025
fe51d28
add global acc limit and unit test
LXIF May 14, 2025
c80561c
Merge branch 'andri/implement-create-account' into andri/implement-up…
LXIF May 14, 2025
dc5863d
add max acc limit to update function
LXIF May 14, 2025
a3c9501
add authorization, add checking if anchor has account (for later)
LXIF May 14, 2025
fa38325
merge main
LXIF May 14, 2025
674bbb0
clippy
LXIF May 14, 2025
72a3294
fix did
LXIF May 14, 2025
893d1f5
Merge branch 'andri/implement-create-account' into andri/implement-up…
LXIF May 14, 2025
6cefda2
add per-acc auth check in account management
LXIF May 14, 2025
a74c252
add tests, restructure per-acc auth check in update_account
LXIF May 14, 2025
81c6521
change variant name, update comment
LXIF May 15, 2025
da58a36
cleanup function inputs
LXIF May 15, 2025
206b259
merge main
LXIF May 15, 2025
037c9e8
cwippy
LXIF May 15, 2025
5e5687d
cwippy again
LXIF May 15, 2025
649bd83
Merge branch 'andri/implement-update-account' into andri/implement-cr…
LXIF May 15, 2025
eca0ed5
minor changes
LXIF May 15, 2025
8de7852
add account delegation preparation function and update endpoint
LXIF May 15, 2025
62e4012
fix did
LXIF May 15, 2025
a46738b
fix did
LXIF May 15, 2025
9e555c2
cwippy
LXIF May 15, 2025
482e80a
fix did again
LXIF May 15, 2025
845308f
cwippy fix
LXIF May 15, 2025
42999ec
fix did?
LXIF May 15, 2025
9f48cf6
fix typing
LXIF May 15, 2025
e76cc72
clippyyy
LXIF May 15, 2025
2eb418f
Merge branch 'main' into andri/implement-create-account-delegation
LXIF May 15, 2025
f0f7089
cleanup
LXIF May 15, 2025
2880261
clippy
LXIF May 15, 2025
ebb0bac
fix read_account method to account for seed_from_anchor
LXIF May 15, 2025
6785d65
Merge branch 'main' into andri/implement-create-account-delegation
LXIF May 16, 2025
87e8f0c
start updating api
LXIF May 16, 2025
7c29d5d
rename
LXIF May 16, 2025
3d38247
move seed generation function into account impl
LXIF May 16, 2025
985dac8
Merge branch 'andri/implement-create-account-delegation' into andri/i…
LXIF May 16, 2025
7f491f4
start adding from
LXIF May 16, 2025
418865c
clippy
LXIF May 16, 2025
8b18d47
add get_account_delegation method in account_management
LXIF May 16, 2025
aefa967
cwippy
LXIF May 16, 2025
7d45b64
cleanup delegation generation, handle default account in has_account_…
LXIF May 16, 2025
340a488
return account from anchor_has_account
LXIF May 16, 2025
90e4a34
Merge branch 'main' into andri/implement-create-account-delegation
LXIF May 16, 2025
50787ea
Merge branch 'andri/implement-create-account-delegation' into andri/i…
LXIF May 16, 2025
789cd5d
merge updates
LXIF May 16, 2025
4fab02b
cleanupt
LXIF May 16, 2025
536a80c
restructure has_account_reference and anchor_has_account
LXIF May 16, 2025
ec29af8
cwippy
LXIF May 16, 2025
b3bead0
Merge branch 'main' into andri/implement-create-account-delegation
LXIF May 16, 2025
4bc169b
return default acc if no application number
LXIF May 16, 2025
adc1ca5
cwippy
LXIF May 16, 2025
fd26acc
cleanup
LXIF May 16, 2025
f75d321
restructure storage borrowing
LXIF May 16, 2025
977357f
Merge branch 'andri/implement-create-account-delegation' into andri/i…
LXIF May 16, 2025
9267170
replaced existing get_delegation with new and more general get_accoun…
LXIF May 16, 2025
0953700
cwippy
LXIF May 16, 2025
a91ea30
cwippy again
LXIF May 16, 2025
489e2c9
update did
LXIF May 16, 2025
a8146d0
update did
LXIF May 16, 2025
cb71a6b
update did
LXIF May 16, 2025
381d5a7
make nicer
LXIF May 16, 2025
cad122e
update list_accounts to return accounts and use read_account
LXIF May 19, 2025
068f900
remove anchor_has_account, pack everything into read_account
LXIF May 19, 2025
ffbfa93
clippy
LXIF May 19, 2025
f23c061
clippy
LXIF May 19, 2025
ed07dc1
add comment
LXIF May 19, 2025
c27bbc3
clippy
LXIF May 19, 2025
fa0773d
change error type
LXIF May 19, 2025
db7d1ed
Merge branch 'main' into andri/implement-create-account-delegation
LXIF May 19, 2025
591c28b
fix function inputs
LXIF May 19, 2025
19e0299
fix tests
LXIF May 19, 2025
52e5349
🤖 cargo-fmt auto-update
github-actions[bot] May 19, 2025
61df5ac
Merge branch 'andri/implement-create-account-delegation' into andri/i…
LXIF May 19, 2025
9ecd180
clippy
LXIF May 19, 2025
7a8c206
clippy
LXIF May 19, 2025
da62ea0
Merge branch 'main' into andri/implement-retrieve-account-delegation
LXIF May 20, 2025
1f37261
add tests, rename some things
LXIF May 20, 2025
4a19f59
minor adjustments
LXIF May 20, 2025
52b09a4
Merge branch 'main' into andri/implement-retrieve-account-delegation
LXIF May 20, 2025
27ea42d
Add account delegation preparation (#3076)
LXIF May 20, 2025
f4530d0
Improve copy in buttons (#3082)
lmuntaner May 20, 2025
d6a6fc4
small fixes
LXIF May 20, 2025
4b8df40
merge main and small fixes
LXIF May 20, 2025
cd592fa
Merge branch 'main' into andri/implement-retrieve-account-delegation
LXIF May 20, 2025
bb85265
run generate
LXIF May 21, 2025
239b83e
Merge branch 'main' into andri/implement-retrieve-account-delegation
LXIF May 21, 2025
4476eff
Merge branch 'main' into andri/implement-retrieve-account-delegation
LXIF May 21, 2025
31ca572
cleanup
LXIF May 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions src/frontend/src/lib/generated/internet_identity_idl.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,10 @@ export const idlFactory = ({ IDL }) => {
'signature' : IDL.Vec(IDL.Nat8),
'delegation' : Delegation,
});
const GetDelegationResponse = IDL.Variant({
'no_such_delegation' : IDL.Null,
'signed_delegation' : SignedDelegation,
const AccountDelegationError = IDL.Variant({
'NoSuchDelegation' : IDL.Null,
'InternalCanisterError' : IDL.Text,
'Unauthorized' : IDL.Principal,
});
const GetAccountsError = IDL.Variant({
'InternalCanisterError' : IDL.Text,
Expand Down Expand Up @@ -263,6 +264,10 @@ export const idlFactory = ({ IDL }) => {
'openid_credentials' : IDL.Opt(IDL.Vec(OpenIdCredential)),
'device_registration' : IDL.Opt(DeviceRegistrationInfo),
});
const GetDelegationResponse = IDL.Variant({
'no_such_delegation' : IDL.Null,
'signed_delegation' : SignedDelegation,
});
const GetIdAliasRequest = IDL.Record({
'rp_id_alias_jwt' : IDL.Text,
'issuer' : FrontendHostname,
Expand Down Expand Up @@ -391,10 +396,6 @@ export const idlFactory = ({ IDL }) => {
'user_key' : UserKey,
'timestamp' : Timestamp,
});
const AccountDelegationError = IDL.Variant({
'InternalCanisterError' : IDL.Text,
'Unauthorized' : IDL.Principal,
});
const PrepareIdAliasRequest = IDL.Record({
'issuer' : FrontendHostname,
'relying_party' : FrontendHostname,
Expand Down Expand Up @@ -544,8 +545,19 @@ export const idlFactory = ({ IDL }) => {
'exit_device_registration_mode' : IDL.Func([UserNumber], [], []),
'fetch_entries' : IDL.Func([], [IDL.Vec(BufferedArchiveEntry)], []),
'get_account_delegation' : IDL.Func(
[UserNumber, FrontendHostname, AccountNumber, SessionKey, Timestamp],
[GetDelegationResponse],
[
UserNumber,
FrontendHostname,
IDL.Opt(AccountNumber),
SessionKey,
Timestamp,
],
[
IDL.Variant({
'Ok' : SignedDelegation,
'Err' : AccountDelegationError,
}),
],
['query'],
),
'get_accounts' : IDL.Func(
Expand Down
8 changes: 5 additions & 3 deletions src/frontend/src/lib/generated/internet_identity_types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { Principal } from '@dfinity/principal';
import type { ActorMethod } from '@dfinity/agent';
import type { IDL } from '@dfinity/candid';

export type AccountDelegationError = { 'InternalCanisterError' : string } |
export type AccountDelegationError = { 'NoSuchDelegation' : null } |
{ 'InternalCanisterError' : string } |
{ 'Unauthorized' : Principal };
export interface AccountInfo {
'name' : [] | [string],
Expand Down Expand Up @@ -444,8 +445,9 @@ export interface _SERVICE {
'exit_device_registration_mode' : ActorMethod<[UserNumber], undefined>,
'fetch_entries' : ActorMethod<[], Array<BufferedArchiveEntry>>,
'get_account_delegation' : ActorMethod<
[UserNumber, FrontendHostname, AccountNumber, SessionKey, Timestamp],
GetDelegationResponse
[UserNumber, FrontendHostname, [] | [AccountNumber], SessionKey, Timestamp],
{ 'Ok' : SignedDelegation } |
{ 'Err' : AccountDelegationError }
>,
'get_accounts' : ActorMethod<
[UserNumber, FrontendHostname],
Expand Down
5 changes: 3 additions & 2 deletions src/internet_identity/internet_identity.did
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 also recreate the TS types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lmuntaner I had to disable the interface tests already for the other PRs because some dummy endpoints did not return Result.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we enable them now?

Copy link
Collaborator

Choose a reason for hiding this comment

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

In another PR I mean

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The PR is already up, but it fails because it apparently compares to the interface of the last release - which would mean we can only re-enable it once we have released.

Copy link
Contributor

Choose a reason for hiding this comment

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

@lmuntaner should be able to force that PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't it pass once this PR is merged?

Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ type UpdateAccountError = variant {
type AccountDelegationError = variant {
InternalCanisterError : text;
Unauthorized : principal;
NoSuchDelegation;
};

type PrepareAccountDelegation = record {
Expand Down Expand Up @@ -888,8 +889,8 @@ service : (opt InternetIdentityInit) -> {
get_account_delegation : (
anchor_number : UserNumber,
origin : FrontendHostname,
account_number : AccountNumber, // Null is unreserved default account
account_number : opt AccountNumber, // Null is unreserved default account
session_key : SessionKey,
expiration : Timestamp
) -> (GetDelegationResponse) query;
) -> (variant { Ok : SignedDelegation; Err : AccountDelegationError }) query;
};
46 changes: 44 additions & 2 deletions src/internet_identity/src/account_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ use crate::{
},
update_root_hash,
};
use ic_canister_sig_creation::{
delegation_signature_msg, signature_map::CanisterSigInputs, DELEGATION_SIG_DOMAIN,
};
use ic_cdk::{api::time, caller};
use internet_identity_interface::internet_identity::types::{
AccountNumber, AccountUpdate, AnchorNumber, CreateAccountError, FrontendHostname, SessionKey,
UpdateAccountError,
AccountNumber, AccountUpdate, AnchorNumber, CreateAccountError, Delegation, FrontendHostname,
SessionKey, SignedDelegation, Timestamp, UpdateAccountError,
};
use serde_bytes::ByteBuf;

Expand Down Expand Up @@ -145,6 +148,45 @@ pub async fn prepare_account_delegation(
})
}

pub fn get_account_delegation(
anchor_number: AnchorNumber,
origin: &FrontendHostname,
account_number: Option<AccountNumber>,
session_key: SessionKey,
expiration: Timestamp,
) -> Result<SignedDelegation, AccountDelegationError> {
check_frontend_length(origin);

storage_borrow(|storage| {
let account = storage
.read_account(ReadAccountParams {
account_number,
anchor_number,
origin,
})
.ok_or(AccountDelegationError::Unauthorized(caller()))?;

state::assets_and_signatures(|certified_assets, sigs| {
let inputs = CanisterSigInputs {
domain: DELEGATION_SIG_DOMAIN,
seed: &account.calculate_seed(),
message: &delegation_signature_msg(&session_key, expiration, None),
};
match sigs.get_signature_as_cbor(&inputs, Some(certified_assets.root_hash())) {
Ok(signature) => Ok(SignedDelegation {
delegation: Delegation {
pubkey: session_key,
expiration,
targets: None,
},
signature: ByteBuf::from(signature),
}),
Err(_) => Err(AccountDelegationError::NoSuchDelegation),
}
})
})
}

#[test]
fn should_create_account_for_origin() {
use crate::state::{storage_borrow_mut, storage_replace};
Expand Down
29 changes: 0 additions & 29 deletions src/internet_identity/src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use ic_canister_sig_creation::{
use ic_cdk::{id, trap};
use ic_certification::Hash;
use internet_identity_interface::internet_identity::types::*;
use serde_bytes::ByteBuf;
use sha2::{Digest, Sha256};
use std::net::IpAddr;

Expand Down Expand Up @@ -65,34 +64,6 @@ fn is_dev_frontend(frontend: &FrontendHostname) -> bool {
false
}

pub fn get_delegation(
anchor_number: AnchorNumber,
frontend: FrontendHostname,
session_key: SessionKey,
expiration: Timestamp,
) -> GetDelegationResponse {
check_frontend_length(&frontend);

state::assets_and_signatures(|certified_assets, sigs| {
let inputs = CanisterSigInputs {
domain: DELEGATION_SIG_DOMAIN,
seed: &calculate_anchor_seed(anchor_number, &frontend),
message: &delegation_signature_msg(&session_key, expiration, None),
};
match sigs.get_signature_as_cbor(&inputs, Some(certified_assets.root_hash())) {
Ok(signature) => GetDelegationResponse::SignedDelegation(SignedDelegation {
delegation: Delegation {
pubkey: session_key,
expiration,
targets: None,
},
signature: ByteBuf::from(signature),
}),
Err(_) => GetDelegationResponse::NoSuchDelegation,
}
})
}

pub fn get_principal(anchor_number: AnchorNumber, frontend: FrontendHostname) -> Principal {
check_frontend_length(&frontend);

Expand Down
33 changes: 25 additions & 8 deletions src/internet_identity/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,15 @@ fn get_delegation(
let Ok(_) = check_authorization(anchor_number) else {
trap(&format!("{} could not be authenticated.", caller()));
};
delegation::get_delegation(anchor_number, frontend, session_key, expiration)
account_management::get_account_delegation(
anchor_number,
&frontend,
None,
session_key,
expiration,
)
.map(GetDelegationResponse::SignedDelegation)
.unwrap_or(GetDelegationResponse::NoSuchDelegation)
}

#[query]
Expand Down Expand Up @@ -385,13 +393,22 @@ async fn prepare_account_delegation(

#[query]
fn get_account_delegation(
_anchor_number: AnchorNumber,
_origin: FrontendHostname,
_account_number: AccountNumber,
_session_key: SessionKey,
_expiration: Timestamp,
) -> GetDelegationResponse {
GetDelegationResponse::NoSuchDelegation
anchor_number: AnchorNumber,
origin: FrontendHostname,
account_number: Option<AccountNumber>,
session_key: SessionKey,
expiration: Timestamp,
) -> Result<SignedDelegation, AccountDelegationError> {
match check_authorization(anchor_number) {
Ok(_) => account_management::get_account_delegation(
anchor_number,
&origin,
account_number,
session_key,
expiration,
),
Err(err) => Err(err.into()),
}
}

#[query]
Expand Down
12 changes: 11 additions & 1 deletion src/internet_identity/src/storage/account.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use candid::{CandidType, Principal};

use crate::{authz_utils::IdentityUpdateError, delegation};
use crate::{
authz_utils::{AuthorizationError, IdentityUpdateError},
delegation,
};
use ic_cdk::trap;
use ic_certification::Hash;
use internet_identity_interface::internet_identity::types::{
Expand Down Expand Up @@ -166,6 +169,13 @@ impl Account {
pub enum AccountDelegationError {
Unauthorized(Principal),
InternalCanisterError(String),
NoSuchDelegation,
}

impl From<AuthorizationError> for AccountDelegationError {
fn from(err: AuthorizationError) -> Self {
AccountDelegationError::Unauthorized(err.principal)
}
}

impl From<IdentityUpdateError> for AccountDelegationError {
Expand Down
Loading