From cd7aacdb4414e3aeee3bae9a21aeddb46e859de4 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Sun, 20 Oct 2024 18:02:16 +0800 Subject: [PATCH] feat: 1. support governance canister as controller; 2. support file hash as access token --- Cargo.lock | 130 +++++++++--------- Cargo.toml | 4 +- .../ic_oss_bucket/ic_oss_bucket.did | 3 + .../ic_oss_bucket/ic_oss_bucket.did.d.ts | 3 + .../ic_oss_bucket/ic_oss_bucket.did.js | 5 + .../ic_oss_cluster/ic_oss_cluster.did | 3 + .../ic_oss_cluster/ic_oss_cluster.did.d.ts | 3 + .../ic_oss_cluster/ic_oss_cluster.did.js | 5 + src/ic_oss_bucket/ic_oss_bucket.did | 3 + src/ic_oss_bucket/src/api_http.rs | 71 +++++----- src/ic_oss_bucket/src/api_init.rs | 8 +- src/ic_oss_bucket/src/api_query.rs | 75 +++++----- src/ic_oss_bucket/src/lib.rs | 2 +- src/ic_oss_bucket/src/store.rs | 31 ++++- src/ic_oss_cluster/ic_oss_cluster.did | 3 + src/ic_oss_cluster/src/init.rs | 8 +- src/ic_oss_cluster/src/lib.rs | 7 +- src/ic_oss_cluster/src/store.rs | 12 ++ .../candid/ic_oss_bucket/ic_oss_bucket.did | 3 + .../ic_oss_bucket/ic_oss_bucket.did.d.ts | 3 + .../candid/ic_oss_bucket/ic_oss_bucket.did.js | 5 + .../candid/ic_oss_cluster/ic_oss_cluster.did | 3 + .../ic_oss_cluster/ic_oss_cluster.did.d.ts | 3 + .../ic_oss_cluster/ic_oss_cluster.did.js | 5 + src/ic_oss_ts/package.json | 12 +- src/ic_oss_types/src/bucket.rs | 1 + src/ic_oss_types/src/cluster.rs | 1 + src/ic_oss_types/src/file.rs | 2 + 28 files changed, 264 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dba3f91..ccfad34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,9 +118,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "arrayvec" @@ -147,7 +147,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -328,14 +328,14 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] name = "cc" -version = "1.1.28" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "shlex", ] @@ -430,7 +430,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -562,7 +562,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -858,7 +858,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -1081,9 +1081,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -1105,9 +1105,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -1130,7 +1130,7 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-util", "rustls", "rustls-pki-types", @@ -1147,7 +1147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.30", + "hyper 0.14.31", "native-tls", "tokio", "tokio-native-tls", @@ -1164,7 +1164,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.0", "pin-project-lite", "socket2", "tokio", @@ -1212,16 +1212,19 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.38.2" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a656d3b25007f59ba0700e65b332efd56d5dbfc6014994000ab3dbb221f54a" +checksum = "0783cc46e082dc4b016ff693a45207db55e552e8e6f5e3e2552514761a285f6d" dependencies = [ "async-lock", "async-trait", "backoff", "cached", "candid", + "der", + "ecdsa", "ed25519-consensus", + "elliptic-curve", "futures-util", "hex", "http 1.1.0", @@ -1237,8 +1240,6 @@ dependencies = [ "rand", "rangemap", "reqwest 0.12.8", - "ring", - "rustls-webpki", "sec1", "serde", "serde_bytes", @@ -1277,7 +1278,7 @@ dependencies = [ "quote", "serde", "serde_tokenstream", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -1323,7 +1324,7 @@ dependencies = [ [[package]] name = "ic-oss" -version = "0.9.3" +version = "0.9.5" dependencies = [ "bytes", "candid", @@ -1340,7 +1341,7 @@ dependencies = [ [[package]] name = "ic-oss-can" -version = "0.9.3" +version = "0.9.5" dependencies = [ "candid", "ciborium", @@ -1353,7 +1354,7 @@ dependencies = [ [[package]] name = "ic-oss-cli" -version = "0.9.3" +version = "0.9.5" dependencies = [ "anyhow", "candid", @@ -1374,7 +1375,7 @@ dependencies = [ [[package]] name = "ic-oss-types" -version = "0.9.3" +version = "0.9.5" dependencies = [ "base64 0.21.7", "candid", @@ -1413,9 +1414,9 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.38.2" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894b183f280e87b29aac98e7de0972cf632435e1f0a462969d9f5e0ccacc4d25" +checksum = "90400f5f1371fda054a07e23717d38813f15093e193b8f21a36fd3e2c62a7179" dependencies = [ "candid", "hex", @@ -1465,7 +1466,7 @@ dependencies = [ [[package]] name = "ic_oss_bucket" -version = "0.9.3" +version = "0.9.5" dependencies = [ "base64 0.21.7", "candid", @@ -1485,7 +1486,7 @@ dependencies = [ [[package]] name = "ic_oss_cluster" -version = "0.9.3" +version = "0.9.5" dependencies = [ "candid", "ciborium", @@ -1651,9 +1652,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -1803,9 +1804,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -1824,7 +1825,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -1835,9 +1836,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -1991,9 +1992,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -2123,7 +2124,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.30", + "hyper 0.14.31", "hyper-tls", "ipnet", "js-sys", @@ -2163,7 +2164,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.0", "hyper-rustls", "hyper-util", "ipnet", @@ -2255,9 +2256,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "once_cell", "ring", @@ -2287,9 +2288,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -2304,9 +2305,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -2408,14 +2409,14 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -2431,7 +2432,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -2443,7 +2444,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -2617,7 +2618,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -2645,9 +2646,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "198514704ca887dd5a1e408c6c6cdcba43672f9b4062e1b24aa34e74e6d7faae" dependencies = [ "proc-macro2", "quote", @@ -2720,7 +2721,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -2795,7 +2796,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] @@ -2888,12 +2889,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -2953,9 +2951,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "vcpkg" @@ -3006,7 +3004,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", "wasm-bindgen-shared", ] @@ -3040,7 +3038,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3298,7 +3296,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.81", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 158d8da..8b2f25a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ strip = true opt-level = 's' [workspace.package] -version = "0.9.3" +version = "0.9.5" edition = "2021" repository = "https://github.com/ldclabs/ic-oss" keywords = ["file", "storage", "oss", "s3", "icp"] @@ -46,7 +46,7 @@ ic-cdk-timers = "0.10" ic-stable-structures = "0.6" icrc-ledger-types = "0.1" ic-http-certification = { version = "2.6", features = ["serde"] } -ic-agent = "0.38" +ic-agent = "0.39" anyhow = "1" crc32fast = "1.4" url = "2.5" diff --git a/src/declarations/ic_oss_bucket/ic_oss_bucket.did b/src/declarations/ic_oss_bucket/ic_oss_bucket.did index 50deea0..cb57b5e 100644 --- a/src/declarations/ic_oss_bucket/ic_oss_bucket.did +++ b/src/declarations/ic_oss_bucket/ic_oss_bucket.did @@ -3,6 +3,7 @@ type BucketInfo = record { total_chunks : nat64; trusted_eddsa_pub_keys : vec blob; managers : vec principal; + governance_canister : opt principal; name : text; max_custom_data_size : nat16; auditors : vec principal; @@ -79,6 +80,7 @@ type FolderInfo = record { }; type FolderName = record { id : nat32; name : text }; type InitArgs = record { + governance_canister : opt principal; name : text; max_custom_data_size : nat16; max_children : nat16; @@ -146,6 +148,7 @@ type UpdateFolderInput = record { name : opt text; }; type UpgradeArgs = record { + governance_canister : opt principal; max_custom_data_size : opt nat16; max_children : opt nat16; enable_hash_index : opt bool; diff --git a/src/declarations/ic_oss_bucket/ic_oss_bucket.did.d.ts b/src/declarations/ic_oss_bucket/ic_oss_bucket.did.d.ts index c9724ae..950f0a0 100644 --- a/src/declarations/ic_oss_bucket/ic_oss_bucket.did.d.ts +++ b/src/declarations/ic_oss_bucket/ic_oss_bucket.did.d.ts @@ -7,6 +7,7 @@ export interface BucketInfo { 'total_chunks' : bigint, 'trusted_eddsa_pub_keys' : Array, 'managers' : Array, + 'governance_canister' : [] | [Principal], 'name' : string, 'max_custom_data_size' : number, 'auditors' : Array, @@ -86,6 +87,7 @@ export interface FolderInfo { } export interface FolderName { 'id' : number, 'name' : string } export interface InitArgs { + 'governance_canister' : [] | [Principal], 'name' : string, 'max_custom_data_size' : number, 'max_children' : number, @@ -175,6 +177,7 @@ export interface UpdateFolderInput { 'name' : [] | [string], } export interface UpgradeArgs { + 'governance_canister' : [] | [Principal], 'max_custom_data_size' : [] | [number], 'max_children' : [] | [number], 'enable_hash_index' : [] | [boolean], diff --git a/src/declarations/ic_oss_bucket/ic_oss_bucket.did.js b/src/declarations/ic_oss_bucket/ic_oss_bucket.did.js index 34f2ad3..d873e60 100644 --- a/src/declarations/ic_oss_bucket/ic_oss_bucket.did.js +++ b/src/declarations/ic_oss_bucket/ic_oss_bucket.did.js @@ -1,5 +1,6 @@ export const idlFactory = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'max_custom_data_size' : IDL.Opt(IDL.Nat16), 'max_children' : IDL.Opt(IDL.Nat16), 'enable_hash_index' : IDL.Opt(IDL.Bool), @@ -7,6 +8,7 @@ export const idlFactory = ({ IDL }) => { 'max_folder_depth' : IDL.Opt(IDL.Nat8), }); const InitArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'max_children' : IDL.Nat16, @@ -66,6 +68,7 @@ export const idlFactory = ({ IDL }) => { 'total_chunks' : IDL.Nat64, 'trusted_eddsa_pub_keys' : IDL.Vec(IDL.Vec(IDL.Nat8)), 'managers' : IDL.Vec(IDL.Principal), + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'auditors' : IDL.Vec(IDL.Principal), @@ -365,6 +368,7 @@ export const idlFactory = ({ IDL }) => { }; export const init = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'max_custom_data_size' : IDL.Opt(IDL.Nat16), 'max_children' : IDL.Opt(IDL.Nat16), 'enable_hash_index' : IDL.Opt(IDL.Bool), @@ -372,6 +376,7 @@ export const init = ({ IDL }) => { 'max_folder_depth' : IDL.Opt(IDL.Nat8), }); const InitArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'max_children' : IDL.Nat16, diff --git a/src/declarations/ic_oss_cluster/ic_oss_cluster.did b/src/declarations/ic_oss_cluster/ic_oss_cluster.did index 3df08a0..040596e 100644 --- a/src/declarations/ic_oss_cluster/ic_oss_cluster.did +++ b/src/declarations/ic_oss_cluster/ic_oss_cluster.did @@ -14,6 +14,7 @@ type ClusterInfo = record { bucket_wasm_total : nat64; ecdsa_key_name : text; managers : vec principal; + governance_canister : opt principal; name : text; bucket_deployed_total : nat64; token_expiration : nat64; @@ -26,6 +27,7 @@ type ClusterInfo = record { type DeployWasmInput = record { args : opt blob; canister : principal }; type InitArgs = record { ecdsa_key_name : text; + governance_canister : opt principal; name : text; token_expiration : nat64; bucket_topup_threshold : nat; @@ -48,6 +50,7 @@ type Token = record { policies : text; }; type UpgradeArgs = record { + governance_canister : opt principal; name : opt text; token_expiration : opt nat64; bucket_topup_threshold : opt nat; diff --git a/src/declarations/ic_oss_cluster/ic_oss_cluster.did.d.ts b/src/declarations/ic_oss_cluster/ic_oss_cluster.did.d.ts index 39e7030..ff878ec 100644 --- a/src/declarations/ic_oss_cluster/ic_oss_cluster.did.d.ts +++ b/src/declarations/ic_oss_cluster/ic_oss_cluster.did.d.ts @@ -22,6 +22,7 @@ export interface ClusterInfo { 'bucket_wasm_total' : bigint, 'ecdsa_key_name' : string, 'managers' : Array, + 'governance_canister' : [] | [Principal], 'name' : string, 'bucket_deployed_total' : bigint, 'token_expiration' : bigint, @@ -37,6 +38,7 @@ export interface DeployWasmInput { } export interface InitArgs { 'ecdsa_key_name' : string, + 'governance_canister' : [] | [Principal], 'name' : string, 'token_expiration' : bigint, 'bucket_topup_threshold' : bigint, @@ -69,6 +71,7 @@ export interface Token { 'policies' : string, } export interface UpgradeArgs { + 'governance_canister' : [] | [Principal], 'name' : [] | [string], 'token_expiration' : [] | [bigint], 'bucket_topup_threshold' : [] | [bigint], diff --git a/src/declarations/ic_oss_cluster/ic_oss_cluster.did.js b/src/declarations/ic_oss_cluster/ic_oss_cluster.did.js index 0e183cd..af3c26c 100644 --- a/src/declarations/ic_oss_cluster/ic_oss_cluster.did.js +++ b/src/declarations/ic_oss_cluster/ic_oss_cluster.did.js @@ -1,5 +1,6 @@ export const idlFactory = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Opt(IDL.Text), 'token_expiration' : IDL.Opt(IDL.Nat64), 'bucket_topup_threshold' : IDL.Opt(IDL.Nat), @@ -7,6 +8,7 @@ export const idlFactory = ({ IDL }) => { }); const InitArgs = IDL.Record({ 'ecdsa_key_name' : IDL.Text, + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'token_expiration' : IDL.Nat64, 'bucket_topup_threshold' : IDL.Nat, @@ -64,6 +66,7 @@ export const idlFactory = ({ IDL }) => { 'bucket_wasm_total' : IDL.Nat64, 'ecdsa_key_name' : IDL.Text, 'managers' : IDL.Vec(IDL.Principal), + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'bucket_deployed_total' : IDL.Nat64, 'token_expiration' : IDL.Nat64, @@ -198,6 +201,7 @@ export const idlFactory = ({ IDL }) => { }; export const init = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Opt(IDL.Text), 'token_expiration' : IDL.Opt(IDL.Nat64), 'bucket_topup_threshold' : IDL.Opt(IDL.Nat), @@ -205,6 +209,7 @@ export const init = ({ IDL }) => { }); const InitArgs = IDL.Record({ 'ecdsa_key_name' : IDL.Text, + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'token_expiration' : IDL.Nat64, 'bucket_topup_threshold' : IDL.Nat, diff --git a/src/ic_oss_bucket/ic_oss_bucket.did b/src/ic_oss_bucket/ic_oss_bucket.did index 50deea0..cb57b5e 100644 --- a/src/ic_oss_bucket/ic_oss_bucket.did +++ b/src/ic_oss_bucket/ic_oss_bucket.did @@ -3,6 +3,7 @@ type BucketInfo = record { total_chunks : nat64; trusted_eddsa_pub_keys : vec blob; managers : vec principal; + governance_canister : opt principal; name : text; max_custom_data_size : nat16; auditors : vec principal; @@ -79,6 +80,7 @@ type FolderInfo = record { }; type FolderName = record { id : nat32; name : text }; type InitArgs = record { + governance_canister : opt principal; name : text; max_custom_data_size : nat16; max_children : nat16; @@ -146,6 +148,7 @@ type UpdateFolderInput = record { name : opt text; }; type UpgradeArgs = record { + governance_canister : opt principal; max_custom_data_size : opt nat16; max_children : opt nat16; enable_hash_index : opt bool; diff --git a/src/ic_oss_bucket/src/api_http.rs b/src/ic_oss_bucket/src/api_http.rs index 657466c..f2b8878 100644 --- a/src/ic_oss_bucket/src/api_http.rs +++ b/src/ic_oss_bucket/src/api_http.rs @@ -82,7 +82,6 @@ static IC_CERTIFICATE_EXPRESSION_HEADER: &str = "ic-certificateexpression"; // https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/1 // http://mmrxu-fqaaa-aaaap-ahhna-cai.localhost:4943/f/1 // download file by id 1 // http://mmrxu-fqaaa-aaaap-ahhna-cai.localhost:4943/h/8546ffa4296a6960e9e64e95de178d40c231a0cd358a65477bc56a105dda1c1d //download file by hash 854... -// TODO: 1. support range request; 2. token verification; 3. cache control #[ic_cdk::query(hidden = true)] fn http_request(request: HttpRequest) -> HttpStreamingResponse { let witness = store::state::http_tree_with(|t| { @@ -124,26 +123,6 @@ fn http_request(request: HttpRequest) -> HttpStreamingResponse { param.file }; - let canister = ic_cdk::id(); - let ctx = match store::state::with(|s| { - s.read_permission( - ic_cdk::caller(), - &canister, - param.token, - ic_cdk::api::time() / SECONDS, - ) - }) { - Ok(ctx) => ctx, - Err((status_code, err)) => { - return HttpStreamingResponse { - status_code, - headers, - body: ByteBuf::from(err.as_bytes()), - ..Default::default() - }; - } - }; - match store::fs::get_file(id) { None => HttpStreamingResponse { status_code: 404, @@ -152,22 +131,44 @@ fn http_request(request: HttpRequest) -> HttpStreamingResponse { ..Default::default() }, Some(file) => { - if file.status < 0 && ctx.role < store::Role::Auditor { - return HttpStreamingResponse { - status_code: 403, - headers, - body: ByteBuf::from("file archived".as_bytes()), - ..Default::default() + if !file.read_by_hash(¶m.token) { + let canister = ic_cdk::id(); + let ctx = match store::state::with(|s| { + s.read_permission( + ic_cdk::caller(), + &canister, + param.token, + ic_cdk::api::time() / SECONDS, + ) + }) { + Ok(ctx) => ctx, + Err((status_code, err)) => { + return HttpStreamingResponse { + status_code, + headers, + body: ByteBuf::from(err.as_bytes()), + ..Default::default() + }; + } }; - } - if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { - return HttpStreamingResponse { - status_code: 403, - headers, - body: ByteBuf::from("permission denied".as_bytes()), - ..Default::default() - }; + if file.status < 0 && ctx.role < store::Role::Auditor { + return HttpStreamingResponse { + status_code: 403, + headers, + body: ByteBuf::from("file archived".as_bytes()), + ..Default::default() + }; + } + + if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { + return HttpStreamingResponse { + status_code: 403, + headers, + body: ByteBuf::from("permission denied".as_bytes()), + ..Default::default() + }; + } } if file.size != file.filled { diff --git a/src/ic_oss_bucket/src/api_init.rs b/src/ic_oss_bucket/src/api_init.rs index 31c7e92..97f3430 100644 --- a/src/ic_oss_bucket/src/api_init.rs +++ b/src/ic_oss_bucket/src/api_init.rs @@ -1,4 +1,4 @@ -use candid::CandidType; +use candid::{CandidType, Principal}; use ic_oss_types::file::MAX_FILE_SIZE; use serde::Deserialize; @@ -20,6 +20,7 @@ pub struct InitArgs { max_custom_data_size: u16, // in bytes, default is 4KB enable_hash_index: bool, // if enabled, indexing will be built using file hash, allowing files to be read by their hash and preventing duplicate hash for files. default is false visibility: u8, // 0: private; 1: public, can be accessed by anyone, default is 0 + governance_canister: Option, } #[derive(Clone, Debug, CandidType, Deserialize)] @@ -29,6 +30,7 @@ pub struct UpgradeArgs { max_children: Option, max_custom_data_size: Option, enable_hash_index: Option, + governance_canister: Option, } impl UpgradeArgs { @@ -89,6 +91,7 @@ fn init(args: Option) { b.max_custom_data_size = args.max_custom_data_size }; b.enable_hash_index = args.enable_hash_index; + b.governance_canister = args.governance_canister; }); } Some(CanisterArgs::Upgrade(_)) => { @@ -133,6 +136,9 @@ fn post_upgrade(args: Option) { if let Some(enable_hash_index) = args.enable_hash_index { s.enable_hash_index = enable_hash_index; } + if let Some(governance_canister) = args.governance_canister { + s.governance_canister = Some(governance_canister); + } }); } Some(CanisterArgs::Init(_)) => { diff --git a/src/ic_oss_bucket/src/api_query.rs b/src/ic_oss_bucket/src/api_query.rs index ca137c3..fad3493 100644 --- a/src/ic_oss_bucket/src/api_query.rs +++ b/src/ic_oss_bucket/src/api_query.rs @@ -55,6 +55,7 @@ fn get_bucket_info(access_token: Option) -> Result auditors: r.auditors.clone(), trusted_ecdsa_pub_keys: r.trusted_ecdsa_pub_keys.clone(), trusted_eddsa_pub_keys: r.trusted_eddsa_pub_keys.clone(), + governance_canister: r.governance_canister.clone(), })) } @@ -92,23 +93,25 @@ fn get_file_info(id: u32, access_token: Option) -> Result Err("file not found".to_string()), Some(file) => { - let canister = ic_cdk::id(); - let ctx = match store::state::with(|s| { - s.read_permission( - ic_cdk::caller(), - &canister, - access_token, - ic_cdk::api::time() / SECONDS, - ) - }) { - Ok(ctx) => ctx, - Err((_, err)) => { - return Err(err); - } - }; + if !file.read_by_hash(&access_token) { + let canister = ic_cdk::id(); + let ctx = match store::state::with(|s| { + s.read_permission( + ic_cdk::caller(), + &canister, + access_token, + ic_cdk::api::time() / SECONDS, + ) + }) { + Ok(ctx) => ctx, + Err((_, err)) => { + return Err(err); + } + }; - if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { - Err("permission denied".to_string())?; + if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { + Err("permission denied".to_string())?; + } } Ok(file.into_info(id)) @@ -162,27 +165,29 @@ fn get_file_chunks( match store::fs::get_file(id) { None => Err("file not found".to_string()), Some(file) => { - let canister = ic_cdk::id(); - let ctx = match store::state::with(|s| { - s.read_permission( - ic_cdk::caller(), - &canister, - access_token, - ic_cdk::api::time() / SECONDS, - ) - }) { - Ok(ctx) => ctx, - Err((_, err)) => { - return Err(err); - } - }; + if !file.read_by_hash(&access_token) { + let canister = ic_cdk::id(); + let ctx = match store::state::with(|s| { + s.read_permission( + ic_cdk::caller(), + &canister, + access_token, + ic_cdk::api::time() / SECONDS, + ) + }) { + Ok(ctx) => ctx, + Err((_, err)) => { + return Err(err); + } + }; - if file.status < 0 && ctx.role < store::Role::Auditor { - Err("file archived".to_string())?; - } + if file.status < 0 && ctx.role < store::Role::Auditor { + Err("file archived".to_string())?; + } - if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { - Err("permission denied".to_string())?; + if !permission::check_file_read(&ctx.ps, &canister, id, file.parent) { + Err("permission denied".to_string())?; + } } Ok(store::fs::get_chunks(id, index, take.unwrap_or(8).min(8))) diff --git a/src/ic_oss_bucket/src/lib.rs b/src/ic_oss_bucket/src/lib.rs index 61f604a..11c9d85 100644 --- a/src/ic_oss_bucket/src/lib.rs +++ b/src/ic_oss_bucket/src/lib.rs @@ -21,7 +21,7 @@ static ANONYMOUS: Principal = Principal::anonymous(); fn is_controller() -> Result<(), String> { let caller = ic_cdk::caller(); - if ic_cdk::api::is_controller(&caller) { + if ic_cdk::api::is_controller(&caller) || store::state::is_controller(&caller) { Ok(()) } else { Err("user is not a controller".to_string()) diff --git a/src/ic_oss_bucket/src/store.rs b/src/ic_oss_bucket/src/store.rs index a01f61f..1a52c71 100644 --- a/src/ic_oss_bucket/src/store.rs +++ b/src/ic_oss_bucket/src/store.rs @@ -7,7 +7,8 @@ use ic_http_certification::{ use ic_oss_types::{ cose::{Token, BUCKET_TOKEN_AAD}, file::{ - FileChunk, FileInfo, UpdateFileInput, CHUNK_SIZE, MAX_FILE_SIZE, MAX_FILE_SIZE_PER_CALL, + FileChunk, FileInfo, UpdateFileInput, CHUNK_SIZE, CUSTOM_KEY_BY_HASH, MAX_FILE_SIZE, + MAX_FILE_SIZE_PER_CALL, }, folder::{FolderInfo, FolderName, UpdateFolderInput}, permission::Policies, @@ -66,6 +67,8 @@ pub struct Bucket { // used to verify the request token signed with ED25519 #[serde(rename = "ed", alias = "trusted_eddsa_pub_keys")] pub trusted_eddsa_pub_keys: Vec>, + #[serde(default, rename = "gov")] + pub governance_canister: Option, } impl Default for Bucket { @@ -85,6 +88,7 @@ impl Default for Bucket { auditors: BTreeSet::new(), trusted_ecdsa_pub_keys: Vec::new(), trusted_eddsa_pub_keys: Vec::new(), + governance_canister: None, } } } @@ -299,6 +303,22 @@ impl FileMetadata { ex: self.ex, } } + + pub fn read_by_hash(&self, access_token: &Option) -> bool { + if let Some(access_token) = access_token { + self.status >= 0 + && self + .custom + .as_ref() + .map_or(false, |c| c.contains_key(CUSTOM_KEY_BY_HASH)) + && self + .hash + .as_ref() + .map_or(false, |h| h.as_slice() == access_token.as_ref()) + } else { + false + } + } } #[derive(Clone, Default, Deserialize, Serialize)] @@ -808,6 +828,15 @@ pub mod state { BUCKET.with(|r| f(&mut r.borrow_mut())) } + pub fn is_controller(caller: &Principal) -> bool { + BUCKET.with(|r| { + r.borrow() + .governance_canister + .as_ref() + .map_or(false, |p| p == caller) + }) + } + pub fn http_tree_with(f: impl FnOnce(&HttpCertificationTree) -> R) -> R { HTTP_TREE.with(|r| f(&r.borrow())) } diff --git a/src/ic_oss_cluster/ic_oss_cluster.did b/src/ic_oss_cluster/ic_oss_cluster.did index 3df08a0..040596e 100644 --- a/src/ic_oss_cluster/ic_oss_cluster.did +++ b/src/ic_oss_cluster/ic_oss_cluster.did @@ -14,6 +14,7 @@ type ClusterInfo = record { bucket_wasm_total : nat64; ecdsa_key_name : text; managers : vec principal; + governance_canister : opt principal; name : text; bucket_deployed_total : nat64; token_expiration : nat64; @@ -26,6 +27,7 @@ type ClusterInfo = record { type DeployWasmInput = record { args : opt blob; canister : principal }; type InitArgs = record { ecdsa_key_name : text; + governance_canister : opt principal; name : text; token_expiration : nat64; bucket_topup_threshold : nat; @@ -48,6 +50,7 @@ type Token = record { policies : text; }; type UpgradeArgs = record { + governance_canister : opt principal; name : opt text; token_expiration : opt nat64; bucket_topup_threshold : opt nat; diff --git a/src/ic_oss_cluster/src/init.rs b/src/ic_oss_cluster/src/init.rs index 995465e..61fc525 100644 --- a/src/ic_oss_cluster/src/init.rs +++ b/src/ic_oss_cluster/src/init.rs @@ -1,4 +1,4 @@ -use candid::CandidType; +use candid::{CandidType, Principal}; use serde::Deserialize; use std::time::Duration; @@ -18,6 +18,7 @@ pub struct InitArgs { token_expiration: u64, // in seconds bucket_topup_threshold: u128, bucket_topup_amount: u128, + governance_canister: Option, } #[derive(Clone, Debug, CandidType, Deserialize)] @@ -26,6 +27,7 @@ pub struct UpgradeArgs { token_expiration: Option, // in seconds bucket_topup_threshold: Option, bucket_topup_amount: Option, + governance_canister: Option, } #[ic_cdk::init] @@ -43,6 +45,7 @@ fn init(args: Option) { }; s.bucket_topup_threshold = args.bucket_topup_threshold; s.bucket_topup_amount = args.bucket_topup_amount; + s.governance_canister = args.governance_canister; }); } ChainArgs::Upgrade(_) => { @@ -85,6 +88,9 @@ fn post_upgrade(args: Option) { if let Some(bucket_topup_amount) = args.bucket_topup_amount { s.bucket_topup_amount = bucket_topup_amount; } + if let Some(governance_canister) = args.governance_canister { + s.governance_canister = Some(governance_canister); + } }); } Some(ChainArgs::Init(_)) => { diff --git a/src/ic_oss_cluster/src/lib.rs b/src/ic_oss_cluster/src/lib.rs index aa2b77b..b4cd3f0 100644 --- a/src/ic_oss_cluster/src/lib.rs +++ b/src/ic_oss_cluster/src/lib.rs @@ -23,7 +23,7 @@ const MILLISECONDS: u64 = 1_000_000; fn is_controller() -> Result<(), String> { let caller = ic_cdk::caller(); - if ic_cdk::api::is_controller(&caller) { + if ic_cdk::api::is_controller(&caller) || store::state::is_controller(&caller) { Ok(()) } else { Err("user is not a controller".to_string()) @@ -32,7 +32,10 @@ fn is_controller() -> Result<(), String> { fn is_controller_or_manager() -> Result<(), String> { let caller = ic_cdk::caller(); - if ic_cdk::api::is_controller(&caller) || store::state::is_manager(&caller) { + if ic_cdk::api::is_controller(&caller) + || store::state::is_controller(&caller) + || store::state::is_manager(&caller) + { Ok(()) } else { Err("user is not a controller or manager".to_string()) diff --git a/src/ic_oss_cluster/src/store.rs b/src/ic_oss_cluster/src/store.rs index a22a018..052aa9e 100644 --- a/src/ic_oss_cluster/src/store.rs +++ b/src/ic_oss_cluster/src/store.rs @@ -55,6 +55,8 @@ pub struct State { pub weak_ed25519_secret_key: ByteArray<32>, // should not be exposed #[serde(default, rename = "wt")] pub weak_ed25519_token_public_key: String, + #[serde(default, rename = "gov")] + pub governance_canister: Option, } impl Storable for State { @@ -207,6 +209,15 @@ thread_local! { pub mod state { use super::*; + pub fn is_controller(caller: &Principal) -> bool { + STATE.with(|r| { + r.borrow() + .governance_canister + .as_ref() + .map_or(false, |p| p == caller) + }) + } + pub fn is_manager(caller: &Principal) -> bool { STATE.with(|r| r.borrow().managers.contains(caller)) } @@ -226,6 +237,7 @@ pub mod state { bucket_wasm_total: WASM_STORE.with(|r| r.borrow().len()), bucket_deployed_total: s.bucket_deployed_list.len() as u64, bucket_deployment_logs: INSTALL_LOGS.with(|r| r.borrow().len()), + governance_canister: s.governance_canister.clone(), }) } diff --git a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did index 50deea0..cb57b5e 100644 --- a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did +++ b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did @@ -3,6 +3,7 @@ type BucketInfo = record { total_chunks : nat64; trusted_eddsa_pub_keys : vec blob; managers : vec principal; + governance_canister : opt principal; name : text; max_custom_data_size : nat16; auditors : vec principal; @@ -79,6 +80,7 @@ type FolderInfo = record { }; type FolderName = record { id : nat32; name : text }; type InitArgs = record { + governance_canister : opt principal; name : text; max_custom_data_size : nat16; max_children : nat16; @@ -146,6 +148,7 @@ type UpdateFolderInput = record { name : opt text; }; type UpgradeArgs = record { + governance_canister : opt principal; max_custom_data_size : opt nat16; max_children : opt nat16; enable_hash_index : opt bool; diff --git a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.d.ts b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.d.ts index c9724ae..950f0a0 100644 --- a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.d.ts +++ b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.d.ts @@ -7,6 +7,7 @@ export interface BucketInfo { 'total_chunks' : bigint, 'trusted_eddsa_pub_keys' : Array, 'managers' : Array, + 'governance_canister' : [] | [Principal], 'name' : string, 'max_custom_data_size' : number, 'auditors' : Array, @@ -86,6 +87,7 @@ export interface FolderInfo { } export interface FolderName { 'id' : number, 'name' : string } export interface InitArgs { + 'governance_canister' : [] | [Principal], 'name' : string, 'max_custom_data_size' : number, 'max_children' : number, @@ -175,6 +177,7 @@ export interface UpdateFolderInput { 'name' : [] | [string], } export interface UpgradeArgs { + 'governance_canister' : [] | [Principal], 'max_custom_data_size' : [] | [number], 'max_children' : [] | [number], 'enable_hash_index' : [] | [boolean], diff --git a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.js b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.js index 34f2ad3..d873e60 100644 --- a/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.js +++ b/src/ic_oss_ts/candid/ic_oss_bucket/ic_oss_bucket.did.js @@ -1,5 +1,6 @@ export const idlFactory = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'max_custom_data_size' : IDL.Opt(IDL.Nat16), 'max_children' : IDL.Opt(IDL.Nat16), 'enable_hash_index' : IDL.Opt(IDL.Bool), @@ -7,6 +8,7 @@ export const idlFactory = ({ IDL }) => { 'max_folder_depth' : IDL.Opt(IDL.Nat8), }); const InitArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'max_children' : IDL.Nat16, @@ -66,6 +68,7 @@ export const idlFactory = ({ IDL }) => { 'total_chunks' : IDL.Nat64, 'trusted_eddsa_pub_keys' : IDL.Vec(IDL.Vec(IDL.Nat8)), 'managers' : IDL.Vec(IDL.Principal), + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'auditors' : IDL.Vec(IDL.Principal), @@ -365,6 +368,7 @@ export const idlFactory = ({ IDL }) => { }; export const init = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'max_custom_data_size' : IDL.Opt(IDL.Nat16), 'max_children' : IDL.Opt(IDL.Nat16), 'enable_hash_index' : IDL.Opt(IDL.Bool), @@ -372,6 +376,7 @@ export const init = ({ IDL }) => { 'max_folder_depth' : IDL.Opt(IDL.Nat8), }); const InitArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'max_custom_data_size' : IDL.Nat16, 'max_children' : IDL.Nat16, diff --git a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did index 3df08a0..040596e 100644 --- a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did +++ b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did @@ -14,6 +14,7 @@ type ClusterInfo = record { bucket_wasm_total : nat64; ecdsa_key_name : text; managers : vec principal; + governance_canister : opt principal; name : text; bucket_deployed_total : nat64; token_expiration : nat64; @@ -26,6 +27,7 @@ type ClusterInfo = record { type DeployWasmInput = record { args : opt blob; canister : principal }; type InitArgs = record { ecdsa_key_name : text; + governance_canister : opt principal; name : text; token_expiration : nat64; bucket_topup_threshold : nat; @@ -48,6 +50,7 @@ type Token = record { policies : text; }; type UpgradeArgs = record { + governance_canister : opt principal; name : opt text; token_expiration : opt nat64; bucket_topup_threshold : opt nat; diff --git a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.d.ts b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.d.ts index 39e7030..ff878ec 100644 --- a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.d.ts +++ b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.d.ts @@ -22,6 +22,7 @@ export interface ClusterInfo { 'bucket_wasm_total' : bigint, 'ecdsa_key_name' : string, 'managers' : Array, + 'governance_canister' : [] | [Principal], 'name' : string, 'bucket_deployed_total' : bigint, 'token_expiration' : bigint, @@ -37,6 +38,7 @@ export interface DeployWasmInput { } export interface InitArgs { 'ecdsa_key_name' : string, + 'governance_canister' : [] | [Principal], 'name' : string, 'token_expiration' : bigint, 'bucket_topup_threshold' : bigint, @@ -69,6 +71,7 @@ export interface Token { 'policies' : string, } export interface UpgradeArgs { + 'governance_canister' : [] | [Principal], 'name' : [] | [string], 'token_expiration' : [] | [bigint], 'bucket_topup_threshold' : [] | [bigint], diff --git a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.js b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.js index 0e183cd..af3c26c 100644 --- a/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.js +++ b/src/ic_oss_ts/candid/ic_oss_cluster/ic_oss_cluster.did.js @@ -1,5 +1,6 @@ export const idlFactory = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Opt(IDL.Text), 'token_expiration' : IDL.Opt(IDL.Nat64), 'bucket_topup_threshold' : IDL.Opt(IDL.Nat), @@ -7,6 +8,7 @@ export const idlFactory = ({ IDL }) => { }); const InitArgs = IDL.Record({ 'ecdsa_key_name' : IDL.Text, + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'token_expiration' : IDL.Nat64, 'bucket_topup_threshold' : IDL.Nat, @@ -64,6 +66,7 @@ export const idlFactory = ({ IDL }) => { 'bucket_wasm_total' : IDL.Nat64, 'ecdsa_key_name' : IDL.Text, 'managers' : IDL.Vec(IDL.Principal), + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'bucket_deployed_total' : IDL.Nat64, 'token_expiration' : IDL.Nat64, @@ -198,6 +201,7 @@ export const idlFactory = ({ IDL }) => { }; export const init = ({ IDL }) => { const UpgradeArgs = IDL.Record({ + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Opt(IDL.Text), 'token_expiration' : IDL.Opt(IDL.Nat64), 'bucket_topup_threshold' : IDL.Opt(IDL.Nat), @@ -205,6 +209,7 @@ export const init = ({ IDL }) => { }); const InitArgs = IDL.Record({ 'ecdsa_key_name' : IDL.Text, + 'governance_canister' : IDL.Opt(IDL.Principal), 'name' : IDL.Text, 'token_expiration' : IDL.Nat64, 'bucket_topup_threshold' : IDL.Nat, diff --git a/src/ic_oss_ts/package.json b/src/ic_oss_ts/package.json index ede39b8..53ca906 100644 --- a/src/ic_oss_ts/package.json +++ b/src/ic_oss_ts/package.json @@ -1,6 +1,6 @@ { "name": "@ldclabs/ic_oss_ts", - "version": "0.9.4", + "version": "0.9.5", "type": "module", "description": "The Typescript version of the client SDK for the ic-oss cluster.", "license": "MIT", @@ -44,15 +44,15 @@ }, "devDependencies": { "@types/eslint": "^9.6.1", - "@types/node": "22.7.5", - "@typescript-eslint/eslint-plugin": "^8.8.1", - "@typescript-eslint/parser": "^8.8.1", - "eslint": "^9.12.0", + "@types/node": "22.7.7", + "@typescript-eslint/eslint-plugin": "^8.10.0", + "@typescript-eslint/parser": "^8.10.0", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.2.1", "prettier": "^3.3.3", "typescript": "^5.6.3", - "vitest": "^2.1.2" + "vitest": "^2.1.3" } } \ No newline at end of file diff --git a/src/ic_oss_types/src/bucket.rs b/src/ic_oss_types/src/bucket.rs index c7335de..db136fa 100644 --- a/src/ic_oss_types/src/bucket.rs +++ b/src/ic_oss_types/src/bucket.rs @@ -27,6 +27,7 @@ pub struct BucketInfo { pub trusted_ecdsa_pub_keys: Vec, // used to verify the request token signed with ED25519 pub trusted_eddsa_pub_keys: Vec>, + pub governance_canister: Option, } #[derive(CandidType, Clone, Debug, Default, Deserialize, Serialize)] diff --git a/src/ic_oss_types/src/cluster.rs b/src/ic_oss_types/src/cluster.rs index 6b538ae..fe36ad4 100644 --- a/src/ic_oss_types/src/cluster.rs +++ b/src/ic_oss_types/src/cluster.rs @@ -18,6 +18,7 @@ pub struct ClusterInfo { pub bucket_wasm_total: u64, pub bucket_deployed_total: u64, pub bucket_deployment_logs: u64, + pub governance_canister: Option, } #[derive(CandidType, Clone, Debug, Deserialize, Serialize)] diff --git a/src/ic_oss_types/src/file.rs b/src/ic_oss_types/src/file.rs index 2833e0d..8228399 100644 --- a/src/ic_oss_types/src/file.rs +++ b/src/ic_oss_types/src/file.rs @@ -11,6 +11,8 @@ pub const CHUNK_SIZE: u32 = 256 * 1024; pub const MAX_FILE_SIZE: u64 = 384 * 1024 * 1024 * 1024; // 384GB pub const MAX_FILE_SIZE_PER_CALL: u64 = 1024 * 2000; // should less than 2MB +pub static CUSTOM_KEY_BY_HASH: &str = "by_hash"; + #[derive(CandidType, Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] pub struct FileInfo { pub id: u32,