Skip to content

Commit

Permalink
expose setter instead of mutable reference
Browse files Browse the repository at this point in the history
  • Loading branch information
abdulmth committed Feb 28, 2024
1 parent 4695ee5 commit c27d711
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 59 deletions.
111 changes: 63 additions & 48 deletions bindings/wasm/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,6 @@ working with storage backed DID documents.</p>
## Members

<dl>
<dt><a href="#StateMetadataEncoding">StateMetadataEncoding</a></dt>
<dd></dd>
<dt><a href="#MethodRelationship">MethodRelationship</a></dt>
<dd></dd>
<dt><a href="#CredentialStatus">CredentialStatus</a></dt>
<dd></dd>
<dt><a href="#SubjectHolderRelationship">SubjectHolderRelationship</a></dt>
Expand All @@ -207,6 +203,9 @@ This variant is the default.</p>
<dt><a href="#Any">Any</a></dt>
<dd><p>The holder is not required to have any kind of relationship to any credential subject.</p>
</dd>
<dt><a href="#StatusPurpose">StatusPurpose</a></dt>
<dd><p>Purpose of a <a href="#StatusList2021">StatusList2021</a>.</p>
</dd>
<dt><a href="#FailFast">FailFast</a></dt>
<dd><p>Declares when validation should return if an error occurs.</p>
</dd>
Expand All @@ -216,9 +215,6 @@ This variant is the default.</p>
<dt><a href="#FirstError">FirstError</a></dt>
<dd><p>Return after the first error occurs.</p>
</dd>
<dt><a href="#StatusPurpose">StatusPurpose</a></dt>
<dd><p>Purpose of a <a href="#StatusList2021">StatusList2021</a>.</p>
</dd>
<dt><a href="#StatusCheck">StatusCheck</a></dt>
<dd><p>Controls validation behaviour when checking whether or not a credential has been revoked by its
<a href="https://www.w3.org/TR/vc-data-model/#status"><code>credentialStatus</code></a>.</p>
Expand All @@ -236,16 +232,17 @@ This variant is the default.</p>
<dt><a href="#SkipAll">SkipAll</a></dt>
<dd><p>Skip all status checks.</p>
</dd>
<dt><a href="#StateMetadataEncoding">StateMetadataEncoding</a></dt>
<dd></dd>
<dt><a href="#MethodRelationship">MethodRelationship</a></dt>
<dd></dd>
</dl>

## Functions

<dl>
<dt><a href="#encodeB64">encodeB64(data)</a> ⇒ <code>string</code></dt>
<dd><p>Encode the given bytes in url-safe base64.</p>
</dd>
<dt><a href="#decodeB64">decodeB64(data)</a> ⇒ <code>Uint8Array</code></dt>
<dd><p>Decode the given url-safe base64-encoded slice into its raw bytes.</p>
<dt><a href="#start">start()</a></dt>
<dd><p>Initializes the console error panic hook for better error messages</p>
</dd>
<dt><a href="#verifyEd25519">verifyEd25519(alg, signingInput, decodedSignature, publicKey)</a></dt>
<dd><p>Verify a JWS signature secured with the <code>EdDSA</code> algorithm and curve <code>Ed25519</code>.</p>
Expand All @@ -255,8 +252,11 @@ This variant is the default.</p>
<p>This function does not check whether <code>alg = EdDSA</code> in the protected header. Callers are expected to assert this
prior to calling the function.</p>
</dd>
<dt><a href="#start">start()</a></dt>
<dd><p>Initializes the console error panic hook for better error messages</p>
<dt><a href="#encodeB64">encodeB64(data)</a> ⇒ <code>string</code></dt>
<dd><p>Encode the given bytes in url-safe base64.</p>
</dd>
<dt><a href="#decodeB64">decodeB64(data)</a> ⇒ <code>Uint8Array</code></dt>
<dd><p>Decode the given url-safe base64-encoded slice into its raw bytes.</p>
</dd>
</dl>

Expand Down Expand Up @@ -1967,6 +1967,7 @@ if the object is being concurrently modified.
* _instance_
* [.id()](#IotaDocument+id)[<code>IotaDID</code>](#IotaDID)
* [.controller()](#IotaDocument+controller)[<code>Array.&lt;IotaDID&gt;</code>](#IotaDID)
* [.setController(controllers)](#IotaDocument+setController)
* [.alsoKnownAs()](#IotaDocument+alsoKnownAs) ⇒ <code>Array.&lt;string&gt;</code>
* [.setAlsoKnownAs(urls)](#IotaDocument+setAlsoKnownAs)
* [.properties()](#IotaDocument+properties) ⇒ <code>Map.&lt;string, any&gt;</code>
Expand Down Expand Up @@ -2039,6 +2040,20 @@ NOTE: controllers are determined by the `state_controller` unlock condition of t
during resolution and are omitted when publishing.

**Kind**: instance method of [<code>IotaDocument</code>](#IotaDocument)
<a name="IotaDocument+setController"></a>

### iotaDocument.setController(controllers)
Sets the controllers of the document.

Note: Duplicates will be ignored.
Use `null` to remove all controllers.

**Kind**: instance method of [<code>IotaDocument</code>](#IotaDocument)

| Param | Type |
| --- | --- |
| controllers | [<code>CoreDID</code>](#CoreDID) \| [<code>Array.&lt;CoreDID&gt;</code>](#CoreDID) \| <code>null</code> |

<a name="IotaDocument+alsoKnownAs"></a>

### iotaDocument.alsoKnownAs() ⇒ <code>Array.&lt;string&gt;</code>
Expand Down Expand Up @@ -6104,14 +6119,6 @@ Deserializes an instance from a JSON object.
| --- | --- |
| json | <code>any</code> |
<a name="StateMetadataEncoding"></a>
## StateMetadataEncoding
**Kind**: global variable
<a name="MethodRelationship"></a>
## MethodRelationship
**Kind**: global variable
<a name="CredentialStatus"></a>
## CredentialStatus
Expand Down Expand Up @@ -6142,6 +6149,12 @@ The holder must match the subject only for credentials where the [`nonTransferab
## Any
The holder is not required to have any kind of relationship to any credential subject.
**Kind**: global variable
<a name="StatusPurpose"></a>
## StatusPurpose
Purpose of a [StatusList2021](#StatusList2021).
**Kind**: global variable
<a name="FailFast"></a>
Expand All @@ -6160,12 +6173,6 @@ Return all errors that occur during validation.
## FirstError
Return after the first error occurs.
**Kind**: global variable
<a name="StatusPurpose"></a>
## StatusPurpose
Purpose of a [StatusList2021](#StatusList2021).
**Kind**: global variable
<a name="StatusCheck"></a>
Expand Down Expand Up @@ -6198,28 +6205,20 @@ Validate the status if supported, skip any unsupported
Skip all status checks.
**Kind**: global variable
<a name="encodeB64"></a>
## encodeB64(data) ⇒ <code>string</code>
Encode the given bytes in url-safe base64.
**Kind**: global function
<a name="StateMetadataEncoding"></a>
| Param | Type |
| --- | --- |
| data | <code>Uint8Array</code> |
## StateMetadataEncoding
**Kind**: global variable
<a name="MethodRelationship"></a>
<a name="decodeB64"></a>
## MethodRelationship
**Kind**: global variable
<a name="start"></a>
## decodeB64(data) ⇒ <code>Uint8Array</code>
Decode the given url-safe base64-encoded slice into its raw bytes.
## start()
Initializes the console error panic hook for better error messages
**Kind**: global function
| Param | Type |
| --- | --- |
| data | <code>Uint8Array</code> |
<a name="verifyEd25519"></a>
## verifyEd25519(alg, signingInput, decodedSignature, publicKey)
Expand All @@ -6242,9 +6241,25 @@ prior to calling the function.
| decodedSignature | <code>Uint8Array</code> |
| publicKey | [<code>Jwk</code>](#Jwk) |
<a name="start"></a>
<a name="encodeB64"></a>
## start()
Initializes the console error panic hook for better error messages
## encodeB64(data) ⇒ <code>string</code>
Encode the given bytes in url-safe base64.
**Kind**: global function
| Param | Type |
| --- | --- |
| data | <code>Uint8Array</code> |
<a name="decodeB64"></a>
## decodeB64(data) ⇒ <code>Uint8Array</code>
Decode the given url-safe base64-encoded slice into its raw bytes.
**Kind**: global function
| Param | Type |
| --- | --- |
| data | <code>Uint8Array</code> |
20 changes: 20 additions & 0 deletions bindings/wasm/src/iota/iota_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ use std::rc::Rc;

use identity_iota::core::Object;
use identity_iota::core::OneOrMany;

use identity_iota::core::OrderedSet;
use identity_iota::core::Timestamp;
use identity_iota::core::Url;
use identity_iota::credential::Credential;
use identity_iota::credential::JwtPresentationOptions;
use identity_iota::credential::Presentation;

use identity_iota::did::DIDUrl;
use identity_iota::iota::block::output::dto::AliasOutputDto;
use identity_iota::iota::block::output::AliasOutput;
Expand Down Expand Up @@ -48,6 +50,7 @@ use crate::credential::WasmJws;
use crate::credential::WasmJwt;
use crate::credential::WasmPresentation;
use crate::did::CoreDocumentLock;

use crate::did::PromiseJws;
use crate::did::PromiseJwt;
use crate::did::WasmCoreDocument;
Expand Down Expand Up @@ -156,6 +159,20 @@ impl WasmIotaDocument {
)
}

/// Sets the controllers of the document.
///
/// Note: Duplicates will be ignored.
/// Use `null` to remove all controllers.
#[wasm_bindgen(js_name = setController)]
pub fn set_controller(&mut self, controller: &OptionArrayIotaDID) -> Result<()> {
let controller: Option<Vec<IotaDID>> = controller.into_serde().wasm_result()?;
match controller {
Some(controller) => self.0.try_write()?.set_controller(controller),
None => self.0.try_write()?.set_controller([]),
};
Ok(())
}

/// Returns a copy of the document's `alsoKnownAs` set.
#[wasm_bindgen(js_name = alsoKnownAs)]
pub fn also_known_as(&self) -> Result<ArrayString> {
Expand Down Expand Up @@ -845,6 +862,9 @@ impl From<IotaDocument> for WasmIotaDocument {

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "IotaDID[] | null")]
pub type OptionArrayIotaDID;

#[wasm_bindgen(typescript_type = "IotaDID[]")]
pub type ArrayIotaDID;

Expand Down
34 changes: 23 additions & 11 deletions identity_iota_core/src/document/iota_document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ impl IotaDocument {
}

/// Returns an iterator yielding the DID controllers.
///
/// NOTE: controllers are determined by the `state_controller` unlock condition of the output
/// during resolution and are omitted when publishing.
pub fn controller(&self) -> impl Iterator<Item = &IotaDID> + '_ {
let core_did_controller_iter = self
.document
Expand All @@ -134,14 +131,29 @@ impl IotaDocument {
.into_iter()
.flatten();

// CORRECTNESS: These casts are OK because the public API does not expose methods
// enabling unchecked mutation of the controllers.
// CORRECTNESS: These casts are OK because the public API only allows setting IotaDIDs.
core_did_controller_iter.map(IotaDID::from_inner_ref_unchecked)
}

/// Returns a mutable reference to the document controller.
pub fn controller_mut(&mut self) -> &mut Option<OneOrSet<CoreDID>> {
self.document.controller_mut()
/// Sets the value of the document controller.
///
/// Note:
/// * Duplicates in `controller` will be ignored.
/// * Use an empty collection to clear all controllers.
pub fn set_controller<T>(&mut self, controller: T)
where
T: IntoIterator<Item = IotaDID>,
{
let controller_core_dids: Option<OneOrSet<CoreDID>> = {
let controller_set: OrderedSet<CoreDID> = controller.into_iter().map(|value| CoreDID::from(value)).collect();

Check failure on line 148 in identity_iota_core/src/document/iota_document.rs

View workflow job for this annotation

GitHub Actions / clippy

redundant closure

error: redundant closure --> identity_iota_core/src/document/iota_document.rs:148:76 | 148 | let controller_set: OrderedSet<CoreDID> = controller.into_iter().map(|value| CoreDID::from(value)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `CoreDID::from` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure = note: `-D clippy::redundant-closure` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
if controller_set.is_empty() {
None
} else {
Some(OneOrSet::new_set(controller_set).expect("controller is checked to be not empty"))
}
};

*self.document.controller_mut() = controller_core_dids;
}

/// Returns a reference to the `alsoKnownAs` set.
Expand Down Expand Up @@ -753,7 +765,7 @@ mod tests {
.unwrap();

let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone());
*original_doc.controller_mut() = None;
original_doc.set_controller([]);

let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did))
.with_state_metadata(original_doc.pack().unwrap())
Expand Down Expand Up @@ -782,7 +794,7 @@ mod tests {
.unwrap();

let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone());
*original_doc.controller_mut() = Some(OneOrSet::new_one(CoreDID::from(alias_controller.clone())));
original_doc.set_controller([alias_controller.clone()]);

let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did))
.with_state_metadata(original_doc.pack().unwrap())
Expand Down Expand Up @@ -815,7 +827,7 @@ mod tests {
.unwrap();

let mut original_doc: IotaDocument = IotaDocument::new_with_id(document_did.clone());
*original_doc.controller_mut() = Some(OneOrSet::new_one(CoreDID::from(external_controller_did.clone())));
original_doc.set_controller([external_controller_did.clone()]);

let alias_output: AliasOutput = AliasOutputBuilder::new_with_amount(1, AliasId::from(&document_did))
.with_state_metadata(original_doc.pack().unwrap())
Expand Down

0 comments on commit c27d711

Please sign in to comment.