opensesame 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"