From 784743082d2296e3e708cf84cf2ce0b0337aa4ef Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 9 Jun 2022 14:56:32 +0300 Subject: [PATCH] feat: add request preprocessor for OpenAPI security requirements --- CHANGELOG.md | 5 ++ LeadKit.podspec | 2 +- TIAppleMapUtils/TIAppleMapUtils.podspec | 2 +- TIAuth/TIAuth.podspec | 2 +- TIFoundationUtils/TIFoundationUtils.podspec | 2 +- TIGoogleMapUtils/TIGoogleMapUtils.podspec | 2 +- TIKeychainUtils/TIKeychainUtils.podspec | 2 +- TIMapUtils/TIMapUtils.podspec | 2 +- .../DefaultJsonNetworkService.swift | 29 +++++-- .../Plugins/AdditionalHeadersPlugin.swift | 19 ----- ...tEndpointSecurityRequestPreprocessor.swift | 76 +++++++++++++++++ ...ltSecuritySchemesRequestPreprocessor.swift | 83 +++++++++++++++++++ .../EndpointRequestPreprocessor.swift | 27 ++++++ .../EndpointSecurityRequestPreprocessor.swift | 29 +++++++ TIMoyaNetworking/TIMoyaNetworking.podspec | 2 +- .../Sources/Request/EndpointRequest.swift | 3 + .../HTTPAuthenticationScheme.swift | 32 +++++++ .../Sources/SpecEntities/OpenAPI.swift | 31 +++++++ .../Sources/SpecEntities/SecurityScheme.swift | 32 +++++++ .../Sources/{ => SpecEntities}/Server.swift | 0 TINetworking/TINetworking.podspec | 2 +- TINetworkingCache/TINetworkingCache.podspec | 2 +- TIPagination/TIPagination.podspec | 2 +- TISwiftUICore/TISwiftUICore.podspec | 2 +- TISwiftUtils/TISwiftUtils.podspec | 2 +- TITableKitUtils/TITableKitUtils.podspec | 2 +- TITransitions/TITransitions.podspec | 2 +- TIUIElements/TIUIElements.podspec | 2 +- TIUIKitCore/TIUIKitCore.podspec | 2 +- TIYandexMapUtils/TIYandexMapUtils.podspec | 2 +- 30 files changed, 359 insertions(+), 43 deletions(-) delete mode 100644 TIMoyaNetworking/Sources/NetworkService/Plugins/AdditionalHeadersPlugin.swift create mode 100644 TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultEndpointSecurityRequestPreprocessor.swift create mode 100644 TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultSecuritySchemesRequestPreprocessor.swift create mode 100644 TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointRequestPreprocessor.swift create mode 100644 TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointSecurityRequestPreprocessor.swift create mode 100644 TINetworking/Sources/SpecEntities/HTTPAuthenticationScheme.swift create mode 100644 TINetworking/Sources/SpecEntities/OpenAPI.swift create mode 100644 TINetworking/Sources/SpecEntities/SecurityScheme.swift rename TINetworking/Sources/{ => SpecEntities}/Server.swift (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98b84531..3bf888ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +### 1.20.0 + +- **Add**: OpenAPI security schemes support for EndpointRequest's. +- **Update**: Replace `AdditionalHeadersPlugin` with `SecuritySchemePreprocessor` and `EndpointRequestPreprocessor` (with default implementations) + ### 1.19.0 - **Add**: Add presenter protocols to `TISwiftUICore` and `TIUIKitCore` modules diff --git a/LeadKit.podspec b/LeadKit.podspec index 39d4ae97..6b04d07f 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "1.19.0" + s.version = "1.20.0" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/TIAppleMapUtils/TIAppleMapUtils.podspec b/TIAppleMapUtils/TIAppleMapUtils.podspec index 4a1ecd33..ae4d5a2b 100644 --- a/TIAppleMapUtils/TIAppleMapUtils.podspec +++ b/TIAppleMapUtils/TIAppleMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIAppleMapUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for map objects clustering and interacting using Apple MapKit.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIAuth/TIAuth.podspec b/TIAuth/TIAuth.podspec index 74df774f..75f5eaa0 100644 --- a/TIAuth/TIAuth.podspec +++ b/TIAuth/TIAuth.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIAuth' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Login, registration, confirmation and other related actions' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec index 073f1d77..981fe47d 100644 --- a/TIFoundationUtils/TIFoundationUtils.podspec +++ b/TIFoundationUtils/TIFoundationUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIFoundationUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for Foundation framework classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIGoogleMapUtils/TIGoogleMapUtils.podspec b/TIGoogleMapUtils/TIGoogleMapUtils.podspec index b0f14e84..d927a348 100644 --- a/TIGoogleMapUtils/TIGoogleMapUtils.podspec +++ b/TIGoogleMapUtils/TIGoogleMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIGoogleMapUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for map objects clustering and interacting using Google Maps SDK.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec index 07aec6a0..73c1d651 100644 --- a/TIKeychainUtils/TIKeychainUtils.podspec +++ b/TIKeychainUtils/TIKeychainUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIKeychainUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for Keychain classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIMapUtils/TIMapUtils.podspec b/TIMapUtils/TIMapUtils.podspec index 10e48856..56a31464 100644 --- a/TIMapUtils/TIMapUtils.podspec +++ b/TIMapUtils/TIMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIMapUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for map objects clustering and interacting.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift b/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift index a0336ea0..2ebfa489 100644 --- a/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift +++ b/TIMoyaNetworking/Sources/NetworkService/DefaultJsonNetworkService.swift @@ -41,18 +41,20 @@ open class DefaultJsonNetworkService { public var jsonDecoder: JSONDecoder public var jsonEncoder: JSONEncoder - public var defaultServer: Server + public var openApi: OpenAPI public var plugins: [PluginType] = [] + public var preprocessors: [EndpointRequestPreprocessor] = [] + public init(session: Session, jsonCodingConfigurator: JsonCodingConfigurator, - defaultServer: Server) { + openApi: OpenAPI) { self.session = session self.jsonDecoder = jsonCodingConfigurator.jsonDecoder self.jsonEncoder = jsonCodingConfigurator.jsonEncoder - self.defaultServer = defaultServer + self.openApi = openApi } open func createProvider() -> MoyaProvider { @@ -63,7 +65,7 @@ open class DefaultJsonNetworkService { open func serialize(request: EndpointRequest) throws -> SerializedRequest { try request.serialize(using: ApplicationJsonBodySerializer(jsonEncoder: jsonEncoder), - defaultServer: defaultServer) + defaultServer: openApi.defaultServer) } @available(iOS 13.0.0, *) @@ -104,14 +106,18 @@ open class DefaultJsonNetworkService { mapMoyaError: @escaping Closure, completion: @escaping ParameterClosure) -> Cancellable { - ScopeCancellable { [serializationQueue, callbackQueue] scope in + ScopeCancellable { [serializationQueue, callbackQueue, preprocessors] scope in let workItem = DispatchWorkItem { guard !scope.isCancelled else { return } do { - let serializedRequest = try self.serialize(request: request) + let preprocessedRequest = try preprocessors.reduce(request) { + try $1.preprocess(request: $0) + } + + let serializedRequest = try self.serialize(request: preprocessedRequest) scope.add(cancellable: self.process(request: serializedRequest, mapSuccess: mapSuccess, @@ -195,4 +201,15 @@ open class DefaultJsonNetworkService { } } } + + public func register(securityPreprocessors: [T: SecuritySchemePreprocessor]) where T.RawValue == String { + let schemePreprocessors = Dictionary(uniqueKeysWithValues: securityPreprocessors.map { + ($0.key.rawValue, $0.value) + }) + + let securityPreprocessor = DefaultEndpointSecurityPreprocessor(openApi: openApi, + schemePreprocessors: schemePreprocessors) + + preprocessors.append(securityPreprocessor) + } } diff --git a/TIMoyaNetworking/Sources/NetworkService/Plugins/AdditionalHeadersPlugin.swift b/TIMoyaNetworking/Sources/NetworkService/Plugins/AdditionalHeadersPlugin.swift deleted file mode 100644 index 5aa45f76..00000000 --- a/TIMoyaNetworking/Sources/NetworkService/Plugins/AdditionalHeadersPlugin.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Moya -import Alamofire -import Foundation - -public protocol AdditionalHeadersPlugin: PluginType { - var additionalHeaders: HTTPHeaders { get } -} - -public extension AdditionalHeadersPlugin { - func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { - var modifiedRequest = request - - for header in additionalHeaders { - modifiedRequest.addValue(header.value, forHTTPHeaderField: header.name) - } - - return modifiedRequest - } -} diff --git a/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultEndpointSecurityRequestPreprocessor.swift b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultEndpointSecurityRequestPreprocessor.swift new file mode 100644 index 00000000..ddacee28 --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultEndpointSecurityRequestPreprocessor.swift @@ -0,0 +1,76 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import TINetworking + +open class DefaultSecuritySchemePreprocessor: SecuritySchemePreprocessor { + struct ValueNotProvidedError: Error {} + + public typealias ValueProvider = () -> String? + + private let valueProvider: ValueProvider + + public init(valueProvider: @escaping ValueProvider) { + self.valueProvider = valueProvider + } + + public init(staticValue: String?) { + self.valueProvider = { staticValue } + } + + // MARK: - EndpointSecurityRequestPreprocessor + + public func preprocess(request: EndpointRequest, using security: SecurityScheme) throws -> EndpointRequest { + var modifiedRequest = request + + guard let value = valueProvider() else { + throw ValueNotProvidedError() + } + + switch security { + case let .http(authenticationScheme): + let headerValue = "\(authenticationScheme.rawValue) \(value)" + var headerParameters = modifiedRequest.headerParameters ?? [:] + headerParameters.updateValue(.init(value: headerValue), + forKey: "Authorization") + + modifiedRequest.headerParameters = headerParameters + case let .apiKey(parameterLocation, parameterName): + switch parameterLocation { + case .header: + var headerParameters = modifiedRequest.headerParameters ?? [:] + headerParameters.updateValue(.init(value: value), + forKey: parameterName) + + modifiedRequest.headerParameters = headerParameters + case .query: + modifiedRequest.queryParameters.updateValue(.init(value: value), + forKey: parameterName) + case .cookie: + modifiedRequest.cookieParameters.updateValue(.init(value: value), + forKey: parameterName) + } + } + + return modifiedRequest + } +} diff --git a/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultSecuritySchemesRequestPreprocessor.swift b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultSecuritySchemesRequestPreprocessor.swift new file mode 100644 index 00000000..66290349 --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/DefaultSecuritySchemesRequestPreprocessor.swift @@ -0,0 +1,83 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import TINetworking + +open class DefaultEndpointSecurityPreprocessor: EndpointRequestPreprocessor { + enum PreprocessError: Error { + case missingSecurityScheme(String, [String: SecurityScheme]) + case unableToSatisfyRequirements(anyOfRequired: [[String]], + registeredPreprocessors: [String: SecuritySchemePreprocessor]) + } + + private let openApi: OpenAPI + + private var schemePreprocessors: [String: SecuritySchemePreprocessor] + + public init(openApi: OpenAPI, schemePreprocessors: [String: SecuritySchemePreprocessor] = [:]) { + self.openApi = openApi + self.schemePreprocessors = schemePreprocessors + } + + public func preprocess(request: EndpointRequest) throws -> EndpointRequest { + guard !request.security.compactMap({ $0 }).isEmpty else { + return request + } + + let endpointSchemes: [[KeyValueTuple]] = try request.security.map { + try $0.map { + guard let securityScheme = openApi.security[$0] else { + throw PreprocessError.missingSecurityScheme($0, openApi.security) + } + + return ($0, securityScheme) + } + } + + for schemeGroup in endpointSchemes { + let preprocessorsGroup: [KeyValueTuple] = schemeGroup.compactMap { + guard let preprocessor = schemePreprocessors[$0.key] else { + return nil + } + + return ($0.value, preprocessor) + } + + guard preprocessorsGroup.count == schemeGroup.count else { + continue // unable to satisfy group requirement + } + + do { + return try preprocessorsGroup.reduce(request) { + try $1.value.preprocess(request: $0, using: $1.key) + } + } + } + + throw PreprocessError.unableToSatisfyRequirements(anyOfRequired: request.security, + registeredPreprocessors: schemePreprocessors) + } + + public func register(preprocessor: SecuritySchemePreprocessor, for scheme: String) { + schemePreprocessors[scheme] = preprocessor + } +} diff --git a/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointRequestPreprocessor.swift b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointRequestPreprocessor.swift new file mode 100644 index 00000000..af190a50 --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointRequestPreprocessor.swift @@ -0,0 +1,27 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import TINetworking + +public protocol EndpointRequestPreprocessor { + func preprocess(request: EndpointRequest) throws -> EndpointRequest +} diff --git a/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointSecurityRequestPreprocessor.swift b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointSecurityRequestPreprocessor.swift new file mode 100644 index 00000000..8fcc1965 --- /dev/null +++ b/TIMoyaNetworking/Sources/NetworkService/Plugins/RequestPreprocessors/EndpointSecurityRequestPreprocessor.swift @@ -0,0 +1,29 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import TINetworking + +public protocol SecuritySchemePreprocessor { + func preprocess(request: EndpointRequest, using security: SecurityScheme) throws -> EndpointRequest +} + + diff --git a/TIMoyaNetworking/TIMoyaNetworking.podspec b/TIMoyaNetworking/TIMoyaNetworking.podspec index 7e8f09f2..9b427432 100644 --- a/TIMoyaNetworking/TIMoyaNetworking.podspec +++ b/TIMoyaNetworking/TIMoyaNetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIMoyaNetworking' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Moya + Swagger network service.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworking/Sources/Request/EndpointRequest.swift b/TINetworking/Sources/Request/EndpointRequest.swift index 99e2971d..6edbe303 100644 --- a/TINetworking/Sources/Request/EndpointRequest.swift +++ b/TINetworking/Sources/Request/EndpointRequest.swift @@ -31,6 +31,7 @@ public struct EndpointRequest { public var headerParameters: [String: Parameter]? public var cookieParameters: [String: Parameter] public var acceptableStatusCodes: Set + public var security: [[String]] public var server: Server? public var customServerVariables: [KeyValueTuple] @@ -42,6 +43,7 @@ public struct EndpointRequest { headerParameters: [String: Parameter]? = nil, cookieParameters: [String: Parameter] = [:], acceptableStatusCodes: Set = HTTPCodes.success.asSet(), + security: [[String]] = [], server: Server? = nil, customServerVariables: [KeyValueTuple] = []) { @@ -55,5 +57,6 @@ public struct EndpointRequest { self.acceptableStatusCodes = acceptableStatusCodes self.server = server self.customServerVariables = customServerVariables + self.security = security } } diff --git a/TINetworking/Sources/SpecEntities/HTTPAuthenticationScheme.swift b/TINetworking/Sources/SpecEntities/HTTPAuthenticationScheme.swift new file mode 100644 index 00000000..16bf0028 --- /dev/null +++ b/TINetworking/Sources/SpecEntities/HTTPAuthenticationScheme.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public struct HTTPAuthenticationScheme: RawRepresentable, Equatable, Hashable { + public static let basic = HTTPAuthenticationScheme(rawValue: "Basic") + public static let bearer = HTTPAuthenticationScheme(rawValue: "Bearer") + + public let rawValue: String + + public init(rawValue: String) { + self.rawValue = rawValue + } +} diff --git a/TINetworking/Sources/SpecEntities/OpenAPI.swift b/TINetworking/Sources/SpecEntities/OpenAPI.swift new file mode 100644 index 00000000..212c1f9a --- /dev/null +++ b/TINetworking/Sources/SpecEntities/OpenAPI.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public struct OpenAPI { + public let defaultServer: Server + public let security: [String: SecurityScheme] + + public init(defaultServer: Server, security: [String: SecurityScheme]) { + self.defaultServer = defaultServer + self.security = security + } +} diff --git a/TINetworking/Sources/SpecEntities/SecurityScheme.swift b/TINetworking/Sources/SpecEntities/SecurityScheme.swift new file mode 100644 index 00000000..b1f0c7a1 --- /dev/null +++ b/TINetworking/Sources/SpecEntities/SecurityScheme.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public enum SecurityScheme { + public enum ParameterLocation { + case header + case query + case cookie + } + + case http(HTTPAuthenticationScheme) + case apiKey(ParameterLocation, parameterName: String) +} diff --git a/TINetworking/Sources/Server.swift b/TINetworking/Sources/SpecEntities/Server.swift similarity index 100% rename from TINetworking/Sources/Server.swift rename to TINetworking/Sources/SpecEntities/Server.swift diff --git a/TINetworking/TINetworking.podspec b/TINetworking/TINetworking.podspec index 79ca472c..b404d0d1 100644 --- a/TINetworking/TINetworking.podspec +++ b/TINetworking/TINetworking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TINetworking' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Swagger-frendly networking layer helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TINetworkingCache/TINetworkingCache.podspec b/TINetworkingCache/TINetworkingCache.podspec index 4c9b9fb6..aa7c649f 100644 --- a/TINetworkingCache/TINetworkingCache.podspec +++ b/TINetworkingCache/TINetworkingCache.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TINetworkingCache' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Caching results of EndpointRequests.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIPagination/TIPagination.podspec b/TIPagination/TIPagination.podspec index 9b9e3e94..286e29b3 100644 --- a/TIPagination/TIPagination.podspec +++ b/TIPagination/TIPagination.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIPagination' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Generic pagination component.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TISwiftUICore/TISwiftUICore.podspec b/TISwiftUICore/TISwiftUICore.podspec index 4fd2f120..3c858af2 100644 --- a/TISwiftUICore/TISwiftUICore.podspec +++ b/TISwiftUICore/TISwiftUICore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUICore' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Core UI elements: protocols, views and helpers..' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec index 8302bf30..2c3d9099 100644 --- a/TISwiftUtils/TISwiftUtils.podspec +++ b/TISwiftUtils/TISwiftUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TISwiftUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Bunch of useful helpers for Swift development.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec index 3030291c..d3445cf2 100644 --- a/TITableKitUtils/TITableKitUtils.podspec +++ b/TITableKitUtils/TITableKitUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITableKitUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for TableKit classes.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec index 6766926a..cf3ad8f5 100644 --- a/TITransitions/TITransitions.podspec +++ b/TITransitions/TITransitions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TITransitions' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of custom transitions to present controller. ' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec index 0c928223..bb3f97ef 100644 --- a/TIUIElements/TIUIElements.podspec +++ b/TIUIElements/TIUIElements.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIElements' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Bunch of useful protocols and views.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec index 4a16d06e..017d9b52 100644 --- a/TIUIKitCore/TIUIKitCore.podspec +++ b/TIUIKitCore/TIUIKitCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIUIKitCore' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Core UI elements: protocols, views and helpers.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' } diff --git a/TIYandexMapUtils/TIYandexMapUtils.podspec b/TIYandexMapUtils/TIYandexMapUtils.podspec index ab16c2d4..523ca586 100644 --- a/TIYandexMapUtils/TIYandexMapUtils.podspec +++ b/TIYandexMapUtils/TIYandexMapUtils.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'TIYandexMapUtils' - s.version = '1.19.0' + s.version = '1.20.0' s.summary = 'Set of helpers for map objects clustering and interacting using Yandex Maps SDK.' s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name s.license = { :type => 'MIT', :file => 'LICENSE' }