-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement report-problem protocol (#78)
Signed-off-by: conanoc <conanoc@gmail.com>
- Loading branch information
Showing
14 changed files
with
290 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
Sources/AriesFramework/problemreports/handlers/ProblemReportHandler.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
import Foundation | ||
import os | ||
|
||
class ProblemReportHandler: MessageHandler { | ||
let agent: Agent | ||
let messageType: String | ||
let logger = Logger(subsystem: "AriesFramework", category: "ProblemReportHandler") | ||
|
||
init(agent: Agent, messageType: String) { | ||
self.agent = agent | ||
self.messageType = messageType | ||
} | ||
|
||
func handle(messageContext: InboundMessageContext) async throws -> OutboundMessage? { | ||
let message = try JSONDecoder().decode(BaseProblemReportMessage.self, from: Data(messageContext.plaintextMessage.utf8)) | ||
logger.debug("Received problem report: \(message.description.en)") | ||
agent.agentDelegate?.onProblemReportReceived(message: message) | ||
return nil | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
Sources/AriesFramework/problemreports/messages/BaseProblemReportMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import Foundation | ||
|
||
public struct DescriptionOptions: Codable { | ||
let en: String | ||
let code: String | ||
} | ||
|
||
public struct FixHintOptions: Codable { | ||
let en: String | ||
} | ||
|
||
public class BaseProblemReportMessage: AgentMessage { | ||
var description: DescriptionOptions | ||
var fixHint: FixHintOptions? | ||
|
||
private enum CodingKeys: String, CodingKey { | ||
case description, fixHint = "fix_hint" | ||
} | ||
|
||
public init(description: DescriptionOptions, fixHint: FixHintOptions? = nil, type: String) { | ||
self.description = description | ||
self.fixHint = fixHint | ||
super.init(id: UUID().uuidString, type: type) | ||
} | ||
|
||
public required init(from decoder: Decoder) throws { | ||
let values = try decoder.container(keyedBy: CodingKeys.self) | ||
description = try values.decode(DescriptionOptions.self, forKey: .description) | ||
fixHint = try values.decodeIfPresent(FixHintOptions.self, forKey: .fixHint) | ||
try super.init(from: decoder) | ||
} | ||
|
||
public override func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
try container.encode(description, forKey: .description) | ||
try container.encodeIfPresent(fixHint, forKey: .fixHint) | ||
try super.encode(to: encoder) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
Sources/AriesFramework/problemreports/messages/CredentialProblemReportMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
import Foundation | ||
|
||
public class CredentialProblemReportMessage: BaseProblemReportMessage { | ||
public static var type: String = "https://didcomm.org/issue-credential/1.0/problem-report" | ||
|
||
public init(threadId: String) { | ||
super.init(description: DescriptionOptions(en: "Issuance abandoned", code: "issuance-abandoned"), type: CredentialProblemReportMessage.type) | ||
thread = ThreadDecorator(threadId: threadId) | ||
} | ||
|
||
public required init(from decoder: Decoder) throws { | ||
try super.init(from: decoder) | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
Sources/AriesFramework/problemreports/messages/MediationProblemReportMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
import Foundation | ||
|
||
public class MediationProblemReportMessage: BaseProblemReportMessage { | ||
public static var type: String = "https://didcomm.org/coordinate-mediation/1.0/problem-report" | ||
|
||
public required init(from decoder: Decoder) throws { | ||
try super.init(from: decoder) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
Sources/AriesFramework/problemreports/messages/PresentationProblemReportMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
import Foundation | ||
|
||
public class PresentationProblemReportMessage: BaseProblemReportMessage { | ||
public static var type: String = "https://didcomm.org/present-proof/1.0/problem-report" | ||
|
||
public init(threadId: String) { | ||
super.init(description: DescriptionOptions(en: "Proof abandoned", code: "abandoned"), type: PresentationProblemReportMessage.type) | ||
thread = ThreadDecorator(threadId: threadId) | ||
} | ||
|
||
public required init(from decoder: Decoder) throws { | ||
try super.init(from: decoder) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
Tests/AriesFrameworkTests/problemreports/ProblemReportsTest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
|
||
import XCTest | ||
@testable import AriesFramework | ||
|
||
class ProblemReportsTest: XCTestCase { | ||
var faberAgent: Agent! | ||
var aliceAgent: Agent! | ||
var credDefId: String! | ||
var faberConnection: ConnectionRecord! | ||
var aliceConnection: ConnectionRecord! | ||
|
||
let credentialPreview = CredentialPreview.fromDictionary([ | ||
"name": "John", | ||
"sex": "Male", | ||
"age": "99" | ||
]) | ||
|
||
class TestDelegate: AgentDelegate { | ||
let expectation: TestHelper.XCTestExpectation | ||
let threadId: String | ||
init(expectation: TestHelper.XCTestExpectation, threadId: String) { | ||
self.expectation = expectation | ||
self.threadId = threadId | ||
} | ||
func onProblemReportReceived(message: BaseProblemReportMessage) { | ||
XCTAssertEqual(message.threadId, threadId) | ||
expectation.fulfill() | ||
} | ||
} | ||
|
||
override func setUp() async throws { | ||
try await super.setUp() | ||
|
||
(faberAgent, aliceAgent, faberConnection, aliceConnection) = try await TestHelper.setupCredentialTests() | ||
credDefId = try await TestHelper.prepareForIssuance(faberAgent, ["name", "sex", "age"]) | ||
} | ||
|
||
override func tearDown() async throws { | ||
try await faberAgent?.reset() | ||
try await aliceAgent?.reset() | ||
try await super.tearDown() | ||
} | ||
|
||
func getCredentialRecord(for agent: Agent, threadId: String) async throws -> CredentialExchangeRecord { | ||
let credentialRecord = try await agent.credentialExchangeRepository.getByThreadAndConnectionId(threadId: threadId, connectionId: nil) | ||
return credentialRecord | ||
} | ||
|
||
func getProofRecord(for agent: Agent, threadId: String) async throws -> ProofExchangeRecord { | ||
let proofRecord = try await agent.proofRepository.getByThreadAndConnectionId(threadId: threadId, connectionId: nil) | ||
return proofRecord | ||
} | ||
|
||
func issueCredential() async throws { | ||
aliceAgent.agentConfig.autoAcceptCredential = .always | ||
faberAgent.agentConfig.autoAcceptCredential = .always | ||
|
||
var faberCredentialRecord = try await faberAgent.credentials.offerCredential( | ||
options: CreateOfferOptions( | ||
connection: faberConnection, | ||
credentialDefinitionId: credDefId, | ||
attributes: credentialPreview.attributes, | ||
comment: "Offer to Alice")) | ||
try await Task.sleep(nanoseconds: UInt64(1 * SECOND)) // Need enough time to finish exchange a credential. | ||
|
||
let threadId = faberCredentialRecord.threadId | ||
let aliceCredentialRecord = try await getCredentialRecord(for: aliceAgent, threadId: threadId) | ||
faberCredentialRecord = try await getCredentialRecord(for: faberAgent, threadId: threadId) | ||
|
||
XCTAssertEqual(aliceCredentialRecord.state, .Done) | ||
XCTAssertEqual(faberCredentialRecord.state, .Done) | ||
} | ||
|
||
func getProofRequest() async throws -> ProofRequest { | ||
let attributes = ["name": ProofAttributeInfo( | ||
name: "name", names: nil, nonRevoked: nil, | ||
restrictions: [AttributeFilter(credentialDefinitionId: credDefId)])] | ||
let predicates = ["age": ProofPredicateInfo( | ||
name: "age", nonRevoked: nil, predicateType: .GreaterThanOrEqualTo, predicateValue: 50, | ||
restrictions: [AttributeFilter(credentialDefinitionId: credDefId)])] | ||
|
||
let nonce = try ProofService.generateProofRequestNonce() | ||
return ProofRequest(nonce: nonce, requestedAttributes: attributes, requestedPredicates: predicates) | ||
} | ||
|
||
func testCredentialDeclinedProblemReport() async throws { | ||
let faberCredentialRecord = try await faberAgent.credentials.offerCredential( | ||
options: CreateOfferOptions( | ||
connection: faberConnection, | ||
credentialDefinitionId: credDefId, | ||
attributes: credentialPreview.attributes, | ||
comment: "Offer to Alice")) | ||
|
||
let threadId = faberCredentialRecord.threadId | ||
let aliceCredentialRecord = try await getCredentialRecord(for: aliceAgent, threadId: threadId) | ||
XCTAssertEqual(aliceCredentialRecord.state, .OfferReceived) | ||
|
||
let expectation = TestHelper.expectation(description: "Problem report received") | ||
faberAgent.agentDelegate = TestDelegate(expectation: expectation, threadId: threadId) | ||
|
||
_ = try await aliceAgent.credentials.declineOffer(credentialRecordId: aliceCredentialRecord.id) | ||
try await TestHelper.wait(for: expectation, timeout: 5) | ||
} | ||
|
||
func testProofDeclinedProblemReport() async throws { | ||
try await issueCredential() | ||
|
||
let proofRequest = try await getProofRequest() | ||
let faberProofRecord = try await faberAgent.proofs.requestProof( | ||
connectionId: faberConnection.id, | ||
proofRequest: proofRequest, | ||
comment: "Request from Alice") | ||
|
||
let threadId = faberProofRecord.threadId | ||
let aliceProofRecord = try await getProofRecord(for: aliceAgent, threadId: threadId) | ||
XCTAssertEqual(aliceProofRecord.state, .RequestReceived) | ||
|
||
let expectation = TestHelper.expectation(description: "Problem report received") | ||
faberAgent.agentDelegate = TestDelegate(expectation: expectation, threadId: threadId) | ||
|
||
_ = try await aliceAgent.proofs.declineRequest(proofRecordId: aliceProofRecord.id) | ||
try await TestHelper.wait(for: expectation, timeout: 5) | ||
} | ||
} |