Friday, March 25, 2016

CORS, Content-Security-Policy and JSONP

CORS (Cross-origin resource sharing) is supported by most browsers to hand cross origin requests. Basically, when html content is loaded from bar.com, and it sends an xmlhttprequest to foo.com, then when foo.com returns the response to the browser, it needs to specify the header of
Access-Control-Allow-Origin: *
or
Access-Control-Allow-Origin: http://bar.com
otherwise, the browser will not load the response to the web content. So in this case browser enforces the check based on the server's response header.

Note CORS does not care how the script is loaded in original html page (bar.com), the browser only makes the decision after the response of cross domain request comes back. It would be better it browser can proactively disable the malicious js code if it is not from trusted source. That is how Content-Security-Policy does.

How Content-Security-Policy works is when the original html page returned from bar.com, the server can specify the trusted source for any javascript, css, so that even if malicious js code gets loaded in the page, it will not be executed. For example, if the policy indicates
script-src 'self'
then only the script from the same domain can be executed. Note this also disable JSONP function when it is used for cross domain request, as the script is loaded from a different domain, and it will not be trusted unless Content-Security-Policy allows it to do so.

By the way, for CORS request, by default, hte browser does not send credentials (cookies and http authentication scheme) with the request. In order to send them with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true. In addition, the server must include Access-Control-Allow-Credentials header, this header tells the browser that the server allows the credential to be used for a cross origin request. If the browser sends the credentials with the request, but the server response does not include a valid Access-Control-Allow-Credential header, then browser will not expose the response to the application, and the ajax request will fail.

Saturday, March 19, 2016

Steps to uppload html&js file to MS Azure web app

Visual Studio can easily upload asp.net app to Azure by default setting. But for simple testing Azure web app with html&js files, ftp is the easier to do so with the following steps.

1. Create an Azure web app in Azure portal
2. optional update deploying credential from webapp settings->Deployment credential page
3. click top toolbar button of "Get Publish Profile"
4. open the downloaded file from xml notepad or any xml editor
5. Find FTP profile, and get the value for "publishUrl", "userName", and "userPWD" fields
6. download filezilla or any other ftp tools
7. set host, username, password to the previous values in webapp profile
8. select the local folder for mapping the remote www folder
9. connect to ftp url, and download or update the html&js file to azure web app

Friday, March 18, 2016

Use Vysor to share Android device to desktop

1. goto http://www.vysor.io/ and download vysor and install Vysor (Beta) to Chrome
2. Connect android device using USB cable to mac, it is not necessary to put device and mac in the same Wifi network
3. launch vysor app from chrome and select the android device to share the display.

Thursday, March 3, 2016

Recent windows security update break iis anonymous authentication

After a recent windows update (2016/02), few asp.net apps on iis get an Access is denied error.
The detailed error information is shown as

Description: An error occurred while accessing the resources required to serve this request. You might not have permission to view the requested resources. 

Error message 401.3: You do not have permission to view this directory or page using the credentials you supplied (access denied due to Access Control Lists). Ask the Web server's administrator to give you access to 'C:\SharedFolder\I826633@git\tools\Cache\Cache\'.


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.114.0

In order to fix the issue, open iis administration console, and select the virtual directory of the asp.net app, right click on the anonymous authentication item, and select edit. Then change anonymous user identity from specific usre of "IUSR" to "Application pool identity"

Tuesday, February 23, 2016

ios Embedded UITabBarController in UINavigationViewController

When designing ios App in storyboard, certain UITabBarController cannot be embedded into UINavigationviewController in the same way as other view controller.

One approach to solve the issue it just adding a regular UIViewController into the storyboard and embedded it into navigation view controller. And then add a view of TabBar into the UIViewController. With this approach, you will need to set the tabbar UIView's delegate by yourself.

Another approach is still using UITabBarController and then open the tabbarcontroller using show method from a segue. With this way, you get the full function provided by UITabBarController, but you cannot set the UINavigationBar's title and bar button from storyboard. Instead you will need to set them from the viewdidLoad() method as shown below.

  override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationItem.title = "Settings"
        
        let leftButton : UIBarButtonItem = UIBarButtonItem(title: "Save", style: UIBarButtonItemStyle.Plain, target: self, action:"save:");
        leftButton.tintColor = UIColor.whiteColor()
        self.navigationItem.leftBarButtonItem = leftButton
        
        let rightButton : UIBarButtonItem = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action:"cancel:");
        rightButton.tintColor = UIColor.whiteColor()
        self.navigationItem.rightBarButtonItem = rightButton

    }
    

    func cancel(sender: UIBarButtonItem) {
        print("cancel clicked")
         self.performSegueWithIdentifier("returnToParent", sender: self)
        
    }
    
    func save(sender: UIBarButtonItem) {
        print("save clicked")
        
        self.performSegueWithIdentifier("saveAndReturnToParentt", sender: self)
    }
     
Option 2 seems better as most of the code required for the function is within the viewDidLoad method.

Sunday, February 21, 2016

Unique swift syntax

 1. Nil Coalescing Operator:  a??b  
The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.

a??b
is shorthand for the code below:
a != nil ? a! : b

2. Inclusive Range Operator: for i in a...b {} 

The closed range operator (a...b) defines a range that runs from a to b, and includes the values a and b. The value of a must not be greater than b.

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}

3. Half-Open Range Operator:  for i in a..<b {} 

The half-open range operator (a..<b) defines a range that runs from a to b, but does not include b. It is said to be half-open because it contains its first value, but not its final value.
for index in 1..<5 {
    print("\(index) times 5 is \(index * 5)")
}

4. Stride
The stride provides steps to loop through a range, either including the last value (through) or excluding the last value
for num in stride(from: 1000, through: 0, by: -100)  {
    print(num)

}

5. Argument and Parameter names for  function
In a method declaration, if the argument (external name) is specified, then when calling the method, the caller must specify the argument name. In order to skip the argument name, set the name to _ in function definition.

func someFunction(_ firstParameterName: Int, _ secondParameterName: Int)  {
    // function body goes here
    // firstParameterName and secondParameterName refer to
    // the argument values for the first and second parameters
}
someFunction(1, 2)

6. Parameter name for Closure
When defining closure variable, only parameter type information is specified, the argument names are skipped as the proper parameter names should be decided by the particular closure or function implementation, and the names are specified when defining the closure implementation body as shown below

    var handlerWithParamAndValue : (Int, String) -> String  =  {pi, ps in
        return pi.description + " " + ps
    }


let k = handlerWithParamAndValue(1, "yes")
print("the value is \(k)") 

7: try, try?, try! expression
try before an expression indicates the expression may throw exception.

try? before an expression indicates the expression returns an optional value. And if an error is thrown while evaluating the expression, the optional value is set to nil, and the error is eaten silently

try! before the expression indicates even if theoretically the expression may throw an error, but in this particular call, it will never throw an error.

8. In for in loop, add a where clause to only loop through the items that match certain condition, for example
for data in numbers where data % 2 == 0 {
    print(data)
}

This follows the same syntax as extension definition
extension Array where Element : Equable {
...
}

Friday, February 19, 2016

iOS shows alert view independent of current viewcontroller

Usually when displaying alert view on ios, it is presented by the current topmost viewcontroller. However, sometime, the current topmost presented viewcontroller may not be easy to get , or the current presented viewcontroller may get dismissed while the new alertview is displayed.

To handle the issue, one option is create a new UIWindow object and make it visible, then create a empty root viewcontroller for the UIWindow. Then show the alert view on top of the new UIWindow's root viewcontroller. This approach can show the uialert view regardless which viewcontroller is currently shown by other part of application logic.

The sample code is shown below:
        __block UIWindow* win= [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        win.rootViewController = [[UIViewController alloc] init];
        win.windowLevel = UIWindowLevelAlert + 1;
        [win makeKeyAndVisible];
        UIAlertController* alert = [UIAlertController
                                    alertControllerWithTitle:@"Change Password"
                                    message:@"The password has been updated, click OK to reload the page."
                                    preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction* defaultAction = [UIAlertAction
                                        actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                        handler:^(UIAlertAction * action) {
                                            [self reloadStartUrl];
                                            win.rootViewController = nil;
                                            win.hidden = true;
                                            win = nil;

                                        }];
        
        [alert addAction:defaultAction];

        [win.rootViewController presentViewController:alert animated:YES completion:nil];