Skip to content

Commit

Permalink
feat(station): external canister input to accept opt policies and per…
Browse files Browse the repository at this point in the history
…missions by type (#366)

With the existing API it was not possible to optionally only update the
ExternalCanister change or call request policies, we always had to
provide both, same with the permissions for read, change, call. This PR
updates that and marks the individual policy and permission types as
optional.

---------

Co-authored-by: mraszyk <[email protected]>
  • Loading branch information
keplervital and mraszyk authored Oct 2, 2024
1 parent 2c18a76 commit df484f8
Show file tree
Hide file tree
Showing 23 changed files with 1,734 additions and 326 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ const save = async (): Promise<void> => {
const saveChangesToExistingExternalCanister = async (canisterId: Principal): Promise<Request> => {
const settings: Partial<ConfigureExternalCanisterSettingsInput> = {};
settings.name = [assertAndReturn(wizard.value.configuration.name, 'name')];
settings.labels = wizard.value.configuration.labels ? [wizard.value.configuration.labels] : [];
settings.state = wizard.value.configuration.state
? [mapExternalCanisterStateEnumToVariant(wizard.value.configuration.state)]
Expand All @@ -156,21 +157,23 @@ const saveChangesToExistingExternalCanister = async (canisterId: Principal): Pro
: [''];
settings.permissions = [
{
read: assertAndReturn(wizard.value.permission.read, 'read permission'),
change: assertAndReturn(wizard.value.permission.change, 'change permission'),
calls: [],
read: [assertAndReturn(wizard.value.permission.read, 'read permission')],
change: [assertAndReturn(wizard.value.permission.change, 'change permission')],
calls: [], // optional field, not updating calls through this dialog
},
];
settings.request_policies = [
{
calls: [],
change: wizard.value.approvalPolicy.change
.filter(item => item.rule !== undefined)
.map(item => ({
policy_id: item.policy_id ? [item.policy_id] : [],
rule: item.rule as RequestPolicyRule,
})),
calls: [], // optional field, not updating calls through this dialog
change: [
wizard.value.approvalPolicy.change
.filter(item => item.rule !== undefined)
.map(item => ({
policy_id: item.policy_id ? [item.policy_id] : [],
rule: item.rule as RequestPolicyRule,
})),
],
},
];
Expand Down
55 changes: 48 additions & 7 deletions apps/wallet/src/generated/station/station.did
Original file line number Diff line number Diff line change
Expand Up @@ -653,9 +653,9 @@ type CreateExternalCanisterOperationInput = record {
// The labels of the external canister.
labels : opt vec text;
// What operations are allowed on the canister.
permissions : ExternalCanisterPermissionsInput;
permissions : ExternalCanisterPermissionsCreateInput;
// The request policies for the canister.
request_policies : ExternalCanisterRequestPoliciesInput;
request_policies : ExternalCanisterRequestPoliciesCreateInput;
};

type ConfigureExternalCanisterSettingsInput = record {
Expand All @@ -665,9 +665,9 @@ type ConfigureExternalCanisterSettingsInput = record {
// The labels of the external canister.
labels : opt vec text;
// What operations are allowed on the canister.
permissions : opt ExternalCanisterPermissionsInput;
permissions : opt ExternalCanisterPermissionsUpdateInput;
// The request policies for the canister.
request_policies : opt ExternalCanisterRequestPoliciesInput;
request_policies : opt ExternalCanisterRequestPoliciesUpdateInput;
// The state of the external canister.
state : opt ExternalCanisterState;
};
Expand Down Expand Up @@ -2310,8 +2310,32 @@ type ExternalCanisterPermissions = record {
calls : vec ExternalCanisterCallPermission;
};

// The create input type for setting the permissions for the external canister.
type ExternalCanisterPermissionsCreateInput = ExternalCanisterPermissions;

// The input type for setting call permissions of an existing external canister.
type ExternalCanisterChangeCallPermissionsInput = variant {
// Replaces all the call permissions with the provided list, if the list is empty
// all the call permissions will be removed.
ReplaceAllBy : vec ExternalCanisterCallPermission;
// Override the call permissions from the specified execution methods.
OverrideSpecifiedByExecutionMethods : vec ExternalCanisterCallPermission;
// Remove call permissions of the specified execution methods.
RemoveByExecutionMethods : vec text;
};

// The input type for setting the permissions for the external canister.
type ExternalCanisterPermissionsInput = ExternalCanisterPermissions;
type ExternalCanisterPermissionsUpdateInput = record {
// Who can read information about the canister (e.g. canister status),
// changes to this permission can be made by the `change` permission.
read : opt Allow;
// Who can make changes to the canister, includes:
// - changing the permissions
// - install operations
change : opt Allow;
// The permissions for calling methods on the canister.
calls : opt ExternalCanisterChangeCallPermissionsInput;
};

// The request policy rules for the external canister.
type ExternalCanisterRequestPolicies = record {
Expand All @@ -2321,14 +2345,31 @@ type ExternalCanisterRequestPolicies = record {
calls : vec ExternalCanisterCallRequestPolicyRule;
};

// The input type for setting the request policies for the external canister.
type ExternalCanisterRequestPoliciesInput = record {
// The input type for setting the request policies for a new external canister.
type ExternalCanisterRequestPoliciesCreateInput = record {
// The request policy rules for the canister change operation.
change : vec ExternalCanisterChangeRequestPolicyRuleInput;
// The request policy rules for the calling methods on the canister.
calls : vec ExternalCanisterCallRequestPolicyRuleInput;
};

type ExternalCanisterChangeCallRequestPoliciesInput = variant {
// Replaces all the call request policies with the provided list.
ReplaceAllBy : vec ExternalCanisterCallRequestPolicyRuleInput;
// Remove call request policies by the provided ids.
RemoveByPolicyIds : vec UUID;
// Override the request policies for the specified execution methods.
OverrideSpecifiedByExecutionMethods : vec ExternalCanisterCallRequestPolicyRuleInput;
};

// The input type for setting the request policies for an existing external canister.
type ExternalCanisterRequestPoliciesUpdateInput = record {
// The request policy rules for the canister change operation.
change : opt vec ExternalCanisterChangeRequestPolicyRuleInput;
// The request policy rules for the calling methods on the canister.
calls : opt ExternalCanisterChangeCallRequestPoliciesInput;
};

// An external canister that the station can interact with.
type ExternalCanister = record {
// The id of the resource in the station.
Expand Down
37 changes: 31 additions & 6 deletions apps/wallet/src/generated/station/station.did.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,24 +204,24 @@ export type ConfigureExternalCanisterOperationKind = { 'SoftDelete' : null } |
{ 'Delete' : null } |
{ 'NativeSettings' : DefiniteCanisterSettingsInput };
export interface ConfigureExternalCanisterSettingsInput {
'permissions' : [] | [ExternalCanisterPermissionsInput],
'permissions' : [] | [ExternalCanisterPermissionsUpdateInput],
'name' : [] | [string],
'labels' : [] | [Array<string>],
'description' : [] | [string],
'request_policies' : [] | [ExternalCanisterRequestPoliciesInput],
'request_policies' : [] | [ExternalCanisterRequestPoliciesUpdateInput],
'state' : [] | [ExternalCanisterState],
}
export interface CreateExternalCanisterOperation {
'canister_id' : [] | [Principal],
'input' : CreateExternalCanisterOperationInput,
}
export interface CreateExternalCanisterOperationInput {
'permissions' : ExternalCanisterPermissionsInput,
'permissions' : ExternalCanisterPermissionsCreateInput,
'kind' : CreateExternalCanisterOperationKind,
'name' : string,
'labels' : [] | [Array<string>],
'description' : [] | [string],
'request_policies' : ExternalCanisterRequestPoliciesInput,
'request_policies' : ExternalCanisterRequestPoliciesCreateInput,
}
export type CreateExternalCanisterOperationKind = {
'AddExisting' : CreateExternalCanisterOperationKindAddExisting
Expand Down Expand Up @@ -405,6 +405,22 @@ export interface ExternalCanisterCallerPrivileges {
'can_call' : Array<ExternalCanisterCallerMethodsPrivileges>,
'can_fund' : boolean,
}
export type ExternalCanisterChangeCallPermissionsInput = {
'OverrideSpecifiedByExecutionMethods' : Array<
ExternalCanisterCallPermission
>
} |
{ 'RemoveByExecutionMethods' : Array<string> } |
{ 'ReplaceAllBy' : Array<ExternalCanisterCallPermission> };
export type ExternalCanisterChangeCallRequestPoliciesInput = {
'RemoveByPolicyIds' : Array<UUID>
} |
{
'OverrideSpecifiedByExecutionMethods' : Array<
ExternalCanisterCallRequestPolicyRuleInput
>
} |
{ 'ReplaceAllBy' : Array<ExternalCanisterCallRequestPolicyRuleInput> };
export interface ExternalCanisterChangeRequestPolicyRule {
'rule' : RequestPolicyRule,
'policy_id' : UUID,
Expand All @@ -420,15 +436,24 @@ export interface ExternalCanisterPermissions {
'read' : Allow,
'change' : Allow,
}
export type ExternalCanisterPermissionsInput = ExternalCanisterPermissions;
export type ExternalCanisterPermissionsCreateInput = ExternalCanisterPermissions;
export interface ExternalCanisterPermissionsUpdateInput {
'calls' : [] | [ExternalCanisterChangeCallPermissionsInput],
'read' : [] | [Allow],
'change' : [] | [Allow],
}
export interface ExternalCanisterRequestPolicies {
'calls' : Array<ExternalCanisterCallRequestPolicyRule>,
'change' : Array<ExternalCanisterChangeRequestPolicyRule>,
}
export interface ExternalCanisterRequestPoliciesInput {
export interface ExternalCanisterRequestPoliciesCreateInput {
'calls' : Array<ExternalCanisterCallRequestPolicyRuleInput>,
'change' : Array<ExternalCanisterChangeRequestPolicyRuleInput>,
}
export interface ExternalCanisterRequestPoliciesUpdateInput {
'calls' : [] | [ExternalCanisterChangeCallRequestPoliciesInput],
'change' : [] | [Array<ExternalCanisterChangeRequestPolicyRuleInput>],
}
export type ExternalCanisterResourceAction = {
'Call' : CallExternalCanisterResourceTarget
} |
Expand Down
47 changes: 35 additions & 12 deletions apps/wallet/src/generated/station/station.did.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,18 @@ export const idlFactory = ({ IDL }) => {
'allow' : Allow,
'validation_method' : ValidationMethodResourceTarget,
});
const ExternalCanisterPermissions = IDL.Record({
'calls' : IDL.Vec(ExternalCanisterCallPermission),
'read' : Allow,
'change' : Allow,
const ExternalCanisterChangeCallPermissionsInput = IDL.Variant({
'OverrideSpecifiedByExecutionMethods' : IDL.Vec(
ExternalCanisterCallPermission
),
'RemoveByExecutionMethods' : IDL.Vec(IDL.Text),
'ReplaceAllBy' : IDL.Vec(ExternalCanisterCallPermission),
});
const ExternalCanisterPermissionsUpdateInput = IDL.Record({
'calls' : IDL.Opt(ExternalCanisterChangeCallPermissionsInput),
'read' : IDL.Opt(Allow),
'change' : IDL.Opt(Allow),
});
const ExternalCanisterPermissionsInput = ExternalCanisterPermissions;
const UserSpecifier = IDL.Variant({
'Id' : IDL.Vec(UUID),
'Any' : IDL.Null,
Expand Down Expand Up @@ -232,24 +238,31 @@ export const idlFactory = ({ IDL }) => {
'validation_method' : ValidationMethodResourceTarget,
'policy_id' : IDL.Opt(UUID),
});
const ExternalCanisterChangeCallRequestPoliciesInput = IDL.Variant({
'RemoveByPolicyIds' : IDL.Vec(UUID),
'OverrideSpecifiedByExecutionMethods' : IDL.Vec(
ExternalCanisterCallRequestPolicyRuleInput
),
'ReplaceAllBy' : IDL.Vec(ExternalCanisterCallRequestPolicyRuleInput),
});
const ExternalCanisterChangeRequestPolicyRuleInput = IDL.Record({
'rule' : RequestPolicyRule,
'policy_id' : IDL.Opt(UUID),
});
const ExternalCanisterRequestPoliciesInput = IDL.Record({
'calls' : IDL.Vec(ExternalCanisterCallRequestPolicyRuleInput),
'change' : IDL.Vec(ExternalCanisterChangeRequestPolicyRuleInput),
const ExternalCanisterRequestPoliciesUpdateInput = IDL.Record({
'calls' : IDL.Opt(ExternalCanisterChangeCallRequestPoliciesInput),
'change' : IDL.Opt(IDL.Vec(ExternalCanisterChangeRequestPolicyRuleInput)),
});
const ExternalCanisterState = IDL.Variant({
'Active' : IDL.Null,
'Archived' : IDL.Null,
});
const ConfigureExternalCanisterSettingsInput = IDL.Record({
'permissions' : IDL.Opt(ExternalCanisterPermissionsInput),
'permissions' : IDL.Opt(ExternalCanisterPermissionsUpdateInput),
'name' : IDL.Opt(IDL.Text),
'labels' : IDL.Opt(IDL.Vec(IDL.Text)),
'description' : IDL.Opt(IDL.Text),
'request_policies' : IDL.Opt(ExternalCanisterRequestPoliciesInput),
'request_policies' : IDL.Opt(ExternalCanisterRequestPoliciesUpdateInput),
'state' : IDL.Opt(ExternalCanisterState),
});
const DefiniteCanisterSettingsInput = IDL.Record({
Expand Down Expand Up @@ -354,6 +367,12 @@ export const idlFactory = ({ IDL }) => {
const RemoveAddressBookEntryOperationInput = IDL.Record({
'address_book_entry_id' : UUID,
});
const ExternalCanisterPermissions = IDL.Record({
'calls' : IDL.Vec(ExternalCanisterCallPermission),
'read' : Allow,
'change' : Allow,
});
const ExternalCanisterPermissionsCreateInput = ExternalCanisterPermissions;
const CreateExternalCanisterOperationKindAddExisting = IDL.Record({
'canister_id' : IDL.Principal,
});
Expand All @@ -364,13 +383,17 @@ export const idlFactory = ({ IDL }) => {
'AddExisting' : CreateExternalCanisterOperationKindAddExisting,
'CreateNew' : CreateExternalCanisterOperationKindCreateNew,
});
const ExternalCanisterRequestPoliciesCreateInput = IDL.Record({
'calls' : IDL.Vec(ExternalCanisterCallRequestPolicyRuleInput),
'change' : IDL.Vec(ExternalCanisterChangeRequestPolicyRuleInput),
});
const CreateExternalCanisterOperationInput = IDL.Record({
'permissions' : ExternalCanisterPermissionsInput,
'permissions' : ExternalCanisterPermissionsCreateInput,
'kind' : CreateExternalCanisterOperationKind,
'name' : IDL.Text,
'labels' : IDL.Opt(IDL.Vec(IDL.Text)),
'description' : IDL.Opt(IDL.Text),
'request_policies' : ExternalCanisterRequestPoliciesInput,
'request_policies' : ExternalCanisterRequestPoliciesCreateInput,
});
const ChangeAddressBookMetadata = IDL.Variant({
'OverrideSpecifiedBy' : IDL.Vec(AddressBookMetadata),
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet/src/pages/ExternalCanisterDetailPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
color="default"
variant="tonal"
class="ml-1 px-2"
:disabled="canisterDetails.moduleHash.loading"
:disabled="!canisterDetails.status.value"
:append-icon="mdiDatabaseCog"
@click="dialogs.install = true"
>
Expand Down
Loading

0 comments on commit df484f8

Please sign in to comment.