Skip to content
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

Improve code documentation for the project #279

Merged
merged 3 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
64 changes: 64 additions & 0 deletions crates/database/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Database crate

A lightweight library for managing MongoDB operations. This library provides an interface, the `Repository` trait with default implementations for interacting with MongoDB collections. It is used by the plugins in the workspace that require database access.
This crate is part of the [DIDComm mediator](https://github.com/adorsys/didcomm-mediator-rs) project.

## Usage

### Requirements

* [MongoDB](https://www.mongodb.com) server instance
* Environment variables:
* `MONGO_URI`: MongoDB connection string
* `MONGO_DBN`: Database name

### Example

* Define an entity

```rust
use database::Repository;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct MyEntity {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
id: Option<ObjectId>,
name: String,
}

impl Identifiable for MyEntity {
fn id(&self) -> Option<ObjectId> {
self.id.clone()
}

fn set_id(&mut self, id: ObjectId) {
self.id = Some(id);
}
}
```

* Implement the `Repository` trait(the only required method is `get_collection`)

```rust
struct MyEntityRepository {
collection: Arc<RwLock<Collection<MyEntity>>>,
}

#[async_trait]
impl Repository<MyEntity> for MyEntityRepository {
fn get_collection(&self) -> Arc<RwLock<Collection<MyEntity>>> {
self.collection.clone()
}
}
```

* Use the repository

```rust
let db = get_or_init_database();
let repo = MyEntityRepository {
collection: Arc::new(RwLock::new(db.read().await.collection("my_entities"))),
};
let entity = MyEntity { id: None, name: "example".to_string() };
repo.store(entity).await?;
```
10 changes: 9 additions & 1 deletion crates/database/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ where
Entity: Identifiable + Unpin,
Entity: Serialize + for<'de> Deserialize<'de>,
{
/// Get a handle to a collection.
fn get_collection(&self) -> Arc<RwLock<Collection<Entity>>>;

/// Retrieve all entities from the database.
async fn find_all(&self) -> Result<Vec<Entity>, RepositoryError> {
let mut entities = Vec::new();
let collection = self.get_collection();
Expand All @@ -83,7 +85,7 @@ where
Ok(entities)
}

/// Counts all entities by filter.
/// Gets the number of documents matching `filter`.
async fn count_by(&self, filter: BsonDocument) -> Result<usize, RepositoryError> {
let collection = self.get_collection();
// Lock the Mutex and get the Collection
Expand All @@ -95,10 +97,12 @@ where
.map_err(|_| RepositoryError::Generic("count overflow".to_owned()))?)
}

/// Find an entity by `id`.
async fn find_one(&self, id: ObjectId) -> Result<Option<Entity>, RepositoryError> {
self.find_one_by(doc! {"_id": id}).await
}

/// Find an entity matching `filter`.
async fn find_one_by(&self, filter: BsonDocument) -> Result<Option<Entity>, RepositoryError> {
let collection = self.get_collection();

Expand All @@ -125,6 +129,8 @@ where
Ok(entity)
}

/// Find all entities matching `filter`.
/// If `limit` is set, only the first `limit` entities are returned.
async fn find_all_by(
&self,
filter: BsonDocument,
Expand All @@ -146,6 +152,7 @@ where
Ok(entities)
}

/// Deletes an entity by `id`.
async fn delete_one(&self, id: ObjectId) -> Result<(), RepositoryError> {
let collection = self.get_collection();

Expand All @@ -158,6 +165,7 @@ where
Ok(())
}

/// Updates an entity.
async fn update(&self, entity: Entity) -> Result<Entity, RepositoryError> {
if entity.id().is_none() {
return Err(RepositoryError::MissingIdentifier);
Expand Down
40 changes: 40 additions & 0 deletions crates/keystore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Keystore Crate

The `keystore` crate is a utility library for managing cryptographic secrets. It is used in the [Didcomm Mediator](https://github.com/adorsys/didcomm-mediator-rs/) to store and retrieve cryptographic keys for DIDcomm interactions.

## Usage

This crate is internal to the [Didcomm Mediator](https://github.com/adorsys/didcomm-mediator-rs/). Below is an example of interacting with the keystore:

```rust
use keystore::{KeyStore, Secrets};
use mongodb::bson::{doc, Bson, Document};
use did_utils::jwk::Jwk;

// Initialize the keystore
let keystore = KeyStore::get();

let jwk: Jwk = serde_json::from_str(
r#"{
"kty": "OKP",
"crv": "X25519",
"x": "SHSUZ6V3x355FqCzIUfgoPzrZB0BQs0JKyag4UfMqHQ",
"d": "0A8SSFkGHg3N9gmVDRnl63ih5fcwtEvnQu9912SVplY"
}"#,
)
.unwrap();

// Store a secret
let secret = Secrets {
id: Some(ObjectId::new()),
kid: "key-1".to_string(),
secret_material: jwk,
};
keystore.store(secret).await?;

// Retrieve a secret by ID
let secret = keystore.find_one(doc! {"kid": "key-1"}).await?;

// Delete a secret by ID
keystore.delete_one(secret.id.unwrap()).await?;
```
2 changes: 2 additions & 0 deletions crates/keystore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tokio::sync::RwLock;

static SECRETS_COLLECTION: OnceCell<Collection<Secrets>> = OnceCell::new();

/// Represents a cryptographic secret stored in the keystore.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Secrets {
#[serde(rename = "_id")]
Expand All @@ -30,6 +31,7 @@ impl Identifiable for Secrets {
}
}

/// A keystore for managing cryptographic secrets.
#[derive(Debug, Clone)]
pub struct KeyStore<T>
where
Expand Down
6 changes: 3 additions & 3 deletions crates/plugin-api/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Server plugin API

The server used for this project provides a system for building versatile applications by integrating functionalities offered by configurable plugins via the plugin API.
An interface that can be used by a generic server to build versatile applications by integrating functionalities offered by configurable plugins via the plugin API. It is part of the [Didcomm Mediator](https://github.com/adorsys/didcomm-mediator-rs/) project.

## Features

Expand Down Expand Up @@ -51,9 +51,9 @@ impl Plugin for MyPlugin {
Ok(())
}

fn routes(&self) -> Router {
fn routes(&self) -> Result<Router, PluginError> {
// Define and return routes here
Router::new().route("/myplugin", get(my_plugin_handler))
Router::new().route("/myplugin", get(my_plugin_handler))?
}
}

Expand Down
33 changes: 18 additions & 15 deletions crates/web-plugins/did-endpoint/README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
# did-endpoint

The `did-endpoint` crate provides tools and functionalities for generating and managing Decentralized Identifiers (DIDs) and web-based interactions.
The `did-endpoint` plugin crate provides a set of tools for generating and validating a DID document. It is a part of the [Didcomm Mediator](https://github.com/adorsys/didcomm-mediator-rs/) project.

## Features

- **Generates keys and forward them for DID generation:**
- **Builds and persists DID document:**
- **Validates the integrity of the persisted DID document**

## Usage

To use `did-endpoint` in your project, add the following to your **Cargo.toml**:

```toml
did-endpoint = "0.1.0"
```

### Example

Here’s a simple example of how you can generate and validate a DID document:

```rust
use did_endpoint::{didgen, validate_diddoc};
use filesystem::{FileSystem, StdFileSystem};
use keystore::KeyStore;

let storage_dirpath = std::env::var("STORAGE_DIRPATH").unwrap(),
let server_public_domain = std::env::var("SERVER_PUBLIC_DOMAIN").unwrap();

let mut filesystem = filesystem::StdFileSystem;
let keystore = keystore::KeyStore::get();

let (storage_dirpath, server_public_domain) = ("target/storage", "https://example.com");
// Generate and persist a new DID document
didgen::didgen(
storage_dirpath,
server_public_domain,
&keystore,
&mut filesystem,
)?;

// generate and persist a did document
didgen(&storage_dirpath, &server_public_domain)?;
// validate the generated did document
assert!(validate_diddoc(&storage_dirpath).is_ok());
// Validate the integrity of the persisted DID document
didgen::validate_diddoc(storage_dirpath, &keystore, &mut filesystem)?;
```
97 changes: 97 additions & 0 deletions crates/web-plugins/didcomm-messaging/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# didcomm-messaging

The `didcomm-messaging` plugin is a web plugin of the [DIDComm mediator](https://github.com/adorsys/didcomm-mediator-rs/) project. It provides implementations of various DIDComm messaging protocols as plugins and features, so protocols can be added and deleted with minimal effort as well as being dynamically loaded.

See the repository [README](https://github.com/adorsys/didcomm-mediator-rs/blob/main/README.md) for the list of currently supported protocols.

## Usage

**Implementing a new protocol:**

* Define handler(s) for the protocol

```rust
use async_trait::async_trait;
use axum::response::{IntoResponse, Response};
use didcomm::Message;
use message_api::{MessageHandler, MessagePlugin, MessageRouter};
use shared::state::AppState;
use std::sync::Arc;

pub struct MockProtocol;

struct ExampleProtocolHandler1;
struct ExampleProtocolHandler2;

#[async_trait]
impl MessageHandler for ExampleProtocolHandler1 {
async fn handle(
&self,
_state: Arc<AppState>,
message: Message,
) -> Result<Option<Message>, Response> {
// do something with the message
Ok(None)
}
}

#[async_trait]
impl MessageHandler for ExampleProtocolHandler2 {
async fn handle(
&self,
_state: Arc<AppState>,
message: Message,
) -> Result<Option<Message>, Response> {
// do something with the message
Ok(None)
}
}

impl MessagePlugin for MockProtocol {
fn name(&self) -> &'static str {
"mock_protocol"
}

fn didcomm_routes(&self) -> MessageRouter {
MessageRouter::new()
.register("message-type-1", ExampleProtocolHandler1)
.register("message-type-2", ExampleProtocolHandler2)
}
}
```

* Add the protocol to the `DIDCOMM_PLUGINS` array in `crates/web-plugins/didcomm-messaging/src/protocols.rs`:

```rust
pub(crate) static DIDCOMM_PLUGINS: Lazy<Vec<Arc<dyn MessagePlugin>>> = Lazy::new(|| {
vec![
#[cfg(feature = "mock-protocol")]
Arc::new(MockProtocol),
// other plugins
]
});
```

* Add the plugin as a feature in `didcomm-messaging` `Cargo.toml`:

```toml
[dependencies]
mock-protocol = { workspace = true, optional = true }

[features]
mock-protocol = ["mock-protocol", ...]

default = ["mock-protocol", ...]
```

* Adjust the workspace `Cargo.toml`:

```toml
[workspace.dependencies]
mock-protocol = { path = "./crates/web-plugins/didcomm-messaging/protocols/mock-protocol", version = "0.1.0" }

[features]
mock-protocol = ["plugin-didcomm_messaging", "didcomm-messaging/mock-protocol"]
```

The plugin manager will automatically handle routing based on the added protocol's routes.
20 changes: 6 additions & 14 deletions crates/web-plugins/didcomm-messaging/did-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ A Rust library for implementing reusable utility code for DID-based applications

## Installation

```rust
cargo install did-utils
Add this to your `Cargo.toml`:

```toml
[dependencies]
did-utils = "0.1"
```

## Usage
Expand Down Expand Up @@ -39,20 +42,9 @@ let encrypted_did_document = did_document.encrypt(&my_public_key);
let decrypted_did_document = encrypted_did_document.decrypt(&my_private_key);
```

## Dependencies

* serde
* sha2
* x25519-dalek

## Documentation

The documentation for the library is available here: https://docs.rs/did-utils/

## Contributors

* Bard
* [Your name]
The documentation for the library is available [here](https://docs.rs/did-utils)

## License

Expand Down
Loading
Loading