Skip Navigation LinksHome > Archive

Working with Making Waves and VGTV – Mobile Services

We’ve just published a great case study:

image

Working with Christer at Making Waves was a blast and they’ve created an awesome Windows 8 application backed by Mobile Services.

Check out Christer and team talking about their experience of using Mobile Services in this short video (<5 mins)

image

 
Josh Post By Josh Twist
10:51 PM
28 Jan 2013

Debugging your Mobile Service scripts

During the twelve days of ZUMO, I posted a couple of articles that showed techniques for unit testing your Mobile Service scripts:

And whilst this is awesome, sometimes you really want to be able to debug a script and go past console.log debugging. If you follow this approach to unit testing your scripts then you can use a couple of techniques to also debug your unit tests (and therefore Mobile Service scripts). I recently purchased a copy of WebStorm during their Mayan Calender end of world promotion (bargain) and it’s a nice tool with built-in node debugging. I asked my team mate Glenn Block if he knew how to use WebStorm to debug Mocha tests. Sure enough, he went off, did the research and posted a great article showing how: Debugging mocha unit tests with WebStorm step by step – follow these steps if you own WebStorm.

For those that don’t have a copy of WebStorm, you can still debug your tests using nothing but node, npm and your favorite WebKit browser (such as Google Chrome).

The first thing you’ll need (assuming you already installed node and npm and the mocha framework) is node-inspector. To install node-inspector, just run this command in npm

npm install -g node-inspector

On my mac, I had to run

sudo npm install -g node-inspector

and enter my password (and note, this can take a while to build the inspector). Next, when you run your unit tests add the --debug-brk switch:

mocha test.js -u tdd --debug-brk

This will start your test and break on the first line. Now you need to start node-inspector in a separate terminal/cmd window:

node-inspector &

And you’re ready to start debugging. Just point your webkit browser to the URL shown in the node-inspector window, typically:

http://0.0.0.0:8080/debug?port=5858

image

Now, unfortunately the first line of code that node and the inspector will break on will be mocha code and it’s all a little big confusing here for a few minutes, but bear with it, because once you’re up and running it gets easier.

The first thing you’ll need to do is advance the script past the line , Mocha = require(‘../’)which will load all the necessary mocha files. Now you can navigate to the file Runnable.js using the left pane.

image

And in this file, put a break on the first line inside Runnable.prototype.run function:

image

If you now hit the start/stop button (F8) to run to that breakpoint, the process will have loaded your test files so you can start to add breaks:

image

Here, I’ve found my test file test.js:

image

And we’re away. After this, the webkit browser will typically remember your breakpoints so you only have to do this once. So there you go, debugging mocha with node-inspector. Or you could just buy WebStorm.

 
Josh Post By Josh Twist
11:34 PM
26 Jan 2013

Dispatching to different query functions in Mobile Services

It’s common to want to run trigger differing behaviors inside your read script based on a parameter. For example, imagine we have a table called ‘foo’ and we want to have a default path and two special operations called ‘op1’ and ‘op2’ that do something slightly different (maybe one loads a summary of the objects to reduce the amount of traffic on the wire whilst the other expands a relationship to load child records).

Here’s my approach to this:

So now, if I hit the HTTP endpoint for my table

http://todolist.azure-mobile.net/tables/foo

We’ll load the records as normal, returning a JSON array. However, if we add a parameter

http://todolist.azure-mobile.net/tables/foo?operation=op1

Then we’ll get the following response:

"this result is from operation1"

And if we hit ?operation=op2 then we’ll get:

"this result is from operation2"

And, with the script above if we hit some undeclared operation (?operation=nonsense) then we’ll go back to the default path (you may decide to throw an error).

 
Josh Post By Josh Twist
3:18 AM
26 Jan 2013

Using the scheduler to backup your Mobile Service database

Recently I launched my first iOS application called ‘doto’. doto is a todolist app with two areas of focus: simplicity and sharing. I wanted a super simple application to share lists with my wife (groceries, trip ideas, gift ideas for the kids, checklist for the camping trip etc). For more info, check out the mini-site or watch the 90 second video:

image

Now that I have a real app that stores real people’s data, I feel a responsibility to ensure that I take good care of it. Whilst it’s unlikely; it is possible that I could do something silly like drop a SQL table and lose a lot of data that is important to those users. So taking a periodic backup and keeping that in a safe location is advisable.

SQL Azure has a cool export feature that creates a ‘.bacpac’ file that contains your schema and your data – it saves the file to blob storage. And what’s more, they have a service endpoint with a REST API.

This means it’s easy for me to invoke an export from a Mobile Services script, even better, I can use the scheduler to do a daily backup.

Here’s the script I use; notice how the URL of the export service varies depending on the location of your database and server.

And now I just have to set a schedule, I’m going to go for 1 minute past midnight UTC.

image

Restore

If I ever need to restore the backup data I can create a new database from an import, right in the portal:

image

Which opens a cool wizard that even helps me navigate my blob storage containers to find the appropriate .bacpac file. To hook this new database up to my Mobile Service I could do an ETL over to the existing connected database or use the Change DB feature in the Mobile Service CONFIGURE tab:

image

Tags:

 
Josh Post By Josh Twist
5:23 PM
20 Jan 2013

A quick lick of paint

At the end of my previous post, I promised to update the layout of the thejoyofcode.com. Well, the situation was clearly so dire that it needed emergency attention and, with the help of the incredible bootstrap, we have a new look. OK, so this design won’t be winning any ‘webbys’ – but it only took a few hours and is much easier to read and more responsive.

Aurevoir 2005!

image

Tags: Other

 
Josh Post By Josh Twist
5:35 AM
03 Jan 2013

Exploring custom identity in Mobile Services (Day 12)

This is the last post in the series the twelve days of ZUMO and we'll pull together many of the themes from the last few days, including unit testing scripts, generating your own auth tokens and setting the auth token.

In today's post, we'll go a little experimental, and explore how we could use all these techniques and the built in flexibility of Mobile Services to implement custom identity for our service, where Mobile Services stores your user's username and password and allows them to logon without using a social network.

In order to set this up, we'll need a table to store the user's details. I called it accounts and we'll use this table to store the credentials and also to login using the Mobile Service client.

accounts table

Since we'll allow anyone to register we set the INSERT permission to only require the application key. All other operations (especially READ) should be set to scripts and admins only.

We'll do all the work in the insert script with two flows:

1. Account creation

A POST (insert) to the /tables/accounts endpoint with a body will start the account creation flow. I'll leave it as an exercise for the reader to decide what other data they might want to store in the accounts table and how you'll validate it (e-mail for example? checkout our integration with sendgrid).

In this flow the majority of the work is generating a salt and hashing the password before we write it to storage. 

2. Login

A POST (insert) to the /tables/accounts endpoint with a login parameter set to "true" means this is a login attempt and we should return a 200 with user and token data if successful, otherwise we'll send a 401 Unauthorized.

In this flow, we load the user account from the database by matching the username. The record loaded should include the salt and hashed password (a unique salt per row helps prevent the use of highly effective lookup tables to crack your hashed passwords, if they should ever end up in the wrong hands). We then hash the submitted password and do an equality check with the stored password, if the credentials are good - the hash will match.

Without further a do, here's the script that does all this and should be uploaded against your accounts table's insert operation.

Unit testing the script

With a script like this, it's always good to have some tests in place and so I created a suite of mocha TDD tests to verify the behavior. This is the first script I've shown that we'll unit test and also uses the 'tables' global in Mobile Services. It's the perfect opportunity to demonstrate a simple mockTables module that I use to mock the tables global in scripts. The idea is simple, first your create the mockTables instance:

var tables = require('./mockTables.js');

Then in each test you clear all data (or whenever appropriate):

tables.clear();

and populate the table with the data required for your test, specifying the name of the table:

tables.addItem('accounts', { 
username: "Josh",
password: "<hash>",
salt: "<blah>",
etc: "…" });

Now you can search this table in your Mobile Service' scripts and it should behave as you'd expect, e.g.

var accounts = tables.getTable('accounts');
accounts.where({ username: "Josh" }).read({
   success: function(results) {
      console.log(results); // will output a single record
   }
}); 

Note this mock is great for reading data but doesn't support setting up particular behaviors (such as returning an error) or verifying the order of invocations - but it's useful nonetheless. You can also use the functional where syntax, e.g:

accounts.where(function(a) {
    return this.x === a
}, 1)).read( // etc

The full unit test code and simple mockTables module are shown at the bottom of the post, before that though - the client.

Implementing the client

Believe it or not that's pretty much all we have to do on the server to implement custom identity for this post. Now for the client. We'll need to support registration and a new login approach, let's take a look at how we'd do this in Objective-C for iOS. I've decided to use categories to extend the MSClient class.

This adds login and register methods to the MSClient, so they feel right at home. And as you can see, the login method simply sets up the user and the token. You could change the register method to automatically log the user in (since, if registration was successful, they obviously have the right credentials).

I created a modified iOS quickstart that you can setup to see this in action. You'll need to set your TodoItem to authenticated for all operations and add the accounts table and script (be sure to create your own hashing key and use your own master key).

IOS Simulator Screen shot Jan 1 2013 7 08 31 PM IOS Simulator Screen shot Jan 1 2013 7 12 38 PM IOS Simulator Screen shot Jan 1 2013 7 14 37 PM

You can download the Xcode project here: CustomIdQuickstart.zip (2.6MB)

The client also uses a slightly modified filter from day 11 that uses NSNotificationCenter. 

Unit Tests and MockTables

As promised, here are the full unit tests and that mockTables code:

IMPORTANT: In this post we follow some best practice with regard to password storage by salting and hashing the password value and using a key-stretching algorithm (pbkdf2) and slower equals comparison. However, security and attacks continue to evolve. Remember, this is code you got from the internet and and comes with no warranty. Check out this article for more detail on password hashing: Salted Password Hashing.

Things we didn't look at

There are many. Perhaps the most obvious is, if you support custom identity, then you'll need to provide a way for users to recover their password in the event that they forget it. This isn't necessary when using Twitter or Facebook as they provide this mechanism for you. Typically, this involves an e-mail loop and as we integrate with sendgrid - this is entirely possible to implement. Of course, another key thing to remember is that Mobile Services composes extremely well with other services in Azure (and beyond) - so it's easy to augment your Mobile Service with other capabilities as necessary.

Another thing I'd want to do to ensure the integrity of my account data before putting this into production is enforcing a unique constraint on the username column, to remove the unlikely race condition

And this closes the series "the twelve days of ZUMO", thanks for reading and I value your feedback. The good news is the team is working hard on making almost everything the series has covered even easier in 2013 - HAPPY NEW YEAR!

PS - it is one of my New Year's Resolutions to fix the layout and design of this blog :)

 
Josh Post By Josh Twist
3:19 AM
01 Jan 2013
© 2005 - 2014 Josh Twist - All Rights Reserved.