Creates a basic authentication manifest for logging in, logging out and
    registering new accounts.

def create_auth_manifest(**kwargs):
    """
    Creates a basic authentication manifest for logging in, logging out and
    registering new accounts.
    """
    class AuthProgram(Program):
        pre_input_middleware = [AuthenticationMiddleware]

    def register(username, password, password2):
        """
        Decorated version of basic_register with a callback added.
        """
        result = basic_register(username, password, password2)
        callback = kwargs.get('post_register_callback', None)
        if callback:
            user = User.objects.get(username=username)
            callback(user)
        return result

    return Manifest({
        'login': [
            AuthProgram(
                """
                Prints out the HTML form for logging in.
                """,
                name="Login (form)",
                input_middleware=[NotAuthenticatedOrRedirect('/')],
                view=BasicView(
                    html=jinja_template('login.html'),
                ),
            ),
            AuthProgram(
                """
                Matches up the username/password against the database, and adds the auth cookies.
                """,
                name="Login (post)",
                input_middleware=[NotAuthenticatedOrDie],
                controllers=['http-post', 'cmd'],
                model=[create_session, {'username': 'mock_user', 'session_key': 'XXXXXXXXXXXXXXX'}],
                view=BasicView(
                    persist=lambda m: {'giotto_session': m['session_key']},
                    html=lambda m: Redirection('/'),
                ),
            ),
        ],
        'logout': AuthProgram(
            """
            Send the user here to log them out. Removes their cookies and deletes the auth session.
            """,
            name="Logout",
            view=BasicView(
                html=Redirection('/'),
            ),
            output_middleware=[LogoutMiddleware],
        ),
        'register': [
            AuthProgram(
                """
                This program returns the HTML page with the form for registering a new account.
                HTTP-get only.
                """,
                name="Register (form)",
                input_middleware=[NotAuthenticatedOrRedirect('/')],
                view=BasicView(
                    html=jinja_template('register.html'),
                ),
            ),
            AuthProgram(
                """
                When you POST the register form, this program handles creating the new user, then redirecting you to '/'
                """,
                name="Register (post)",
                controllers=['http-post'],
                model=[register],
                view=BasicView(
                    persist=lambda m: {'giotto_session': m['session_key']},
                    html=lambda m: Redirection('/'),
                ),
            ),
        ],
    })