opensesame 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +40 -0
- data/app/controllers/open_sesame/application_controller.rb +2 -2
- data/app/controllers/open_sesame/sessions_controller.rb +26 -2
- data/app/helpers/open_sesame/application_helper.rb +0 -5
- data/app/views/open_sesame/sessions/new.html.erb +9 -5
- data/lib/open_sesame/configuration.rb +34 -2
- data/lib/open_sesame/engine.rb +21 -5
- data/lib/open_sesame/failure_app.rb +14 -0
- data/lib/open_sesame/version.rb +1 -1
- data/lib/open_sesame.rb +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/views/home/index.html.erb +1 -0
- data/spec/dummy/config/application.rb +0 -1
- data/spec/dummy/config/initializers/opensesame.rb +2 -0
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +16 -0
- data/spec/dummy/log/development.log +6 -0
- data/spec/dummy/log/test.log +1477 -10
- data/spec/dummy/tmp/capybara/capybara-201205020845084431324775.html +14 -0
- data/spec/dummy/tmp/capybara/capybara-201205020845417136358435.html +14 -0
- data/spec/dummy/tmp/capybara/capybara-201205020846032430049397.html +14 -0
- data/spec/dummy/tmp/capybara/capybara-201205020848165144257335.html +26 -0
- data/spec/dummy/tmp/capybara/capybara-201205020849371072293414.html +26 -0
- data/spec/dummy/tmp/capybara/capybara-201205020851069360249571.html +26 -0
- data/spec/lib/open_sesame/configuration_spec.rb +61 -0
- data/spec/lib/open_sesame/sessions_spec.rb +33 -0
- data/spec/spec_helper.rb +7 -1
- metadata +63 -16
- 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,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
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
<
|
4
|
-
|
5
|
-
|
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
|
data/lib/open_sesame/engine.rb
CHANGED
@@ -16,16 +16,32 @@ module OpenSesame
|
|
16
16
|
include OpenSesame::ViewHelper
|
17
17
|
end
|
18
18
|
|
19
|
-
initializer "
|
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::
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
data/lib/open_sesame/version.rb
CHANGED
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"
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Welcome Home!</h1>
|
data/spec/dummy/config/routes.rb
CHANGED
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
|
+
[1m[36m (0.1ms)[0m [1mselect sqlite_version(*)[0m
|
2
|
+
[1m[35m (2.4ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
3
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
4
|
+
[1m[35m (0.7ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
5
|
+
[1m[36m (0.2ms)[0m [1mselect sqlite_version(*)[0m
|
6
|
+
[1m[35m (0.1ms)[0m SELECT "schema_migrations"."version" FROM "schema_migrations"
|