Posts

Adding Authentication to the Blog App

In the last post, we developed a very basic blog application using Happstack. Now that we have a simple application without an authentication mechanism, let's see how much effort it takes to add authentication using the Happstack-Auth module mentioned here . First let's make an outline of what needs to be done. We need the following pieces of functionality: Pages for login/registration Routines to handle the POSTed form data from the above A page to log the user out Blog posts should contain the name of the author Only authenticated users should be able to create new posts. The first thing we have to do is import the auth module. > import Happstack.Auth Let's start by looking at the first three bullets of functionaliy mentioned above. I'll implement the login/registration pages in pretty much the same way they were implemented in my old posts. A single login.html file will have a form for both registration and login. This suggests the following cod...

Basic Happstack Blog App

Happstack is improving, and my old blog posts on HAppS are now out of date. So we're in need of a bare-bones app to demonstrate functionality. I also wanted a simple app without authentication capability to demonstrate how to integrate Happstack-Auth into a project. Blog apps seem to be one of the canonical beginner's examples in the web framework world, so I thought that would be a good choice to start with. As usual, this post is literate haskell and should compile as Main.lhs. > {-# OPTIONS -fglasgow-exts #-} > {-# LANGUAGE TemplateHaskell , FlexibleInstances, > FlexibleContexts, UndecidableInstances, OverlappingInstances, > MultiParamTypeClasses, GeneralizedNewtypeDeriving #-} > > module Main where > > import Control.Concurrent > import Control.Monad > import Control.Monad.Reader > import Control.Monad.State (modify,put,get,gets,MonadState) > import Data.Generics hiding ((:+:)) > import Happstack.Serv...

A Standalone Auth Framework for Happstack

It's been awhile since my series of posts outlining some of the basic ideas behind the HAppS Haskell web framework (which is since been renamed Happstack ). Ever since I started developing it I envisioned a standalone library, perhaps shipped as a part of happstack, that would make it trivial for anyone to add robust authentication to their application. After doing some more work on Happs(tack) applications I've finally gotten around to working on the auth framework. I have created a github repository for the auth framework. It still needs a lot more work, but hopefully it will demonstrate some of the potential of Haskell and Happstack as a web development framework, and motivate some more improvement in this area. Comments, suggestions, or code contributions would be greatly apprectiated.

Happstack: An Interview with Matthew Elder

HAppS development has been all but stopped for almost a year (as have my posts about it). Recently Matthew Elder took up the flag with a new project called Happstack . I thought this would be a good time to catch up with Matthew and find out why he is doing this and where he is going with it. So without further ado, here is Matthew Elder on Happstack. Is Happstack a fork or a rename? Happstack is both a fork and a rename :) But it is not a fork in the traditional sense -- the original code in Lemmih's words (the only active developer left) is orphaned. So even though we are forking the code base to a new repository under the name "Happstack", the original project is not being worked on so it is more of a direction change than a fork. Why are you trying to take over? What happened to the previous developers? The previous developers tapered off over the last year and the only one left is Lemmih. I started out by submitting a couple of patches -- nothing fancy -- just ...

To Template Or Not To Template

Since developing the tutorial in the last few posts, I have been working on developing a real web app in Haskell with HAppS. Now that I know my way around the basics of HAppS, I need to move on to generating actual HTML (as opposed to the plaint text messages that the tutorial used). Before starting, I had to decide what methodology I would use to generate the HTML. I'm new to web development, so I may be missing something, but as I see it there are three main possibilities: Serve static pages that use AJAX to load dynamic content Dynamically generate pages with Haskell and HAppS Use Haskell to populate static page templates with dynamic content Let's first take a look at the last option, static templates. Most of the web frameworks that I've seen (ROR and several Python frameworks) use templates. The main argument for them seems to be that templates allow a separation (MVC style) of the view and controller. The page template defines the view and the Python c...

HAppS Demo

Several people requested that I post a link to a running instance of the HAppS code that I developed here over several posts. One person was nice enough to actually offer me the use of a server. So the demo is now up and running. It's not at all meant to be user friendly, since it's just a demo of the basic HAppS capabilities. So here are a list of links that are useful. http://happs.dnspass.com:8001/login - A login page where you can create a new user or log in. http://happs.dnspass.com:8001/view - A page that shows you what user you are logged in as. http://happs.dnspass.com:8001/list - A page that displays a list of all the users in the system. Hopefully this will be useful.

How I Learned to Stop Worrying And Love Haskell's Type Inference

In developing the HAppS example that I have been posting here, I came upon a problem that gave me new insight to Haskell. I don't think it was a particularly deep insight, but it is significant to me as someone new to the language, and new to type inference. Consider a user authentication function that retrieves a map from the reader monad, looks up a username, and compares the password retrieved with a passed in parameter. I first implemented this function something like this: data User = User { username :: String, password :: String } authUser name pass = do u In the process of getting there, I stumbled around rearranging and inserting various liftM calls until I finally got it to work. Many of the reasons behind the type errors still seemed like voodoo to me. And my haphazard approach to fixing them is evident looking at the code. The problem with this function is how it behaves when the username does not exist in the map. A look at the lo...