opensesame 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/README.md +40 -0
  2. data/app/controllers/open_sesame/application_controller.rb +2 -2
  3. data/app/controllers/open_sesame/sessions_controller.rb +26 -2
  4. data/app/helpers/open_sesame/application_helper.rb +0 -5
  5. data/app/views/open_sesame/sessions/new.html.erb +9 -5
  6. data/lib/open_sesame/configuration.rb +34 -2
  7. data/lib/open_sesame/engine.rb +21 -5
  8. data/lib/open_sesame/failure_app.rb +14 -0
  9. data/lib/open_sesame/version.rb +1 -1
  10. data/lib/open_sesame.rb +3 -1
  11. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  12. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  13. data/spec/dummy/app/views/home/index.html.erb +1 -0
  14. data/spec/dummy/config/application.rb +0 -1
  15. data/spec/dummy/config/initializers/opensesame.rb +2 -0
  16. data/spec/dummy/config/routes.rb +2 -1
  17. data/spec/dummy/db/development.sqlite3 +0 -0
  18. data/spec/dummy/db/schema.rb +16 -0
  19. data/spec/dummy/log/development.log +6 -0
  20. data/spec/dummy/log/test.log +1477 -10
  21. data/spec/dummy/tmp/capybara/capybara-201205020845084431324775.html +14 -0
  22. data/spec/dummy/tmp/capybara/capybara-201205020845417136358435.html +14 -0
  23. data/spec/dummy/tmp/capybara/capybara-201205020846032430049397.html +14 -0
  24. data/spec/dummy/tmp/capybara/capybara-201205020848165144257335.html +26 -0
  25. data/spec/dummy/tmp/capybara/capybara-201205020849371072293414.html +26 -0
  26. data/spec/dummy/tmp/capybara/capybara-201205020851069360249571.html +26 -0
  27. data/spec/lib/open_sesame/configuration_spec.rb +61 -0
  28. data/spec/lib/open_sesame/sessions_spec.rb +33 -0
  29. data/spec/spec_helper.rb +7 -1
  30. metadata +63 -16
  31. data/README.rdoc +0 -3
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # OpenSesame
2
+
3
+ OpenSesame is a [Warden](https://github.com/hassox/warden) strategy for providing "walled garden" authentication for access to Rack-based applications via Omniauth. For example, your company has internal apps and/or staging enviroments for multiple projects and you want something better than HTTP basic auth. The intent is protect the visibility of your app from the outside world.
4
+
5
+ Enter OpenSesame. To authenticate, OpenSesame currently uses Omniauth and the Github API to require that a user is both logged in to Github and a member of the configurable Github organization.
6
+
7
+ ## Usage
8
+
9
+ In your Gemfile:
10
+
11
+ $ gem "opensesame"
12
+
13
+ Register your application(s) with Github for OAuth access. For each application, you need a name, the site url,
14
+ and a callback for OAuth. The OmniAuth-Github OAuth strategy used under the hood will expect the callback at mount path + '/auth/github/callback'. So the development version of your client application might be registered as:
15
+
16
+ Name: MyApp - local
17
+ URL: http://localhost:3000
18
+ Callback URL: http://localhost:3000/welcome/auth/github/callback
19
+
20
+ Configure OpenSesame:
21
+
22
+ ```ruby
23
+ # Rails config/initializers/opensesame.rb or Sinatra app.rb
24
+
25
+ require 'opensesame'
26
+
27
+ OpenSesame.configure do |config|
28
+ config.github ENV['CAPITAN_GITHUB_KEY'], ENV['CAPITAN_GITHUB_SECRET']
29
+ config.organization 'challengepost'
30
+ config.mounted_at '/welcome'
31
+ end
32
+ ```
33
+
34
+ Mount OpenSesame in your Rails routes.rb:
35
+
36
+ ```ruby
37
+ # Rails config/routes.rb
38
+
39
+ mount OpenSesame::Engine => "/welcome", :as => "opensesame"
40
+ ```
@@ -1,6 +1,6 @@
1
1
  module OpenSesame
2
2
  class ApplicationController < ActionController::Base
3
- unloadable
4
- include OpenSesame::ControllerHelper
3
+ include OpenSesame::ViewHelper
4
+
5
5
  end
6
6
  end
@@ -1,10 +1,16 @@
1
1
  module OpenSesame
2
- class SessionsController < ApplicationController
3
- unloadable
2
+ class SessionsController < OpenSesame::ApplicationController
4
3
 
5
4
  skip_before_filter :authenticate_opensesame!
5
+ skip_authorization_check if defined?(CanCan)
6
+ before_filter :attempt_auto_authenticate, :only => :new
7
+ after_filter :clear_auto_attempt!, :only => :create
6
8
 
7
9
  def new
10
+ if warden.message
11
+ flash.now[:notice] = warden.message
12
+ end
13
+ render :layout => 'open_sesame/application'
8
14
  end
9
15
 
10
16
  def create
@@ -23,5 +29,23 @@ module OpenSesame
23
29
  raise params.inspect
24
30
  end
25
31
 
32
+ protected
33
+
34
+ def attempt_auto_authenticate
35
+ return unless attempt_auto_access?
36
+
37
+ redirect_to identity_request_path(OpenSesame.auto_access_provider)
38
+ end
39
+
40
+ def attempt_auto_access?
41
+ return false unless OpenSesame.auto_access_provider.present?
42
+ attempts = session[:opensesame_auto_access_attempt].to_i
43
+ session[:opensesame_auto_access_attempt] = attempts + 1
44
+ attempts < 1
45
+ end
46
+
47
+ def clear_auto_attempt!
48
+ session[:opensesame_auto_access_attempt] = nil
49
+ end
26
50
  end
27
51
  end
@@ -2,10 +2,5 @@ module OpenSesame
2
2
  module ApplicationHelper
3
3
  include OpenSesame::ViewHelper
4
4
 
5
- def page_header(text)
6
- content_tag(:header, class: "content-header") do
7
- content_tag(:h1, text)
8
- end
9
- end
10
5
  end
11
6
  end
@@ -1,7 +1,11 @@
1
- <%= page_header 'Login' %>
2
- <p>Welcome! You have arrived at a <%= OpenSesame.organization_name.titleize %> application requiring additional credentials. To continue, please log in via:</p>
3
- <div class="table">
4
- <div class="table-cell align-middle">
5
- <%= login_image_link_to('github') %>
1
+ <div id="opensesame-session">
2
+ <header class="content-header">
3
+ <h1>Login</h1>
4
+ </header>
5
+ <p>Welcome! You have arrived at a <%= OpenSesame.organization_name.titleize %> application requiring additional credentials. To continue, please log in via:</p>
6
+ <div class="table">
7
+ <div class="table-cell align-middle">
8
+ <%= login_image_link_to('github') %>
9
+ </div>
6
10
  </div>
7
11
  </div>
@@ -2,13 +2,18 @@ module OpenSesame
2
2
  class ConfigurationError < RuntimeError; end
3
3
 
4
4
  class Configuration
5
- CONFIGURABLE_ATTRIBUTES = [:organization_name, :mount_prefix, :github_client]
5
+ CONFIGURABLE_ATTRIBUTES = [:organization_name, :mount_prefix, :github_client,
6
+ :enabled, :enable_clause, :full_host, :auto_access_provider]
6
7
  attr_accessor *CONFIGURABLE_ATTRIBUTES
7
8
 
8
9
  def mounted_at(mount_prefix)
9
10
  self.mount_prefix = mount_prefix
10
11
  end
11
12
 
13
+ def host(full_host)
14
+ self.full_host = full_host
15
+ end
16
+
12
17
  def github(client_id, client_secret)
13
18
  self.github_client = { :id => client_id, :secret => client_secret }
14
19
  end
@@ -17,6 +22,30 @@ module OpenSesame
17
22
  self.organization_name = organization_name
18
23
  end
19
24
 
25
+ def auto_login(provider)
26
+ self.auto_access_provider = provider
27
+ end
28
+
29
+ def enable_if(conditional)
30
+ self.enabled = nil
31
+ self.enable_clause = lambda { conditional }
32
+ end
33
+
34
+ def enable!
35
+ self.enable_clause = nil
36
+ self.enabled = true
37
+ end
38
+
39
+ def disable!
40
+ self.enable_clause = nil
41
+ self.enabled = false
42
+ end
43
+
44
+ def enabled?
45
+ (!self.enabled.nil? && self.enabled) ||
46
+ (!self.enable_clause.nil? && self.enable_clause.call)
47
+ end
48
+
20
49
  def configure
21
50
  yield self
22
51
  end
@@ -28,11 +57,14 @@ module OpenSesame
28
57
  [:id, :secret].all? { |key| self.github_client.keys.include?(key) }
29
58
  end
30
59
 
60
+ def configured?
61
+ [:organization_name, :mount_prefix, :github_client].any? { |required| send(required).present? }
62
+ end
63
+
31
64
  def validate!
32
65
  return true if valid?
33
66
  message = <<-MESSAGE
34
67
 
35
-
36
68
  Update your OpenSesame configuration. Example:
37
69
 
38
70
  # config/initializers/open_sesame.rb
@@ -16,16 +16,32 @@ module OpenSesame
16
16
  include OpenSesame::ViewHelper
17
17
  end
18
18
 
19
- initializer "gardenwall.middleware", :after => :load_config_initializers do |app|
19
+ initializer "opensesame.middleware", :after => :load_config_initializers do |app|
20
20
  OpenSesame.configuration.validate!
21
21
 
22
22
  OpenSesame::Github.organization_name = OpenSesame.organization_name
23
23
 
24
- middleware.use OmniAuth::Strategies::GitHub, OpenSesame.github_client[:id], OpenSesame.github_client[:secret]
24
+ middleware.use OmniAuth::Builder do
25
+ configure do |config|
26
+ config.path_prefix = '/auth'
27
+ config.full_host = OpenSesame.full_host if OpenSesame.full_host
28
+ end
25
29
 
26
- app.config.middleware.use Warden::Manager do |manager|
27
- manager.scope_defaults :opensesame, :strategies => [:opensesame_github]
28
- manager.failure_app = lambda { |env| OpenSesame::SessionsController.action(:new).call(env) }
30
+ provider :github, OpenSesame.github_client[:id], OpenSesame.github_client[:secret]
31
+ end
32
+
33
+ if defined?(Devise)
34
+ Devise.setup do |config|
35
+ config.warden do |manager|
36
+ manager.default_strategies(:opensesame_github, :scope => :opensesame)
37
+ manager.failure_app = OpenSesame::FailureApp.new
38
+ end
39
+ end
40
+ else
41
+ app.config.middleware.use Warden::Manager do |manager|
42
+ manager.default_strategies(:opensesame_github, :scope => :opensesame)
43
+ manager.failure_app = lambda { |env| OpenSesame::SessionsController.action(:new).call(env)}
44
+ end
29
45
  end
30
46
 
31
47
  end
@@ -0,0 +1,14 @@
1
+ require 'devise'
2
+ module OpenSesame
3
+ class FailureApp < Devise::Delegator
4
+
5
+ def call(env)
6
+ if (env['warden.options'] && (scope = env["warden.options"][:scope]) && scope == :opensesame)
7
+ OpenSesame::SessionsController.action(:new).call(env)
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module OpenSesame
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/open_sesame.rb CHANGED
@@ -4,8 +4,10 @@ module OpenSesame
4
4
  autoload :Configuration, 'open_sesame/configuration'
5
5
  autoload :ControllerHelper, 'open_sesame/controller_helper'
6
6
  autoload :ViewHelper, 'open_sesame/view_helper'
7
+ autoload :FailureApp, 'open_sesame/failure_app'
7
8
 
8
9
  delegate *Configuration::CONFIGURABLE_ATTRIBUTES, :to => :configuration
10
+ delegate :enabled?, :to => :configuration
9
11
 
10
12
  mattr_accessor :configuration
11
13
  @@configuration = Configuration.new
@@ -16,4 +18,4 @@ module OpenSesame
16
18
  end
17
19
  end
18
20
 
19
- require "open_sesame/engine"
21
+ require "open_sesame/engine"
@@ -1,3 +1,5 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
+
4
+ before_filter :authenticate_opensesame!
3
5
  end
@@ -0,0 +1,4 @@
1
+ class HomeController < ApplicationController
2
+
3
+ def index; end
4
+ end
@@ -0,0 +1 @@
1
+ <h1>Welcome Home!</h1>
@@ -9,7 +9,6 @@ require "sprockets/railtie"
9
9
  # require "rails/test_unit/railtie"
10
10
 
11
11
  Bundler.require
12
- require "opensesame"
13
12
 
14
13
  module Dummy
15
14
  class Application < Rails::Application
@@ -1,3 +1,5 @@
1
+ require "opensesame"
2
+
1
3
  OpenSesame.configure do |config|
2
4
  config.organization 'challengepost'
3
5
  config.mounted_at '/welcome'
@@ -1,4 +1,5 @@
1
1
  Rails.application.routes.draw do
2
+ root :to => "home#index"
2
3
 
3
- mount OpenSesame::Engine => "/opensesame"
4
+ mount OpenSesame::Engine => "/welcome"
4
5
  end
Binary file
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 0) do
15
+
16
+ end
@@ -0,0 +1,6 @@
1
+  (0.1ms) select sqlite_version(*)
2
+  (2.4ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
3
+  (0.0ms) PRAGMA index_list("schema_migrations")
4
+  (0.7ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
5
+  (0.2ms) select sqlite_version(*)
6
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations"