Skip to content
Open
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
92 changes: 92 additions & 0 deletions EdgeAgentSDK/Domain/Sources/BBs/Pollux.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,95 @@
)
}
}

public enum OperationResult {
case credential(Credential)
case forward(type: String, format: String?, payload: Data)
case verification(verified: Bool)

public var credential: Credential? {
switch self {

Check warning on line 138 in EdgeAgentSDK/Domain/Sources/BBs/Pollux.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this "switch" statement with "if" statement to increase readability.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbh_TA8riFkvjGw7&open=AZsDGbh_TA8riFkvjGw7&pullRequest=192
case .credential(let credential):
return credential
default:
return nil
}
}

public var forwardType: String? {
switch self {

Check warning on line 147 in EdgeAgentSDK/Domain/Sources/BBs/Pollux.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this "switch" statement with "if" statement to increase readability.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbh_TA8riFkvjGw8&open=AZsDGbh_TA8riFkvjGw8&pullRequest=192
case .forward(type: let type, format: _, payload: _):
return type
default:
return nil
}
}

public var forwardPayload: Data? {
switch self {

Check warning on line 156 in EdgeAgentSDK/Domain/Sources/BBs/Pollux.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this "switch" statement with "if" statement to increase readability.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbh_TA8riFkvjGw9&open=AZsDGbh_TA8riFkvjGw9&pullRequest=192
case .forward(type: _, format: _, payload: let payload):
return payload
default:
return nil
}
}

public var isVerified: Bool? {
switch self {

Check warning on line 165 in EdgeAgentSDK/Domain/Sources/BBs/Pollux.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this "switch" statement with "if" statement to increase readability.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbh_TA8riFkvjGw-&open=AZsDGbh_TA8riFkvjGw-&pullRequest=192
case .verification(verified: let verified):
return verified
default:
return nil
}
}
}

public protocol PolluxPlugin {
var version: String { get }
var supportedOperations: [String] { get }

func requiredOptions(operation: String) -> [CredentialOperationsOptions]

func operation(type: String, format: String?, payload: Data?, options: [CredentialOperationsOptions]) async throws -> OperationResult
}

public protocol CredentialPlugin: PolluxPlugin {
var credentialType: String { get }

func createCredential(_ credentialData: Data) async throws -> Credential
func credential(_ imported: Data) async throws -> Credential
}

public protocol ProtocolPlugin: PolluxPlugin {
var supportedCredentialTypes: [String] { get }
}

public protocol ProtocolCreateIssuancePlugin: ProtocolPlugin {
var protocolType: String { get }
var version: String { get }

// This is just a mock still to define
func issueOffer(withClaims: [ClaimFilter], issuer: DID, subject: DID) async throws -> OperationResult
// This is just a mock still to define
func issueCredential(withClaims: [ClaimFilter], issuer: DID, subject: DID) async throws -> OperationResult
}

public protocol ProtocolCreatePresentationPlugin: ProtocolPlugin {
var protocolType: String { get }
var version: String { get }

// This needs to be mocked still
func requestPresentation(withClaims: [ClaimFilter]) async throws -> OperationResult
}

extension ProtocolPlugin {
var credentialIssuance: ProtocolCreateIssuancePlugin? {
return self as? ProtocolCreateIssuancePlugin
}
}

extension ProtocolPlugin {
var credentialPresentation: ProtocolCreatePresentationPlugin? {
return self as? ProtocolCreatePresentationPlugin
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
let downloader = DownloadDataWithResolver(castor: castor)
guard
let attachment = message.attachments.first,
let format = attachment.format

Check warning on line 131 in EdgeAgentSDK/EdgeAgent/Sources/DIDCommAgent/DIDCommAgent+Credentials.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this useless assignment to local variable "format"

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbf1TA8riFkvjGw6&open=AZsDGbf1TA8riFkvjGw6&pullRequest=192

Check warning on line 131 in EdgeAgentSDK/EdgeAgent/Sources/DIDCommAgent/DIDCommAgent+Credentials.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused "format" local variable.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbf1TA8riFkvjGw5&open=AZsDGbf1TA8riFkvjGw5&pullRequest=192
else {
throw PolluxError.unsupportedIssuedMessage
}
Expand All @@ -146,15 +146,22 @@
throw EdgeAgentError.invalidAttachmentFormat(nil)
}

let credential = try await pollux.parseCredential(
type: format,
credentialPayload: jsonData,
guard let plugin = edgeAgent.credentialPlugins.first( where: { $0.supportedOperations.contains(message.type)
}) else {
throw EdgeAgentError.invalidAttachmentFormat(nil)
}
guard let credential = try await plugin.operation(
type: message.type,
format: attachment.format,
payload: jsonData,
options: [
.linkSecret(id: "", secret: linkSecretString),
.credentialDefinitionDownloader(downloader: downloader),
.schemaDownloader(downloader: downloader)
]
)
).credential else {
throw EdgeAgentError.invalidAttachmentFormat(nil)
}

guard let storableCredential = credential.storable else {
return credential
Expand Down
3 changes: 3 additions & 0 deletions EdgeAgentSDK/EdgeAgent/Sources/EdgeAgent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class EdgeAgent {
public let castor: Castor
public let pluto: Pluto
public let pollux: Pollux & CredentialImporter
public let credentialPlugins: [PolluxPlugin]

public static func setupLogging(logLevels: [LogComponent: LogLevel]) {
SDKLogger.logLevels = logLevels
Expand All @@ -35,12 +36,14 @@ public class EdgeAgent {
castor: Castor,
pluto: Pluto,
pollux: Pollux & CredentialImporter,
credentialPlugins: [PolluxPlugin] = [],
seed: Seed? = nil
) {
self.apollo = apollo
self.castor = castor
self.pluto = pluto
self.pollux = pollux
self.credentialPlugins = credentialPlugins
self.seed = seed ?? apollo.createRandomSeed().seed
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Domain
import Foundation

struct DIDCommPlugin: ProtocolPlugin {
let version: String = "0.1"
let supportedOperations: [String] = [
"https://didcomm.org/issue-credential/3.0/offer-credential",

Check warning on line 7 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/DIDCommPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor your code to get this URI from a customizable parameter.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiSTA8riFkvjGxD&open=AZsDGbiSTA8riFkvjGxD&pullRequest=192
"https://didcomm.org/issue-credential/3.0/issue-credential"

Check warning on line 8 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/DIDCommPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor your code to get this URI from a customizable parameter.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiSTA8riFkvjGxE&open=AZsDGbiSTA8riFkvjGxE&pullRequest=192
]
var supportedCredentialTypes: [String] {
credentialPlugins.map(\.credentialType)
}
private let supportProtocols: [ProtocolPlugin]
private let credentialPlugins: [CredentialPlugin]

func requiredOptions(operation: String) -> [Domain.CredentialOperationsOptions] {
[]
}
func operation(
type: String,
format: String?,
payload: Data?,
options: [Domain.CredentialOperationsOptions]
) async throws -> Domain.OperationResult {
guard let format else { throw PolluxError.unsupportedIssuedMessage }
switch type {
case "https://didcomm.org/issue-credential/3.0/offer-credential":

Check warning on line 27 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/DIDCommPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor your code to get this URI from a customizable parameter.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiSTA8riFkvjGxF&open=AZsDGbiSTA8riFkvjGxF&pullRequest=192
guard
let supportProtocol = supportProtocols
.first(where: {
$0.supportedOperations.contains("offer-credential") && $0.supportedCredentialTypes.contains(format)
})
else {
throw PolluxError.unsupportedIssuedMessage
}
return try await supportProtocol.operation(
type: "offer-credential",
format: format,
payload: payload,
options: options
)
case "https://didcomm.org/issue-credential/3.0/issue-credential":

Check warning on line 42 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/DIDCommPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor your code to get this URI from a customizable parameter.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiSTA8riFkvjGxG&open=AZsDGbiSTA8riFkvjGxG&pullRequest=192
guard
let supportProtocol = supportProtocols
.first(where: {
$0.supportedOperations.contains("issue-credential")
&& $0.supportedCredentialTypes.contains(format)
})
else {
throw PolluxError.unsupportedIssuedMessage
}
return try await supportProtocol.operation(
type: "issue-credential",
format: format,
payload: payload,
options: options
)
default:
return .verification(verified: false)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import Domain
import Foundation
import JSONWebKey
import JSONWebToken
import JSONWebSignature

struct JWTCredentialPlugin: CredentialPlugin {
let version = "0.1"
let credentialType = "jwt"
let supportedOperations = [
"offer",
"offer-credential",
"issue",
"issue-credential"
]

func requiredOptions(operation: String) -> [Domain.CredentialOperationsOptions] {
[]
}

func operation(
type: String,
format: String?,
payload: Data?,
options: [Domain.CredentialOperationsOptions]
) async throws -> Domain.OperationResult {
guard let payload else { throw PolluxError.invalidJWTCredential }
switch type {
case "offer", "offer-credential":
let processedJWTCredentialRequest = try await processJWTCredentialRequest(
offerData: payload,
options: options
)
return try .forward(
type: "request-credential",
format: format,
payload: processedJWTCredentialRequest.tryToData()
)
case "issue", "issue-credential":
return try await .credential(createCredential(payload))
default:
throw PolluxError.unsupportedIssuedMessage
}
}

func createCredential(_ credentialData: Data) async throws -> Credential {
try JWTCredential(data: credentialData)
}

func credential(_ imported: Data) async throws -> Credential {
try JWTCredential(data: imported)
}

private func processJWTCredentialRequest(offerData: Data, options: [CredentialOperationsOptions]) async throws -> String {
guard
let subjectDIDOption = options.first(where: {
if case .subjectDID = $0 { return true }

Check warning on line 57 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/JWTCredentialPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reformat the code to have only one statement per line.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiGTA8riFkvjGxA&open=AZsDGbiGTA8riFkvjGxA&pullRequest=192
return false
}),
case let CredentialOperationsOptions.subjectDID(did) = subjectDIDOption
else {
throw PolluxError.invalidPrismDID
}

guard
let exportableKeyOption = options.first(where: {
if case .exportableKey = $0 { return true }

Check warning on line 67 in EdgeAgentSDK/Pollux/Sources/Plugins/DIDCommPlugin/JWTCredentialPlugin.swift

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reformat the code to have only one statement per line.

See more on https://sonarcloud.io/project/issues?id=hyperledger-identus_sdk-swift&issues=AZsDGbiGTA8riFkvjGw_&open=AZsDGbiGTA8riFkvjGw_&pullRequest=192
return false
}),
case let CredentialOperationsOptions.exportableKey(exportableKey) = exportableKeyOption
else {
throw PolluxError.requiresExportableKeyForOperation(operation: "Create Credential Request")
}

return try await CreateJWTCredentialRequest.create(didStr: did.string, key: exportableKey, offerData: offerData)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Domain
import Foundation
import JSONWebKey
import JSONWebToken
import JSONWebSignature

struct PrismJWTCredentialPlugin: CredentialPlugin {
let credentialType = "prismJWT"
var version: String { jwtPlugin.version }
var supportedOperations: [String] { jwtPlugin.supportedOperations }
private let jwtPlugin = JWTCredentialPlugin()

func createCredential(_ credentialData: Data) async throws -> Credential {
try await jwtPlugin.createCredential(credentialData)
}

func credential(_ imported: Data) async throws -> Credential {
try await jwtPlugin.credential(imported)
}

func requiredOptions(operation: String) -> [Domain.CredentialOperationsOptions] {
jwtPlugin.requiredOptions(operation: operation)
}

func operation(
type: String,
format: String?,
payload: Data?,
options: [Domain.CredentialOperationsOptions]
) async throws -> Domain.OperationResult {
try await jwtPlugin.operation(
type: type,
format: format,
payload: payload,
options: options
)
}
}
Loading