Jul 20, 2009

Competitor

My business pretty much depends on a single customer. Last week I found out that I have a major competitor. Either he gets the account or I do. It's an all or nothing game. My competitor is further along in the development process than I am, plus he has been communicating extensively with the customer. I've been communicating with the customer as well, but I really think the other guy beat me to it.

For these reasons, I'm scrapping my original business idea and will put development of the software on hold.

However, all is not lost. What I have done so far are users, permissions, sessions, authentication, and a UI framework. This is the first part of what needs to be built for any web application.

Fortunately, I have a few other business ideas, and I can use what I've built already for any of those projects. I'm going to take a few weeks off to decide exactly what direction I'd like to go. But I have a big asset in the work I've already done.

Jul 10, 2009

Pumping Out Code

The next week or so will not be too glamorous. I won't be doing any design, just coding coding coding. I know what I need to get done, it's just a matter of putting in the hours to write the code to make it happen.

I made an elegant workaround for ticket #633 and am in the process of finishing up the permissions system in my app. Coding coding coding. I won't have a test site ready this week, but it should be up during the early part of next week.

I also finally settled on a name for the web domain, application, and business.

Jul 7, 2009

CakePHP Trac Ticket #633 = Headache!

Take a look at this major limitation of CakePHP:
Recursive Association Support

Users belong to Chapters. Chapters belong to Conferences. Given a user's ID, how can I find out which conference he is in?

I can do this quite easily with SQL, but the whole point of using a framework is to abstract away from SQL. I've been trying to figure out how to do this in CakePHP all day, and then I realized that the framework doesn't support this type of recursive association.

Grrrr!!!

There are some hacky hacks out there, but I'm real nervous about copying someone else's hacky code. I think I'll resort to hand-writing SQL queries for this. I wish I would have know about this bug eight hours ago!

Jul 6, 2009

Goals For The Week

I'd like to have a working UAT site by the end of this week. Specifically, this is what I'll need to do to accomplish this:

Create the permissions table
Set up the four permission levels
Write code to handle permissions
Create the Chapters and Conferences tables
Associate users to permissions
Associate users to chapters
Associate chapters to conferences
Make a final decision on the domain name
Deploy to a server
Create a feedback mechanism
Start a blog

I eventually want to get my old attendance software ready for sale as well. I'll just need to make a few minor changes to it.

Jul 4, 2009

Goodbye To SQL

I haven't had to write a single SQL query, and I don't plan to. Good frameworks will take care of all of this for you. In the .NET world, Linq To Sql abstracts away SQL calls. CakePHP also includes very powerful tools to perform CRUD operations on database tables. Creating relationships between tables is extremely easy as well. Find and save operations automatically look for associated data (although you can limit this recursively). It's so so nice.

Never ever try to develop a web app without a framework!

I fixed a few minor bugs yesterday. The first field of each form automatically receives focus now. Kind of a nice feature. Also the menu links are working so I don't have to type URLs every time I want to see a page.

Next week, I'll work on permissions, and then I'll be working on deploying to a server to start user acceptance testing. I plan on doing iterative private beta releases so I can get feedback early. I'll also start a blog and some sort of feedback mechanism.

Jul 2, 2009

Authentication and Sessions

The entire day was spent on user authentication. Here's what I got done:
  • The application checks for a valid session on every page request. It displays an error message and reverts to the login page if the session has expired or contains invalid user information.
  • Users with default passwords are automatically redirected to the Change Password screen and are not allowed access to any other screens until their passwords have been changed.


Man, it feels like I did a lot more work, but really, that's it in a nutshell. Really, getting the entire authentication functionality done in one day is making pretty good time. I haven't started adding functionality for role-based security yet. Now, if a user is logged in, they have access to everything.

So the User controller is as done as it can get until I add functionality for all the stuff that users are linked to.

I'm ticking bugs off my list faster than I'm adding them, so I guess that's good news.

One thing that's a bit different: the Change Password page does not require an authenticated session; the user ID can be passed through the URL as a UUID. But this is not a breach of security, because the user must still provide login credentials on this page. This was an easy way to solve the problem of locking out new-but-not-password-changed users from all parts of the application. I just added Change Password to my list of exceptions for which actions require login. And I did a whole bunch of other stuff to make things nice and bulletproof. But I'm not telling you what they are!

Jul 1, 2009

Cross Site Request Forgeries

Before, I was using CakePHP's Security component to defend against CSRF attacks. This component generates a secret token and includes it as a hidden field on every page. On every request, CakePHP checks to see if the token coming back from the POST data matches the expected value. If not, the request is denied. This is a pretty bulletproof way to stop CSRF attacks.

However, the Security component was giving me random bugs, and after about two hours of research and debugging, I decided to finally give it the axe. I won't have the tokens any more, but I am requiring all actions that change state be either POST, PUT, or DELETE, depending on the action. Also, the session timeout is set for 10 minutes. These two things will reduce the risk of CSRF attacks as well. I've decided not to check the referer because a lot of school networks strip this off of their HTTP traffic and I'd be denying legitimate users.

Also, I don't allow users to upload images or scripts. All user input is severely sanitized.

The measures I have in place are not 100% bulletproof against CSRF, but in my judgement they're good enough. It would be very difficult for an attacker to be successful.

Today I finished the Delete User and Log In pages, with SHA1 password hashing and everything. I have a few placeholders that the User model depends on, which I hope to get to next. Actually my next project is authentication.

CakePHP has a built-in component for this too, but it won't suit my needs. It requires only one username and one password field. But I want my users to log in with their first name, last name, and password. There's no way to hack around that limitation in Cake, so I'll be writing my own authentication methods. This isn't a bad thing because I'll have a much deeper understanding of how it works.

The login page is pretty because it has a picture on it.