web development and photography
Posts tagged coding
Flomo iphone app
Jul 12th
A few weeks ago I decided to start playing around with iPhone app development. It would, I thought, be a relatively straightforward thing. Even small children could do it.
But what to choose as a test project? Perhaps something stupid that made some kind of farty noise each time you shook your iPhone? Nah… build something useful Matthew. Something I and others like me would want to use.
Uploading images to Flickr seemed like a cool idea. There are some really nice apps out there that do this already. Hmmm…
Another thing was simple image manipulation. You know, make your crappy iPhone photos look like you took them with a Lomo ie turn them into something bad yet cool. Already done. Hmmm….
I know – combine the two! Brilliant idea! Let’s call it Flomo (flickr + lomo). Lame name – yes. Arsed to think up a better name – no. I even designed a funky logo (above).
Turning the idea into reality has proven to be somewhat more tricky than I’d thought. Trying to run before learning how to walk is a cliché that springs to mind. But it’s been a useful lesson in iPhone development.
Specifically it’s taught me:
1. How to access flickr’s API. Authentication with their API is like sticking hot pins in your arm at the best of times, never mind in an unfamiliar language (Objective-C).
2. Objective-C doesn’t have a simple way of doing MD5 hashes. It’s a pretty much build your own kind of thing. Ugh.
3. How to process images. Thanks to some online help and general banging-head-on-wall type thinking, I’ve finally realized that image processing isn’t all that hard. Neither is it easy. Finding stuff on forums like (I paraphrase) “listen you newbie scum, this kind of thing is so trivially easy I’m not even going to explain how to do it” didn’t help. But I got there. I’ll publish relevant bits of my code in the next post.
4. Multithreading is really useful. Do you want a nice spinny wheel thing while the image is uploading, so your user doesn’t think the app has broken? Well you *have* to use multithreading. Obvious if you know that it’s obvious. Like so much in iPhone world.
5. XML parsing? Not easy and not fun. Just parsing a simple web service response is bad enough. Making any sense at all of complex XML seems like far too much hard work. PHP SimpleXML – I love you!
There are all kinds of other bits and pieces which I’ve had “fun” with. I’ve probably implemented them really badly. But I don’t care. I have an iPhone app which works. Just a little more work and it’ll be ready to submit to Apple and wait months before it ever appears on the store for free.
Oh, and those news reports about small children coding for the iPhone? Two words: parental guidance.
WordPress MU and user registration grief
Apr 2nd
WordPress MU (WPMU) is a great tool.
It’s basically a fork from the main WordPress software that lets you set up and maintain potentially vast numbers of blogs from a single codebase. It’s particularly popular with universities and HE institutions, such as Harvard Law School (http://blogs.law.harvard.edu), and a range of UK universities including here at Kent.
Why registration?
So, why would you want to allow user registration for blogs? Mostly, blogging is all about free commenting on posts, and the onus is on the blogger to filter out dodgy comments.
If you’re like me with just a handful of comments every month, fine.
If you’re an institution like a university, this opens up the proverbial can of worms (I’ve never seen a real can of worms, but I’m sure it’s not pretty) to do with complaints, disciplinary procedures, legal stuff. Far better to force people to register before making a comment, so there’s at least a way of telling whether they’re from the institution, or a member of the public.
No comment.
WordPress MU registration system is bad. Not in a cool sense of bad. It’s just terrible.
1. Confusing to users. You might want to register for MyHappyBlog because you want to comment on a blog post. The moment you register you’re sent on a multi-click process which takes you far, far away not just from the familiarity of MyHappyBlog, but from the post, and any memory of the stinging critique you were going to deliver. No comment, quite literally.
1a. …oh and by the way, just to make it even more confusing, the user will be sent an impossible-to-remember password after they’ve registered. Although this is touted as being secure (I’m sure it is), it’s just impractical. Either the user will forget the password, or they’ll forget to change it.
2. Confusing to developers. WordPress MU registration works fine so long as you follow the way it does things. If for some bizarre reason you want to change the way the registration page looks (you mad fool!), you have to change the core code. As any developer will tell you, this is generally a very stupid thing to do, and ipso facto a stupid thing to force people to do.
Logged out
I should just add that it’s actually not just the registration system in WPMU. Standard WordPress has a curious login page which is very hard to change. Yes, you can get round this in part with filters and plugins and whatnot. But the point is that changing the way something looks should never, never, require a developer to hack around a bit. This is what themes are for.
Summary
My advice to anyone considering user registrations in WPMU? Don’t. The fact that the registration system is so quirky might be indicative of the relatively relaxed approach most bloggers have towards commenting. You may want to ask why it is that you absolutely must have user registrations for your institutional blogs.
symfony’s sfGuard plugin and LDAP
Jun 29th
A while ago I needed to hook up symfony’s excellent sfGuard plugin to some LDAP functionality. There are a couple of issues with the plugin and the readme which I think need fixing. In particular, there is no support for checking both LDAP and standard sfGuard passwords. This is absolutely essential (eg an admin user or guest users who aren’t in LDAP), and I’m somewhat amazed that there’s no provision for this. Moreover, the plugin structure generally makes it seemingly impossible (or if it is possible it’s just too horrible to contemplate) to write your own checkPassword() which does do both sorts of checking.
Anyway this post is partly an attempt for me to get my head round something which I’ve either totally misunderstood, or just isn’t well documented.
Confusing README
The README file that comes with the plugin is great, but it’s a little confusing for explaining how you might override its own way of checking passwords with something that’s LDAP-based. It’s really very simple to do when written out in plain English:
1. Make a file called myLDAP.class.php in your application’s lib folder. Put this in it:
class myLDAP extends sfGuardSecurityUser
{
}
2. Now put a method inside the class you just created:
public static function checkLDAPPassword($username, $password)
{
// put your preferred LDAP-checking code in here
// should return true or false
}
3. Add this to your application’s app.yml file:
all:
sf_guard_plugin:
check_password_callable: [myLDAP, checkLDAPPassword]
where myLDAP is the file called myLDAP.class.php that you created in step 1 above. checkLDAPPassword is the method you made inside myLDAP.class.php that you made in step 2.
And there you have it. Basic LDAP password checking.
How does checkPassword() actually work?
The above code is all very well, but what’s really going on?
Well, there are a couple of steps which I managed to work out:
1. sfGuardUserValidator contains a call to $user->checkPassword($password) where $user is a result of sfGuardUserPeer::retrieveByUsername($username)
2. PluginsfGuardUser (extends BasesfGuardUser) has a method called checkPassword() too. This calls the method you listed in your app.yml file (checkLDAPPassword in this case), or does a standard sfGuard password check (checkPasswordByGuard) if you didn’t specify anything:
public function checkPassword($password)
{
if ($callable = sfConfig::get('app_sf_guard_plugin_check_password_callable'))
{
return call_user_func_array($callable, array($this->getUsername(), $password));
}
else
{
return $this->checkPasswordByGuard($password);
}
}
Which it does depends on how you set up your app.yml file (see Step 3 above).
At this point, if you set up your app.yml correctly you’ll be in your custom checkLDAPPassword() method, which will do whatever you want it to do to check LDAP passwords. So long as it returns true or false depending on whether the check was successful or not, you’ll be ok.
Note that sfGuardSecurityUser class also contains a checkPassword() method. This basically does the same thing as the in sfGuardUserValidator, but in a slightly different way, and allows access to checkPassword() in templates and controllers through the $sf_user object. The important thing to realise is that both pieces of code end up calling the same checkPassword() method in PluginsfGuardUser.
So how about LDAP and sfGuard checking?
Now the fun begins. The problem is that it’s seemingly impossible to call checkPasswordByGuard() yourself from inside your custom-built checkLDAPPassword() method. Why would you want to do this? Because that way you can do some standard password checking first to see if your user is in fact a sfGuard user and not an LDAP user. Only if that failed would you do LDAP checking (I suppose you could do it the other way round if you wanted.) Even better, you wouldn’t need to alter checkPasswordByGuard().
So why is it impossible to call checkPasswordByGuard() ‘by hand’? As far as I can see, it assumes that you’re not in a static context, and that you have some kind of user object available. But of course, my checkLDAPPassword() is in a static context. It had to be that way because it was called by call_user_func_array() which uses the output of sfConfig::get() as an argument.
Sigh…
If you find a way of doing this, please let me know. Losing the will to live is merely one of the symptoms of battling with this sort of thing. I have a life to live.
All I can suggest to you in the meantime is to modify your copy of PluginsfGuardUser.php to allow both sorts of password checking. That’s what I did and it worked for me. It’s just a pity that you can’t override the checkPasswordByGuard() method in some way without changing the core of the plugin.