@@ -33,11 +33,10 @@ public class ApiInvoker {
3333 // An object containing the configuration for executing API requests
3434 private let configuration : Configuration ;
3535
36- // RSA key for password encryption
3736#if os(Linux)
3837 // Encryption of passwords in query params not supported on linux
3938#else
40- private var encryptionKey : SecKey ? ;
39+ private let encryptor : Encryptor ;
4140#endif
4241
4342 // Cached value of oauth2 authorization tokeт.
@@ -56,26 +55,31 @@ public class ApiInvoker {
5655 private let httpStatusCodeTimeout = 408 ;
5756
5857 // Initialize ApiInvoker object with specific configuration
58+ #if os(Linux)
5959 public init ( configuration : Configuration ) {
6060 self . configuration = configuration;
6161 self . mutex = NSLock ( ) ;
6262 self . accessTokenCache = nil ;
63-
64- #if os(Linux)
65- // Encryption of passwords in query params not supported on linux
63+ }
6664#else
67- self . encryptionKey = nil ;
68- #endif
65+ public init ( configuration : Configuration , encryptor: Encryptor ) {
66+ self . configuration = configuration;
67+ self . mutex = NSLock ( ) ;
68+ self . accessTokenCache = nil ;
69+ this. encryptor = encryptor;
6970 }
71+ #endif
7072
7173 // Internal class for represent API response
7274 private class InvokeResponse {
7375 public var data : Data ? ;
76+ public var headers : [ String : String ] ;
7477 public var errorCode : Int ;
7578 public var errorMessage : String ? ;
7679
7780 public init ( errorCode : Int ) {
7881 self . errorCode = errorCode;
82+ self . headers = [ String : String] ( ) ;
7983 }
8084 }
8185
@@ -85,7 +89,7 @@ public class ApiInvoker {
8589 }
8690
8791 // Invoke request to the API with the specified set of arguments and execute callback after the request is completed
88- public func invoke( apiRequestData : WordsApiRequestData , callback: @escaping ( _ response: Data ? , _ error: Error ? ) -> ( )
92+ public func invoke( apiRequestData : WordsApiRequestData , callback: @escaping ( _ response: Data ? , _ headers : [ String : String ] , _ error: Error ? ) -> ( )
8993 ) {
9094 // Create URL request object
9195 var request = URLRequest ( url: apiRequestData. getURL ( ) ) ;
@@ -115,29 +119,29 @@ public class ApiInvoker {
115119 self . invokeRequest ( urlRequest: & request, accessToken: accessToken, callback: { response in
116120 if ( response. errorCode == self . httpStatusCodeOK) {
117121 // Api request success
118- callback ( response. data, nil ) ;
122+ callback ( response. data, response . headers , nil ) ;
119123 }
120124 else {
121- callback ( nil , WordsApiError . requestError ( errorCode: response. errorCode, message: response. errorMessage) ) ;
125+ callback ( nil , [ String : String ] ( ) , WordsApiError . requestError ( errorCode: response. errorCode, message: response. errorMessage) ) ;
122126 }
123127 } ) ;
124128 }
125129 else {
126- callback ( nil , WordsApiError . requestError ( errorCode: statusCode, message: " Authorization failed. " ) ) ;
130+ callback ( nil , [ String : String ] ( ) , WordsApiError . requestError ( errorCode: statusCode, message: " Authorization failed. " ) ) ;
127131 }
128132 } ) ;
129133 }
130134 else if ( response. errorCode == self . httpStatusCodeOK) {
131135 // Api request success
132- callback ( response. data, nil ) ;
136+ callback ( response. data, response . headers , nil ) ;
133137 }
134138 else {
135- callback ( nil , WordsApiError . requestError ( errorCode: response. errorCode, message: response. errorMessage) ) ;
139+ callback ( nil , [ String : String ] ( ) , WordsApiError . requestError ( errorCode: response. errorCode, message: response. errorMessage) ) ;
136140 }
137141 } ) ;
138142 }
139143 else {
140- callback ( nil , WordsApiError . requestError ( errorCode: statusCode, message: " Authorization failed. " ) ) ;
144+ callback ( nil , [ String : String ] ( ) , WordsApiError . requestError ( errorCode: statusCode, message: " Authorization failed. " ) ) ;
141145 }
142146 } ) ;
143147 }
@@ -189,6 +193,9 @@ public class ApiInvoker {
189193 if ( rawResponse != nil ) {
190194 invokeResponse. errorCode = rawResponse!. statusCode;
191195 invokeResponse. errorMessage = rawResponse!. description;
196+ for header in rawResponse!. allHeaderFields {
197+ invokeResponse. headers [ String ( describing: header. key) ] = String ( describing: header. value) ;
198+ }
192199 }
193200 else {
194201 invokeResponse. errorCode = self . httpStatusCodeBadRequest;
@@ -296,65 +303,11 @@ public class ApiInvoker {
296303 return lengthField;
297304 }
298305
299- public func setEncryptionData( data : PublicKeyResponse ) throws {
300306#if os(Linux)
301- // Encryption of passwords in query params not supported on linux
302- #else
303- let exponent = Data ( base64Encoded: data. getExponent ( ) !) !;
304- let modulus = Data ( base64Encoded: data. getModulus ( ) !) !;
305- let exponentBytes = [ UInt8] ( exponent) ;
306- var modulusBytes = [ UInt8] ( modulus) ;
307- modulusBytes. insert ( 0x00 , at: 0 ) ;
308-
309- var modulusEncoded : [ UInt8 ] = [ ] ;
310- modulusEncoded. append ( 0x02 ) ;
311- modulusEncoded. append ( contentsOf: lengthField ( of: modulusBytes) ) ;
312- modulusEncoded. append ( contentsOf: modulusBytes) ;
313-
314- var exponentEncoded : [ UInt8 ] = [ ] ;
315- exponentEncoded. append ( 0x02 ) ;
316- exponentEncoded. append ( contentsOf: lengthField ( of: exponentBytes) ) ;
317- exponentEncoded. append ( contentsOf: exponentBytes) ;
318-
319- var sequenceEncoded : [ UInt8 ] = [ ] ;
320- sequenceEncoded. append ( 0x30 ) ;
321- sequenceEncoded. append ( contentsOf: lengthField ( of: ( modulusEncoded + exponentEncoded) ) ) ;
322- sequenceEncoded. append ( contentsOf: ( modulusEncoded + exponentEncoded) ) ;
323-
324- let keyData = Data ( bytes: sequenceEncoded) ;
325- let keySize = ( modulusBytes. count * 8 ) ;
326-
327- let attributes : [ String : Any ] = [
328- kSecAttrKeyType as String : kSecAttrKeyTypeRSA,
329- kSecAttrKeyClass as String : kSecAttrKeyClassPublic,
330- kSecAttrKeySizeInBits as String : keySize
331- ] ;
332-
333- encryptionKey = SecKeyCreateWithData ( keyData as CFData , attributes as CFDictionary , nil ) ;
334- #endif
335- }
336-
337- public func encryptString( value : String ) throws -> String {
338- #if os(Linux)
339- // Encryption of passwords in query params not supported on linux
340- return value;
307+ // Encryption of passwords in query params not supported on linux
341308#else
342- let buffer = value. data ( using: . utf8) !;
343- var error : Unmanaged < CFError > ? = nil ;
344-
345- // Encrypto should less than key length
346- let secData = SecKeyCreateEncryptedData ( encryptionKey!, . rsaEncryptionPKCS1, buffer as CFData , & error) !;
347- var secBuffer = [ UInt8] ( repeating: 0 , count: CFDataGetLength ( secData) ) ;
348- CFDataGetBytes ( secData, CFRangeMake ( 0 , CFDataGetLength ( secData) ) , & secBuffer) ;
349- return Data ( bytes: secBuffer) . base64EncodedString ( ) . replacingOccurrences ( of: " + " , with: " %2B " ) . replacingOccurrences ( of: " / " , with: " %2F " ) ;
350- #endif
309+ public func encryptString( data : String ) throws -> String {
310+ return encryptor. encrypt ( data) ;
351311 }
352-
353- public func isEncryptionAllowed( ) -> Bool {
354- #if os(Linux)
355- return false ;
356- #else
357- return true ;
358312#endif
359- }
360313}
0 commit comments