Archive for October 2009

CSS Popups are annoying

I was just Googling for some information and found a relevant search result from a forum somewhere. While reading through the forum responses, the page faded to dark and a CSS popup window came up telling me that the site I was visitng was an online community of something or others.

No shit? I’m reading a forum answer that involves multiple people posting. Obviously, it’s an online community of some sort. Why did you interrupt my reading to tell me this? I’ll say one thing, whatever your community is, there is no chance of me signing up.

No, in fact, I didn’t even read the rest of the discussion, I went back to Google and tried another search result. Annoying guest users is not the best way to attract them to your community.

Some sites are even worse, they use CSS popups for advertising. Popping up advertisements in front of whatever the user is reading is another sure way of ensuring they won’t return. Don’t expect people will be more likely to generate ad revenue because you hit them over the head with an ad.

Another recent trend is ecommerce sites that pop up a, “We’d really appreciate it if you provide feedback about your shopping experience,” survey request while you’re shopping. Well, for starters, I’d have enjoyed my shopping experience a lot more if you hadn’t interrupted it with this stupid survey.

(Updated) I just noticed that even Stack Overflow is doing this now, with a, “new to this site, read the FAQ,” popup. It’s less obtrusive than some, showing up at the top of the page, but I am NOT new to Stack Overflow, and if I was, I would read the FAQ only if I wanted to. They shouldn’t be doing this. Bad Stack Overflow!

This is so obvious, I can’t believe I’m discussing it: Don’t annoy your web visitors unless you don’t want them to come back.

Arch Linux Was Invented In Canada

Arch Linux was invented in Canada by a guy called Judd. I want everyone to remember that. Why? Because if the great taco vs poutine war ever turns bloody, we must remember our roots.

Also, I’d like to announce a new Arch Linux community, the bringing Arch Linux home community, the community for Canadian Archers:

I dunno what we’ll discuss. If you need help, the official forums are the best place to get it, so my thinking is this is a forum for Canadian socializing (and plans of world domination, something most Canadians are not aware we should be trying to achieve). Huge communities like the Arch Linux community are great, I love it and am proud to be part of it. But smaller communities are also nice because you can get to know individuals better, and have more in common.

It’s not closed to non-Canadians, but if you don’t know how to properly use ‘eh’ in a sentence, can’t form a good snowball, think tacos are better than poutine, or believe hockey is a silly sport, you probably won’t fit in. ;-)

Django Permissions System Issues

In a recent post I bashed Django’s url handling as being too complex. In this one I’m going to bash (with a great deal of respect) the permission system. Before I do this, I want to state one thing unequivocally:

I love Django. It’s incredibly powerful, and most of the time it makes complex stuff simple, and trivial stuff easy. I don’t believe there is a web framework out there that is more suitable for most of the tasks I need to do (I use extensively for some of those exceptions). But Django has issues (usually based in over-engineering: the primary pest of Python programming), and my goal is to remind people not to assume that just because something is the “proper” way to do things in Django does not mean it is the proper way to do it in Python.

The Django permissions system works extremely well in this scenario: You have a bunch of different tasks related to models (usually add, edit, and delete, which Django kindly automatically creates for every model you create) that you want to allow different people to be able to do, based on the type of model. You can classify permissions into groups, such that different groups have specific access to different types of models. Then you can add users to those groups. But if you want to fine-tune permissions on a user-by-user basis, you are free to do so.

This model is great for broadcast sites like blogs and news sites (the original problem domain for which Django was designed). But when you have interactive sites where users can log in, it fails drastically because it lacks row level permissions. I can’t use the Django permission system to ensure that a user can only modify posts they created, and not the posts of their mortal enemy on another account.

That’s a well-known beef with the Django permissions system, and there are various work-arounds available. In this case, however, Django fails to make a complex task simple.

But that’s not my main beef with Django’s permissions.

Most of the specs I receive seem to classify users into groups, similar to the Django concept of groups. Certain groups are able to do certain things. But my specs don’t generally define the permissions so well. They usually associate groups with views. Group A can access View B, Group B can access Views C and D. This is a much coarser grain of control than Django permissions.

The Django permission system supports this. All I have to do is figure out which permissions are active in any given view and ensure that those permissions are required (Django gives me a nice decorator to do this) to access the view. Then I just need to make sure each group of users have exactly the permissions they require to access those views.

What? That’s all I have to do? In practice, that is even more complicated than it sounds. I need to define fixtures for the groups (which sometimes fail since we’re dealing with content types here, and they don’t cooperate with fixtures) so that end users don’t have to go mucking with permissions. It’s easy to overlook a permission in a group or in a view, which makes it impossible for a group of users to access a view they’re supposed to be able to access. Worse, it’s also easy to add a permission to a group that shouldn’t have it. With n3 (n is the number of models) or more permissions, it’s really easy to get confused.

My solution to date has been to write a whole passel of tests to ensure that exactly the right people are accessing exactly the right views. That’s a good thing, of course. Lots of tests always is. The disturbing thing is how many of those tests fail when I write them. If I overlooked any tests, there are probably outstanding permission bugs. That could be a simple annoyance when a user can’t log in, or a blatant security hole when an anonymous user manages to access (or worse: modify) data meant to be private.

In this case, Django is failing to make a simple task trivial.

Over time, I’ve started “cutting corners” to save time. Instead of checking individual permissions, I set my views up to check which groups the user is in. This obviously doesn’t give me as much control, but it is working at an abstraction level suitable to the task. If I suddenly need more control over permissions, I can easily fall back on Django’s permissions system. I’ve realized that my “cutting corners” is actually “writing less complicated, easier to maintain, more Pythonic code.” Having realized this, I’ll probably write a few extra auth decorators like @group_required to simplify my code.

In summary, while the Django permissions system is best of class for it’s intended purpose, it does not extend adequately to more complicated tasks (row-level permissions), nor does it simplify elegantly to cover more trivial tasks (group-level permissions).

Google Wave Bugtracker… concept

Last night I received access to the Google Wave Developer Sandbox. My original request for access was made when I had a lot more free time than I do now (I’m measuring free time on a negative scale now: I don’t expect to have any until May). My plan at the time was to integrate Google Wave with bugtracking software (written from scratch). I haven’t actually looked at the wave APIs yet, but I had considered all three methods of extending Wave for use with a bug tracker:

  • Embedding: An embedded wave on an external bug tracking webapp would make discussion much simpler and more robust. Most bug trackers don’t even have threaded comments right now. The ability of a wave to allow synchronous or asynchronous discussion would make the discussion system much more useful (most discussion on bugs currently happens “out of band” on mailing lists or in chats). In addition, a “subscription” feature could be as simple as adding yourself to the wave. Finally, the ability to edit wave postings (wiki style) would allow the data in the bug report to be easily organized and classified. People wouldn’t have to read entire lists of comments to get an overview.
  • Robots: At the simplest form, adding a robot to an existing wave would create a new bug report based on that wave. It would be nice if you could also have the robot automatically set bug attributes such as project, version, milestone, architecture, etc (whatever the project demands).
  • Extensions: An extension to wave could allow bugs to be integrated into other waves, instead of just waves into bugs. Instead of being stuck on a fixed bug report server somewhere, the bugs could be sent to other wave users. That could even include upstream authors. This is the most interesting prospect, because it could lead to a “global bug tracking service” where bugs are not attached to a single reporting tool, but are easily routed to the people most able to fix them.

In Arch Linux, many, but not all, of our bugs are related to specific packages. It would be nice if bug reports could be attached to packages in our web interface. Then it would be easy for users to report bugs on specific packages, and for developers to find all bugs related to their packages.

Our team includes a few dedicated (and extremely under-appreciated) users who classify incoming bugs and assign them to the developers who ought to be responsible for fixing them. I imagine a wave scenario where this can be done as easily as forwarding all new bugs to these “bug wranglers” wave accounts, and allowing them to add other developers to the wave and have them automatically assigned.

Ideally, we would host the wave server ourselves, so as to be in complete control of our information. Of course, if someone else wants to add themselves to a wave from a different service, that should not pose a problem.

Unfortunately, I suspect that when I have time to complete this project, I’ll have been swept up in some new and exciting venture. But it’s certainly an interesting tool to think about.