Flex

WireframeSketcher Review

I’ve been waiting for an Eclipse-based wireframing/mockup tool for a while now, and it’s finally here :) and at $75, i think it’s a reasonable price to pay for such a useful plugin, although still a little highly priced.

WireframeSketcher is an Eclipse plugin which offers a similar feature-set to Balsamiq Mockups, although personally i prefer WireframeSketcher. Firstly, it plugs right in to my current workflow in Eclipse – that already wins it many points in my book! Aside from that, the plugin feels a lot more stable than Balsamiq and offers a few interesting features, such as:

  • Wiki syntax formatting on all supported controls
  • Screens vs Masters vs Storyboards
    • A Screen is a view that you can build
    • A Master is a reusable component that can be used in Screens
    • A Storyboard is made up of a collection of Screens
  • Well thought-out presentation mode allowing you to jump between screens

All in all, i like the way it’s structured; i like that you can create separate files for logically separate areas of your whole application mockup and bring them together in a storyboard. I’ve used it on a couple practical examples that i was planning to do, and it feels comfortable and usable.

If you’re developing your a Java application with SWT, there’s also a neat plugin to export your wireframes as SWT code :)

Maybe an MXML export feature is on the cards too! That would certainly be wonderful…

aerial-logo

Introducing Aerial CMS

Well, I finally let my irritation get to me… I’ve been developing Flash, Flex & AIR applications for two years now – most of them pulling data through AMFPHP from a PHP-based back-end. In those two years, I’ve tried nearly all the suggested solutions for managing content on the back-end and pulling it through to the front-end; Drupal, MODx, WordPress, Symfony. They are all fantastic PHP-based frameworks and systems, but they don’t allow me to develop applications the way I want to. So, as a consequence of this combination of irritation, frustration, egotism and flat-out boredom with writing the same code, over and over, for each project, I’ve decided to build a CMS – Aerial CMS.

aerial-logo

What is Aerial CMS?

Aerial CMS (named Aerial because it was the first word i could think of with “RIA” in it) is a simple content management framework. I decided to rethink the concept of a content management system, because – the way I see it – CMSs these days are about content management AND content presentation. I think that these two massive areas of development & design need to stay very far away from each other. They are like brother and sister to us now, but sometimes – when stuck in a room together for so long – they breed and the results are disastrous (on top of being scandalous!).

Design Philosophy

Look at how the MVC (Model View Controller) pattern came about: software engineers found that separating application logic from presentation from data has serious design benefits. Now, i’m not attempting to bad-mouth all the incredible efforts of the CMS developers… I’m saying that for Rich Internet Application development, it really becomes a chore to use systems like Drupal or Symfony because they were not meant to be used in that way. They do what they do superbly well, but for RIAs they fail to impress me.

Aerial CMS has been built from the first line of code for optimized Rich Internet Application development. It focuses only on content management and development tooling, and wants nothing to do with how you present the data. It’s certainly a change from the standard model, and i’m convinced about how I want to develop my RIAs, but that’s why i’ve put out this early release – to see if you all agree with me. This CMS still has a very, very long way to go; it works well for most situations but the tools haven’t been developed yet.

Technology

Aerial has been built on two very well established and loved open-source frameworks, namely AMFPHP 1.9 and Doctrine 1.2.1. The Aerial framework is built for compatibility with PHP 5 only. Aerial enforces no rules upon you when you get down to developing your back-end code, but it does stick to Doctrine’s method of generating database tables and models. In essence, once you’ve set up your database schema, you can do whatever you like :) you can plug into Doctrine’s API or you can write your own code; it really gives you the freedom to code the way you’re comfortable with.

Tutorials and Videos

I’ve made a Getting Started video to get you familiar with the framework and i’ll be writing a series of tutorials in the Wiki section of the Google Code page for Aerial CMS. I’ve also got plans for a couple more video tutorials, so keep checking the site for updates or follow me on Twitter (@dannykopping).

Comments, Suggestions, et al

I’d love to hear what you have to say (as long as it’s in English – being monolingual sucks)! I’m very open to suggestions, any offers to help contribute would be welcomed and all constructive criticism is encouraged!

Dynamically controlling cross-domain permissions

What are crossdomain.xml files?

As any developer who has ever dipped their toes into the murky pond that is cross-domain configuration with Flash will tell you, it is quite a confusing and somewhat aggravating task to accomplish. In this post, I’m going to demonstrate how you can control access to your APIs from Flash applications by dynamically generating crossdomain.xml files that work the same as static crossdomain.xml files.

But before we go any further, what the hell is a crossdomain.xml file?

The definition of a cross-domain configuration file is (taken from http://www.senocular.com/pub/adobe/crossdomain/policyfiles.html):

A cross-domain policy file is a XML document that grants a web client, such as Adobe Flash Player, permission to handle data across multiple domains. When a client hosts a content from a particular source domain and that content makes requests directed towards a domain other than its own, the remote domain would need to host a cross-domain policy file that would grant access to the source domain allowing the client to continue with the transaction. Policy files grant read access to data as well as permit a client to include custom headers in cross-domain requests.

Essentially what this means is that if you have a Flash application and you need to pull data (other than images or video) from a domain which is not the domain of your hosted application, you will need to place a crossdomain.xml file on the server you are requesting data from.

The configuration file needs to be placed in the webroot of the server; you can have a look at some of the more popular sites’ crossdomain.xml files:

This post is not a “how-to” on crossdomain.xml files unfortunately: for that, you can visit http://www.adobe.com/devnet/flashplayer/articles/cross_domain_policy.html – a great article by Lucas Adamski.

The Problem

You would like to control access to your application’s API based on a database table, for instance:

You have an application that serves up a list of products like Amazon.com to be made available via AMF requests (could be a REST-based architecture, SOAP, etc). You have a service offering whereby Flash/Flex application developers can register with your company to be allowed to access this wonderful API. You charge a set price per year for your service and you keep a database of authorized subscribers. At this stage, you can either allow any domain to access your API by using the following crossdomain.xml file:

1
2
3
4
5
6
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
 
<cross-domain-policy>
   <site-control permitted-cross-domain-policies="master-only"/>
   <allow-access-from domain="*"/>
</cross-domain-policy>

The problem with this configuration is that any domain can send requests to your API from their Flash applications, and for obvious reasons this is not such a great idea.

The other (more secure) option would be to manually stick in each subscriber’s domain name into the crossdomain.xml file as follows:

1
2
3
4
5
6
7
8
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
 
<cross-domain-policy>
   <site-control permitted-cross-domain-policies="master-only"/>
   <allow-access-from domain="example1.com"/>
   <allow-access-from domain="example2.com"/>
   <allow-access-from domain="example3.com"/>
</cross-domain-policy>

With the above configuration, you will start running into major headaches your subscribers either start cancelling their accounts or fail to pay in full. You will manually have to go and remove their domains from the configuration each time.

The Solution

When Flash applies a security policy like this, it automatically looks for a crossdomain.xml file on the requested server in the webroot. We can use a nifty combination of Apache rewriting and a PHP script to dynamically generate a list of authorized domains.

Apache Configuration

We want Apache to listen for an incoming request for our crossdomain.xml file, but instead of serving the XML file, we want to process a PHP script called generate-config.php to generate our configuration options. This example is quite simplistic, and I encourage you to take this further with whatever rules your application may require.

We are going to create a .htaccess file in the webroot of our server with the following contents:

RewriteEngine On
RewriteCond %{REQUEST_URI} crossdomain.xml
RewriteRule ^crossdomain\.xml$ generate-config.php [L]
RewriteEngine On
RewriteCond %{REQUEST_URI} crossdomain.xml
RewriteRule ^crossdomain\.xml$ generate-config.php [L]

This will present the output of our generate-config.php file as the contents of the crossdomain.xml file – essentially using another file’s content in place of another.

PHP & MySQL

In our generate-config.php file, we are going to:

  1. Connect to a database
  2. Run a SQL query that will return a list of subscribers
  3. Iterate through our list and add them to our XML output
  4. Echo the XML output back to Apache

First, create a database called crossdomain_test and then run the following SQL query to create our subscribers table:

CREATE TABLE IF NOT EXISTS `subscribers` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Insert a couple of test rows:

INSERT INTO `subscribers` (`ID`, `name`, `domain`, `active`) VALUES
(1, 'YouTube', 'youtube.com', 1),
(2, 'Twitter', 'twitter.com', 1);

Now we’re going to create our generate-config.php file in the webroot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
	// create our config skeleton according to the crossdomain.xml rules
	$xml = '<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<site-control permitted-cross-domain-policies="master-only"/>
</cross-domain-policy>';
 
	// create $config variable to hold our config data
	$config = new SimpleXMLElement($xml);
 
	// connect to MySQL and select database
	$conn = mysql_connect("localhost", "username", "password");
	mysql_select_db("crossdomain_test", $conn);
 
	// loop through all rows, and create xml nodes
	$res = mysql_query("SELECT domain FROM subscribers WHERE active = 1");
	while($subscriber = mysql_fetch_object($res))
	{
		$child = $config->addChild("allow-access-from", null);
		$child->addAttribute("domain", $subscriber->domain);
	}
 
	// echo back to Apache
	echo $config->asXML();
?>

If we navigate to the crossdomain.xml file in the browser, we should see:

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<site-control permitted-cross-domain-policies="master-only"/>
	<allow-access-from domain="youtube.com"/>
	<allow-access-from domain="twitter.com"/>
</cross-domain-policy>

and if we delete one of the records out of the table (try deleting YouTube), and navigate to that page again, you’ll see:

1
2
3
4
5
6
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
	<site-control permitted-cross-domain-policies="master-only"/>
	<allow-access-from domain="twitter.com"/>
</cross-domain-policy>

And that’s it! Not too difficult at all :)

A Workaround for all frustrated developers consuming REST services

As a side-note, if you ever encounter a site that you need to pull data from and they do not have a crossdomain.xml file, all you have to do is write a simple “proxy” file with PHP (or whichever language you choose) that will accept one parameter (the URL to be called) and send the results back:

1
2
3
4
5
<?php
 
	$url = $_GET["url"];
	echo file_get_contents($url);
?>

Make sure that this proxy file is sitting in your domain though, or a domain with a crossdomain.xml file present.