From a6820f670df01938ec0ea02e0523d15e3ef13f3b Mon Sep 17 00:00:00 2001 From: SiddharthMurugaiyan Date: Tue, 24 Sep 2019 12:31:52 +0530 Subject: [PATCH 1/8] Update OAuth2Module.swift support for swift 5 --- AeroGearOAuth2/OAuth2Module.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AeroGearOAuth2/OAuth2Module.swift b/AeroGearOAuth2/OAuth2Module.swift index 469050b..fb15ad5 100644 --- a/AeroGearOAuth2/OAuth2Module.swift +++ b/AeroGearOAuth2/OAuth2Module.swift @@ -358,7 +358,7 @@ open class OAuth2Module: AuthzModule { func extractCode(_ notification: Notification, completionHandler: @escaping (AnyObject?, NSError?) -> Void) { let info = notification.userInfo! - let url: URL? = info[UIApplicationLaunchOptionsKey.url] as? URL + let url: URL? = info[UIApplication.LaunchOptionsKey.url] as? URL // extract the code from the URL let queryParamsDict = self.parametersFrom(queryString: url?.query) From 362690e97ca787d6153fc5e243273d78ed00fdbe Mon Sep 17 00:00:00 2001 From: Siddharth Date: Tue, 24 Sep 2019 13:06:35 +0530 Subject: [PATCH 2/8] Commit for supporting swift 5 version --- AeroGearOAuth2.xcodeproj/project.pbxproj | 5 +++-- AeroGearOAuth2/OAuth2Module.swift | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/AeroGearOAuth2.xcodeproj/project.pbxproj b/AeroGearOAuth2.xcodeproj/project.pbxproj index 4987dad..99540ae 100644 --- a/AeroGearOAuth2.xcodeproj/project.pbxproj +++ b/AeroGearOAuth2.xcodeproj/project.pbxproj @@ -298,6 +298,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 4833045819AF1635002F8DA9; @@ -594,7 +595,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -616,7 +617,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/AeroGearOAuth2/OAuth2Module.swift b/AeroGearOAuth2/OAuth2Module.swift index 469050b..fb15ad5 100644 --- a/AeroGearOAuth2/OAuth2Module.swift +++ b/AeroGearOAuth2/OAuth2Module.swift @@ -358,7 +358,7 @@ open class OAuth2Module: AuthzModule { func extractCode(_ notification: Notification, completionHandler: @escaping (AnyObject?, NSError?) -> Void) { let info = notification.userInfo! - let url: URL? = info[UIApplicationLaunchOptionsKey.url] as? URL + let url: URL? = info[UIApplication.LaunchOptionsKey.url] as? URL // extract the code from the URL let queryParamsDict = self.parametersFrom(queryString: url?.query) From 5b3d19122b55d95ad9e1764fe1270a88ad6de400 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Wed, 15 Apr 2020 15:53:30 +0530 Subject: [PATCH 3/8] Commit for changing webview to wkwebview --- AeroGearOAuth2/Config.swift | 14 +++++++------- AeroGearOAuth2/OAuth2WebViewController.swift | 11 +++++++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/AeroGearOAuth2/Config.swift b/AeroGearOAuth2/Config.swift index 3a3fdcc..6557a9f 100644 --- a/AeroGearOAuth2/Config.swift +++ b/AeroGearOAuth2/Config.swift @@ -24,12 +24,12 @@ open class Config { /** Applies the baseURL to the configuration. */ - open let baseURL: String + public let baseURL: String /** Applies the "callback URL" once request token issued. */ - open let redirectURL: String + public let redirectURL: String /** Applies the "authorization endpoint" to the request token. @@ -44,17 +44,17 @@ open class Config { /** Endpoint for request to invalidate both accessToken and refreshToken. */ - open let revokeTokenEndpoint: String? + public let revokeTokenEndpoint: String? /** Endpoint for request a refreshToken. */ - open let refreshTokenEndpoint: String? + public let refreshTokenEndpoint: String? /** Endpoint for OpenID Connect to get user information. */ - open let userInfoEndpoint: String? + public let userInfoEndpoint: String? /** Boolean to indicate whether OpenID Connect on authorization code grant flow is used. @@ -84,12 +84,12 @@ open class Config { /** Applies the "client id" obtained with the client registration process. */ - open let clientId: String + public let clientId: String /** Applies the "client secret" obtained with the client registration process. */ - open let clientSecret: String? + public let clientSecret: String? /** Applies the "audience" obtained with the client registration process. diff --git a/AeroGearOAuth2/OAuth2WebViewController.swift b/AeroGearOAuth2/OAuth2WebViewController.swift index 81c0ad9..c844837 100644 --- a/AeroGearOAuth2/OAuth2WebViewController.swift +++ b/AeroGearOAuth2/OAuth2WebViewController.swift @@ -18,21 +18,24 @@ import Foundation import UIKit +import WebKit + /** OAuth2WebViewController is a UIViewController to be used when the Oauth2 flow used an embedded view controller rather than an external browser approach. */ -open class OAuth2WebViewController: UIViewController, UIWebViewDelegate { +open class OAuth2WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { /// Login URL for OAuth. var targetURL: URL! /// WebView instance used to load login page. - var webView: UIWebView = UIWebView() + var webView: WKWebView = WKWebView() /// Override of viewDidLoad to load the login page. override open func viewDidLoad() { super.viewDidLoad() webView.frame = UIScreen.main.bounds - webView.delegate = self + webView.navigationDelegate = self + webView.uiDelegate = self self.view.addSubview(webView) loadAddressURL() } @@ -48,6 +51,6 @@ open class OAuth2WebViewController: UIViewController, UIWebViewDelegate { func loadAddressURL() { let req = URLRequest(url: targetURL) - webView.loadRequest(req) + webView.load(req) } } From 309c493c7a9116e30942b13e87d8d11ea6969a77 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Wed, 15 Apr 2020 16:05:25 +0530 Subject: [PATCH 4/8] POD spec changes --- AeroGearOAuth2.xcodeproj/project.pbxproj | 38 ++---------------------- Podfile.lock | 7 ++++- 2 files changed, 8 insertions(+), 37 deletions(-) diff --git a/AeroGearOAuth2.xcodeproj/project.pbxproj b/AeroGearOAuth2.xcodeproj/project.pbxproj index 99540ae..fd49682 100644 --- a/AeroGearOAuth2.xcodeproj/project.pbxproj +++ b/AeroGearOAuth2.xcodeproj/project.pbxproj @@ -240,7 +240,6 @@ 4833045E19AF1635002F8DA9 /* Frameworks */, 4833045F19AF1635002F8DA9 /* Headers */, 4833046019AF1635002F8DA9 /* Resources */, - 7BA5AFF5C6DA9134893CDFC3 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -261,7 +260,6 @@ 4833046B19AF1635002F8DA9 /* Resources */, 6F1432B31A16857C003BEE5B /* Copy Frameworks */, 81DD998A611C4EAF191D8BE0 /* [CP] Embed Pods Frameworks */, - 8C9D4DEB6C7183EC37B53099 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -348,54 +346,22 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 7BA5AFF5C6DA9134893CDFC3 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AeroGearOAuth2/Pods-AeroGearOAuth2-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 81DD998A611C4EAF191D8BE0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-AeroGearOAuth2Tests/Pods-AeroGearOAuth2Tests-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-AeroGearOAuth2Tests/Pods-AeroGearOAuth2Tests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/OHHTTPStubs/OHHTTPStubs.framework", - "${BUILT_PRODUCTS_DIR}/AeroGearHttp/AeroGearHttp.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OHHTTPStubs.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AeroGearHttp.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AeroGearOAuth2Tests/Pods-AeroGearOAuth2Tests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 8C9D4DEB6C7183EC37B53099 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AeroGearOAuth2Tests/Pods-AeroGearOAuth2Tests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AeroGearOAuth2Tests/Pods-AeroGearOAuth2Tests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FE44ED274111AE8BBB6AE3E2 /* [CP] Check Pods Manifest.lock */ = { diff --git a/Podfile.lock b/Podfile.lock index bb0da8c..29b0d86 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -18,10 +18,15 @@ DEPENDENCIES: - AeroGearHttp (= 2.0.0) - OHHTTPStubs (= 5.2.2) +SPEC REPOS: + https://github.com/CocoaPods/Specs.git: + - AeroGearHttp + - OHHTTPStubs + SPEC CHECKSUMS: AeroGearHttp: 65bf374aefd3521e1d8d33547e4db96047b745aa OHHTTPStubs: 34d9d0994e64fcf8552dbfade5ce82ada913ee31 PODFILE CHECKSUM: 7b302d89355d58023f6fc008e933fbcf534556a8 -COCOAPODS: 1.3.1 +COCOAPODS: 1.9.1 From b87d8bc86c816a01a44428a80949f283604ccd30 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Thu, 16 Apr 2020 12:36:17 +0530 Subject: [PATCH 5/8] commit for changing UIwebview to WKwebview --- AeroGearOAuth2/AccountManager.swift | 5 +- AeroGearOAuth2/OAuth2Module.swift | 26 +++++--- AeroGearOAuth2/OAuth2WebViewController.swift | 70 ++++++++++++++++++-- 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/AeroGearOAuth2/AccountManager.swift b/AeroGearOAuth2/AccountManager.swift index ccf95d0..af67ff9 100644 --- a/AeroGearOAuth2/AccountManager.swift +++ b/AeroGearOAuth2/AccountManager.swift @@ -95,14 +95,15 @@ open class KeycloakConfig: Config { :param: realm to identify which realm to use. A realm group a set of application/OAuth2 client together. :param: isOpenIDConnect to identify if fetching id information is required. */ - public init(clientId: String, host: String, realm: String? = nil, isOpenIDConnect: Bool = false) { + public init(clientId: String, host: String, realm: String? = nil, isOpenIDConnect: Bool = false, redirectUrl: String? = nil) { let bundleString = Bundle.main.bundleIdentifier ?? "keycloak" let defaulRealmName = String(format: "%@-realm", clientId) let realm = realm ?? defaulRealmName + let redirectUrl = redirectUrl ?? "\(bundleString)://oauth2Callback" super.init( base: "\(host)/auth", authzEndpoint: "realms/\(realm)/protocol/openid-connect/auth", - redirectURL: "\(bundleString)://oauth2Callback", + redirectURL: redirectUrl, accessTokenEndpoint: "realms/\(realm)/protocol/openid-connect/token", clientId: clientId, refreshTokenEndpoint: "realms/\(realm)/protocol/openid-connect/token", diff --git a/AeroGearOAuth2/OAuth2Module.swift b/AeroGearOAuth2/OAuth2Module.swift index fb15ad5..4c23c98 100644 --- a/AeroGearOAuth2/OAuth2Module.swift +++ b/AeroGearOAuth2/OAuth2Module.swift @@ -356,13 +356,7 @@ open class OAuth2Module: AuthzModule { // MARK: Internal Methods - func extractCode(_ notification: Notification, completionHandler: @escaping (AnyObject?, NSError?) -> Void) { - let info = notification.userInfo! - let url: URL? = info[UIApplication.LaunchOptionsKey.url] as? URL - - // extract the code from the URL - let queryParamsDict = self.parametersFrom(queryString: url?.query) - let code = queryParamsDict["code"] + fileprivate func extractCodeFromQuery(_ code: String?, _ completionHandler: @escaping (AnyObject?, NSError?) -> Void, _ queryParamsDict: [String : String]) { // if exists perform the exchange if (code != nil) { self.exchangeAuthorizationCodeForAccessToken(code: code!, completionHandler: completionHandler) @@ -374,10 +368,24 @@ open class OAuth2Module: AuthzModule { completionHandler(nil, error) return } - + let errorDescription = queryParamsDict["error_description"] ?? "There was an error!" let error = NSError(domain: AGAuthzErrorDomain, code: 1, userInfo: ["error": errorName, "errorDescription": errorDescription]) - + + completionHandler(nil, error) + } + } + + func extractCode(_ notification: Notification, completionHandler: @escaping (AnyObject?, NSError?) -> Void) { + let info = notification.userInfo! + if let url = info[UIApplication.LaunchOptionsKey.url] as? URL { + //let url: URL? = info[UIApplication.LaunchOptionsKey.url] as? URL + // extract the code from the URL + let queryParamsDict = self.parametersFrom(queryString: url.query) + let code = queryParamsDict["code"] + extractCodeFromQuery(code, completionHandler, queryParamsDict) + } else { + let error = NSError(domain: AGAuthzErrorDomain, code: 1, userInfo: ["error": "Url Failed", "errorDescription": "error in fetching code"]) completionHandler(nil, error) } // finally, unregister diff --git a/AeroGearOAuth2/OAuth2WebViewController.swift b/AeroGearOAuth2/OAuth2WebViewController.swift index c844837..e1e71f5 100644 --- a/AeroGearOAuth2/OAuth2WebViewController.swift +++ b/AeroGearOAuth2/OAuth2WebViewController.swift @@ -24,21 +24,25 @@ import WebKit OAuth2WebViewController is a UIViewController to be used when the Oauth2 flow used an embedded view controller rather than an external browser approach. */ -open class OAuth2WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { +open class OAuth2WebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate { /// Login URL for OAuth. var targetURL: URL! /// WebView instance used to load login page. var webView: WKWebView = WKWebView() + let SESSION_STATE: String = "session_state" + let CODE: String = "code" /// Override of viewDidLoad to load the login page. override open func viewDidLoad() { super.viewDidLoad() - webView.frame = UIScreen.main.bounds - webView.navigationDelegate = self - webView.uiDelegate = self - self.view.addSubview(webView) + intializeWKWebview() loadAddressURL() } + + override open func viewWillDisappear(_ animated: Bool) { + webView.cleanAllCookies() + webView.refreshCookies() + } override open func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() @@ -48,9 +52,65 @@ open class OAuth2WebViewController: UIViewController, WKNavigationDelegate, WKUI override open func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } + + fileprivate func intializeWKWebview() { + webView.frame = UIScreen.main.bounds + webView.navigationDelegate = self + let contentController = WKUserContentController() + //Script to disable zoomin and zoomout in webview + let source: String = "var meta = document.createElement('meta');" + + "meta.name = 'viewport';" + + "meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no';" + + "var head = document.getElementsByTagName('head')[0];" + + "head.appendChild(meta);" + let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: true) + contentController.addUserScript(script) + let config = WKWebViewConfiguration() + config.userContentController = contentController + webView = WKWebView(frame: .zero, configuration: config ) + webView.scrollView.delegate = self + webView.sizeToFit() + webView.navigationDelegate = self + webView.uiDelegate = self + view = webView + } func loadAddressURL() { let req = URLRequest(url: targetURL) webView.load(req) } + + /** + WKWebview delegate methods + */ + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping ((WKNavigationActionPolicy) -> Void)) { + if let url = navigationAction.request.url?.absoluteString { + if url.contains(SESSION_STATE) && url.contains(CODE) { + if let urlReq = URL(string: url) { + let notification = Notification(name: Notification.Name(AGAppLaunchedWithURLNotification), object: nil, userInfo: [UIApplication.LaunchOptionsKey.url: urlReq]) + NotificationCenter.default.post(notification) + } + decisionHandler(.cancel) + } else { + decisionHandler(.allow) + } + } + } + public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation?) { + + } } +extension WKWebView { + func cleanAllCookies() { + HTTPCookieStorage.shared.removeCookies(since: Date.distantPast) + WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in + records.forEach { record in + WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {}) + } + } + } + func refreshCookies() { + self.configuration.processPool = WKProcessPool() + } +} + From 7667df7ff9f5861c7cd0eec12e79cabe0e674d8f Mon Sep 17 00:00:00 2001 From: Siddharth Date: Tue, 21 Apr 2020 10:37:09 +0530 Subject: [PATCH 6/8] commit for showing the login page in fullscreen --- AeroGearOAuth2/Config.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/AeroGearOAuth2/Config.swift b/AeroGearOAuth2/Config.swift index 6557a9f..4cab9d6 100644 --- a/AeroGearOAuth2/Config.swift +++ b/AeroGearOAuth2/Config.swift @@ -121,6 +121,7 @@ open class Config { */ open var webViewHandler: ((UIViewController, _ completionHandler: (AnyObject?, NSError?) -> Void) -> ()) = { (webView, completionHandler) in + webView.modalPresentationStyle = .fullScreen UIApplication.shared.keyWindow?.rootViewController?.present(webView, animated: true, completion: nil) } From 8ec635644c65d7b06835e9c17d35ed4fae00f366 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Fri, 22 Jan 2021 17:57:13 +0530 Subject: [PATCH 7/8] Commit for removing .get to add headers in request --- Podfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Podfile b/Podfile index acfba41..ce49f6d 100644 --- a/Podfile +++ b/Podfile @@ -5,7 +5,8 @@ platform :ios, '9.0' use_frameworks! target 'AeroGearOAuth2' do - pod 'AeroGearHttp', '2.0.0' + #pod 'AeroGearHttp', '2.0.0' + pod 'AeroGearHttp', :git => 'https://github.com/SiddharthMurugaiyan/aerogear-ios-http.git' target 'AeroGearOAuth2Tests' do inherit! :search_paths From 512487c4e4ede29f7a2b760aead9724d585a2ef8 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Fri, 22 Jan 2021 18:05:45 +0530 Subject: [PATCH 8/8] commit for changing the pod file ti support header in get method --- Podfile.lock | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 29b0d86..d544ac1 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -15,18 +15,26 @@ PODS: - OHHTTPStubs/OHPathHelpers (5.2.2) DEPENDENCIES: - - AeroGearHttp (= 2.0.0) + - AeroGearHttp (from `https://github.com/SiddharthMurugaiyan/aerogear-ios-http.git`) - OHHTTPStubs (= 5.2.2) SPEC REPOS: https://github.com/CocoaPods/Specs.git: - - AeroGearHttp - OHHTTPStubs +EXTERNAL SOURCES: + AeroGearHttp: + :git: https://github.com/SiddharthMurugaiyan/aerogear-ios-http.git + +CHECKOUT OPTIONS: + AeroGearHttp: + :commit: 75fcb49ed92eb81dedcf7a007ebb5d49c8d6cb66 + :git: https://github.com/SiddharthMurugaiyan/aerogear-ios-http.git + SPEC CHECKSUMS: - AeroGearHttp: 65bf374aefd3521e1d8d33547e4db96047b745aa + AeroGearHttp: ef1cdf2d14ba52bb927c42e6de6ccc26db9adf98 OHHTTPStubs: 34d9d0994e64fcf8552dbfade5ce82ada913ee31 -PODFILE CHECKSUM: 7b302d89355d58023f6fc008e933fbcf534556a8 +PODFILE CHECKSUM: e217247915055a5df60ec7c79ba313e6823f85d2 COCOAPODS: 1.9.1