2
2
//
3
3
// This source file is part of the Swift open source project
4
4
//
5
- // Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
5
+ // Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See http://swift.org/LICENSE.txt for license information
@@ -24,15 +24,17 @@ public struct RegistryConfiguration: Hashable {
24
24
public var defaultRegistry : Registry ?
25
25
public var scopedRegistries : [ PackageIdentity . Scope : Registry ]
26
26
public var registryAuthentication : [ String : Authentication ]
27
+ public var security : Security ?
27
28
28
29
public init ( ) {
29
30
self . defaultRegistry = nil
30
31
self . scopedRegistries = [ : ]
31
32
self . registryAuthentication = [ : ]
33
+ self . security = nil
32
34
}
33
35
34
36
public var isEmpty : Bool {
35
- return self . defaultRegistry == nil && self . scopedRegistries. isEmpty
37
+ self . defaultRegistry == nil && self . scopedRegistries. isEmpty
36
38
}
37
39
38
40
public mutating func merge( _ other: RegistryConfiguration ) {
@@ -57,6 +59,33 @@ public struct RegistryConfiguration: Hashable {
57
59
guard let host = registryURL. host else { return nil }
58
60
return self . registryAuthentication [ host]
59
61
}
62
+
63
+ public func signing( for package : PackageIdentity , registry: Registry ) throws -> Security . Signing {
64
+ guard case ( let scope, _) ? = package . scopeAndName else {
65
+ throw StringError ( " Only package identity in <scope>.<name> format is supported: ' \( package ) ' " )
66
+ }
67
+
68
+ let global = self . security? . default. signing
69
+ let registryOverrides = registry. url. host. flatMap { host in self . security? . registryOverrides [ host] ? . signing }
70
+ let scopeOverrides = self . security? . scopeOverrides [ scope] ? . signing
71
+ let packageOverrides = self . security? . packageOverrides [ package ] ? . signing
72
+
73
+ var signing = Security . Signing. default
74
+ if let global = global {
75
+ signing. merge ( global)
76
+ }
77
+ if let registryOverrides = registryOverrides {
78
+ signing. merge ( registryOverrides)
79
+ }
80
+ if let scopeOverrides = scopeOverrides {
81
+ signing. merge ( scopeOverrides)
82
+ }
83
+ if let packageOverrides = packageOverrides {
84
+ signing. merge ( packageOverrides)
85
+ }
86
+
87
+ return signing
88
+ }
60
89
}
61
90
62
91
extension RegistryConfiguration {
@@ -76,16 +105,178 @@ extension RegistryConfiguration {
76
105
}
77
106
}
78
107
108
+ extension RegistryConfiguration {
109
+ public struct Security : Hashable {
110
+ public var `default` : Global
111
+ public var registryOverrides : [ String : RegistryOverride ]
112
+ public var scopeOverrides : [ PackageIdentity . Scope : ScopePackageOverride ]
113
+ public var packageOverrides : [ PackageIdentity : ScopePackageOverride ]
114
+
115
+ public init ( ) {
116
+ self . default = Global ( )
117
+ self . registryOverrides = [ : ]
118
+ self . scopeOverrides = [ : ]
119
+ self . packageOverrides = [ : ]
120
+ }
121
+
122
+ public struct Global : Hashable , Codable {
123
+ public var signing : Signing ?
124
+
125
+ public init ( ) {
126
+ self . signing = nil
127
+ }
128
+ }
129
+
130
+ public struct RegistryOverride : Hashable , Codable {
131
+ public var signing : Signing ?
132
+
133
+ public init ( ) {
134
+ self . signing = nil
135
+ }
136
+ }
137
+
138
+ public struct Signing : Hashable , Codable {
139
+ static let `default` : Signing = {
140
+ var signing = Signing ( )
141
+ signing. onUnsigned = . prompt
142
+ signing. onUntrustedCertificate = . prompt
143
+ signing. trustedRootCertificatesPath = nil
144
+ signing. includeDefaultTrustedRootCertificates = true
145
+
146
+ var validationChecks = Signing . ValidationChecks ( )
147
+ validationChecks. certificateExpiration = . disabled
148
+ validationChecks. certificateRevocation = . disabled
149
+ signing. validationChecks = validationChecks
150
+
151
+ return signing
152
+ } ( )
153
+
154
+ public var onUnsigned : OnUnsignedAction ?
155
+ public var onUntrustedCertificate : OnUntrustedCertificateAction ?
156
+ public var trustedRootCertificatesPath : String ?
157
+ public var includeDefaultTrustedRootCertificates : Bool ?
158
+ public var validationChecks : ValidationChecks ?
159
+
160
+ public init ( ) {
161
+ self . onUnsigned = nil
162
+ self . onUntrustedCertificate = nil
163
+ self . trustedRootCertificatesPath = nil
164
+ self . includeDefaultTrustedRootCertificates = nil
165
+ self . validationChecks = nil
166
+ }
167
+
168
+ mutating func merge( _ other: Signing ) {
169
+ if let onUnsigned = other. onUnsigned {
170
+ self . onUnsigned = onUnsigned
171
+ }
172
+ if let onUntrustedCertificate = other. onUntrustedCertificate {
173
+ self . onUntrustedCertificate = onUntrustedCertificate
174
+ }
175
+ if let trustedRootCertificatesPath = other. trustedRootCertificatesPath {
176
+ self . trustedRootCertificatesPath = trustedRootCertificatesPath
177
+ }
178
+ if let includeDefaultTrustedRootCertificates = other. includeDefaultTrustedRootCertificates {
179
+ self . includeDefaultTrustedRootCertificates = includeDefaultTrustedRootCertificates
180
+ }
181
+ if let validationChecks = other. validationChecks {
182
+ self . validationChecks? . merge ( validationChecks)
183
+ }
184
+ }
185
+
186
+ mutating func merge( _ other: ScopePackageOverride . Signing ) {
187
+ if let trustedRootCertificatesPath = other. trustedRootCertificatesPath {
188
+ self . trustedRootCertificatesPath = trustedRootCertificatesPath
189
+ }
190
+ if let includeDefaultTrustedRootCertificates = other. includeDefaultTrustedRootCertificates {
191
+ self . includeDefaultTrustedRootCertificates = includeDefaultTrustedRootCertificates
192
+ }
193
+ }
194
+
195
+ public enum OnUnsignedAction : String , Hashable , Codable {
196
+ case error
197
+ case prompt
198
+ case warn
199
+ case silentAllow
200
+ }
201
+
202
+ public enum OnUntrustedCertificateAction : String , Hashable , Codable {
203
+ case error
204
+ case prompt
205
+ case warn
206
+ case silentTrust
207
+ }
208
+
209
+ public struct ValidationChecks : Hashable , Codable {
210
+ public var certificateExpiration : CertificateExpirationCheck ?
211
+ public var certificateRevocation : CertificateRevocationCheck ?
212
+
213
+ public init ( ) {
214
+ self . certificateExpiration = nil
215
+ self . certificateRevocation = nil
216
+ }
217
+
218
+ mutating func merge( _ other: ValidationChecks ) {
219
+ if let certificateExpiration = other. certificateExpiration {
220
+ self . certificateExpiration = certificateExpiration
221
+ }
222
+ if let certificateRevocation = other. certificateRevocation {
223
+ self . certificateRevocation = certificateRevocation
224
+ }
225
+ }
226
+
227
+ public enum CertificateExpirationCheck : String , Hashable , Codable {
228
+ case enabled
229
+ case disabled
230
+ }
231
+
232
+ public enum CertificateRevocationCheck : String , Hashable , Codable {
233
+ case strict
234
+ case allowSoftFail
235
+ case disabled
236
+ }
237
+ }
238
+ }
239
+
240
+ public struct ScopePackageOverride : Hashable , Codable {
241
+ public var signing : Signing ?
242
+
243
+ public init ( ) {
244
+ self . signing = nil
245
+ }
246
+
247
+ public struct Signing : Hashable , Codable {
248
+ public var trustedRootCertificatesPath : String ?
249
+ public var includeDefaultTrustedRootCertificates : Bool ?
250
+
251
+ public init ( ) {
252
+ self . trustedRootCertificatesPath = nil
253
+ self . includeDefaultTrustedRootCertificates = nil
254
+ }
255
+
256
+ mutating func merge( _ other: Signing ) {
257
+ if let trustedRootCertificatesPath = other. trustedRootCertificatesPath {
258
+ self . trustedRootCertificatesPath = trustedRootCertificatesPath
259
+ }
260
+ if let includeDefaultTrustedRootCertificates = other. includeDefaultTrustedRootCertificates {
261
+ self . includeDefaultTrustedRootCertificates = includeDefaultTrustedRootCertificates
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+
79
269
// MARK: - Codable
80
270
81
271
extension RegistryConfiguration : Codable {
82
272
private enum CodingKeys : String , CodingKey {
83
273
case registries
84
274
case authentication
275
+ case security
85
276
case version
86
277
}
87
278
88
- private struct ScopeCodingKey : CodingKey , Hashable {
279
+ fileprivate struct ScopeCodingKey : CodingKey , Hashable {
89
280
static let `default` = ScopeCodingKey ( stringValue: " [default] " )
90
281
91
282
var stringValue : String
@@ -96,11 +287,11 @@ extension RegistryConfiguration: Codable {
96
287
}
97
288
98
289
init ? ( intValue: Int ) {
99
- return nil
290
+ nil
100
291
}
101
292
}
102
293
103
- private struct AuthenticationCodingKey : CodingKey , Hashable {
294
+ fileprivate struct PackageCodingKey : CodingKey , Hashable {
104
295
var stringValue : String
105
296
var intValue : Int ? { nil }
106
297
@@ -109,7 +300,7 @@ extension RegistryConfiguration: Codable {
109
300
}
110
301
111
302
init ? ( intValue: Int ) {
112
- return nil
303
+ nil
113
304
}
114
305
}
115
306
@@ -130,9 +321,17 @@ extension RegistryConfiguration: Codable {
130
321
}
131
322
self . scopedRegistries = scopedRegistries
132
323
133
- self . registryAuthentication = try container. decodeIfPresent ( [ String : Authentication ] . self, forKey: . authentication) ?? [ : ]
324
+ self . registryAuthentication = try container. decodeIfPresent (
325
+ [ String : Authentication ] . self,
326
+ forKey: . authentication
327
+ ) ?? [ : ]
328
+ self . security = try container. decodeIfPresent ( Security . self, forKey: . security) ?? nil
134
329
case nil :
135
- throw DecodingError . dataCorruptedError ( forKey: . version, in: container, debugDescription: " invalid version: \( version) " )
330
+ throw DecodingError . dataCorruptedError (
331
+ forKey: . version,
332
+ in: container,
333
+ debugDescription: " invalid version: \( version) "
334
+ )
136
335
}
137
336
}
138
337
@@ -151,5 +350,79 @@ extension RegistryConfiguration: Codable {
151
350
}
152
351
153
352
try container. encode ( self . registryAuthentication, forKey: . authentication)
353
+ try container. encodeIfPresent ( self . security, forKey: . security)
354
+ }
355
+ }
356
+
357
+ extension RegistryConfiguration . Security : Codable {
358
+ private enum CodingKeys : String , CodingKey {
359
+ case `default`
360
+ case registryOverrides
361
+ case scopeOverrides
362
+ case packageOverrides
363
+ }
364
+
365
+ public init ( from decoder: Decoder ) throws {
366
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
367
+
368
+ self . default = try container. decodeIfPresent ( Global . self, forKey: . default) ?? Global ( )
369
+ self . registryOverrides = try container. decodeIfPresent (
370
+ [ String : RegistryOverride ] . self,
371
+ forKey: . registryOverrides
372
+ ) ?? [ : ]
373
+
374
+ let scopeOverridesContainer = try container. decodeIfPresent (
375
+ [ String : ScopePackageOverride ] . self,
376
+ forKey: . scopeOverrides
377
+ ) ?? [ : ]
378
+ var scopeOverrides : [ PackageIdentity . Scope : ScopePackageOverride ] = [ : ]
379
+ for (key, scopeOverride) in scopeOverridesContainer {
380
+ let scope = try PackageIdentity . Scope ( validating: key)
381
+ scopeOverrides [ scope] = scopeOverride
382
+ }
383
+ self . scopeOverrides = scopeOverrides
384
+
385
+ let packageOverridesContainer = try container. decodeIfPresent (
386
+ [ String : ScopePackageOverride ] . self,
387
+ forKey: . packageOverrides
388
+ ) ?? [ : ]
389
+ var packageOverrides : [ PackageIdentity : ScopePackageOverride ] = [ : ]
390
+ for (key, packageOverride) in packageOverridesContainer {
391
+ let packageIdentity = PackageIdentity . plain ( key)
392
+ guard packageIdentity. scopeAndName != nil else {
393
+ throw DecodingError . dataCorruptedError (
394
+ forKey: . packageOverrides,
395
+ in: container,
396
+ debugDescription: " invalid package identity: \( key) "
397
+ )
398
+ }
399
+ packageOverrides [ packageIdentity] = packageOverride
400
+ }
401
+ self . packageOverrides = packageOverrides
402
+ }
403
+
404
+ public func encode( to encoder: Encoder ) throws {
405
+ var container = encoder. container ( keyedBy: CodingKeys . self)
406
+
407
+ try container. encode ( self . default, forKey: . default)
408
+ try container. encode ( self . registryOverrides, forKey: . registryOverrides)
409
+
410
+ var scopeOverridesContainer = container. nestedContainer (
411
+ keyedBy: RegistryConfiguration . ScopeCodingKey. self,
412
+ forKey: . scopeOverrides
413
+ )
414
+ for (scope, scopeOverride) in self . scopeOverrides {
415
+ let key = RegistryConfiguration . ScopeCodingKey ( stringValue: scope. description)
416
+ try scopeOverridesContainer. encode ( scopeOverride, forKey: key)
417
+ }
418
+
419
+ var packageOverridesContainer = container. nestedContainer (
420
+ keyedBy: RegistryConfiguration . PackageCodingKey. self,
421
+ forKey: . packageOverrides
422
+ )
423
+ for (packageIdentity, packageOverride) in self . packageOverrides {
424
+ let key = RegistryConfiguration . PackageCodingKey ( stringValue: packageIdentity. description)
425
+ try packageOverridesContainer. encode ( packageOverride, forKey: key)
426
+ }
154
427
}
155
428
}
0 commit comments