opensesame 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/README.md +9 -8
  2. data/app/assets/stylesheets/open_sesame/{application.css → opensesame.css} +0 -1
  3. data/app/assets/stylesheets/open_sesame/{welcome.css.scss → welcome.css} +50 -1
  4. data/app/controllers/open_sesame/application_controller.rb +1 -1
  5. data/app/controllers/open_sesame/sessions_controller.rb +22 -5
  6. data/app/helpers/open_sesame/application_helper.rb +1 -1
  7. data/app/views/layouts/open_sesame/application.html.erb +1 -2
  8. data/config/routes.rb +2 -2
  9. data/lib/open_sesame/configuration.rb +10 -13
  10. data/lib/open_sesame/engine.rb +21 -22
  11. data/lib/open_sesame/failure/app.rb +10 -0
  12. data/lib/open_sesame/failure/devise_app.rb +17 -0
  13. data/lib/open_sesame/github_auth.rb +9 -0
  14. data/lib/open_sesame/github_warden.rb +26 -0
  15. data/lib/open_sesame/{controller_helper.rb → helpers/controller_helper.rb} +2 -1
  16. data/lib/open_sesame/{view_helper.rb → helpers/view_helper.rb} +4 -3
  17. data/lib/open_sesame/member.rb +65 -0
  18. data/lib/open_sesame/version.rb +2 -1
  19. data/lib/open_sesame.rb +16 -4
  20. data/spec/dummy/app/views/home/index.html.erb +3 -1
  21. data/spec/dummy/config/initializers/opensesame.rb +16 -2
  22. data/spec/dummy/config/initializers/session_store.rb +1 -1
  23. data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
  24. data/spec/dummy/config/routes.rb +1 -1
  25. data/spec/dummy/db/development.sqlite3 +0 -0
  26. data/spec/dummy/log/development.log +135 -6
  27. data/spec/dummy/log/test.log +41874 -530
  28. data/spec/dummy/tmp/cache/assets/C09/2F0/sprockets%2F76045b33d436a11b0156b36a91560651 +0 -0
  29. data/spec/dummy/tmp/cache/assets/C54/300/sprockets%2Fb83307a70e6040f817087f997dc73122 +0 -0
  30. data/spec/dummy/tmp/cache/assets/CAA/920/sprockets%2Ff2904820584f0723f5ab256dcf1a9225 +0 -0
  31. data/spec/dummy/tmp/cache/assets/CC2/790/sprockets%2F020f956f67983c52c9889ac9801ca4b4 +0 -0
  32. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  33. data/spec/dummy/tmp/cache/assets/CEC/240/sprockets%2Fdec29f626939d38247d1745e057c6ab2 +0 -0
  34. data/spec/dummy/tmp/cache/assets/D0C/2A0/sprockets%2F04922c120a656b333dd5fcd28c9f8f53 +0 -0
  35. data/spec/dummy/tmp/cache/assets/D12/EF0/sprockets%2F98d5a511dcf32074eef97c372f294a20 +0 -0
  36. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  37. data/spec/dummy/tmp/cache/assets/D38/DB0/sprockets%2Fe4441bec5b04f6a4ad4bf7056181558e +0 -0
  38. data/spec/dummy/tmp/cache/assets/D45/CE0/sprockets%2F6c1b76a50b27d5e7485d41cef59eb427 +0 -0
  39. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  40. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  41. data/spec/dummy/tmp/cache/assets/D60/400/sprockets%2F1f456ac6c7c736a4407ead0832adb42c +0 -0
  42. data/spec/dummy/tmp/cache/assets/D72/880/sprockets%2Fe5615e8c12de3dbb5626aee43388cb39 +0 -0
  43. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  44. data/spec/dummy/tmp/cache/assets/DDD/910/sprockets%2Ff8ed9a8d47ac232db51e9c7adb8377a9 +0 -0
  45. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  46. data/spec/dummy/tmp/cache/assets/E09/D90/sprockets%2Fd85890cff0dcafde74d69601baae198e +0 -0
  47. data/spec/dummy/tmp/cache/assets/E3C/B20/sprockets%2Fde9e6fc28cd2dfe38cc53fd0455b5b9e +0 -0
  48. data/spec/dummy/tmp/cache/sass/19921c2f5bb8eaa817ba254313d0f93dbf32f1df/opensesame.css.scssc +0 -0
  49. data/spec/dummy/tmp/cache/sass/19921c2f5bb8eaa817ba254313d0f93dbf32f1df/opensesame_bootstrap.css.scssc +0 -0
  50. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_accordion.scssc +0 -0
  51. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_alerts.scssc +0 -0
  52. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_breadcrumbs.scssc +0 -0
  53. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_button-groups.scssc +0 -0
  54. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_buttons.scssc +0 -0
  55. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_carousel.scssc +0 -0
  56. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_close.scssc +0 -0
  57. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_code.scssc +0 -0
  58. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_component-animations.scssc +0 -0
  59. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_dropdowns.scssc +0 -0
  60. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_forms.scssc +0 -0
  61. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_grid.scssc +0 -0
  62. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_hero-unit.scssc +0 -0
  63. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_labels-badges.scssc +0 -0
  64. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_layouts.scssc +0 -0
  65. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_mixins.scssc +0 -0
  66. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_modals.scssc +0 -0
  67. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_navbar.scssc +0 -0
  68. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_navs.scssc +0 -0
  69. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_pager.scssc +0 -0
  70. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_pagination.scssc +0 -0
  71. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_popovers.scssc +0 -0
  72. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_progress-bars.scssc +0 -0
  73. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_reset.scssc +0 -0
  74. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_scaffolding.scssc +0 -0
  75. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_sprites.scssc +0 -0
  76. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_tables.scssc +0 -0
  77. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_thumbnails.scssc +0 -0
  78. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_tooltip.scssc +0 -0
  79. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_type.scssc +0 -0
  80. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_utilities.scssc +0 -0
  81. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_variables.scssc +0 -0
  82. data/spec/dummy/tmp/cache/sass/bf8de80767f3492905bcacdfb6abfd679aef3272/_wells.scssc +0 -0
  83. data/spec/dummy/tmp/cache/sass/c0430781249a04c227e0b0aca38159d7478590b1/_bootstrap.scssc +0 -0
  84. data/spec/dummy/tmp/capybara/{capybara-201205020845417136358435.html → capybara-201208201553167621643394.html} +2 -0
  85. data/spec/lib/open_sesame/configuration_spec.rb +0 -40
  86. data/spec/lib/open_sesame/github_auth_spec.rb +30 -0
  87. data/spec/lib/open_sesame/github_warden_spec.rb +44 -0
  88. data/spec/lib/open_sesame/member_spec.rb +51 -0
  89. data/spec/lib/open_sesame/sessions_spec.rb +23 -8
  90. data/spec/lib/open_sesame_spec.rb +7 -2
  91. data/spec/spec_helper.rb +0 -3
  92. data/spec/support/capybara.rb +24 -0
  93. data/spec/support/request_helpers.rb +61 -0
  94. data/spec/support/vcr.rb +22 -0
  95. data/spec/vcr/member/retrieves_attributes_from_github.yml +46 -0
  96. data/spec/vcr/member/returns_nil_if_no_github_member_found.yml +46 -0
  97. data/spec/vcr/member/serialize_from_session_returns_member_from_given_member_id.yml +89 -0
  98. data/spec/vcr/member/serialize_into_session_returns_given_member_id_in_array.yml +46 -0
  99. data/spec/vcr/session/allows_auto_login.yml +132 -0
  100. data/spec/vcr/session/enforces_opensesame_login.yml +132 -0
  101. data/spec/vcr/session/skips_auto_login_if_just_logged_out.yml +175 -0
  102. data/spec/vcr/session/tries_auto_login_and_ends_up_on_opensesame_page_after_failure.yml +46 -0
  103. metadata +239 -41
  104. data/app/assets/javascripts/open_sesame/application.js +0 -15
  105. data/app/assets/stylesheets/open_sesame/opensesame_bootstrap.css.scss +0 -8
  106. data/lib/open_sesame/failure_app.rb +0 -14
  107. data/spec/dummy/tmp/capybara/capybara-201205020845084431324775.html +0 -14
  108. data/spec/dummy/tmp/capybara/capybara-201205020846032430049397.html +0 -14
  109. data/spec/dummy/tmp/capybara/capybara-201205020848165144257335.html +0 -26
  110. data/spec/dummy/tmp/capybara/capybara-201205020849371072293414.html +0 -26
  111. data/spec/dummy/tmp/capybara/capybara-201205020851069360249571.html +0 -26
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # OpenSesame
2
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.
3
+ OpenSesame is a [Warden](https://github.com/hassox/warden) strategy for providing "walled garden" authentication for access to Rack-based applications via Omniauth. The intent is protect the visibility of your app from the outside world. For example, your company has internal apps and/or staging enviroments for multiple projects and you want something better than HTTP basic auth.
4
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.
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 Github organization for which OpenSesame is configured.
6
6
 
7
7
  ## Usage
8
8
 
@@ -11,23 +11,24 @@ In your Gemfile:
11
11
  $ gem "opensesame"
12
12
 
13
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:
14
+ and a callback for OAuth. The OmniAuth-Github OAuth strategy used under the hood will expect the callback at mount path + '/github/callback'. So the development version of your client application might be registered as:
15
15
 
16
16
  Name: MyApp - local
17
17
  URL: http://localhost:3000
18
- Callback URL: http://localhost:3000/welcome/auth/github/callback
18
+ Callback URL: http://localhost:3000/opensesame/github/callback
19
19
 
20
20
  Configure OpenSesame:
21
21
 
22
22
  ```ruby
23
- # Rails config/initializers/opensesame.rb or Sinatra app.rb
23
+ # Rails config/initializers/opensesame.rb
24
24
 
25
25
  require 'opensesame'
26
26
 
27
27
  OpenSesame.configure do |config|
28
- config.github ENV['CAPITAN_GITHUB_KEY'], ENV['CAPITAN_GITHUB_SECRET']
28
+ config.enable Rails.env.staging?
29
+ config.github ENV['GITHUB_APP_ID'], ENV['GITHUB_SECRET']
29
30
  config.organization 'challengepost'
30
- config.mounted_at '/welcome'
31
+ config.mounted_at '/opensesame'
31
32
  end
32
33
  ```
33
34
 
@@ -36,5 +37,5 @@ Mount OpenSesame in your Rails routes.rb:
36
37
  ```ruby
37
38
  # Rails config/routes.rb
38
39
 
39
- mount OpenSesame::Engine => "/welcome", :as => "opensesame"
40
+ mount OpenSesame::Engine => "/opensesame", :as => "opensesame"
40
41
  ```
@@ -9,6 +9,5 @@
9
9
  * compiled file, but it's generally better to create a new file per style scope.
10
10
  *
11
11
  *= require_self
12
- *= require ./opensesame_bootstrap
13
12
  *= require ./welcome
14
13
  */
@@ -49,4 +49,53 @@ pre, code { font-family: monospace, sans-serif; font-size: 1em; color:#080; }
49
49
  .field input { border: 1px solid #CCC; }
50
50
 
51
51
  #grant, #deny { padding: 5px 0px }
52
- .green { color: green }
52
+ .green { color: green }
53
+
54
+ .btn {
55
+ display: inline-block;
56
+ padding: 4px 10px 4px;
57
+ margin-bottom: 0;
58
+ font-size: 13px;
59
+ line-height: 18px;
60
+ color: #333;
61
+ text-align: center;
62
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
63
+ vertical-align: middle;
64
+ cursor: pointer;
65
+ background-color: whiteSmoke;
66
+ background-image: -ms-linear-gradient(top, white, #E6E6E6);
67
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(white), to(#E6E6E6));
68
+ background-image: -webkit-linear-gradient(top, white, #E6E6E6);
69
+ background-image: -o-linear-gradient(top, white, #E6E6E6);
70
+ background-image: linear-gradient(top, white, #E6E6E6);
71
+ background-image: -moz-linear-gradient(top, white, #E6E6E6);
72
+ background-repeat: repeat-x;
73
+ border: 1px solid #CCC;
74
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
75
+ border-bottom-color: #B3B3B3;
76
+ -webkit-border-radius: 4px;
77
+ -moz-border-radius: 4px;
78
+ border-radius: 4px;
79
+ filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
80
+ filter: progid:dximagetransform.microsoft.gradient(enabled=false);
81
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
82
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
83
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
84
+ }
85
+
86
+ .btn-large {
87
+ font-size: 20px;
88
+ font-weight: normal;
89
+ padding: 14px 24px;
90
+ margin-right: 10px;
91
+ -webkit-border-radius: 6px;
92
+ -moz-border-radius: 6px;
93
+ border-radius: 6px;
94
+ }
95
+
96
+ .content-header {
97
+ border-bottom: 1px solid #ccc;
98
+ margin-bottom: 1em;
99
+
100
+ }
101
+ .content-header h1 { font-size: 24px; }
@@ -1,6 +1,6 @@
1
1
  module OpenSesame
2
2
  class ApplicationController < ActionController::Base
3
- include OpenSesame::ViewHelper
3
+ include OpenSesame::Helpers::ViewHelper
4
4
 
5
5
  end
6
6
  end
@@ -14,14 +14,12 @@ module OpenSesame
14
14
  end
15
15
 
16
16
  def create
17
- warden.authenticate!(:scope => :opensesame)
18
- flash[:success] = "Welcome!"
17
+ login_opensesame
19
18
  redirect_to main_app.root_url
20
19
  end
21
20
 
22
21
  def destroy
23
- warden.logout(:opensesame)
24
- flash[:notice] = "Logged out!"
22
+ logout_opensesame
25
23
  redirect_to main_app.root_url
26
24
  end
27
25
 
@@ -33,19 +31,38 @@ module OpenSesame
33
31
 
34
32
  def attempt_auto_authenticate
35
33
  return unless attempt_auto_access?
36
-
34
+
37
35
  redirect_to identity_request_path(OpenSesame.auto_access_provider)
38
36
  end
39
37
 
40
38
  def attempt_auto_access?
39
+ return false if just_logged_out?
41
40
  return false unless OpenSesame.auto_access_provider.present?
42
41
  attempts = session[:opensesame_auto_access_attempt].to_i
43
42
  session[:opensesame_auto_access_attempt] = attempts + 1
44
43
  attempts < 1
45
44
  end
46
45
 
46
+ def just_logged_out?
47
+ !!session[:opensesame_logged_out].tap do
48
+ session[:opensesame_logged_out] = nil
49
+ end
50
+ end
51
+
47
52
  def clear_auto_attempt!
48
53
  session[:opensesame_auto_access_attempt] = nil
49
54
  end
55
+
56
+ def login_opensesame
57
+ warden.authenticate!(:scope => :opensesame)
58
+ flash[:success] = "Welcome!"
59
+ end
60
+
61
+ def logout_opensesame
62
+ warden.logout(:opensesame)
63
+ session[:opensesame_logged_out] = 1
64
+ flash[:notice] = "Logged out!"
65
+ end
66
+
50
67
  end
51
68
  end
@@ -1,6 +1,6 @@
1
1
  module OpenSesame
2
2
  module ApplicationHelper
3
- include OpenSesame::ViewHelper
3
+ include OpenSesame::Helpers::ViewHelper
4
4
 
5
5
  end
6
6
  end
@@ -2,8 +2,7 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>OpenSesame</title>
5
- <%= stylesheet_link_tag "open_sesame/application", :media => "all" %>
6
- <%= javascript_include_tag "open_sesame/application" %>
5
+ <%= stylesheet_link_tag "open_sesame/opensesame", :media => "all" %>
7
6
  <%= csrf_meta_tags %>
8
7
  </head>
9
8
  <body>
data/config/routes.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  OpenSesame::Engine.routes.draw do
2
2
  root :to => "sessions#new"
3
3
 
4
- match '/auth/:provider/callback', :to => 'sessions#create'
5
- match '/auth/failure', :to => 'sessions#failure'
4
+ match '/:provider/callback', :to => 'sessions#create'
5
+ match '/:provider/failure', :to => 'sessions#failure'
6
6
  match '/login', :to => 'sessions#new', :as => :sign_in
7
7
  match '/logout', :to => 'sessions#destroy', :as => :sign_out
8
8
  end
@@ -1,9 +1,10 @@
1
+ # encoding: utf-8
1
2
  module OpenSesame
2
3
  class ConfigurationError < RuntimeError; end
3
4
 
4
5
  class Configuration
5
- CONFIGURABLE_ATTRIBUTES = [:organization_name, :mount_prefix, :github_client,
6
- :enabled, :enable_clause, :full_host, :auto_access_provider]
6
+ CONFIGURABLE_ATTRIBUTES = [:organization_name, :mount_prefix, :github_client,
7
+ :enabled, :full_host, :auto_access_provider]
7
8
  attr_accessor *CONFIGURABLE_ATTRIBUTES
8
9
 
9
10
  def mounted_at(mount_prefix)
@@ -26,24 +27,20 @@ module OpenSesame
26
27
  self.auto_access_provider = provider
27
28
  end
28
29
 
29
- def enable_if(conditional)
30
- self.enabled = nil
31
- self.enable_clause = lambda { conditional }
32
- end
33
-
34
30
  def enable!
35
- self.enable_clause = nil
36
31
  self.enabled = true
37
32
  end
38
33
 
39
34
  def disable!
40
- self.enable_clause = nil
41
35
  self.enabled = false
42
36
  end
43
37
 
38
+ def enable(enabled)
39
+ self.enabled = !!enabled
40
+ end
41
+
44
42
  def enabled?
45
- (!self.enabled.nil? && self.enabled) ||
46
- (!self.enable_clause.nil? && self.enable_clause.call)
43
+ self.enabled
47
44
  end
48
45
 
49
46
  def configure
@@ -70,14 +67,14 @@ module OpenSesame
70
67
  # config/initializers/open_sesame.rb
71
68
  OpenSesame.configure do |config|
72
69
  config.organization 'challengepost'
73
- config.mounted_at '/welcome'
70
+ config.mounted_at '/opensesame'
74
71
  config.github ENV['CAPITAN_GITHUB_KEY'], ENV['CAPITAN_GITHUB_SECRET']
75
72
  end
76
73
 
77
74
  When you register the app, make sure to point the callback url to
78
75
  the engine mountpoint + /auth/github/callback. For example, if your
79
76
  development app is on http://localhost:3000 and you're mounting
80
- the OpenSesame::Engine at '/welcome', your github
77
+ the OpenSesame::Engine at '/opensesame', your github
81
78
  callback url should be:
82
79
 
83
80
  http://localhost:3000/auth/github/callback
@@ -1,4 +1,4 @@
1
- require 'opensesame-github'
1
+ # encoding: utf-8
2
2
 
3
3
  module OpenSesame
4
4
  class Engine < ::Rails::Engine
@@ -9,41 +9,40 @@ module OpenSesame
9
9
  end
10
10
 
11
11
  ActiveSupport.on_load(:action_controller) do
12
- include OpenSesame::ControllerHelper
12
+ include OpenSesame::Helpers::ControllerHelper
13
13
  end
14
14
 
15
15
  ActiveSupport.on_load(:action_view) do
16
- include OpenSesame::ViewHelper
16
+ include OpenSesame::Helpers::ViewHelper
17
17
  end
18
18
 
19
19
  initializer "opensesame.middleware", :after => :load_config_initializers do |app|
20
- OpenSesame.configuration.validate!
20
+ if OpenSesame.enabled?
21
+ require 'open_sesame/github_warden'
21
22
 
22
- OpenSesame::Github.organization_name = OpenSesame.organization_name
23
+ app.config.assets.precompile += ['opensesame.css']
23
24
 
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
+ OpenSesame.configuration.validate!
29
26
 
30
- provider :github, OpenSesame.github_client[:id], OpenSesame.github_client[:secret]
31
- end
27
+ app.config.middleware.use OpenSesame::GithubAuth,
28
+ OpenSesame.github_client[:id],
29
+ OpenSesame.github_client[:secret],
30
+ :path_prefix => OpenSesame.mount_prefix
32
31
 
33
- if defined?(Devise)
34
- Devise.setup do |config|
35
- config.warden do |manager|
32
+ if defined?(Devise)
33
+ Devise.setup do |config|
34
+ config.warden do |manager|
35
+ manager.default_strategies(:opensesame_github, :scope => :opensesame)
36
+ manager.failure_app = OpenSesame::Failure::DeviseApp.new
37
+ end
38
+ end
39
+ else
40
+ app.config.middleware.use ::Warden::Manager do |manager|
36
41
  manager.default_strategies(:opensesame_github, :scope => :opensesame)
37
- manager.failure_app = OpenSesame::FailureApp.new
42
+ manager.failure_app = OpenSesame::Failure::App.new
38
43
  end
39
44
  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
45
45
  end
46
-
47
46
  end
48
47
  end
49
48
  end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module OpenSesame
3
+ module Failure
4
+ class App
5
+ def call(env)
6
+ OpenSesame::SessionsController.action(:new).call(env)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require 'devise'
3
+ module OpenSesame
4
+ module Failure
5
+ class DeviseApp < ::Devise::Delegator
6
+
7
+ def call(env)
8
+ if (env['warden.options'] && (scope = env["warden.options"][:scope]) && scope == :opensesame)
9
+ OpenSesame::SessionsController.action(:new).call(env)
10
+ else
11
+ super
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require 'omniauth-github'
3
+
4
+ module OpenSesame
5
+ class GithubAuth < ::OmniAuth::Strategies::GitHub
6
+ option :name, 'github'
7
+ option :path_prefix, OpenSesame.mount_prefix
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require 'warden'
3
+
4
+ module OpenSesame
5
+ class GithubWarden < ::Warden::Strategies::Base
6
+
7
+ def valid?
8
+ auth_hash && auth_hash["provider"] == "github"
9
+ end
10
+
11
+ def authenticate!
12
+ if member = OpenSesame::Member.find(auth_hash["uid"])
13
+ success! member
14
+ else
15
+ fail 'Sorry, you do not have access'
16
+ end
17
+ end
18
+
19
+ def auth_hash
20
+ request.env['omniauth.auth']
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ ::Warden::Strategies.add(:opensesame_github, OpenSesame::GithubWarden)
@@ -1,5 +1,6 @@
1
+ # encoding: utf-8
1
2
  module OpenSesame
2
- module ControllerHelper
3
+ module Helpers::ControllerHelper
3
4
  extend ActiveSupport::Concern
4
5
 
5
6
  def warden
@@ -1,14 +1,15 @@
1
+ # encoding: utf-8
1
2
  module OpenSesame
2
- module ViewHelper
3
+ module Helpers::ViewHelper
3
4
 
4
5
  def login_image_link_to(provider)
5
- link_to identity_request_path(provider), class: "btn btn-large" do
6
+ link_to identity_request_path(provider), :class => "btn btn-large" do
6
7
  image_tag("open_sesame/#{provider}_64.png") + "<br/><span>#{provider}</span>".html_safe
7
8
  end
8
9
  end
9
10
 
10
11
  def identity_request_path(provider)
11
- [OpenSesame.mount_prefix, 'auth', provider].join('/')
12
+ [OpenSesame.mount_prefix, provider].join('/')
12
13
  end
13
14
 
14
15
  end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ require "octokit"
3
+
4
+ module OpenSesame
5
+ class Member
6
+
7
+ def self.organization_name
8
+ OpenSesame.organization_name
9
+ end
10
+
11
+ def self.find(member_id)
12
+ return nil unless member_id.present?
13
+ attributes = organization_members.detect { |member| member.id.to_s == member_id.to_s }
14
+ return nil unless attributes.present?
15
+ new(attributes)
16
+ end
17
+
18
+ def self.organization_members
19
+ github_api.organization_members(organization_name)
20
+ end
21
+
22
+ def self.github_api
23
+ @github_api ||= Octokit.new
24
+ end
25
+
26
+ def self.lazy_attr_reader(*attrs)
27
+ attrs.each do |attribute|
28
+ class_eval do
29
+ define_method(attribute) do
30
+ @attributes[attribute.to_s] || @attributes[attribute] # allow string or symbol access
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def self.serialize_into_session(member)
37
+ [member.id]
38
+ end
39
+
40
+ def self.serialize_from_session(*args)
41
+ id = args.shift
42
+ find(id)
43
+ end
44
+
45
+ attr_accessor :attributes
46
+ lazy_attr_reader :id, :login, :avatar_url, :gravatar_id, :url
47
+
48
+ def initialize(attributes = {})
49
+ @attributes = attributes
50
+ end
51
+
52
+ def id
53
+ @attributes["id"]
54
+ end
55
+
56
+ def organization_name
57
+ self.class.organization_name
58
+ end
59
+
60
+ def ==(other)
61
+ super || (other.class == self.class && other.id == self.id)
62
+ end
63
+
64
+ end
65
+ end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module OpenSesame
2
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
3
4
  end
data/lib/open_sesame.rb CHANGED
@@ -2,11 +2,23 @@ module OpenSesame
2
2
  extend self
3
3
 
4
4
  autoload :Configuration, 'open_sesame/configuration'
5
- autoload :ControllerHelper, 'open_sesame/controller_helper'
6
- autoload :ViewHelper, 'open_sesame/view_helper'
5
+ autoload :GithubAuth, 'open_sesame/github_auth'
6
+ autoload :GithubWarden, 'open_sesame/github_warden'
7
7
  autoload :FailureApp, 'open_sesame/failure_app'
8
+ autoload :Member, 'open_sesame/member'
8
9
 
9
- delegate *Configuration::CONFIGURABLE_ATTRIBUTES, :to => :configuration
10
+ module Helpers
11
+ autoload :ControllerHelper, 'open_sesame/helpers/controller_helper'
12
+ autoload :ViewHelper, 'open_sesame/helpers/view_helper'
13
+ end
14
+
15
+ module Failure
16
+ autoload :App, 'open_sesame/failure/app'
17
+ autoload :DeviseApp, 'open_sesame/failure/devise_app'
18
+ end
19
+
20
+ @to_configuration = Configuration::CONFIGURABLE_ATTRIBUTES + [:to => :configuration]
21
+ delegate *@to_configuration
10
22
  delegate :enabled?, :to => :configuration
11
23
 
12
24
  mattr_accessor :configuration
@@ -18,4 +30,4 @@ module OpenSesame
18
30
  end
19
31
  end
20
32
 
21
- require "open_sesame/engine"
33
+ require "open_sesame/engine" if defined?(Rails)
@@ -1 +1,3 @@
1
- <h1>Welcome Home!</h1>
1
+ <h1>Welcome Home!</h1>
2
+
3
+ <%= link_to "Logout", opensesame.sign_out_path %>
@@ -1,7 +1,21 @@
1
1
  require "opensesame"
2
2
 
3
+ app_id = ENV['GITHUB_APP_ID']
4
+ secret = ENV['GITHUB_SECRET']
5
+
6
+ if app_id.nil?
7
+ puts "Setting app_id to dummy string"
8
+ app_id = 'dummy_app_id'
9
+ end
10
+
11
+ if secret.nil?
12
+ puts "Setting secret to dummy string"
13
+ secret = 'dummy_secret'
14
+ end
15
+
3
16
  OpenSesame.configure do |config|
17
+ config.enable true
4
18
  config.organization 'challengepost'
5
- config.mounted_at '/welcome'
6
- config.github 'github_client_id', 'github_client_secret'
19
+ config.mounted_at '/opensesame'
20
+ config.github app_id, secret
7
21
  end
@@ -1,6 +1,6 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
3
+ Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
4
4
 
5
5
  # Use the database for sessions instead of the cookie-based default,
6
6
  # which shouldn't be used to store highly confidential information
@@ -5,7 +5,7 @@
5
5
 
6
6
  # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7
7
  ActiveSupport.on_load(:action_controller) do
8
- wrap_parameters format: [:json]
8
+ wrap_parameters :format => [:json]
9
9
  end
10
10
 
11
11
  # Disable root element in JSON by default.
@@ -1,5 +1,5 @@
1
1
  Rails.application.routes.draw do
2
2
  root :to => "home#index"
3
3
 
4
- mount OpenSesame::Engine => "/welcome"
4
+ mount OpenSesame::Engine => "/opensesame", :as => :opensesame
5
5
  end
Binary file