Repository: cordova-ios
Updated Branches:
  refs/heads/master f99e0be24 -> 6cc86efbb


CB-10942 - Cannot <allow-navigation href="https://foo.bar"; /> for links in that 
site, if you have <allow-intent href="https://*"; />


Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/6cc86efb
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/6cc86efb
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/6cc86efb

Branch: refs/heads/master
Commit: 6cc86efbb17f59f2a9626b0867406be697fd47ab
Parents: f99e0be
Author: Shazron Abdullah <[email protected]>
Authored: Wed Mar 23 18:45:04 2016 -0700
Committer: Shazron Abdullah <[email protected]>
Committed: Mon Apr 4 17:45:46 2016 -0700

----------------------------------------------------------------------
 .../CDVIntentAndNavigationFilter.h              |  9 +++
 .../CDVIntentAndNavigationFilter.m              | 65 ++++++++++++--------
 tests/CordovaLibTests/CDVWhitelistTests.m       | 18 ++++++
 3 files changed, 67 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/6cc86efb/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h
----------------------------------------------------------------------
diff --git 
a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h
 
b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h
index 7f18c59..9a2ef80 100644
--- 
a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h
+++ 
b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.h
@@ -18,7 +18,16 @@
  */
 
 #import "CDVPlugin.h"
+#import "CDVWhitelist.h"
+
+typedef NS_ENUM(NSInteger, CDVIntentAndNavigationFilterValue) {
+    CDVIntentAndNavigationFilterValueIntentAllowed,
+    CDVIntentAndNavigationFilterValueNavigationAllowed,
+    CDVIntentAndNavigationFilterValueNoneAllowed
+};
 
 @interface CDVIntentAndNavigationFilter : CDVPlugin <NSXMLParserDelegate>
 
++ (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url 
intentsWhitelist:(CDVWhitelist*)intentsWhitelist 
navigationsWhitelist:(CDVWhitelist*)navigationsWhitelist;
+
 @end

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/6cc86efb/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m
----------------------------------------------------------------------
diff --git 
a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m
 
b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m
index 365db3f..a7e2fe3 100644
--- 
a/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m
+++ 
b/CordovaLib/Classes/Private/Plugins/CDVIntentAndNavigationFilter/CDVIntentAndNavigationFilter.m
@@ -71,41 +71,56 @@
     }
 }
 
++ (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url 
intentsWhitelist:(CDVWhitelist*)intentsWhitelist 
navigationsWhitelist:(CDVWhitelist*)navigationsWhitelist
+{
+    // a URL can only allow-intent OR allow-navigation, if both are specified,
+    // only allow-navigation is allowed
+    
+    BOOL allowNavigationsPass = [navigationsWhitelist URLIsAllowed:url 
logFailure:NO];
+    BOOL allowIntentPass = [intentsWhitelist URLIsAllowed:url logFailure:NO];
+    
+    if (allowNavigationsPass && allowIntentPass) {
+        return CDVIntentAndNavigationFilterValueNavigationAllowed;
+    } else if (allowNavigationsPass) {
+        return CDVIntentAndNavigationFilterValueNavigationAllowed;
+    } else if (allowIntentPass) {
+        return CDVIntentAndNavigationFilterValueIntentAllowed;
+    }
+    
+    return CDVIntentAndNavigationFilterValueNoneAllowed;
+}
+
+- (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url
+{
+    return [[self class] filterUrl:url 
intentsWhitelist:self.allowIntentsWhitelist 
navigationsWhitelist:self.allowNavigationsWhitelist];
+}
+
 - (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request 
navigationType:(UIWebViewNavigationType)navigationType
 {
     NSString* allowIntents_whitelistRejectionFormatString = @"ERROR External 
navigation rejected - <allow-intent> not set for url='%@'";
     NSString* allowNavigations_whitelistRejectionFormatString = @"ERROR 
Internal navigation rejected - <allow-navigation> not set for url='%@'";
     
     NSURL* url = [request URL];
-    BOOL allowNavigationsPass = NO;
-    NSMutableArray* errorLogs = [NSMutableArray array];
+    CDVIntentAndNavigationFilterValue filterValue = [self filterUrl:url];
     
-    switch (navigationType) {
-        case UIWebViewNavigationTypeLinkClicked:
-            // Note that the rejection strings will *only* print if
-            // it's a link click (and url is not whitelisted by <allow-*>)
-            if ([self.allowIntentsWhitelist URLIsAllowed:url logFailure:NO]) {
-                // the url *is* in a <allow-intent> tag, push to the system
+    switch (filterValue) {
+        case CDVIntentAndNavigationFilterValueNavigationAllowed:
+            return YES;
+        case CDVIntentAndNavigationFilterValueIntentAllowed:
+            // only allow-intent if it's a UIWebViewNavigationTypeLinkClicked 
(anchor tag)
+            if (UIWebViewNavigationTypeLinkClicked == navigationType) {
                 [[UIApplication sharedApplication] openURL:url];
-                return NO;
-            } else {
-                [errorLogs addObject:[NSString 
stringWithFormat:allowIntents_whitelistRejectionFormatString, [url 
absoluteString]]];
             }
-            // fall through, to check whether you can load this in the webview
-        default:
-            // check whether we can internally navigate to this url
-            allowNavigationsPass = [self.allowNavigationsWhitelist 
URLIsAllowed:url logFailure:NO];
-            // log all failures only when this last filter fails
-            if (!allowNavigationsPass){
-                [errorLogs addObject:[NSString 
stringWithFormat:allowNavigations_whitelistRejectionFormatString, [url 
absoluteString]]];
-
-                // this is the last filter and it failed, now print out all 
previous error logs
-                for (NSString* errorLog in errorLogs) {
-                    NSLog(@"%@", errorLog);
-                }
+            // consume the request (i.e. no error) if it wasn't a 
UIWebViewNavigationTypeLinkClicked
+            return NO;
+        case CDVIntentAndNavigationFilterValueNoneAllowed:
+            // allow-navigation attempt failed for sure
+            NSLog(@"%@", [NSString 
stringWithFormat:allowNavigations_whitelistRejectionFormatString, [url 
absoluteString]]);
+            // anchor tag link means it was an allow-intent attempt that 
failed as well
+            if (UIWebViewNavigationTypeLinkClicked == navigationType) {
+                NSLog(@"%@", [NSString 
stringWithFormat:allowIntents_whitelistRejectionFormatString, [url 
absoluteString]]);
             }
-            
-            return allowNavigationsPass;
+            return NO;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/6cc86efb/tests/CordovaLibTests/CDVWhitelistTests.m
----------------------------------------------------------------------
diff --git a/tests/CordovaLibTests/CDVWhitelistTests.m 
b/tests/CordovaLibTests/CDVWhitelistTests.m
index 5f979c0..9f83f2a 100644
--- a/tests/CordovaLibTests/CDVWhitelistTests.m
+++ b/tests/CordovaLibTests/CDVWhitelistTests.m
@@ -20,6 +20,7 @@
 #import <XCTest/XCTest.h>
 
 #import <Cordova/CDVWhitelist.h>
+#import "CDVIntentAndNavigationFilter.h"
 
 @interface CDVWhitelistTests : XCTestCase
 @end
@@ -280,4 +281,21 @@
     XCTAssertTrue([whitelist URLIsAllowed:[NSURL 
URLWithString:@"http://user:[email protected]";]]);
 }
 
+- (void)testAllowIntentsAndNavigations
+{
+    NSArray* allowIntents = @[ @"https://*"; ];
+    NSArray* allowNavigations = @[ @"https://*.apache.org"; ];
+    
+    CDVWhitelist* intentsWhitelist = [[CDVWhitelist alloc] 
initWithArray:allowIntents];
+    CDVWhitelist* navigationsWhitelist = [[CDVWhitelist alloc] 
initWithArray:allowNavigations];
+    
+    // Test allow-navigation superceding allow-intent
+    XCTAssertEqual([CDVIntentAndNavigationFilter filterUrl:[NSURL 
URLWithString:@"https://apache.org/foo.html";] intentsWhitelist:intentsWhitelist 
navigationsWhitelist:navigationsWhitelist], 
CDVIntentAndNavigationFilterValueNavigationAllowed);
+    // Test wildcard https as allow-intent
+    XCTAssertEqual([CDVIntentAndNavigationFilter filterUrl:[NSURL 
URLWithString:@"https://google.com";] intentsWhitelist:intentsWhitelist 
navigationsWhitelist:navigationsWhitelist], 
CDVIntentAndNavigationFilterValueIntentAllowed);
+    // Test http (not allowed in either)
+    XCTAssertEqual([CDVIntentAndNavigationFilter filterUrl:[NSURL 
URLWithString:@"http://google.com";] intentsWhitelist:intentsWhitelist 
navigationsWhitelist:navigationsWhitelist], 
CDVIntentAndNavigationFilterValueNoneAllowed);
+}
+
+
 @end


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to