els_token 1.0.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -2
- data/lib/els_token.rb +209 -113
- data/lib/els_token/{els_user.rb → els_identity.rb} +15 -6
- data/lib/els_token/version.rb +1 -1
- data/test/dummy/Gemfile +9 -0
- data/test/dummy/Gemfile.lock +17 -1
- data/test/dummy/app/assets/javascripts/application.js +1 -2
- data/test/dummy/app/assets/javascripts/els_session.js.coffee +7 -0
- data/test/dummy/app/controllers/application_controller.rb +45 -6
- data/test/dummy/app/controllers/els_session_controller.rb +91 -0
- data/test/dummy/app/models/els_faker.rb +8 -0
- data/test/dummy/app/views/els_session/new.html.erb +41 -0
- data/test/dummy/app/views/els_session/show.html.erb +4 -0
- data/test/dummy/app/views/layouts/application.html.erb +6 -1
- data/test/dummy/config/application.rb +3 -39
- data/test/dummy/config/els_token.yml +21 -0
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/config/environments/uat.rb +67 -0
- data/test/dummy/config/initializers/els_token.rb +1 -1
- data/test/dummy/config/routes.rb +9 -55
- data/test/dummy/log/development.log +2170 -4
- data/test/dummy/tmp/cache/assets/C65/500/sprockets%2F53516304d6d54f9499b5a7788631e5c5 +0 -0
- data/test/dummy/tmp/cache/assets/CA6/630/sprockets%2F8af9c2296e34c4f01a58747a12c07130 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D49/140/sprockets%2Fd128539bcb29d65cf7e28a43f8563a2f +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D9C/D00/sprockets%2F66ef3d03a58dfcc273e3453b04fdf81b +0 -0
- data/test/dummy/tmp/cache/assets/D9F/AA0/sprockets%2Fab395cb72ff1e290f0de1f739a87bd50 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- metadata +41 -54
- data/test/dummy/app/assets/javascripts/hello.js +0 -2
- data/test/dummy/app/assets/stylesheets/hello.css +0 -4
- data/test/dummy/app/controllers/hello_controller.rb +0 -4
- data/test/dummy/app/views/hello/index.html.erb +0 -1
- data/test/dummy/config/els.yml +0 -12
- data/test/els_token_test.rb.old +0 -7
- data/test/hello_controller_test.rb +0 -32
@@ -2,16 +2,55 @@ class ApplicationController < ActionController::Base
|
|
2
2
|
protect_from_forgery
|
3
3
|
|
4
4
|
include ElsToken
|
5
|
-
|
5
|
+
els_config ELS_CONFIG
|
6
6
|
|
7
|
-
|
7
|
+
helper_method :remote_user, :rpa_username, :els_identity
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# will set a @cdid instance variable
|
12
|
+
# determined by the REMOTE_USER or RPA_USERNAME headers.
|
13
|
+
# cdid doesn't change often so it's gets stashed in the session
|
14
|
+
#
|
15
|
+
def cdid
|
16
|
+
@cdid ||=
|
17
|
+
session[:cdid] ||=
|
18
|
+
request.headers["REMOTE_USER"] ||=
|
19
|
+
request.headers["RPA_USERNAME"]
|
20
|
+
end
|
21
|
+
|
22
|
+
# the els_identity is backed by the ELS SSO system.
|
23
|
+
# It will try to get a full identity object and then store
|
24
|
+
# that in a memcache as raw retrieval currently hits performance.
|
25
|
+
# Whilst SSO is brilliant, it can be a bit of a drag working around
|
26
|
+
# it during development.
|
27
|
+
#
|
28
|
+
# This method will allow an end user to circumvent
|
29
|
+
# the domain specific ELS login by authenticating directly with the ELS
|
30
|
+
# system or, if a cookie is already resent, use that to retrieve an identity.
|
31
|
+
# As an additional development bonus, it's possible to fake the identity -
|
32
|
+
# setting it to whatever username is desired.
|
33
|
+
#
|
34
|
+
# It's up to the implementer to test the validity of that username in
|
35
|
+
# their own application.
|
36
|
+
# Likewise once you have an ElsIdentity object you may want to call your own
|
37
|
+
# usermodel based on some value. 'cdid' and 'employee_number'
|
38
|
+
# are common ones.
|
39
|
+
#
|
40
|
+
# One of the best things about the ElsIdentity is that it contains Group
|
41
|
+
# information :) So, rather than implementing yet-another-role system in
|
42
|
+
# your app, let the identity be managed centrally. Once you have the
|
43
|
+
# ElsIdentity you can ask it whether it belongs to some role:
|
44
|
+
#
|
45
|
+
# @els_identity.has_role? "some group"
|
46
|
+
#
|
47
|
+
def els_identity
|
48
|
+
@els_identity = Rails.cache.fetch(session[:els_token], :namespace => "els_identity")
|
49
|
+
unless @els_identity
|
50
|
+
Rails.logger.debug("no identity in cache. Redirecting")
|
51
|
+
session[:redirect_to] = request.env["PATH_INFO"]
|
52
|
+
logger.debug("user will be returned to #{session[:redirect_to]}")
|
53
|
+
redirect_to els_session_new_path
|
15
54
|
end
|
16
55
|
end
|
17
56
|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
class ElsSessionController < ApplicationController
|
2
|
+
|
3
|
+
before_filter :els_identity, :only => [:show]
|
4
|
+
|
5
|
+
def show
|
6
|
+
end
|
7
|
+
|
8
|
+
# When in dev/qa we may need to provide credentials
|
9
|
+
# if ELS has not been setup
|
10
|
+
# this will be valid if a known cookie exists
|
11
|
+
def new
|
12
|
+
@els_identity = get_identity rescue nil
|
13
|
+
if @els_identity
|
14
|
+
session[:els_token] = @els_identity.token_id
|
15
|
+
Rails.cache.write(session[:els_token], @els_identity,
|
16
|
+
:namespace => "els_identity",
|
17
|
+
:expires_in => 1200)
|
18
|
+
go_back
|
19
|
+
end
|
20
|
+
# or get some login details
|
21
|
+
end
|
22
|
+
|
23
|
+
# Should not get here during production
|
24
|
+
def create
|
25
|
+
begin
|
26
|
+
if params["override"]
|
27
|
+
# just fake the session
|
28
|
+
logger.debug("faking session with id #{params["username"]}")
|
29
|
+
@els_identity = ElsFaker.new(params["username"])
|
30
|
+
else
|
31
|
+
logger.debug("attempting to authenticate #{params["username"]}")
|
32
|
+
token = authenticate(params["username"],params["password"])
|
33
|
+
logger.debug("got token #{token}")
|
34
|
+
if token
|
35
|
+
@els_identity = get_token_identity(token)
|
36
|
+
flash[:notice] = "cannot retrieve identity" unless @els_identity
|
37
|
+
else
|
38
|
+
flash[:error] = "unable to authenticate"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
rescue Exception => e
|
42
|
+
flash[:error] = "Something went wrong #{e.message}"
|
43
|
+
end
|
44
|
+
if @els_identity
|
45
|
+
update_and_return
|
46
|
+
else
|
47
|
+
render :new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def destroy
|
52
|
+
Rails.cache.delete(session[:els_token])
|
53
|
+
session[:els_token] = nil
|
54
|
+
cookies.delete(ELS_CONFIG['cookie'], :domain => request.env["SERVER_NAME"])
|
55
|
+
redirect_to els_session_new_path
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# This app should really be running behind an els processor
|
61
|
+
# stashing the els token against the current host should allow
|
62
|
+
# for a better dev/qa experience without affecting production
|
63
|
+
def stash_cookie
|
64
|
+
cookies[ELS_CONFIG['cookie']] = {
|
65
|
+
:value => @els_identity.token_id,
|
66
|
+
:domain => request.env["SERVER_NAME"],
|
67
|
+
:path => '/',
|
68
|
+
:expires => Time.now + 24.hours
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_and_return
|
73
|
+
stash_cookie
|
74
|
+
session[:els_token] = @els_identity.token_id
|
75
|
+
logger.debug("got token id #{session[:els_token]}")
|
76
|
+
Rails.cache.write(session[:els_token], @els_identity,
|
77
|
+
:namespace => "els_identity",
|
78
|
+
:expires_in => 1200)
|
79
|
+
go_back
|
80
|
+
end
|
81
|
+
|
82
|
+
def go_back
|
83
|
+
if session[:redirect_to] =~ /els_session\//
|
84
|
+
# Do not redirect back to a session action
|
85
|
+
redirect_to root_path
|
86
|
+
else
|
87
|
+
redirect_to session[:redirect_to]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<h1>Oops! Authentication Required</h1>
|
2
|
+
<p>We are currently running with a <span class="env"><%= Rails.env %></span> configuration</p>
|
3
|
+
|
4
|
+
<div class='flash'>
|
5
|
+
<% if flash[:notice] %>
|
6
|
+
<p class="notice"><%= flash[:notice] %></p>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<% if flash[:error] %>
|
10
|
+
<p class="error"><%= flash[:error] %></p>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<% if Rails.env.eql? "development" %>
|
15
|
+
<p>As a convenience, anyone can login as anyone when in dev mode - just enter a valid cdid and go</p>
|
16
|
+
<p>If you need to test real authentication, uncheck the override box and enter a UAT password.<br>
|
17
|
+
If you don't know what your UAT cdid password is then speak to someone in EIO@teamaol.com</p>
|
18
|
+
<% else %>
|
19
|
+
<p>This login screen should only appear when in development mode so something has gone wrong.<br>
|
20
|
+
However, you can still use the system if you enter valid cdid credentials.<br>
|
21
|
+
Someone has been notified of the situation so don't worry :)
|
22
|
+
</p>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<%= form_tag els_session_create_path, :class => "els_session" do %>
|
26
|
+
<div class="field">
|
27
|
+
<%= label_tag :username %>
|
28
|
+
<%= text_field_tag :username, params[:username] %>
|
29
|
+
</div>
|
30
|
+
<div class="field<%= Rails.env.eql?("development") ? ' default_hidden' : '' %>">
|
31
|
+
<%= label_tag :password %>
|
32
|
+
<%= password_field_tag :password, params[:password] %>
|
33
|
+
</div>
|
34
|
+
<% if Rails.env.eql? "development" %>
|
35
|
+
<div class="field">
|
36
|
+
<%= label_tag "Override: Just log me in and forget the password. I know what I'm doing, honest :)" %>
|
37
|
+
<%= check_box_tag :override, params[:override] %>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
<div class="actions"><%= submit_tag "Log in" %></div>
|
41
|
+
<% end %>
|
@@ -1,12 +1,17 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title>
|
4
|
+
<title>ElsSession</title>
|
5
5
|
<%= stylesheet_link_tag "application", :media => "all" %>
|
6
6
|
<%= javascript_include_tag "application" %>
|
7
7
|
<%= csrf_meta_tags %>
|
8
8
|
</head>
|
9
9
|
<body>
|
10
|
+
<% if @els_identity %>
|
11
|
+
<div class='els_logout'>
|
12
|
+
<%= button_to "logout", els_session_destroy_path, :method => :delete %>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
10
15
|
|
11
16
|
<%= yield %>
|
12
17
|
|
@@ -7,50 +7,14 @@ require "els_token"
|
|
7
7
|
|
8
8
|
module Dummy
|
9
9
|
class Application < Rails::Application
|
10
|
-
# Settings in config/environments/* take precedence over those specified here.
|
11
|
-
# Application configuration should go into files in config/initializers
|
12
|
-
# -- all .rb files in that directory are automatically loaded.
|
13
10
|
|
14
|
-
# Custom directories with classes and modules you want to be autoloadable.
|
15
|
-
# config.autoload_paths += %W(#{config.root}/extras)
|
16
|
-
|
17
|
-
# Only load the plugins named here, in the order given (default is alphabetical).
|
18
|
-
# :all can be used as a placeholder for all plugins not explicitly named.
|
19
|
-
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
20
|
-
|
21
|
-
# Activate observers that should always be running.
|
22
|
-
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
23
|
-
|
24
|
-
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
25
|
-
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
26
|
-
# config.time_zone = 'Central Time (US & Canada)'
|
27
|
-
|
28
|
-
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
29
|
-
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
30
|
-
# config.i18n.default_locale = :de
|
31
|
-
|
32
|
-
# Configure the default encoding used in templates for Ruby 1.9.
|
33
11
|
config.encoding = "utf-8"
|
34
|
-
|
35
|
-
# Configure sensitive parameters which will be filtered from the log file.
|
36
12
|
config.filter_parameters += [:password]
|
37
|
-
|
38
|
-
# Use SQL instead of Active Record's schema dumper when creating the database.
|
39
|
-
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
40
|
-
# like if you have constraints or database-specific column types
|
41
|
-
# config.active_record.schema_format = :sql
|
42
|
-
|
43
|
-
# Enforce whitelist mode for mass assignment.
|
44
|
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
45
|
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
46
|
-
# parameters by using an attr_accessible or attr_protected declaration.
|
47
|
-
# config.active_record.whitelist_attributes = true
|
48
|
-
|
49
|
-
# Enable the asset pipeline
|
50
13
|
config.assets.enabled = true
|
51
|
-
|
52
|
-
# Version of your assets, change this if you want to expire all your assets
|
53
14
|
config.assets.version = '1.0'
|
15
|
+
config.cache_store = :memory_store
|
16
|
+
#, :size => 100.megabytes
|
17
|
+
#, :namespace => "els_identity", :expires_in => 1200
|
54
18
|
end
|
55
19
|
end
|
56
20
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
development:
|
2
|
+
uri: https://elsuat-sso.corp.aol.com/opensso/identity
|
3
|
+
cookie: iPlanetDirectoryProuat
|
4
|
+
|
5
|
+
test:
|
6
|
+
faker:
|
7
|
+
name: neilcuk
|
8
|
+
employee_number: 09095
|
9
|
+
roles:
|
10
|
+
- Passport Admins
|
11
|
+
- Domain Users
|
12
|
+
uri: https://els-sso.corp.aol.com/opensso/identity
|
13
|
+
cookie: iPlanetDirectoryPro
|
14
|
+
|
15
|
+
uat:
|
16
|
+
uri: https://els-sso.corp.aol.com/opensso/identity
|
17
|
+
cookie: iPlanetDirectoryPro
|
18
|
+
|
19
|
+
production:
|
20
|
+
uri: https://els-sso.corp.aol.com/opensso/identity
|
21
|
+
cookie: iPlanetDirectoryPro
|
@@ -11,7 +11,7 @@ Dummy::Application.configure do
|
|
11
11
|
|
12
12
|
# Show full error reports and disable caching
|
13
13
|
config.consider_all_requests_local = true
|
14
|
-
config.action_controller.perform_caching =
|
14
|
+
config.action_controller.perform_caching = true
|
15
15
|
|
16
16
|
# Don't care if the mailer can't send
|
17
17
|
config.action_mailer.raise_delivery_errors = false
|
@@ -0,0 +1,67 @@
|
|
1
|
+
Dummy::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
|
4
|
+
# Code is not reloaded between requests
|
5
|
+
config.cache_classes = true
|
6
|
+
|
7
|
+
# Full error reports are disabled and caching is turned on
|
8
|
+
config.consider_all_requests_local = false
|
9
|
+
config.action_controller.perform_caching = true
|
10
|
+
|
11
|
+
# Disable Rails's static asset server (Apache or nginx will already do this)
|
12
|
+
config.serve_static_assets = false
|
13
|
+
|
14
|
+
# Compress JavaScripts and CSS
|
15
|
+
config.assets.compress = true
|
16
|
+
|
17
|
+
# Don't fallback to assets pipeline if a precompiled asset is missed
|
18
|
+
config.assets.compile = false
|
19
|
+
|
20
|
+
# Generate digests for assets URLs
|
21
|
+
config.assets.digest = true
|
22
|
+
|
23
|
+
# Defaults to Rails.root.join("public/assets")
|
24
|
+
# config.assets.manifest = YOUR_PATH
|
25
|
+
|
26
|
+
# Specifies the header that your server uses for sending files
|
27
|
+
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
|
28
|
+
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
29
|
+
|
30
|
+
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
31
|
+
# config.force_ssl = true
|
32
|
+
|
33
|
+
# See everything in the log (default is :info)
|
34
|
+
# config.log_level = :debug
|
35
|
+
|
36
|
+
# Prepend all log lines with the following tags
|
37
|
+
# config.log_tags = [ :subdomain, :uuid ]
|
38
|
+
|
39
|
+
# Use a different logger for distributed setups
|
40
|
+
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
41
|
+
|
42
|
+
# Use a different cache store in production
|
43
|
+
# config.cache_store = :mem_cache_store
|
44
|
+
|
45
|
+
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
46
|
+
# config.action_controller.asset_host = "http://assets.example.com"
|
47
|
+
|
48
|
+
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
49
|
+
# config.assets.precompile += %w( search.js )
|
50
|
+
|
51
|
+
# Disable delivery errors, bad email addresses will be ignored
|
52
|
+
# config.action_mailer.raise_delivery_errors = false
|
53
|
+
|
54
|
+
# Enable threaded mode
|
55
|
+
# config.threadsafe!
|
56
|
+
|
57
|
+
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
58
|
+
# the I18n.default_locale when a translation can not be found)
|
59
|
+
config.i18n.fallbacks = true
|
60
|
+
|
61
|
+
# Send deprecation notices to registered listeners
|
62
|
+
config.active_support.deprecation = :notify
|
63
|
+
|
64
|
+
# Log the query plan for queries taking more than this (works
|
65
|
+
# with SQLite, MySQL, and PostgreSQL)
|
66
|
+
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
67
|
+
end
|
data/test/dummy/config/routes.rb
CHANGED
@@ -1,60 +1,14 @@
|
|
1
1
|
Dummy::Application.routes.draw do
|
2
|
-
get "hello/index"
|
3
|
-
|
4
|
-
# The priority is based upon order of creation:
|
5
|
-
# first created -> highest priority.
|
6
|
-
|
7
|
-
# Sample of regular route:
|
8
|
-
# match 'products/:id' => 'catalog#view'
|
9
|
-
# Keep in mind you can assign values other than :controller and :action
|
10
|
-
|
11
|
-
# Sample of named route:
|
12
|
-
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
|
13
|
-
# This route can be invoked with purchase_url(:id => product.id)
|
14
|
-
|
15
|
-
# Sample resource route (maps HTTP verbs to controller actions automatically):
|
16
|
-
# resources :products
|
17
|
-
|
18
|
-
# Sample resource route with options:
|
19
|
-
# resources :products do
|
20
|
-
# member do
|
21
|
-
# get 'short'
|
22
|
-
# post 'toggle'
|
23
|
-
# end
|
24
2
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
28
|
-
# end
|
29
|
-
|
30
|
-
# Sample resource route with sub-resources:
|
31
|
-
# resources :products do
|
32
|
-
# resources :comments, :sales
|
33
|
-
# resource :seller
|
34
|
-
# end
|
35
|
-
|
36
|
-
# Sample resource route with more complex sub-resources
|
37
|
-
# resources :products do
|
38
|
-
# resources :comments
|
39
|
-
# resources :sales do
|
40
|
-
# get 'recent', :on => :collection
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
|
44
|
-
# Sample resource route within a namespace:
|
45
|
-
# namespace :admin do
|
46
|
-
# # Directs /admin/products/* to Admin::ProductsController
|
47
|
-
# # (app/controllers/admin/products_controller.rb)
|
48
|
-
# resources :products
|
49
|
-
# end
|
50
|
-
|
51
|
-
# You can have the root of your site routed with "root"
|
52
|
-
# just remember to delete public/index.html.
|
53
|
-
# root :to => 'welcome#index'
|
3
|
+
# session handlers
|
4
|
+
#
|
5
|
+
get "els_session/new"
|
54
6
|
|
55
|
-
|
7
|
+
get "els_session/show"
|
8
|
+
|
9
|
+
post "els_session/create"
|
56
10
|
|
57
|
-
|
58
|
-
|
59
|
-
|
11
|
+
delete "els_session/destroy"
|
12
|
+
|
13
|
+
root :to => 'els_session#show'
|
60
14
|
end
|