Monday, January 27, 2014

Back from MarsJUG hackengarten#2

Last Saturday in Marseille, I participated in MarsJUG hackengarten#2. A bunch of known faces from my previous visit of the first edition of MArsJUG hackengarten (Hey, it looks like I'm part of the usual participants). Thanks to Julien and Benjamin for organizing the event and making such a nice place to be.

The day started with a short introduction of the proposed open source projects. Very different subjects: CRaSH, DataFari, CodevTT, RHQ, Audela and AeroGear. Having presented AeroGear last Wednesday with my fellow Sebastien Blanc (you can find slides here), I gave a very short introduction and presented the list of possible contributions from hackengarten wiki page.

Quick lunch (with Quick food) and back to work. Several teams formed: Nico and Thomas want to use AeroGear Push for RHQ Alert mobile app, trying out Cordova Push plugin. And making a double contribution to AeroGear and RHQ projects. Sylvain is brave enough to upgrade to XCode 5 and delve in iOS code with OAuth2 and Facebook. There's even a JIRA code for this one. Xavier tried simple push quickstart and even submitted his first PR. Time is always too short, but we can carry on those ideas. Mailing list is our friend.

I'm always impressed with all the ideas that come up during a hack-together day, but the best is the enthusiasm that you can feel. The reward of course is the Pull Request being accepted. Keep in touch and let's work for the holy graal: the Pull Request.

Sunday, January 19, 2014

Secure your runtime #Groovy #Hackengarten

Hackengarten is over, we had such a great time!

Thank you all for coming and making this event so special (after a long week of work). Special thanks to Nicolas Berge (@LesSatellites) for giving us a roof (useful by this rainy day). And for @CedricChampeau (who left Bretagne to see the sun) and @fabricematrat for organising and driving the event.

Wanna see in how it went? Here the twitter story:
Early start with french croissants. Sebi didn't forget them:
Meeting time, Cedric talk about AST, giving tricks how to work with the beast. How to read the GroovyConsole and some very useful debug tips. (Cedric talking with hands like a real South of France guy). Fabrice took over delving in SecureRuntimeASTCustomizer. Code is showing up!

We warm up with some coding using GroovyConsole and making test passed. One by one, step by step.
Geek lunch with ...

Pizza and beers, of course! (Greasy hands couldn't tweet that one)
Back to work in the afternoon, people working in pair, talking, coding, designing, talking again, merging... Hard work, man. And to finish, what did we produce: What our French Riviera community said about it: What's next?
Still some failing tests to go over before sending the Pull Request. The core design is here, you're welcome to hack more tests making them passed. Same approach as we did. Pick an item in wiki page, fix it commit on secureruntime branch. Once all use cases are treated will come the time to refactor (lots of ideas showed up).
Other related blog:
Fabrice talks about it too

Sunday, January 12, 2014

RivieraGUG - Groovy hackengarten

Remember the RivieraGUG coding WE back in the old days?
That was fun. A whole WE of live coding and snoring;)
Just browse our etherpad log to get the idea.

We decided to get back together for some hacking. The event will be hosted at Les Satellites, Saturday 18th January (note that les Satellites has moved - still in Nice). And this time we have Cedric Champeau (core committer on Groovy) with us!

What are we going to do?
Nothing less than contributing to Groovy language! We'd like to work on SecureASTCustomizer to secure your Groovy scripts not only at compile time but at runtime too. Be prepared to code some AST transform... Get all the details in our announcement page.

Brainstorming is ongoing, check out the forked repo groovy-core with secureruntime branch. This is a proposal, nothing written in marble. Feel free to add new ideas on Groovy-Secure hackengarten wiki page, try the code snippets, comment on it or simply add your contribution. The more we have, the more we can discuss and make progress during our hackengarten. Come and join us, this is an wonderful opportunity to contribute to an open source project.

OSS needs you!!
And remember we have a goal: make a pull request by the end of Saturday!

Wednesday, January 8, 2014

OAuth2 discussion - part2

We talked about OAuth2 protocol in part 1, let's see it in action in this second part. We'll take a demo app from aerogear-ios-cookbook and I'm going to drive you through it step by step.

GroogleDrive app displays the list of documents in your Google Drive using OAuth2 to authorize with aerogear-ios library.

Let's do Google setup

Before we start you will need to register your app, follow the steps below:
1. Have a Google account
2. Go to Google cloud console, create a new project
3. Go to APIs & auth menu, then select APIs and turn on Drive API
4. Always in APIs & auth menu, select Credentials and hit create new client id button Select iOS client and enter your bundle id. Enter a correct bundle id as it will be use in URL schema (if you don't know about URL Schemas I suggest you read about it) to specify the callback URL.

Once completed you will have your information displayed as below:



You'll get a Client Id, a Client Secret and a callback URL, open Xcode (or AppCode whathever you like best), go to GoogleDrive-Info.plist and add an new URL schema entry as shown below:



Show me the code

In AGViewController.m:

- (IBAction)authorize:(UIButton *)sender {
    AGAuthorizer* authorizer = [AGAuthorizer authorizer];

    _restAuthzModule = [authorizer authz:^(id config) {              [1]
        config.name = @"restAuthMod";
        config.baseURL = [[NSURL alloc] initWithString:@"https://accounts.google.com"];
        config.authzEndpoint = @"/o/oauth2/auth";
        config.accessTokenEndpoint = @"/o/oauth2/token";
        config.clientId = @"XXXXX";
        config.redirectURL = @"org.aerogear.GoogleDrive:/oauth2Callback";
        config.scopes = @[@"https://www.googleapis.com/auth/drive"];
    }];

    [_restAuthzModule requestAccessSuccess:^(id object) {                           [2]
        [self fetchGoogleDriveDocuments:_restAuthzModule];                          [4]
    } failure:^(NSError *error) {
    }];
}
[1]: configuration with all required URLs and endpoints.
[2]: requestAccessSuccess:failure: is the method dealing with all the steps needed to authorize. Within this method, we're going to bring the UI grant web page, once authorization is granted, we go back to the mobile app and then we exchange code for access token. this is the heart of OAuth2 dance ;)

In AGAppDelegate.m:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation
{                                                                                   [3]
    NSNotification *notification = [NSNotification notificationWithName:@"AGAppLaunchedWithURLNotification" 
    object:nil userInfo:[NSDictionary dictionaryWithObject:url forKey:@"UIApplicationLaunchOptionsURLKey"]];
    [[NSNotificationCenter defaultCenter] postNotification:notification];

    return YES;
}
[3]: once popup has been answered, go back to GoogleDrive app and notified AeroGear framework. If this method is not well implemented, the browser won't be able to callback the application. Back to the app, access code is excahnge with access token (step 2).
[4]: the success callback takes the access token as parameter. The access token is stored in memory with AGAuthzModule. It's up to the developer to store permanently the access token for next app launch. Note that access token has an expiration date (1h for Google).

In AGViewController.m:

-(void)fetchGoogleDriveDocuments:(id) authzModule {
    NSString* readGoogleDriveURL = @"https://www.googleapis.com/drive/v2";
    NSURL* serverURL = [NSURL URLWithString:readGoogleDriveURL];
    AGPipeline* googleDocuments = [AGPipeline pipelineWithBaseURL:serverURL];

    id documents = [googleDocuments pipe:^(id config) {       [5]
        [config setName:@"files"];
        [config setAuthzModule:authzModule];                                        [6]
    }];

    [documents read:^(id responseObject) {                                          [7]
        _documents = [[self buildDocumentList:responseObject[0]] copy];
        [self.tableView reloadData];
    } failure:^(NSError *error) {
        // when an error occurs... at least log it to the console..
        NSLog(@"Read: An error occured! \n%@", error);
    }];
}
[5]: create your Pipeline and Pipe objects as usual.
[6]: setting authz module in your pipe configuration will pass the access token for each pipe operations transparently.
[7]: read the pipe as usual.

As a conclusion

No need to learn and use different providers SDK, Aerogear-iOS library allows you to use OAuth2 with any providers. Once you're authorized, you can use the pipes transparently (no need for you to pass the access token, the framework does it for you).
OAuth2 will be shipped in 1.4.0. Give it a trial, give us your feedback and enjoy!

Monday, January 6, 2014

OAuth2 discussion - part1

Sometimes pronounced with one syllable "oath", but I like it better with two syllables "Oh Auth", add a 2 at the end and here is OAuth2, an open standard for authorization. It allows users to share their private resources (e.g. photos, documents etc...) stored on one site with another site or application without having to hand out their credentials. Widely adopted from Google to Facebook, easy and less cumbersome than his elder brother OAuth1, let's see together how to practice the OAuth2 dance.

Actually, the dance comparison is often used to describe OAuth2, but I think it's more a 3 players discussion so we're going to use a script metaphor. Here is our casting: Mr Google (our cloud based service provider), MyGoogleDrive app (our native mobile app which main functionality is to list Google Drive files) and Bob our end user who want to access his Google drive content via MyGoogleDrive app. We want to write a native iOS client app using third party backend.

Before we start, MyGoogleDrive developer has already registered his app to consume Google Drive services.  Each provider offers an admin console: GoogleCloud console... Depending on provider, you can choose want kind of access you need (read/write). Once registered you should get a client id, a client secret and a callback URI.

Bob starts MyGoogleDrive app on his iPhone.

1. Hello, Mr Google I'm GoogleDrive app, could I get access to Google Drive services? Here is my client id and the URL you can call me back on.
2. Which account, please identify yourself?
3. I am Bob, here's my login and password
4. Hello, Bob, do you want to grant access to GoogleDrive app?
5. Yes I do. I trust this app.
6. Ok fine, Let me use the client callback URL to get back to the app. Here is an access code for you GoogleDrive.
7. Thanks. Mr Google may I exchange my code for an access token?
8. Here's your access token GoogleDrive Enjoy.
9. So Mr Google could I get access to Bob's list of files, here's my access token.
10. Let me see if your access token is still valid, ok fine here's the list your requested.

Easy peasy.
One of the reasons of OAuth2 (apart from the cryptographic signatures vs SSL/TLS protection) is the need to serve not only web app but also, mobile app. OAuth2 defines 3 type of profiles: web application (end user has no access to credentials, access tokens), web browser client (OAuth credential not trusted, some provider won't issue a client_secret) and native application (dynamically issued credentials such as access tokens or refresh tokens can receive an acceptable level of protection).

For native app one of the main challenge is somehow to include a third party UI to grant access either by forwarding your app to a web browser or by embedding a WebView and, once successfully authenticated and authorized, to go back to the original app. With minimal provider configuration, AeroGear libraries handles it for you.

In the second part of this blog, we'll see how using AeroGear iOS libraries, we managed the OAuth2 back and forth discussion easily and how the OAuth2 implementation integrates transparently with Pipes.