Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for re-signing already signed Nanopubs. fix js test script
Browse files Browse the repository at this point in the history
vemonet committed Mar 2, 2024

Verified

This commit was signed with the committer’s verified signature.
vemonet Vincent Emonet
1 parent a866e21 commit 28a05ae
Showing 9 changed files with 97 additions and 16 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ jobs:
- uses: actions/checkout@v4
- run: |
rustup update
cargo install wasm-pack
./scripts/test-js.sh
test-python:
@@ -48,6 +49,7 @@ jobs:
- uses: actions/checkout@v4
- run: |
rustup update
venv .venv
./scripts/test-python.sh
cov:
@@ -103,7 +105,7 @@ jobs:

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4


compare:
2 changes: 1 addition & 1 deletion js/index.html
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ <h1 class="text-xl font-semibold">Nanopublication dev</h1>
// console.log("CHECKED", checked.info());

const profile = new NpProfile(privKey, orcid, "Your Name", "");
const np = await new Nanopub(rdfStr).publish(profile, "");
const np = await new Nanopub(rdfStr).publish(profile);
// const np = await new Nanopub(rdfStr).publish();

console.log("Published Nanopub:", np.info());
1 change: 1 addition & 0 deletions lib/src/constants.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ pub const TEST_SERVER: &str = "https://np.test.knowledgepixels.com/";

pub const NP_PREF_NS: &str = "https://w3id.org/np/";
pub const NP_TEMP_URI: &str = "http://purl.org/nanopub/temp/";
// pub const NP_TEMP_URI: &str = "http://purl.org/nanopub/temp/mynanopub#";

pub const DEFAULT_NP_PROFILE: &str = "~/.nanopub/profile.yml";

2 changes: 1 addition & 1 deletion lib/src/extract.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use sophia::iri::Iri;
use std::fmt;

/// Infos extracted from a nanopublication: graphs URLs, signature, trusty hash...
#[derive(Clone, Serialize)]
#[derive(Clone, Serialize, Debug)]
pub struct NpInfo {
pub uri: Iri<String>,
#[serde(serialize_with = "serialize_namespace")]
58 changes: 54 additions & 4 deletions lib/src/nanopub.rs
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ impl RdfSource for &String {
}

/// A nanopublication object
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Nanopub {
pub info: NpInfo,
pub dataset: LightDataset,
@@ -206,7 +206,11 @@ impl Nanopub {
openssl_probe::init_ssl_cert_env_vars();
self.dataset = replace_bnodes(&self.dataset, &self.info.ns, &self.info.uri)?;
self.info = extract_np_info(&self.dataset)?;
// println!("DEBUG: sign info {}", self.info);
if !self.info.signature.is_empty() {
println!("Nanopub already signed, unsigning it before re-signing");
self = self.unsign()?;
// println!("DEBUG: Unsigned: {}", self.get_rdf()?);
}

// Add triples about the signature in the pubinfo
self.dataset.insert(
@@ -361,9 +365,12 @@ impl Nanopub {
server_url: Option<&str>,
) -> Result<Self, NpError> {
self = if let Some(profile) = profile {
// if !self.info.signature.is_empty() {
// // TODO: handle when the user provide a Profile and a signed Nanopub.
// // We should re-sign the Nanopub with the new profile
// return Err(NpError("Profile provided to sign an already signed Nanopub. Re-signing an already signed Nanopub is not supported yet".to_string()));
// }
println!("Profile provided, signing Nanopub before publishing");
// TODO: handle when the user provide a Profile and a signed Nanopub.
// We should re-sign the Nanopub with the new profile
self.sign(profile)?
} else if self.info.signature.is_empty() {
return Err(NpError(format!(
@@ -405,6 +412,49 @@ impl Nanopub {
Ok(self)
}

/// Unsign a signed nanopub RDF. Remove signature triples and replace trusty URI with default temp URI
pub fn unsign(mut self) -> Result<Self, NpError> {
self.dataset.remove(
&self.info.signature_iri,
ns("npx").get("hasPublicKey")?,
&*self.info.public_key,
Some(&self.info.pubinfo),
)?;
self.dataset.remove(
&self.info.signature_iri,
ns("npx").get("hasAlgorithm")?,
&*self.info.algo,
Some(&self.info.pubinfo),
)?;
self.dataset.remove(
&self.info.signature_iri,
ns("npx").get("hasSignatureTarget")?,
&self.info.uri,
Some(&self.info.pubinfo),
)?;
self.dataset.remove(
&self.info.signature_iri,
ns("npx").get("hasSignature")?,
&*self.info.signature,
Some(&self.info.pubinfo),
)?;
self.dataset = replace_ns_in_quads(
&self.dataset,
&self.info.ns,
&self.info.uri,
NP_TEMP_URI,
NP_TEMP_URI,
)?;
self.info.uri = Iri::new_unchecked(NP_TEMP_URI.to_string());
self.info.ns = Namespace::new_unchecked(NP_TEMP_URI.to_string());
self.info = extract_np_info(&self.dataset)?;
// self.info.published = None;
// self.info.trusty_hash = "".to_string();
// self.info.signature = "".to_string();
// self.info.public_key = "".to_string();
Ok(self)
}

/// Create a Nanopub intro for a Profile
///
/// # Arguments
19 changes: 16 additions & 3 deletions lib/tests/nanopub_test.rs
Original file line number Diff line number Diff line change
@@ -37,15 +37,28 @@ async fn publish_proteinatlas() -> Result<(), Box<dyn Error>> {
let np_rdf = fs::read_to_string("tests/testsuite/valid/plain/proteinatlas-16-1.trig")?;
// let np_rdf = fs::read_to_string("./tests/resources/nanopub_test_blank.trig")?;
let profile = NpProfile::new(&get_test_key(), "", "", None)?;
let np = Nanopub::new(&np_rdf)?.publish(Some(&profile), None).await?;
let np = Nanopub::new(&np_rdf)?
.publish(Some(&profile), Some(""))
.await?;
assert!(np.info.published.is_some());
Ok(())
}

#[tokio::test]
async fn publish_already_signed() -> Result<(), Box<dyn Error>> {
async fn publish_already_signed_no_profile() -> Result<(), Box<dyn Error>> {
let np_rdf = fs::read_to_string("./tests/resources/signed.simple1-rsa.trig")?;
let np = Nanopub::new(&np_rdf)?.publish(None, Some("")).await?;
let np = Nanopub::new(&np_rdf)?.publish(None, None).await?;
assert!(np.info.published.is_some());
Ok(())
}

#[tokio::test]
async fn publish_already_signed_with_profile() -> Result<(), Box<dyn Error>> {
let np_rdf = fs::read_to_string("./tests/resources/signed.simple1-rsa.trig")?;
let profile = NpProfile::new(&get_test_key(), "", "", None)?;
let np = Nanopub::new(&np_rdf)?.publish(Some(&profile), None).await?;
// println!("{}", np.info);
// println!("{}", np.get_rdf()?);
assert!(np.info.published.is_some());
Ok(())
}
18 changes: 18 additions & 0 deletions scripts/dev-js.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e

# ./scripts/test-js.sh

cd js

# npm install
# npm run test


# wasm-pack build --target web
# cargo build --target=wasm32-unknown-unknown

# python3 -m webbrowser http://0.0.0.0:8000

python3 -m http.server
# Or npm run start
1 change: 1 addition & 0 deletions scripts/test-js.sh
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ set -e

cd js

npm install
npm run test

# wasm-pack build --target web
8 changes: 2 additions & 6 deletions scripts/test-python.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#!/usr/bin/env bash
set -e

if [ -d ".venv" ]; then
echo "Activating virtual environment"
source .venv/bin/activate
else
echo ".venv directory does not exist running without virtual environment"
fi
echo "Activating virtual environment"
source .venv/bin/activate

cd python

0 comments on commit 28a05ae

Please sign in to comment.