Update security samples for swift. (#5324)

This commit is contained in:
Paŭlo Ebermann 2017-04-05 12:04:53 +02:00 committed by wing328
parent 5b16694afc
commit be83329946
8 changed files with 187 additions and 46 deletions

View File

@ -4,7 +4,10 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.9'
s.version = '0.0.1'
s.source = { :git => 'git@github.com:swagger-api/swagger-mustache.git', :tag => 'v1.0.0' }
s.license = 'Apache License, Version 2.0'
s.authors = 'Swagger Codegen'
s.license = 'Proprietary'
s.homepage = 'https://github.com/swagger-api/swagger-codegen'
s.summary = 'SwaggerClient Swift SDK'
s.source_files = 'SwaggerClient/Classes/Swaggers/**/*.swift'
s.dependency 'Alamofire', '~> 3.1.5'
s.dependency 'Alamofire', '~> 3.4.1'
end

View File

@ -19,6 +19,16 @@ class APIHelper {
return destination
}
static func rejectNilHeaders(source: [String:AnyObject?]) -> [String:String] {
var destination = [String:String]()
for (key, nillableValue) in source {
if let value: AnyObject = nillableValue {
destination[key] = "\(value)"
}
}
return destination
}
static func convertBoolToString(source: [String: AnyObject]?) -> [String:AnyObject]? {
guard let source = source else {
return nil

View File

@ -7,7 +7,7 @@
import Foundation
public class SwaggerClientAPI {
public static var basePath = "https://petstore.swagger.io *_/ ' \" =end \\r\\n \\n \\r/v2 *_/ ' \" =end \\r\\n \\n \\r"
public static var basePath = "https://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r"
public static var credential: NSURLCredential?
public static var customHeaders: [String:String] = [:]
static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
@ -31,17 +31,21 @@ public class APIBase {
public class RequestBuilder<T> {
var credential: NSURLCredential?
var headers: [String:String] = [:]
var headers: [String:String]
let parameters: [String:AnyObject]?
let isBody: Bool
let method: String
let URLString: String
required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) {
/// Optional block to obtain a reference to the request's progress instance when available.
public var onProgressReady: ((NSProgress) -> ())?
required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool, headers: [String:String] = [:]) {
self.method = method
self.URLString = URLString
self.parameters = parameters
self.isBody = isBody
self.headers = headers
addHeaders(SwaggerClientAPI.customHeaders)
}

View File

@ -11,9 +11,9 @@ import Alamofire
public class FakeAPI: APIBase {
/**
To test code injection *_/ ' \" =end \\r\\n \\n \\r
To test code injection *_/ ' \" =end -- \\r\\n \\n \\r
- parameter testCodeInjectEndRnNR: (form) To test code injection *_/ &#39; \&quot; &#x3D;end \\r\\n \\n \\r (optional)
- parameter testCodeInjectEndRnNR: (form) To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r (optional)
- parameter completion: completion handler to receive the data and the error objects
*/
public class func testCodeInjectEndRnNR(testCodeInjectEndRnNR testCodeInjectEndRnNR: String? = nil, completion: ((error: ErrorType?) -> Void)) {
@ -24,10 +24,10 @@ public class FakeAPI: APIBase {
/**
To test code injection *_/ ' \" =end \\r\\n \\n \\r
To test code injection *_/ ' \" =end -- \\r\\n \\n \\r
- PUT /fake
- parameter testCodeInjectEndRnNR: (form) To test code injection *_/ &#39; \&quot; &#x3D;end \\r\\n \\n \\r (optional)
- parameter testCodeInjectEndRnNR: (form) To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r (optional)
- returns: RequestBuilder<Void>
*/
@ -36,7 +36,7 @@ public class FakeAPI: APIBase {
let URLString = SwaggerClientAPI.basePath + path
let nillableParameters: [String:AnyObject?] = [
"test code inject */ &#39; &quot; &#x3D;end \r\n \n \r": testCodeInjectEndRnNR
"test code inject */ &#39; &quot; &#x3D;end -- \r\n \n \r": testCodeInjectEndRnNR
]
let parameters = APIHelper.rejectNil(nillableParameters)

View File

@ -12,12 +12,37 @@ class AlamofireRequestBuilderFactory: RequestBuilderFactory {
}
}
public struct SynchronizedDictionary<K: Hashable, V> {
private var dictionary = [K: V]()
private let queue = dispatch_queue_create("SynchronizedDictionary", DISPATCH_QUEUE_CONCURRENT)
public subscript(key: K) -> V? {
get {
var value: V?
dispatch_sync(queue) {
value = self.dictionary[key]
}
return value
}
set {
dispatch_barrier_sync(queue) {
self.dictionary[key] = newValue
}
}
}
}
// Store manager to retain its reference
private var managerStore: [String: Alamofire.Manager] = [:]
private var managerStore = SynchronizedDictionary<String, Alamofire.Manager>()
class AlamofireRequestBuilder<T>: RequestBuilder<T> {
required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool) {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody)
required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool, headers: [String : String] = [:]) {
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers)
}
override func execute(completion: (response: Response<T>?, error: ErrorType?) -> Void) {
@ -57,15 +82,22 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold,
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
self.processRequest(upload, managerId, completion)
case .Success(let uploadRequest, _, _):
if let onProgressReady = self.onProgressReady {
onProgressReady(uploadRequest.progress)
}
self.processRequest(uploadRequest, managerId, completion)
case .Failure(let encodingError):
completion(response: nil, error: encodingError)
completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError))
}
}
)
} else {
processRequest(manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding), managerId, completion)
let request = manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding)
if let onProgressReady = self.onProgressReady {
onProgressReady(request.progress)
}
processRequest(request, managerId, completion)
}
}
@ -75,11 +107,79 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential)
}
request.validate().responseJSON(options: .AllowFragments) { response in
managerStore.removeValueForKey(managerId)
let cleanupRequest = {
managerStore[managerId] = nil
}
let validatedRequest = request.validate()
switch T.self {
case is String.Type:
validatedRequest.responseString(completionHandler: { (stringResponse) in
cleanupRequest()
if stringResponse.result.isFailure {
completion(
response: nil,
error: ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!)
)
return
}
completion(
response: Response(
response: stringResponse.response!,
body: (stringResponse.result.value ?? "") as! T
),
error: nil
)
})
case is Void.Type:
validatedRequest.responseData(completionHandler: { (voidResponse) in
cleanupRequest()
if voidResponse.result.isFailure {
completion(
response: nil,
error: ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
)
return
}
completion(
response: Response(
response: voidResponse.response!,
body: nil
),
error: nil
)
})
case is NSData.Type:
validatedRequest.responseData(completionHandler: { (dataResponse) in
cleanupRequest()
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
)
return
}
completion(
response: Response(
response: dataResponse.response!,
body: dataResponse.data as! T
),
error: nil
)
})
default:
validatedRequest.responseJSON(options: .AllowFragments) { response in
cleanupRequest()
if response.result.isFailure {
completion(response: nil, error: response.result.error)
completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!))
return
}
@ -98,7 +198,8 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
return
}
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])))
}
}
}

View File

@ -58,11 +58,17 @@ extension Dictionary: JSONEncodable {
}
}
extension NSData: JSONEncodable {
func encodeToJSON() -> AnyObject {
return self.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
}
}
private let dateFormatter: NSDateFormatter = {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter
let fmt = NSDateFormatter()
fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX")
return fmt
}()
extension NSDate: JSONEncodable {
@ -71,4 +77,10 @@ extension NSDate: JSONEncodable {
}
}
extension NSUUID: JSONEncodable {
func encodeToJSON() -> AnyObject {
return self.UUIDString
}
}

View File

@ -10,18 +10,22 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject
}
public enum ErrorResponse : ErrorType {
case Error(Int, NSData?, ErrorType)
}
public class Response<T> {
public let statusCode: Int
public let header: [String: String]
public let body: T
public let body: T?
public init(statusCode: Int, header: [String: String], body: T) {
public init(statusCode: Int, header: [String: String], body: T?) {
self.statusCode = statusCode
self.header = header
self.body = body
}
public convenience init(response: NSHTTPURLResponse, body: T) {
public convenience init(response: NSHTTPURLResponse, body: T?) {
let rawHeader = response.allHeaderFields
var header = [String:String]()
for (key, value) in rawHeader {
@ -62,9 +66,15 @@ class Decoders {
if T.self is Int64.Type && source is NSNumber {
return source.longLongValue as! T;
}
if T.self is NSUUID.Type && source is String {
return NSUUID(UUIDString: source as! String) as! T
}
if source is T {
return source as! T
}
if T.self is NSData.Type && source is String {
return NSData(base64EncodedString: source as! String, options: NSDataBase64DecodingOptions()) as! T
}
let key = "\(T.self)"
if let decoder = decoders[key] {
@ -111,6 +121,7 @@ class Decoders {
"yyyy-MM-dd'T'HH:mm:ss.SSS"
].map { (format: String) -> NSDateFormatter in
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier:"en_US_POSIX")
formatter.dateFormat = format
return formatter
}

View File

@ -8,9 +8,9 @@
import Foundation
/** Model for testing reserved words *_/ &#39; \&quot; &#x3D;end \\r\\n \\n \\r */
/** Model for testing reserved words *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r */
public class Return: JSONEncodable {
/** property description *_/ &#39; \&quot; &#x3D;end \\r\\n \\n \\r */
/** property description *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r */
public var _return: Int32?
public init() {}