Skip to content

Commit

Permalink
Merge pull request #54 from niscy-eudiw/main
Browse files Browse the repository at this point in the history
Enhance DocClaimsDecodable and related structures: update documentation, add docDataFormat property
  • Loading branch information
phisakel authored Dec 18, 2024
2 parents 90584d4 + 52aa256 commit ef353c4
Show file tree
Hide file tree
Showing 10 changed files with 447 additions and 413 deletions.
12 changes: 6 additions & 6 deletions Sources/MdocDataModel18013/DocumentClaims/DocClaim.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ limitations under the License.

import Foundation

/// This structure is used to store and manage pairs of names and their corresponding values.
/// It provides functionality for comparing instances, generating string representations for
/// debugging and display purposes, and ensuring safe concurrent access.
/// This structure is used to store document claim values and associated metadata.
/// It provides functionality for generating string representations for
/// debugging and display purposes.
@DebugDescription
public struct DocClaim: Equatable, CustomStringConvertible, CustomDebugStringConvertible, Sendable {
public init(name: String, displayName: String? = nil, docDataValue: DocDataValue? = nil, valueType: String? = nil, stringValue: String, isOptional: Bool = false, order: Int = 0, namespace: String? = nil, children: [DocClaim]? = nil) {
public init(name: String, displayName: String? = nil, dataValue: DocDataValue, stringValue: String, valueType: String? = nil, isOptional: Bool = false, order: Int = 0, namespace: String? = nil, children: [DocClaim]? = nil) {
self.name = name
self.displayName = displayName
self.docDataValue = docDataValue
self.dataValue = dataValue
self.valueType = valueType
self.stringValue = stringValue
self.isOptional = isOptional
Expand All @@ -42,7 +42,7 @@ public struct DocClaim: Equatable, CustomStringConvertible, CustomDebugStringCon
/// The value of the claim as a string.
public let stringValue: String
/// The value of the claim as a `DocDataValue` (enum with associated values)
public let docDataValue: DocDataValue?
public let dataValue: DocDataValue
/// The type of the value of the claim, originated from VCI metadata/claims.
public let valueType: String?
/// A flag indicating whether the claim is optional, originated from VCI metadata/claims.
Expand Down
18 changes: 10 additions & 8 deletions Sources/MdocDataModel18013/DocumentClaims/DocClaimsDecodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ limitations under the License.

import Foundation
import SwiftCBOR
#if canImport(UIKit)
import UIKit
#endif

/// A conforming type represents claims data.
///
Expand All @@ -34,12 +31,15 @@ public protocol DocClaimsDecodable: Sendable, AgeAttesting {
var modifiedAt: Date? { get }
/// The display name of the document.
var displayName: String? { get }
// The document type. It is not null for CBOR (mso-mdoc) documents
// The document type. For CBOR (mso_mdoc) documents is native, for SD-JWT (vc+sd-jwt) documents is the type of the document.
var docType: String? { get }
// document claims in a format agnostic way
var docClaims: [DocClaim] { get }
/// The format of the document data.
var docDataFormat: DocDataFormat { get }
} // end protocol

/// Methods to extract CBOR values.
extension DocClaimsDecodable {

public static func getCborItemValue<T>(_ issuerSigned: IssuerSigned, _ s: String) -> T? {
Expand Down Expand Up @@ -97,7 +97,7 @@ extension DocClaimsDecodable {
return Set( agesDict.filter { $1 == false }.keys.map { "age_over_\($0)" })
}

/// Extracts a display string or image from a CBOR value.
/// Extracts a CBOR value.
///
/// - Parameters:
/// - name: The name associated with the CBOR value.
Expand All @@ -109,10 +109,10 @@ extension DocClaimsDecodable {
/// - Returns: A `DocClaim` object containing the extracted display string or image.
public static func extractCborClaim(_ name: String, _ cborValue: CBOR, _ bDebugDisplay: Bool, _ namespace: NameSpace, _ order: Int, _ displayNames: [String:String]? = nil, _ mandatory: [String:Bool]? = nil, _ valueTypes: [String:String]? = nil) -> DocClaim {
var stringValue = bDebugDisplay ? cborValue.debugDescription : cborValue.description
let dt = cborValue.mdocDataValue
let dt = cborValue.mdocDataValue ?? .string(stringValue)
if name == "sex", let isex = Int(stringValue), isex <= 2 { stringValue = NSLocalizedString(isex == 1 ? "male" : "female", comment: "") }
let isMandatory = mandatory?[name] ?? true
var node = DocClaim(name: name, displayName: displayNames?[name], docDataValue: dt, valueType: valueTypes?[name], stringValue: stringValue, isOptional: !isMandatory, order: order, namespace: namespace)
var node = DocClaim(name: name, displayName: displayNames?[name], dataValue: dt, stringValue: stringValue, valueType: valueTypes?[name], isOptional: !isMandatory, order: order, namespace: namespace)
if case let .map(m) = cborValue {
let innerJsonMap = CBOR.decodeDictionary(m, unwrap: false)
for (o2,(k,v)) in innerJsonMap.enumerated() {
Expand All @@ -135,7 +135,9 @@ extension DocClaimsDecodable {
/// - Parameters:
/// - nameSpaces: A dictionary where the key is a `NameSpace` and the value is an array of `IssuerSignedItem`.
/// - docClaims: An inout parameter that will be populated with `DocClaim` items extracted from the namespaces.
/// - labels: A dictionary where the key is the elementIdentifier and the value is a string representing the label.
/// - claimDisplayNames: A dictionary where the key is the elementIdentifier and the value is a string representing the label.
/// - mandatoryClaims: A dictionary where the key is the elementIdentifier and the value is a boolean indicating whether the claim is mandatory.
/// - claimValueTypes: A dictionary where the key is the elementIdentifier and the value is a string representing the value type.
/// - nsFilter: An optional array of `NameSpace` to filter/sort the extraction. Defaults to `nil`.
public static func extractCborClaims(_ nameSpaces: [NameSpace: [IssuerSignedItem]], _ docClaims: inout [DocClaim], _ claimDisplayNames: [NameSpace: [String: String]]? = nil, _ mandatoryClaims: [NameSpace: [String: Bool]]? = nil, _ claimValueTypes: [NameSpace: [String: String]]? = nil, nsFilter: [NameSpace]? = nil) {
let bDebugDisplay = UserDefaults.standard.bool(forKey: "DebugDisplay")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

import Foundation

/// A protocol to create a ``DocClaimsDecodable`` from a cbor encoded ``IssuerSigned`` struct
public protocol DocClaimsDecodableFactory: Sendable {
func makeClaimsDecodableFromCbor(id: String, createdAt: Date, issuerSigned: IssuerSigned, displayName: String?, claimDisplayNames: [NameSpace: [String: String]]?, mandatoryClaims: [NameSpace: [String: Bool]]?, claimValueTypes: [NameSpace: [String: String]]?) -> (any DocClaimsDecodable)?
}
22 changes: 22 additions & 0 deletions Sources/MdocDataModel18013/DocumentClaims/DocDataFormat.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation
/// Format of document data
/// ``cbor``: IssuerSigned struct cbor encoded
/// ``sdjwt``: vc+sd-jwt encoded
///
/// Raw value must be a 4-length string due to keychain requirements
public enum DocDataFormat: String, Sendable, CustomStringConvertible, CustomDebugStringConvertible, Codable {
case cbor = "cbor"
case sdjwt = "sjwt"

/// A description to display
public var description: String {
switch self {
case .cbor: return "mso_mdoc"
case .sdjwt: return "vc+sd-jwt"
}
}

public var debugDescription: String {
description
}
}
Loading

0 comments on commit ef353c4

Please sign in to comment.