Commits

Michael Granger  committed fd61434

Initial checkin

  • Participants

Comments (0)

Files changed (16)

+\.env$
+\.sqlite$
+# .rvm.gems generated gem export file. Note that any env variable settings will be missing. Append these after using a ';' field separator
+configurability -v1.1.0
+sequel -v3.35.0
+#strelka -v0.0.1
+#amalgalite -v1.1.2
+
+#!/usr/bin/env bash
+
+# This is an RVM Project .rvmrc file, used to automatically load the ruby
+# development environment upon cd'ing into the directory
+
+environment_id="ruby-1.9.3@strelka-authtoken"
+rvmdir=${rvm_path:-$HOME/.rvm}
+gemset_file=".rvm.gems"
+
+if [[ -d "${rvmdir}/environments" && -s "${rvmdir}/environments/$environment_id" ]]; then
+	echo "Using ${environment_id}"
+	. "${rvmdir}/environments/$environment_id"
+
+	if [[ -s "${rvmdir}/hooks/after_use" ]]; then
+		. "${rvmdir}/hooks/after_use"
+	fi
+else
+	# If the environment file has not yet been created, use the RVM CLI to select.
+	if ! rvm --create use  "$environment_id"; then
+		echo "Failed to create RVM environment '${environment_id}'."
+		exit 1
+	fi
+fi
+
+if [[ -s "$gemset_file" ]]; then
+	rvm gemset import "$gemset_file"
+fi
+

File History.rdoc

+## 0.0.1 [2012-05-17] Michael Granger <ged@FaerieMUD.org>
+
+Initial release.
+

File Manifest.txt

+History.rdoc
+README.rdoc
+Rakefile
+data/strelka/_auth_token/apps/strelka/_auth_token_app
+data/strelka/_auth_token/templates/layout.tmpl
+data/strelka/_auth_token/templates/top.tmpl
+lib/strelka/_auth_token.rb
+spec/strelka/_auth_token_spec.rb
+# Foreman procfile
+mongrel2: m2sh.rb -c mongrel2.sqlite start
+demo: strelka -l debug -c datas/strelka-authtoken/demo-config.yml start demo
+
+= Strelka-AuthToken
+
+* FIX (url)
+
+== Description
+
+FIX (describe your package)
+
+== Installation
+
+    gem install Strelka-AuthToken
+
+== License
+
+Copyright (c) 2012, FIX
+All rights reserved.
+#!/usr/bin/env rake
+
+begin
+	require 'hoe'
+rescue LoadError
+	abort "This Rakefile requires 'hoe' (gem install hoe)"
+end
+
+# Sign gems
+Hoe.plugin :signing
+
+Hoe.spec 'Strelka-AuthToken' do
+	self.readme_file = 'README.rdoc'
+	self.history_file = 'History.rdoc'
+	self.extra_rdoc_files = FileList[ '*.rdoc' ]
+
+	self.developer 'FIX', 'FIX' # (name, email)
+
+	self.dependency 'strelka', '~> 0.1'
+	self.dependency 'rspec', '~> 2.7', :developer
+
+	self.require_ruby_version( '~> 1.9' )
+end
+

File data/strelka-authtoken/apps/demo

+#!/usr/bin/env ruby
+
+require 'strelka'
+
+# An application that demonstrates the 'authtoken' auth provider for Strelka apps.
+class AuthTokenDemo < Strelka::App
+
+	# The Strelka appid
+	ID = 'authtoken-demo'
+
+
+	# Auth plugin
+	plugin :auth
+	auth_provider :authtoken
+	require_auth_for '/restricted'
+
+
+	# Templating plugin
+	plugin :templating
+	layout 'authtoken/layout.tmpl'
+	templates form: 'authtoken/form.tmpl',
+	          success: 'authtoken/success.tmpl'
+
+
+	# Routing plugin
+	plugin :routing
+	get do |req|
+		return :form
+	end
+
+	get 'restricted' do |req|
+		return :success
+	end
+
+end # class AuthTokenDemo
+
+AuthTokenDemo.run if $0 == __FILE__
+

File data/strelka-authtoken/demo-config.yml

+---
+mongrel2:
+  configdb: mongrel2.sqlite
+
+logging:
+  __default__: debug (color)
+  inversion: info(color)
+

File data/strelka-authtoken/gen-config.rb

+# -*- ruby -*-
+# vim: set nosta noet ts=4 sw=4:
+#encoding: utf-8
+
+# The Mongrel config used by the demo app.
+#
+#   m2sh.rb -c mongrel2.sqlite load data/strelka-authtoken/gen-config.rb
+#
+
+require 'strelka'
+require 'mongrel2'
+require 'mongrel2/config/dsl'
+
+Strelka.load_config( 'data/strelka-authtoken/demo-config.yml' )
+
+# samples server
+server 'demo' do
+
+	name         'Strelka AuthToken Demo'
+	default_host 'localhost'
+
+	access_log   '/logs/access.log'
+	error_log    '/logs/error.log'
+	chroot       '/var/mongrel2'
+	pid_file     '/run/mongrel2.pid'
+
+	bind_addr    '127.0.0.1'
+	port         8118
+
+	host 'localhost' do
+		route '/', handler( 'tcp://127.0.0.1:9818', 'authtoken-demo' )
+	end
+
+end
+
+setting "zeromq.threads", 1
+
+mkdir_p 'var'
+mkdir_p 'run'
+mkdir_p 'logs'
+

File data/strelka-authtoken/templates/authtoken/form.tmpl

+<?import request ?>
+
+
+<!-- $Id$ -->
+<form action="[?urlencode request.uri ?]" method="get" accept-charset="utf-8">
+	<label for="username">Username</label>
+	<input type="text" name="username" value="" id="username-field">
+
+	<label for="password">Password</label>
+	<input type="password" name="password" value="" id="password-field">
+
+	<p><input type="submit" value="Authenticate &rarr;"></p>
+</form>
+

File data/strelka-authtoken/templates/authtoken/layout.tmpl

+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title><?subscribe title || Demo ?></title>
+
+	<style type="text/css" media="screen">
+		html {
+			background: #eee;
+			color: #333;
+			margin: 0;
+			padding: 4em 2em;
+			font-family: sans-serif;
+		}
+	</style>
+</head>
+<body>
+
+	<header>
+		<h1><?subscribe title || Demo ?></h1>
+	</header>
+
+	<section id="body"><?attr body ?></section>
+
+	<footer>
+		<p>Copyright &copy; 2012, Michael Granger</p>
+	</footer>
+
+</body>
+</html>
+

File data/strelka-authtoken/templates/authtoken/success.tmpl

+<p><strong>Success!</strong></p>

File lib/strelka/authprovider/authtoken.rb

+# -*- ruby -*-
+# vim: set nosta noet ts=4 sw=4:
+
+require 'loggability'
+require 'configurability'
+
+require 'strelka' unless defined?( Strelka )
+require 'strelka/app' unless defined?( Strelka::App )
+require 'strelka/authprovider'
+require 'strelka/mixins'
+
+# AuthToken authentication provider for Strelka applications.
+#
+# This plugin provides cookie-based authentication using the "Secure Cookie Protocol"
+# described in:
+#
+#   http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf
+#
+# == Configuration
+#
+# The configuration for this provider is read from the 'auth' section of the config, and
+# may contain the following keys:
+#
+# [users]::   a Hash of username: SHA1+Base64'ed passwords
+#
+# An example:
+#
+#   --
+#   auth:
+#     realm: Acme Admin Console
+#     users:
+#       mgranger: "9d5lIumnMJXmVT/34QrMuyj+p0E="
+#       jblack: "1pAnQNSVtpL1z88QwXV4sG8NMP8="
+#       kmurgen: "MZj9+VhZ8C9+aJhmwp+kWBL76Vs="
+#
+class Strelka::AuthProvider::Basic < Strelka::AuthProvider
+	extend Loggability,
+	       Configurability,
+	       Strelka::MethodUtilities
+	include Strelka::Constants
+
+	# Configurability API - set the section of the config
+	config_key :auth
+
+
+	@users = nil
+	@realm = nil
+
+	##
+	# The Hash of users and their SHA1+Base64'ed passwords
+	singleton_attr_accessor :users
+
+	##
+	# The authentication realm
+	singleton_attr_accessor :realm
+
+
+	### Configurability API -- configure the auth provider instance.
+	def self::configure( config=nil )
+		if config
+			self.log.debug "Configuring Basic authprovider: %p" % [ config ]
+			self.realm = config['realm'] if config['realm']
+			self.users = config['users'] if config['users']
+		else
+			self.realm = nil
+			self.users = {}
+		end
+	end
+
+
+	#################################################################
+	###	I N S T A N C E   M E T H O D S
+	#################################################################
+
+	### Create a new Default AuthProvider.
+	def initialize( * )
+		super
+
+		# Default the authentication realm to the application's ID
+		unless self.class.realm
+			self.log.warn "No realm configured -- using the app id"
+			self.class.realm = self.app.conn.app_id
+		end
+
+		unless self.class.users
+			self.log.warn "No users configured -- using an empty user list"
+			self.class.users = {}
+		end
+	end
+
+
+	######
+	public
+	######
+
+	# Check the authentication present in +request+ (if any) for validity, returning the
+	# authenticating user's name if authentication succeeds.
+	def authenticate( request )
+		authheader = request.header.authorization or
+			self.log_failure "No authorization header in the request."
+
+		# Extract the credentials bit
+		base64_userpass = authheader[ /^\s*Basic\s+(\S+)$/i, 1 ] or
+			self.log_failure "Invalid Basic Authorization header (%p)" % [ authheader ]
+
+		# Unpack the username and password
+		credentials = base64_userpass.unpack( 'm' ).first
+		self.log_failure "Malformed credentials %p" % [ credentials ] unless
+			credentials.index(':')
+
+		# Split the credentials, check for valid user
+		username, password = credentials.split( ':', 2 )
+		digest = self.class.users[ username ] or
+			self.log_failure "No such user %p." % [ username ]
+
+		# Fail if the password's hash doesn't match
+		self.log_failure "Password mismatch." unless
+			digest == Digest::SHA1.base64digest( password )
+
+		# Success!
+		self.log.info "Authentication for %p succeeded." % [ username ]
+		return username
+	end
+
+
+	#########
+	protected
+	#########
+
+	### Syntax sugar to allow returning 'false' while logging a reason for doing so.
+	### Log a message at 'info' level and return false.
+	def log_failure( reason )
+		self.log.warn "Auth failure: %s" % [ reason ]
+		header = "Basic realm=%s" % [ self.class.realm ]
+		finish_with( HTTP::AUTH_REQUIRED, "Requires authentication.", www_authenticate: header )
+	end
+
+end # class Strelka::AuthProvider::Basic

File spec/strelka/authprovider/authtoken_spec.rb

+#!/usr/bin/env rspec -cfd -b
+
+BEGIN {
+	require 'pathname'
+	basedir = Pathname( __FILE__ ).dirname.parent
+	libdir = basedir + 'lib'
+
+	$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
+}
+
+require 'rspec'
+require 'strelka/_auth_token'
+
+describe Strelka-AuthToken do
+
+	it "is well-tested" do
+		fail "it isn't"
+	end
+
+end
+