Project 6.0: Gamez

Feb 7, 2011

Objective

Learn how to implement the basics of a multi-user application.

Prerequisites

You should have completed Project 5. You should have completed Unit 6.

Requirements

You must create an application that has three distinct areas: public, admin and members. Users must authenticate (log in) in order to access the admin or members areas. Access to admin and members areas is limited to users with particular roles.

You will reuse this functionality in all future applications.

Premise

You've decided that working for Articl.es may have been a great way to test your Rails mettle, but there's no way you could build an application according to requirements from the CEO's relatives. After much thought and many pints of orange juice, you had decided to venture out on your own and create a basic application for listing and rating games.

"Naah, nobody would be interested in keeping track of that," says your friend after hearing you describe your idea. "Now, keeping track of funny things that happen during games and rating their shamefulness? Now that would be funny. Or, fun. Fun and funny. You know what I mean. Game-shame-dot-com! Shameful things that happen during games. All games, not just computer games. Think "Yahtzee," he says, "Jenga, Monopoly, bridge," and "Mind Games My Ex-Lover Tortured Me With--".

You interrupt. "That sounds great. Look, I've got to get to work." you say, thank him and leave the cafe. "Hmmm... games or shames? It doesn't matter, I'm going to have to get some basics working first. Let's get to work."

You've decided the first step in your venture is to create a boilerplate application that includes:

Let's dive into the spec!

Purpose

Gamez is a database-backed Web application that allows people to create their own lists of games and rate them.

Scenarios

Howie Gaimur, Game Lover (member role)

Howie Gaimur is a card-game fanatic and wants to create a list of the most enjoyable card games he knows. Don't ask why -- Howie rarely speaks. He's been working in the basement of Ontario's tallest building babysitting an old VAX machine that somehow still manages to provide GigaBurger Inc's payroll services. Needless to say, he plays a lot of cards down there. He hears of Gamez through his friend Philip, his only friend Philip, who suggests he try your application.

"The Gaiminator," as he prefers to be called, visits your URL in his browser and sees a screen that displays a list of games recently entered into the system. He clicks a link to register, fills out a form (which includes his choice of uploading a picture of David Hasselhoff) and sees a new screen that says "Welcome, Howie Gaimur," and a list titled "My Games"

"Oh... my... my dream app has materialized! I can list all of the 2,038 games I know," entranced, he types and clicks well into the night.

Philip Greenspun, Gamez Creator (admin role)

Philip Greenspun, the same Philip whom Mr. Gaimur, The Gaiminator, calls "friend," is actually the developer behind Gamez. Yes, that sly Greenspun created the app and pretended that he'd "heard of it, through another game-loving friend of mine... it's even invite-only, Howie!" But Howie wasn't the only person he'd told; Philip told everyone he knew. Which is approximately three other people.

Anxious to check out the data in his application (which he plans to extract, mine and sell to game companies for just $20,000, the price of a used Porsche 968 he'd been wanting since his teens) he visits his URL, clicks the "Log In" link and completes the login form. He then sees his admin interface, which displays a menubar containing links to games, users and roles. The application provides him simple navigation between these three elements of the system and the ability to list and edit any of them.

Michael Hacker, Anonymous Web Surfer (public user role)

Michael Hacker has despised Philip Greenspun since second grade (it's a long story). He hears of Philip's Gamez application and tries to see what he can access. "I'm sure Philip isn't following Web app best practices. He's probably using Rails, which isn't secure. It's true, I heard it, believe me," he says to himself, interacting with his own self-defiance in a strange kind of inner dialogue.

He visits the Gamez URL and tries /members and is warned "You do not have permission" He then tries /admin and is warned "You do not have permission Michael, go away! Get over it! It was 20 years ago!" It seems the only things Michael can do are see a list on the main application screen, log in, and register.

"Hmmm... who is this Howie Gaimur? I know him, he works in the basement at the office."

Howie Gaimur, Upset Friend (member role)

Having been told that Philip was behind Gamez by a mysterious stranger, who went only by "MH," Howie decided to try to access the admin portion of the application. He logs into the application and then visits /admin and sees a red message that states, "You don't have permission to do that."

Screen-by-Screen Specification

First, here's a high-level overview of the general architecture of this application.

When users visit the root url of your app they should see the Home screen. It looks like this:

Now, this might change a little if the user is logged in. For example, if the user is a Member, then it might look like:

Or if the user is an Admin it might look like:

The Home screen basically displays a paginated list of games in the system.

Users should be able to log in. You need to have a publicly accessible Log In screen and a Register screen:

Notice that users can upload an embarrassing photo of themselves to the application.

Once a new user registers, or a returning user logs in, they should see the Member Home screen. It looks like this:

The member can click on his or her name to edit personal information:

And the user may create a new game:

And can edit a game:

The member can only edit a game that he or she created. If the member somehow tries to edit a game he or she did not create, a red "Permission denied" message should be displayed near the top of the Member Home screen.

That's about it for the typical user. Now, when you log in, you have "admin rights" to the system. As such, after logging in you see the Admin Home screen:

You can edit your own information by clicking your name in the upper right. You can navigate to other areas of the system via a menubar. For example, you can view all the users in the system:

And you can edit any user, including changing his or her role:

Of course, you can create a new game:

And edit any game in the system, including changing which user is created the game:

Lastly, you have full CRUD access to Roles in the system.

You should implement the typical CRUD-based behavior for Roles. All roles must have names (no empty strings).

Additional Requirements

Use haml and sass.

Use authlogic and declarative_authorization.

Use will_paginate and paperclip.

Use the recaptcha plugin.

Recommended Steps

First, relax. This seems like a lot, but it really isn't. Much of the work is handled by gems.

In your repository, create a directory called project06, place an appropriate .gitignore file in the directory and initialize a new Rails 2.3.x app.

The purpose of this assignment is to show you how to implement a secure, multi-user, role-dependent application. This functionality is absolutely essential and common for most Web applications. Public users can do a few simple things, including register. Admins can access an admin area with full CRUD over the domain. Members can access certain members-only areas with limited CRUD access over the domain.

IMPORTANT: the code you create here will be something you can (and will) reuse, so it's important to get the user/role management right. As such, I recommend you focus on users and roles first, and then add the Game model last. Before you add the Game model, tag your codebase with git (git tag basic_multiuser_system). Think of this as naming the current state of your repository so that you can easily return to that state. This tagged version of your repository should reference a basic Rails app with only user login/admin/members functionality. In the future, you can checkout this tag, and reuse the code in another application. (The best way to do this is with app templates, but we're not going to cover that in this class.)

Hints

Start early, and ask questions on the forum. For example, what's the best way to handle the ratings? How do you use namespaced classes and routes to create an /admin area and a /members area?

See the links and topics in Unit 6.

Start small and accomplish one thing at a time. Implement as many features as you can, one at a time. For example, you could add the declarative_authorization features last.

Don't get caught up with how your application looks. Save that for the end, when the functionality is done, if you have the extra time. I am entirely concerned with server-side code, not how your app looks.

If you find yourself relying on scaffolding and hate having to convert the erb to haml manually, you might try out Ryan Bates nifty-generators gem (use the --haml option).

Grading criteria (2000 points)

I must be able to pull your repository and see your project06 directory contains your app root. (eg, project06/app, project06/config, etc)

Your project06 directory must not include things that shouldn't be present in a repository (eg, logs, database). (100 points)

You must provide seed data. (100 points) I must be able to run rake:db:setup to bootstrap your application's data. IMPORTANT: Your seed data must create

You must have a root route declared in routes.rb (100 points).

You must have namespaced routes declared in routes.rb (100 points).

Your user registration screen should use a captcha, via the recaptcha plugin. (100 points)

Your views must use haml and your stylesheets should be generated from sass. (100 points)

Your application should make use of three layouts: public, admin and members. (100 points)

Your application must meet as many of the functional requirements as possible by the deadline.

There are two due dates.

Initial review and feedback: due by 9AM on Tuesday March 1. You must have some work submitted (the more the better!) and I'll provide you some intermediate feedback.

Final deadline: due by 9AM on Monday March 7.