auth works - yaaay

This commit is contained in:
Emi Matchu 2010-10-18 17:58:45 -04:00
parent e0ee659f86
commit 895c6e721e
18 changed files with 268 additions and 0 deletions

View file

@ -8,6 +8,11 @@ gem 'haml', '~> 3.0.18'
gem 'rdiscount', '~> 1.6.5'
gem 'RocketAMF', '~> 0.2.1'
gem 'will_paginate', '~> 3.0.pre2'
gem 'warden', '~> 1.0.1'
gem 'rails_warden', '~> 0.5.2'
gem 'msgpack', '~> 0.4.3'
gem 'openneo-auth-signatory', '~> 0.0.4'
gem 'jammit', '~> 0.5.3'

View file

@ -87,6 +87,9 @@ GEM
mime-types
treetop (>= 1.4.5)
mime-types (1.16)
msgpack (0.4.3)
openneo-auth-signatory (0.0.4)
ruby-hmac
polyglot (0.3.1)
rack (1.2.1)
rack-fiber_pool (0.9.0)
@ -102,6 +105,8 @@ GEM
activesupport (= 3.0.0)
bundler (~> 1.0.0)
railties (= 3.0.0)
rails_warden (0.5.2)
warden
railties (3.0.0)
actionpack (= 3.0.0)
activesupport (= 3.0.0)
@ -121,10 +126,13 @@ GEM
rspec-expectations (= 2.0.0.beta.22)
rspec-rails (2.0.0.beta.22)
rspec (= 2.0.0.beta.22)
ruby-hmac (0.4.0)
thor (0.14.2)
treetop (1.4.8)
polyglot (>= 0.3.1)
tzinfo (0.3.23)
warden (1.0.1)
rack (>= 1.0.0)
will_paginate (3.0.pre2)
yui-compressor (0.9.1)
@ -142,9 +150,13 @@ DEPENDENCIES
factory_girl_rails (~> 1.0)
haml (~> 3.0.18)
jammit (~> 0.5.3)
msgpack (~> 0.4.3)
mysqlplus!
openneo-auth-signatory (~> 0.0.4)
rack-fiber_pool
rails (= 3.0.0)
rails_warden (~> 0.5.2)
rdiscount (~> 1.6.5)
rspec-rails (~> 2.0.0.beta.22)
warden (~> 1.0.1)
will_paginate (~> 3.0.pre2)

View file

@ -1,3 +1,19 @@
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user, :user_signed_in?
protected
def current_user
@current_user ||= warden.authenticate
end
def user_signed_in?
current_user ? true : false
end
def warden
env['warden']
end
end

View file

@ -0,0 +1,32 @@
class SessionsController < ApplicationController
rescue_from Openneo::Auth::Session::InvalidSignature, :with => :invalid_signature
rescue_from Openneo::Auth::Session::MissingParam, :with => :missing_param
skip_before_filter :verify_authenticity_token, :only => [:create]
def new
redirect_to Openneo::Auth.remote_auth_url(params, session)
end
def create
session = Openneo::Auth::Session.from_params(params)
session.save!
render :text => 'Success'
end
def destroy
warden.logout
redirect_to root_path
end
protected
def invalid_signature(exception)
render :text => "Signature did not match. Check secret.",
:status => :unprocessable_entity
end
def missing_param(exception)
render :text => exception.message, :status => :unprocessable_entity
end
end

15
app/models/user.rb Normal file
View file

@ -0,0 +1,15 @@
class User < ActiveRecord::Base
DefaultAuthServerId = 1
def self.find_or_create_from_remote_auth_data(user_data)
user = find_or_initialize_by_remote_id_and_auth_server_id(
user_data['id'],
DefaultAuthServerId
)
if user.new_record?
user.name = user_data['name']
user.save
end
user
end
end

View file

@ -7,6 +7,13 @@
= javascript_include_tag "http://#{RemoteImpressHost}/assets/js/analytics.js"
%body{:class => params[:action]}
#container
- if user_signed_in?
You are logged in as
= current_user.name
== (#{current_user.id})
= link_to 'Log out', logout_path
- else
= link_to 'Log in', login_path
%h1
= link_to items_path do
= image_tag 'http://images.neopets.com/items/mall_floatingneggfaerie.gif'

View file

@ -21,3 +21,8 @@ OpenneoImpressItems::Application.configure do
end
RemoteImpressHost = 'beta.impress.openneo.net'
OPENNEO_AUTH_CONFIG = {
:app => 'beta.items.impress',
:auth_server => 'openneo-id',
:secret => 'zaheh2draswAb8eneca$3an?2ADAsTuwra8h7BujUBr_w--p2-a@e?u!taQux3tr'
}

View file

@ -25,3 +25,9 @@ end
RemoteImpressHost = 'beta.impress.openneo.net'
USE_FIBER_POOL = true
OPENNEO_AUTH_CONFIG = {
:app => 'beta.items.impress',
:auth_server => 'beta.id.openneo.net',
:secret => 'zaheh2draswAb8eneca$3an?2ADAsTuwra8h7BujUBr_w--p2-a@e?u!taQux3tr'
}

View file

@ -0,0 +1,16 @@
Rails.configuration.middleware.use RailsWarden::Manager do |manager|
manager.default_strategies :openneo_auth_token, :openneo_auth_redirect
manager.failure_app = SessionsController.action(:failure)
end
require 'openneo-auth'
Openneo::Auth.configure do |config|
OPENNEO_AUTH_CONFIG.each do |key, value|
config.send("#{key}=", value)
end
config.user_finder do |user_data|
User.find_or_create_from_remote_auth_data(user_data)
end
end

View file

@ -1,4 +1,5 @@
OpenneoImpressItems::Application.routes.draw do |map|
root :to => 'items#index'
match '/' => 'items#index', :as => :items
match '/index.js' => 'items#index', :format => :js
match '/items.json' => 'items#index', :format => :json
@ -18,5 +19,9 @@ OpenneoImpressItems::Application.routes.draw do |map|
resources :pet_attributes, :only => [:index]
resources :pets, :only => [:show]
match '/login' => 'sessions#new', :as => :login
match '/logout' => 'sessions#destroy', :as => :logout
match '/users/authorize' => 'sessions#create'
match '/wardrobe' => 'outfits#edit', :as => :wardrobe
end

47
lib/openneo-auth.rb Normal file
View file

@ -0,0 +1,47 @@
require 'openneo-auth/session'
require 'openneo-auth/strategy'
Warden::Strategies.add :openneo_auth_token, Openneo::Auth::Strategy
module Openneo
module Auth
class Config
attr_accessor :app, :auth_server, :secret
def find_user(data)
raise "Must set a user finder for Openneo Auth to find a user" unless @user_finder
@user_finder.call(data)
end
def user_finder(&block)
@user_finder = block
end
end
class << self
def config
@@config ||= Config.new
end
def configure(&block)
block.call(config)
end
def remote_auth_url(params, session)
raise "Must set config.app to this app's subdomain" unless config.app
raise "Must set config.auth_server to remote server's hostname" unless config.auth_server
query = {
:app => config.app,
:session_id => session[:session_id],
:path => params[:return_to] || '/'
}.to_query
uri = URI::HTTP.build({
:host => config.auth_server,
:path => '/',
:query => query
})
uri.to_s
end
end
end
end

View file

@ -0,0 +1,84 @@
require 'active_support/core_ext/hash'
require 'msgpack'
require 'openneo-auth-signatory'
module Openneo
module Auth
class Session
REMOTE_MSG_KEYS = %w(session_id source user)
TMP_STORAGE_DIR = Rails.root.join('tmp', 'openneo-auth-sessions')
attr_writer :id
def save!
FileUtils.mkdir_p TMP_STORAGE_DIR
File.open(tmp_storage_path, 'w') do |file|
file.write MessagePack.pack(@message).force_encoding('utf-8')
end
end
def destroy!
File.delete(tmp_storage_path)
end
def load_message!
raise NotFound, "Session #{id} not found" unless File.exists?(tmp_storage_path)
@message = File.open(tmp_storage_path, 'r') do |file|
MessagePack.unpack file.read
end
end
def params=(params)
unless Auth.config.secret
raise "Must set config.secret to the remote auth server's secret"
end
given_signature = params['signature']
signatory = Auth::Signatory.new(Auth.config.secret.force_encoding('utf-8'))
REMOTE_MSG_KEYS.each do |key|
unless params.include?(key)
raise MissingParam, "Missing required param #{key.inspect}"
end
end
@message = params.slice(*REMOTE_MSG_KEYS)
correct_signature = signatory.sign(@message)
unless given_signature == correct_signature
raise InvalidSignature, "Signature (#{given_signature}) " +
"did not match message #{@message.inspect} (#{correct_signature})"
end
end
def user
Auth.config.find_user(@message['user'])
end
def self.from_params(params)
session = new
session.params = params
session
end
def self.find(id)
session = new
session.id = id
session.load_message!
session
end
private
def id
@id ||= @message[:session_id]
end
def tmp_storage_path
name = "#{id}.mpac"
File.join TMP_STORAGE_DIR, name
end
class InvalidSession < ArgumentError;end
class InvalidSignature < InvalidSession;end
class MissingParam < InvalidSession;end
class NotFound < StandardError;end
end
end
end

View file

@ -0,0 +1,18 @@
require 'warden'
module Openneo
module Auth
class Strategy < Warden::Strategies::Base
def authenticate!
begin
auth_session = Session.find session[:session_id]
rescue Session::NotFound => e
fail! e.message
else
auth_session.destroy!
success! auth_session.user
end
end
end
end
end

BIN
vendor/cache/msgpack-0.4.3.gem vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/cache/rails_warden-0.5.2.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/ruby-hmac-0.4.0.gem vendored Normal file

Binary file not shown.

BIN
vendor/cache/warden-1.0.1.gem vendored Normal file

Binary file not shown.