oydid 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/oydid.rb +68 -31
- data/spec/oydid_spec.rb +56 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66decf23cb4e474d0703a8948e20474be619c05083bd8abd5ab8d45857ac4ac0
|
|
4
|
+
data.tar.gz: db83f3c7ba0a20c5e4f8fd8ba8b9977b42b9b78fc56ad11df8a8bf12e9657704
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8856635688f0dd47b246443d7fcc7a994ceef87e7d2594530da0f3489445a544f3c7cc9d20327fec7da3988e83872d1ddf3c854bd4db25b367b72fa917ba09c3
|
|
7
|
+
data.tar.gz: '08956cf2da8ed63a35261a7ffa01cb58b11a177c77fe8b5f873f8ed4d59592695c0e80bd72d118c28f4266728b10e420b4eaab7189c406dd6c7731e52f40e38d'
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.8.
|
|
1
|
+
0.8.2
|
data/lib/oydid.rb
CHANGED
|
@@ -1058,6 +1058,18 @@ class Oydid
|
|
|
1058
1058
|
return [nil, did_info["message"].to_s]
|
|
1059
1059
|
end
|
|
1060
1060
|
|
|
1061
|
+
# A client that holds no private revocation key - a secure element does
|
|
1062
|
+
# not export one - submits the record it kept from creating or updating
|
|
1063
|
+
# the DID. Rebuilding it here is impossible, and re-signing it would not
|
|
1064
|
+
# help: the hash committed in the TERMINATE entry would no longer match.
|
|
1065
|
+
if !options[:log_revoke].nil?
|
|
1066
|
+
verified, vmsg = verify_revocation_log(did_info, options[:log_revoke], "log_revoke", options)
|
|
1067
|
+
if verified.nil?
|
|
1068
|
+
return [nil, vmsg]
|
|
1069
|
+
end
|
|
1070
|
+
return [link_revocation_log(verified, did_info), ""]
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1061
1073
|
did = did_info["did"]
|
|
1062
1074
|
did_hash = did.delete_prefix("did:oyd:")
|
|
1063
1075
|
did10 = did_hash[0,10]
|
|
@@ -1224,6 +1236,15 @@ class Oydid
|
|
|
1224
1236
|
# the location extracted from the DID may be percent-encoded
|
|
1225
1237
|
# (e.g. "http%3A%2F%2Flocalhost%3A3000"); decode before using as URL
|
|
1226
1238
|
doc_location = doc_location.to_s.gsub("%3A", ":").gsub("%2F", "/")
|
|
1239
|
+
# percent_encode strips the default scheme, so a DID published to an
|
|
1240
|
+
# https location carries a bare host ("oydid.ownyourdata.eu"). Without
|
|
1241
|
+
# putting the scheme back this is not recognised as a remote location
|
|
1242
|
+
# and the revocation is written to a local file instead - which is how
|
|
1243
|
+
# the branch below used to be reached at all.
|
|
1244
|
+
if !(doc_location == "" || doc_location == "local") &&
|
|
1245
|
+
!doc_location.start_with?("http")
|
|
1246
|
+
doc_location = "https://" + doc_location
|
|
1247
|
+
end
|
|
1227
1248
|
|
|
1228
1249
|
# publish revocation log based on location
|
|
1229
1250
|
case doc_location.to_s
|
|
@@ -1236,10 +1257,10 @@ class Oydid
|
|
|
1236
1257
|
return [nil, msg]
|
|
1237
1258
|
end
|
|
1238
1259
|
else
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1260
|
+
# did_old / did10_old were never defined here - they are locals of
|
|
1261
|
+
# generate_base. Writing the revocation next to the previous DID is
|
|
1262
|
+
# the job of the caller that knows about it.
|
|
1263
|
+
write_private_storage(revoc_log.to_json, did10 + ".log")
|
|
1243
1264
|
end
|
|
1244
1265
|
|
|
1245
1266
|
return [did, ""]
|
|
@@ -1367,6 +1388,44 @@ class Oydid
|
|
|
1367
1388
|
end
|
|
1368
1389
|
end
|
|
1369
1390
|
|
|
1391
|
+
# Verification relationships in the payload either name a key by fragment
|
|
1392
|
+
# ("#key-doc") or embed a whole verification method. Both need the DID
|
|
1393
|
+
# prefixed onto the identifier; an embedded method additionally needs a
|
|
1394
|
+
# controller, which the client cannot supply - the DID is the hash of the
|
|
1395
|
+
# document that would have to contain it, so it is not known while the
|
|
1396
|
+
# document is being written.
|
|
1397
|
+
def self.expand_verification_methods(payload, wd, did)
|
|
1398
|
+
return wd if !payload.is_a?(Hash)
|
|
1399
|
+
|
|
1400
|
+
[ "authentication",
|
|
1401
|
+
"assertionMethod",
|
|
1402
|
+
"keyAgreement",
|
|
1403
|
+
"capabilityInvocation",
|
|
1404
|
+
"capabilityDelegation" ].each do |vm|
|
|
1405
|
+
next if payload[vm].to_s == ""
|
|
1406
|
+
entries = payload[vm]
|
|
1407
|
+
entries = [entries] if entries.is_a?(Hash) || entries.is_a?(String)
|
|
1408
|
+
|
|
1409
|
+
new_entries = []
|
|
1410
|
+
entries.each do |el|
|
|
1411
|
+
if el.is_a?(String)
|
|
1412
|
+
new_entries << percent_encode(did) + el
|
|
1413
|
+
else
|
|
1414
|
+
new_el = el.transform_keys(&:to_s)
|
|
1415
|
+
new_el["id"] = percent_encode(did) + new_el["id"].to_s
|
|
1416
|
+
if new_el["controller"].to_s == ""
|
|
1417
|
+
new_el["controller"] = percent_encode(did)
|
|
1418
|
+
end
|
|
1419
|
+
new_entries << new_el
|
|
1420
|
+
end
|
|
1421
|
+
end
|
|
1422
|
+
|
|
1423
|
+
wd[vm] = new_entries.length > 0 ? new_entries : payload[vm]
|
|
1424
|
+
payload.delete(vm)
|
|
1425
|
+
end
|
|
1426
|
+
wd
|
|
1427
|
+
end
|
|
1428
|
+
|
|
1370
1429
|
def self.w3c(did_info, options)
|
|
1371
1430
|
# check if doc is already W3C DID
|
|
1372
1431
|
is_already_w3c_did = (did_info.transform_keys(&:to_s)["doc"]["doc"].has_key?("@context") &&
|
|
@@ -1527,6 +1586,10 @@ class Oydid
|
|
|
1527
1586
|
if location.nil?
|
|
1528
1587
|
location = get_location(did_info["did"].to_s)
|
|
1529
1588
|
end
|
|
1589
|
+
# a payload carrying a service used to skip the handling below
|
|
1590
|
+
# entirely and get merged verbatim, which left fragment identifiers
|
|
1591
|
+
# unresolved and embedded methods without a controller
|
|
1592
|
+
wd = expand_verification_methods(didDoc["doc"], wd, did)
|
|
1530
1593
|
wd = wd.merge(didDoc["doc"])
|
|
1531
1594
|
if wd["service"] != []
|
|
1532
1595
|
if wd["service"].is_a?(Array)
|
|
@@ -1547,33 +1610,7 @@ class Oydid
|
|
|
1547
1610
|
if didDoc["doc"].is_a?(Hash)
|
|
1548
1611
|
if didDoc["doc"] != {}
|
|
1549
1612
|
didDoc = didDoc["doc"]
|
|
1550
|
-
|
|
1551
|
-
vms = [ "authentication",
|
|
1552
|
-
"assertionMethod",
|
|
1553
|
-
"keyAgreement",
|
|
1554
|
-
"capabilityInvocation",
|
|
1555
|
-
"capabilityDelegation" ]
|
|
1556
|
-
|
|
1557
|
-
vms.each do |vm|
|
|
1558
|
-
if didDoc[vm].to_s != ""
|
|
1559
|
-
new_entries = []
|
|
1560
|
-
didDoc[vm].each do |el|
|
|
1561
|
-
if el.is_a?(String)
|
|
1562
|
-
new_entries << percent_encode(did) + el
|
|
1563
|
-
else
|
|
1564
|
-
new_el = el.transform_keys(&:to_s)
|
|
1565
|
-
new_el["id"] = percent_encode(did) + new_el["id"]
|
|
1566
|
-
new_entries << new_el
|
|
1567
|
-
end
|
|
1568
|
-
end unless didDoc[vm].nil?
|
|
1569
|
-
if new_entries.length > 0
|
|
1570
|
-
wd[vm] = new_entries
|
|
1571
|
-
else
|
|
1572
|
-
wd[vm] = didDoc[vm]
|
|
1573
|
-
end
|
|
1574
|
-
didDoc.delete(vm)
|
|
1575
|
-
end
|
|
1576
|
-
end
|
|
1613
|
+
wd = expand_verification_methods(didDoc, wd, did)
|
|
1577
1614
|
if didDoc["alsoKnownAs"].to_s != ""
|
|
1578
1615
|
if didDoc["alsoKnownAs"].is_a?(Array)
|
|
1579
1616
|
dda = didDoc["alsoKnownAs"]
|
data/spec/oydid_spec.rb
CHANGED
|
@@ -528,4 +528,60 @@ describe "OYDID handling" do
|
|
|
528
528
|
end
|
|
529
529
|
end
|
|
530
530
|
|
|
531
|
+
# W3C conversion of verification relationships carried in the payload
|
|
532
|
+
describe "verification relationships in the payload" do
|
|
533
|
+
let(:did) { "did:oyd:zQmaBZTghndXTgxNwfbdpVLWdFf6faYE4oeuN2zzXdQt1kh" }
|
|
534
|
+
let(:keys) do
|
|
535
|
+
"z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S:" \
|
|
536
|
+
"z6MkqGC3nWZhYieEVTVDKW5v588CiGfsDSmRVG9ZwwWTvLSK"
|
|
537
|
+
end
|
|
538
|
+
let(:attestation) do
|
|
539
|
+
{ "id" => "#key-attest",
|
|
540
|
+
"type" => "Ed25519VerificationKey2020",
|
|
541
|
+
"publicKeyMultibase" => "z6Mkg49NtQR2LyYRDCQFK4w1VVHqhypZSSRo7HsyuN7SV7v5" }
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def convert(payload)
|
|
545
|
+
Oydid.w3c({ "did" => did, "doc" => { "doc" => payload, "key" => keys } }, {})
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
it "prefixes the DID onto a key named by fragment" do
|
|
549
|
+
wd = convert({ "authentication" => ["#key-doc"] })
|
|
550
|
+
expect(wd["authentication"]).to eq ["#{did}#key-doc"]
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
it "prefixes the DID onto an embedded verification method" do
|
|
554
|
+
wd = convert({ "assertionMethod" => [attestation] })
|
|
555
|
+
expect(wd["assertionMethod"].first["id"]).to eq "#{did}#key-attest"
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
# a client cannot supply the controller: the DID is the hash of the
|
|
559
|
+
# document that would contain it
|
|
560
|
+
it "fills in the controller of an embedded verification method" do
|
|
561
|
+
wd = convert({ "assertionMethod" => [attestation] })
|
|
562
|
+
expect(wd["assertionMethod"].first["controller"]).to eq did
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
it "keeps a controller the payload already carries" do
|
|
566
|
+
own = attestation.merge("controller" => "did:oyd:zSomeoneElse")
|
|
567
|
+
wd = convert({ "assertionMethod" => [own] })
|
|
568
|
+
expect(wd["assertionMethod"].first["controller"]).to eq "did:oyd:zSomeoneElse"
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
# regression: a payload carrying a service took a different branch and was
|
|
572
|
+
# merged verbatim, leaving fragments unresolved
|
|
573
|
+
it "handles relationships next to a service entry" do
|
|
574
|
+
wd = convert({ "assertionMethod" => [attestation],
|
|
575
|
+
"service" => [{ "id" => "#payload", "type" => "Custom" }] })
|
|
576
|
+
expect(wd["assertionMethod"].first["id"]).to eq "#{did}#key-attest"
|
|
577
|
+
expect(wd["assertionMethod"].first["controller"]).to eq did
|
|
578
|
+
expect(wd["service"]).to be_an(Array)
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
it "accepts a single embedded method that is not wrapped in an array" do
|
|
582
|
+
wd = convert({ "assertionMethod" => attestation })
|
|
583
|
+
expect(wd["assertionMethod"].first["id"]).to eq "#{did}#key-attest"
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
531
587
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: oydid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christoph Fabianek
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-08-
|
|
10
|
+
date: 2026-08-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: simple_dag
|