@@ -24,7 +24,13 @@ public protocol AuthorizationProvider {
24
24
}
25
25
26
26
public protocol AuthorizationWriter {
27
- func addOrUpdate( for url: URL , user: String , password: String , persist: Bool , callback: @escaping ( Result < Void , Error > ) -> Void )
27
+ func addOrUpdate(
28
+ for url: URL ,
29
+ user: String ,
30
+ password: String ,
31
+ persist: Bool ,
32
+ callback: @escaping ( Result < Void , Error > ) -> Void
33
+ )
28
34
29
35
func remove( for url: URL , callback: @escaping ( Result < Void , Error > ) -> Void )
30
36
}
@@ -36,9 +42,9 @@ public enum AuthorizationProviderError: Error {
36
42
case other( String )
37
43
}
38
44
39
- public extension AuthorizationProvider {
45
+ extension AuthorizationProvider {
40
46
@Sendable
41
- func httpAuthorizationHeader( for url: URL ) -> String ? {
47
+ public func httpAuthorizationHeader( for url: URL ) -> String ? {
42
48
guard let ( user, password) = self . authentication ( for: url) else {
43
49
return nil
44
50
}
@@ -50,8 +56,8 @@ public extension AuthorizationProvider {
50
56
}
51
57
}
52
58
53
- private extension URL {
54
- var authenticationID : String ? {
59
+ extension URL {
60
+ fileprivate var authenticationID : String ? {
55
61
guard let host = host? . lowercased ( ) else {
56
62
return nil
57
63
}
@@ -75,7 +81,13 @@ public class NetrcAuthorizationProvider: AuthorizationProvider, AuthorizationWri
75
81
_ = try Self . load ( fileSystem: fileSystem, path: path)
76
82
}
77
83
78
- public func addOrUpdate( for url: URL , user: String , password: String , persist: Bool = true , callback: @escaping ( Result < Void , Error > ) -> Void ) {
84
+ public func addOrUpdate(
85
+ for url: URL ,
86
+ user: String ,
87
+ password: String ,
88
+ persist: Bool = true ,
89
+ callback: @escaping ( Result < Void , Error > ) -> Void
90
+ ) {
79
91
guard let machine = url. authenticationID else {
80
92
return callback ( . failure( AuthorizationProviderError . invalidURLHost) )
81
93
}
@@ -87,7 +99,9 @@ public class NetrcAuthorizationProvider: AuthorizationProvider, AuthorizationWri
87
99
88
100
// Same entry already exists, no need to add or update
89
101
let netrc = try ? Self . load ( fileSystem: self . fileSystem, path: self . path)
90
- guard netrc? . machines. first ( where: { $0. name. lowercased ( ) == machine && $0. login == user && $0. password == password } ) == nil else {
102
+ guard netrc? . machines
103
+ . first ( where: { $0. name. lowercased ( ) == machine && $0. login == user && $0. password == password } ) == nil
104
+ else {
91
105
return callback ( . success( ( ) ) )
92
106
}
93
107
@@ -108,12 +122,18 @@ public class NetrcAuthorizationProvider: AuthorizationProvider, AuthorizationWri
108
122
109
123
callback ( . success( ( ) ) )
110
124
} catch {
111
- callback ( . failure( AuthorizationProviderError . other ( " Failed to update netrc file at \( self . path) : \( error) " ) ) )
125
+ callback ( . failure(
126
+ AuthorizationProviderError
127
+ . other ( " Failed to update netrc file at \( self . path) : \( error. interpolationDescription) " )
128
+ ) )
112
129
}
113
130
}
114
131
115
132
public func remove( for url: URL , callback: @escaping ( Result < Void , Error > ) -> Void ) {
116
- callback ( . failure( AuthorizationProviderError . other ( " User must edit netrc file at \( self . path) manually to remove entries " ) ) )
133
+ callback ( . failure(
134
+ AuthorizationProviderError
135
+ . other ( " User must edit netrc file at \( self . path) manually to remove entries " )
136
+ ) )
117
137
}
118
138
119
139
public func authentication( for url: URL ) -> ( user: String , password: String ) ? {
@@ -124,7 +144,9 @@ public class NetrcAuthorizationProvider: AuthorizationProvider, AuthorizationWri
124
144
}
125
145
126
146
private func machine( for url: URL ) -> Basics . Netrc . Machine ? {
127
- if let machine = url. authenticationID, let existing = self . machines. first ( where: { $0. name. lowercased ( ) == machine } ) {
147
+ if let machine = url. authenticationID,
148
+ let existing = self . machines. first ( where: { $0. name. lowercased ( ) == machine } )
149
+ {
128
150
return existing
129
151
}
130
152
if let existing = self . machines. first ( where: { $0. isDefault } ) {
@@ -164,7 +186,13 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
164
186
self . observabilityScope = observabilityScope
165
187
}
166
188
167
- public func addOrUpdate( for url: URL , user: String , password: String , persist: Bool = true , callback: @escaping ( Result < Void , Error > ) -> Void ) {
189
+ public func addOrUpdate(
190
+ for url: URL ,
191
+ user: String ,
192
+ password: String ,
193
+ persist: Bool = true ,
194
+ callback: @escaping ( Result < Void , Error > ) -> Void
195
+ ) {
168
196
guard let server = url. authenticationID else {
169
197
return callback ( . failure( AuthorizationProviderError . invalidURLHost) )
170
198
}
@@ -214,12 +242,14 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
214
242
}
215
243
216
244
do {
217
- guard let existingItem = try self . search ( server: server, protocol: self . protocol ( for: url) ) as? [ String : Any ] ,
218
- let passwordData = existingItem [ kSecValueData as String ] as? Data ,
219
- let password = String ( data: passwordData, encoding: String . Encoding. utf8) ,
220
- let account = existingItem [ kSecAttrAccount as String ] as? String
245
+ guard let existingItem = try self
246
+ . search ( server: server, protocol: self . protocol ( for: url) ) as? [ String : Any ] ,
247
+ let passwordData = existingItem [ kSecValueData as String ] as? Data ,
248
+ let password = String ( data: passwordData, encoding: String . Encoding. utf8) ,
249
+ let account = existingItem [ kSecAttrAccount as String ] as? String
221
250
else {
222
- throw AuthorizationProviderError . other ( " Failed to extract credentials for server \( server) from keychain " )
251
+ throw AuthorizationProviderError
252
+ . other ( " Failed to extract credentials for server \( server) from keychain " )
223
253
}
224
254
return ( user: account, password: password)
225
255
} catch {
@@ -229,7 +259,10 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
229
259
case AuthorizationProviderError . other( let detail) :
230
260
self . observabilityScope. emit ( error: detail)
231
261
default :
232
- self . observabilityScope. emit ( error: " Failed to find credentials for server \( server) in keychain: \( error) " )
262
+ self . observabilityScope. emit (
263
+ error: " Failed to find credentials for server \( server) in keychain " ,
264
+ underlyingError: error
265
+ )
233
266
}
234
267
return nil
235
268
}
@@ -244,7 +277,8 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
244
277
245
278
let status = SecItemAdd ( query as CFDictionary , nil )
246
279
guard status == errSecSuccess else {
247
- throw AuthorizationProviderError . other ( " Failed to save credentials for server \( server) to keychain: status \( status) " )
280
+ throw AuthorizationProviderError
281
+ . other ( " Failed to save credentials for server \( server) to keychain: status \( status) " )
248
282
}
249
283
}
250
284
@@ -260,7 +294,8 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
260
294
return false
261
295
}
262
296
guard status == errSecSuccess else {
263
- throw AuthorizationProviderError . other ( " Failed to update credentials for server \( server) in keychain: status \( status) " )
297
+ throw AuthorizationProviderError
298
+ . other ( " Failed to update credentials for server \( server) in keychain: status \( status) " )
264
299
}
265
300
return true
266
301
}
@@ -271,7 +306,8 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
271
306
kSecAttrProtocol as String : `protocol`]
272
307
let status = SecItemDelete ( query as CFDictionary )
273
308
guard status == errSecSuccess else {
274
- throw AuthorizationProviderError . other ( " Failed to delete credentials for server \( server) from keychain: status \( status) " )
309
+ throw AuthorizationProviderError
310
+ . other ( " Failed to delete credentials for server \( server) from keychain: status \( status) " )
275
311
}
276
312
}
277
313
@@ -290,7 +326,8 @@ public class KeychainAuthorizationProvider: AuthorizationProvider, Authorization
290
326
throw AuthorizationProviderError . notFound
291
327
}
292
328
guard status == errSecSuccess else {
293
- throw AuthorizationProviderError . other ( " Failed to find credentials for server \( server) in keychain: status \( status) " )
329
+ throw AuthorizationProviderError
330
+ . other ( " Failed to find credentials for server \( server) in keychain: status \( status) " )
294
331
}
295
332
296
333
return item
0 commit comments