Skip to content

Commit

Permalink
add documentation and example
Browse files Browse the repository at this point in the history
  • Loading branch information
michallis committed May 28, 2024
1 parent 1741502 commit ffb3e39
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "smart-id-rust-client"
version = "0.1.3"
version = "0.1.4"
description = "Smart ID Rust Client"
homepage = "https://smart-id.com"
authors = ["Michallis Pashidis <michallis@trust1team.com>"]
Expand Down
125 changes: 124 additions & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,127 @@ cargo test
```zsh
cargo doc --no-deps --open
```


## Example Client

See the examples folder for a simple example client.
To create an SmartID account, download the app:
[SmartID App](https://www.smart-id.com/download/)

The example application goes through the following use cases:
- Verify Certificate Existence
- SmartID Authentication
- SmartID Digital Signature

The example is using a MOCK ID to simulate the SmartID user.

```shell
cargo run --example smart_id_client
```

### Configuration
SmartID configuration can be loaded form environment variables:
```shell
/// Get default Config (from environment variables)
let cfg = get_config_from_env();
```

Or using the builder pattern:
```shell
/// Config Builder
let cfg = SmartIDConfigBuilder::new().url("https://sid.demo.sk.ee/smart-id-rp/v2").build().expect("Error building config");
```

### Verify Certificate Existence

To check whether a user has been onboarded, use the `get_certificate_by_semantic_identifier`:
```shell
async fn uc_get_certificate_choice(cfg: &SmartIDConfig) -> Result<()> {

/// Create the semantic identifier
let sem_id = SemanticsIdentifier::new_from_enum_mock(IdentityType::PNO, CountryCode::BE);

/// Verify if a certificate exists for given id
let res = get_certificate_by_semantic_identifier(&cfg, sem_id).await;
match res {
Ok(r) => {
let cert = validate_response_success(r).map(|res| res.cert.unwrap().value.unwrap())?;
info!("Smart ID Certificate {:#?}", cert);
Ok(())
}
Err(_) => Err(anyhow::anyhow!("Error getting certificate"))
}
}
```
### SmartID Authentication
To authenticate a user, use the `authenticate_by_semantic_identifier`:
```shell
async fn uc_authenticate_by_semantic_identifier(cfg: &SmartIDConfig) -> Result<()> {
/// Create the semantic identifier
let sem_id = SemanticsIdentifier::new_from_enum_mock(IdentityType::PNO, CountryCode::BE);

/// Define interactions
let interactions: Vec<Interaction> = vec![Interaction::diplay_text_and_pin("Authenticate to Application: ReadMyCards")];

/// Create hash
let hash_type = HashType::SHA256;
let hash = sha_digest("This is a test string".to_string().into_bytes(), &hash_type)?;
let b64_hash = base64::engine::general_purpose::STANDARD.encode(hash.as_ref());
let verification_code_for_user = generate_verification_number(hash.as_ref().to_vec())?;
info!("Verification code for user: {}", verification_code_for_user);

/// Ask user for authentication
let res = authenticate_by_semantic_identifier(&cfg, sem_id, interactions, b64_hash, hash_type).await;

match res {
Ok(r) => {
let session_result = validate_response_success(r).map(|res| res.result)?;
info!("Smart ID Authentication result {:#?}", session_result);
Ok(())
}
Err(_) => Err(anyhow::anyhow!("Error during authentication"))
}
}
```
### SmartID Digital Signature
To sign a document as a user, use the `sign_by_semantic_identifier`:
```shell
async fn uc_sign_by_semantic_identifier(cfg: &SmartIDConfig) -> Result<()> {
/// Create the semantic identifier
let sem_id = SemanticsIdentifier::new_from_enum_mock(IdentityType::PNO, CountryCode::BE);

/// Define interactions
let interactions: Vec<Interaction> = vec![Interaction::confirmation_message("Are you sure to sign document: something.pdf?"), Interaction::diplay_text_and_pin("Sign using ReadMyCards")];

/// Create hash
let hash_type = HashType::SHA256;
let hash = sha_digest("This is a test string".to_string().into_bytes(), &hash_type)?;
let b64_hash = base64::engine::general_purpose::STANDARD.encode(hash.as_ref());

/// Create verification cod
let verification_code_for_user = generate_verification_number(hash.as_ref().to_vec())?;
info!("Verification code for user: {}", verification_code_for_user);

/// Ask user to sign
let res = sign_by_semantic_identifier(&cfg, sem_id, interactions, b64_hash, hash_type).await;
match res {
Ok(r) => {
match validate_response_success(r).map(|res| res.signature)? {
None => {
warn!("No signature");
Ok(())
}
Some(signature) => {
info!("Smart ID signature result {:#?}", signature);
Ok(())
}
}
}
Err(_) => Err(anyhow::anyhow!("Error signing digest"))
}
}
```
3 changes: 1 addition & 2 deletions src/client/smart_id_connector.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::models::common::{SemanticsIdentifier};
use crate::models::session::SessionStatus;
use anyhow::Result;
use tracing::debug;
use tracing::log::info;
use tracing::{debug, info};
use crate::client::reqwest_generic::{get, post};
use crate::models::requests::{AuthenticationSessionRequest, CertificateRequest, SignatureSessionRequest};
use crate::models::responses::{AuthenticationSessionResponse, CertificateChoiceResponse, SignatureSessionResponse};
Expand Down

0 comments on commit ffb3e39

Please sign in to comment.