rack-cas-rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0818a3cce11d21fc1c56fe4b1e70fefbb52c1cc
4
- data.tar.gz: bad76f891b70a7c54228b4e6001623f6a5e7caef
3
+ metadata.gz: b7d484d2b59603bbedf3a28c4917a463edf86c08
4
+ data.tar.gz: 7bbe3d6ae9fdbf53eef3fcb523c1d019d1afe1f1
5
5
  SHA512:
6
- metadata.gz: 6549563c5255ef7d4864b66566774744dd58ef2e104f3620325599fb4cd720e625b9fe6fe5d0ef6e36a85c1f85de7fe34abf70eaae2ae5b2a2073f8b116d17f2
7
- data.tar.gz: 79dd96b5624f71039b3facbfe1aed8bb39c7b9898a827345f753211e8aee422fb1a590ffb913e289cd17bdecb1b598cb71e06a6be6365c4c1a6fa31ba93fef4d
6
+ metadata.gz: 26517014d8fc90148db433d49e79084aa83fb2d7697174e1e9b201b5d98eae5d2e04ce784b659eb68a2d3fecf860241aa57e4aca33d2d1fd30c2d6d7f7c7ccbf
7
+ data.tar.gz: 2413da86e88601ae8995cb1813b4d429a8c3f1dfa0ae9b0f836d5e95240c9e34b1d48ee7a80d454cd2a1161be6586eb2971e8fce19da26e3847e6cd4dd1e2c24
data/README.md CHANGED
@@ -1,104 +1,223 @@
1
1
  # rack-cas-rails
2
2
 
3
- While [rbCAS/CASinoApp](http://rbcas.com) and [biola/rack-cas](https://github.com/biola/rack-cas) are both great
4
- and wonderful, there is gap between them. Namely, the bits needed to enable a Rails application to use rack-cas to integrate with
5
- CASinoApp for authentication are still missing.
3
+ [rbCAS/CASinoApp](https://github.com/rbcas/casinoapp) is a great single sign-on authentication server, and
4
+ [biola/rack-cas](https://github.com/biola/rack-cas) provides a simple means to integrate with it. However, these two things
5
+ coupled with your Rails application do not a **single sign-on enabled application** make. That is, there are still some bits
6
+ missing.
6
7
 
7
- This gem aims to fill in this void.
8
+ This gem aims to provide some of the bits to close the gap.
8
9
 
9
10
  ## Installation
10
11
 
11
- Add the following line to a Rails application's Gemfile:
12
+ Add the following to your Rails application's Gemfile:
12
13
 
13
14
  ```ruby
14
15
  gem "rack-cas-rails"
15
16
  ```
16
17
 
17
- Then open up your config/application.rb file, and add the following:
18
+ Then run
19
+
20
+ ```ruby
21
+ bundle install
22
+ ```
18
23
 
19
24
  ## Requirements
20
25
 
21
26
  The rack-cas-rails gem relies on the following:
22
27
 
23
- * A CAS-compliant server, such as [CASinoApp](http://rbcas.com)
28
+ * A working installation of [CASinoApp](http://rbcas.com), although theoretically it should work with any CAS-compliant server
24
29
  * [rack-cas](https://github.com/biola/rack-cas)
25
30
  * [rails](http://rubyonrails.org/)
26
31
 
32
+ Having access to a working CAS-compliant server is a pre-requisite. [CASinoApp](http://rbcas.com) is a simple one to set up and
33
+ use, especially if you go with the ***directly on your server*** option. Whiichever CAS server you go with, you'll need to
34
+ know the password of at least one login for testing purposes.
35
+
36
+ ### Disclaimer
37
+
38
+ I don't have access to any other CAS servers except an instance of CASinoApp I have installed and configured. So I have
39
+ only ever developed and tested against it. If you are able to try it against others, please let me know how well it works.
40
+
27
41
  ## Basic Usage
28
42
 
29
- The first thing you need to do is to make your Application class (file ```config/application.rb```) aware of the CAS-compliant
30
- server you are integrating with by pointing out its base URL, like so:
43
+ Now that you have access to a functioning CAS-compliant server, the next thing you need to do is to make your ```Rails::Application```
44
+ subclass aware of the server you are integrating with by pointing out its base URL, as shown here.
45
+
46
+ Note that setting the ```@cas_server_url``` variable is important as the ```login_url``` helper will make use of it.
31
47
 
32
48
  ```ruby
49
+ # config/application.rb
50
+
51
+ require "rack-cas"
33
52
  module MyGreatApplication
34
53
  class Application < Rails::Application
35
54
  # ...
36
- # URL of CAS server
37
- config.rack_cas.server_url = "https://sso.example.org/"
55
+ # Root URL of the CAS server
56
+ @cas_server_url = "https://sso.example.org/"
57
+ config.rack_cas.server_url = @cas_server_url
38
58
  end
39
59
  end
40
60
  ```
41
61
 
42
- In the simplest scenario, you'll want your entire application protected by authentication. That is, unless a user has authenticated,
43
- he can do nothing. To do so, add the following ```before_action``` callback to your ApplicationController
44
- (file ```app/controllers/application_ronctoller.rb```):
62
+ In the simplest case, you'll want your entire application protected by authentication. That is, unless a user has authenticated,
63
+ he can do nothing. To do so, add the following ```before_action``` callback to your ```ApplicationController```:
45
64
 
46
65
  ```ruby
66
+ # app/controllers/application_ronctoller.rb
67
+
68
+ require "rack_cas_rails"
47
69
  class ApplicationController < ActionController::Base
48
- # authenticate all actions for all controllers
70
+ # Prevent CSRF attacks by raising an exception.
71
+ # For APIs, you may want to use :null_session instead.
72
+ protect_from_forgery with: :exception
49
73
  before_action :authenticate!
50
- # ...
51
74
  end
52
75
  ```
53
76
 
54
- The ```authenticate!``` method will check to see if a browser session is authenticated. If it is, controller execution will continue.
55
- Otherwise, it will render the ```public/401.html``` file as well as return a HTTP status of 401.
77
+ The ```authenticate!``` helper will check to see if a browser session is authenticated. If it is, controller execution will continue.
78
+ Otherwise, it will render the ```public/401.html``` file if one exists, as well as return a HTTP status of 401.
56
79
 
57
- So, now, create a ```pubilc/401.html``` file in your application. You can simply copy an existing file, rename and change its
58
- contents.
80
+ At this point, if you fire up your application and browse to access any view of any controller subclassed from
81
+ ```ApplicationController```, the browser will get re-directed to the CAS server's log-in page.
59
82
 
60
83
  ## Helper Methods
61
84
 
62
- The rack-cas-rails gem also augments the ApplicationHelper module with these methods:
85
+ The rack-cas-rails gem also adds some helper methods:
86
+
87
+ * authenticate!
88
+ * authenticated?
89
+ * login_url
90
+ * logout_url
91
+
92
+ You have already seen ```authenticate!``` at work. The ```authenticated?``` helper allows your application to determine whether
93
+ a browser is authenticated or not and take appropriate action. When invoked, the latter two helpers will return the
94
+ CAS-integrated login and log out URLs, respectively. They, in turn, enable you to implement *partial authentication*.
95
+
96
+ ## Partial Authentication
63
97
 
64
- * login_url
65
- * logout_url
98
+ In this case, only certain portions of your application requires authentication. For example, perhaps actions that are
99
+ *read-only* need not be protected by authentication. To do this, change your ```ApplicationController``` as follows:
100
+
101
+ ```ruby
102
+ # app/controllers/application_ronctoller.rb
103
+
104
+ require "rack_cas_rails"
105
+ class ApplicationController < ActionController::Base
106
+ # Prevent CSRF attacks by raising an exception.
107
+ # For APIs, you may want to use :null_session instead.
108
+ protect_from_forgery with: :exception
109
+ before_action :authenticate!, except: [:index, :show]
110
+ end
111
+ ```
112
+
113
+ Restart your application and browse to a *read-only* endpoint like ```/index``` or ```/show```, and you will not be re-directed
114
+ to the CAS log-in page. But if you browse to other endpoints like ```/new```, you will be re-directed and prompted to
115
+ authenticate.
116
+
117
+ Go back and look at the read-only endpoint. It would be nice to have some indication telling a user whether he's logged in or not.
118
+ So, open up your application layout and add a ```<div>``` container that will behave differently bepending on the authentication
119
+ status of a browser session.
120
+
121
+ ```erb
122
+ <!-- views/layouts/application.html.erb -->
123
+
124
+ <!DOCTYPE html>
125
+ <html>
126
+ <head>
127
+ <title>MyGreatApplication</title>
128
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
129
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
130
+ <%= csrf_meta_tags %>
131
+ </head>
132
+ <body>
133
+ <div id="header">
134
+ <% if authenticated? %>
135
+ <span>You are logged in.</span>
136
+ <span style="float:right"><%= link_to "Logout", logout_url %></span>
137
+ <% else %>
138
+ <span>You are not logged in.</span>
139
+ <span style="float:right"><%= link_to "Login", login_url %></span>
140
+ <% end %>
141
+ </div>
142
+ <hr />
143
+ <div>
144
+ <%= yield %>
145
+ </div>
146
+ </body>
147
+ </html>
148
+ ```
66
149
 
67
- When invoked, these helpers will renturn the CAS-integrated login in and log out URLs, respectively.
150
+ Refresh your browser. This time you'll see that you're not logged in, but you are also given a login URL. Click on it, and you'll
151
+ be prompted to log-in once again.
68
152
 
69
153
  ## What Is Still Missing
70
154
 
71
- Even with the rack-cas and rack-cas-rails gems, the aforementioned basic authentication scheme is still incomplete. Namely, for an
72
- authenticated session, which user does it belong to?
155
+ However, the basic authentication scheme we have cooked up is still incomplete. Namely:
156
+
157
+ * What credentails should a user use to login, and how does your application verify it?
158
+ * Once a user has authenticated, how does your application know about that user?
159
+
160
+ The first point is that your application doesn't have to worry about it, since that is the whole point of CAS (and single sign-on).
161
+ Once your CAS server is set up, any application you write and integrate with it won't have to worry about it. Your CAS
162
+ server will take care of it for you.
163
+
164
+ The second point, however,requires some explanation and experimentation...
73
165
 
74
- Various Rails authentication gems makes the currently authenticated user available as an object via the ```current_user``` helper
75
- method. The rack-cas-rails gem does not provide this functionality. But you can look to gems such as
76
- [OmniAuth](https://github.com/intridea/omniauth), [Devise](https://github.com/plataformatec/devise),
77
- [Authlogic](https://github.com/binarylogic/authlogic) and so on to provide it.
166
+ Once a user has authenticated, the [rack-cas](https://github.com/biola/rack-cas) gem will insert some information about
167
+ that user into your application's session for it to retrieve. Your application should then take this information, usually
168
+ in the form of a username, and look up information about that user. Based on the information available, your application can
169
+ then implement additional features such as authorziation (not covered here).
78
170
 
79
- But, assuming your application has a ActiveRecord model named ```User``` where its accmpanying database table containing user records
80
- which are uniquely identifiable by a ```username``` attribute, you can add the following code to your ApplictionController to
81
- provide your application with the ```current_user``` method:
171
+ Ideally, your application should use the same data repository as your CAS server to look up user information. That repository can
172
+ be a SQL database table, some LDAP server, or any number of things. But for now, we can fake it.
173
+
174
+ Go ahead and create a scaffold around a Person model (or any other name you'd like to use), like so:
175
+
176
+ ```
177
+ $ rails generate scaffold person name:string age:integer
178
+ $ rake db:migrate
179
+ ```
180
+
181
+ Populate the ```people``` table with at least one row where the ```name``` column has the same value as one of the users your CAS
182
+ server knows about and you know the password of. For example, let's use "jsmith":
183
+
184
+ ```
185
+ $ rails console
186
+ Loading development environment (Rails 4.2.0)
187
+ 2.2.0 :001 > person = Person.new(name: "jsmith", age: 123)
188
+ => #<Person id: nil, name: "jsmith", age: 123, created_at: nil, updated_at: nil>
189
+ 2.2.0 :002 > person.save!
190
+ (0.2ms) begin transaction
191
+ SQL (33.5ms) INSERT INTO "people" ("name", "age", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "jsmith"],
192
+ ["age", 123], ["created_at", "2015-02-16 02:27:18.121111"], ["updated_at", "2015-02-16 02:27:18.121111"]]
193
+ (1.5ms) commit transaction
194
+ => true
195
+ 2.2.0 :003 > quit
196
+ ```
197
+
198
+ Now, let's add a helper named ```current_user``` (or any other name you like) to your application:
82
199
 
83
200
  ```ruby
84
- class ApplicationController
201
+ # app/controllers/application_ronctoller.rb
85
202
 
86
- # ...
87
-
203
+ require "rack_cas_rails"
204
+ class ApplicationController < ActionController::Base
205
+ # Prevent CSRF attacks by raising an exception.
206
+ # For APIs, you may want to use :null_session instead.
207
+ protect_from_forgery with: :exception
208
+ before_action :authenticate!, except: [:index, :show]
88
209
  def current_user
89
- authenciated? ? User.find_by_login(request.session["cas"]["user"]) : nil
210
+ authenticated? ? Person.find_by_name(request.session["cas"]["user"]) : nil
90
211
  end
91
-
92
212
  helper_method :current_user
93
-
94
213
  end
95
214
  ```
96
215
 
97
- *Note the user records should be the same ones available to CASinoApp for authentication.*
98
-
99
- Lastly, change your ```views/layouts/application.html.erb``` to be as follows:
216
+ Next, change your layout to be as follows:
100
217
 
101
218
  ```erb
219
+ <!-- views/layouts/application.html.erb -->
220
+
102
221
  <!DOCTYPE html>
103
222
  <html>
104
223
  <head>
@@ -108,12 +227,13 @@ Lastly, change your ```views/layouts/application.html.erb``` to be as follows:
108
227
  <%= csrf_meta_tags %>
109
228
  </head>
110
229
  <body>
111
- <divi id="nav-header">
230
+ <div id="header">
112
231
  <% if authenticated? %>
113
- <span>Logged in as <%= current_user.username %>.</span>
232
+ <span>You are logged in as <%= current_user.name %>.</span>
114
233
  <span style="float:right"><%= link_to "Logout", logout_url %></span>
115
234
  <% else %>
116
- <span><%= link_to "Login", login_url %></span>
235
+ <span>You are not logged in.</span>
236
+ <span style="float:right"><%= link_to "Login", login_url %></span>
117
237
  <% end %>
118
238
  </div>
119
239
  <hr />
@@ -124,20 +244,27 @@ Lastly, change your ```views/layouts/application.html.erb``` to be as follows:
124
244
  </html>
125
245
  ```
126
246
 
247
+ Restart your application again, and visit an ```/index``` endpoint. Click the __Login__ link, and authenticate using "jsmith"
248
+ (or whichever user you chose) and the correct password. Once authenticated, you'll be re-directed back to the original page.
249
+ This time, you are shown whom you are logged in as. Now visit a ```/new``` endpoint, and you won't be prompted to authenticate
250
+ again, until you click the __Logout__ link or restart your browser.
251
+
127
252
  ## Summary
128
253
 
129
- To recap, you'll have integrated your Rails application with a CAS-compliant server by making these changes to your application:
254
+ With rack-cas-rails, you can integrate your Rails application with CASinoApp or another CAS-compliant server for
255
+ authentication by making these changes in it:
130
256
 
131
- 1. Add ```config.rack_cas.server_url``` to config/application.rb
132
- 2. Add ```before_action :authenticate!``` to ApplicationController
133
- 3. Add ```current_user``` method to ApplictionController
134
- 4. Add simple navigational header to make use of ```current_user``` and the ```login_url```/```logout_url``` helpers
257
+ 1. Your Rails::Application subclass (in config/application.rb)
258
+ 2. Your ApplicationController class (in app/controllers/application_controller.rb)
259
+ 3. Your layout template (in app/views/layouts/application.html.erb)
260
+ 4. Add a model (or some other means) by which you can retrieve information about the currently logged in user
135
261
 
136
- As such, you can expect the following behavior:
262
+ With these changes in place, you can expect your application to exhibit the following behavior:
137
263
 
138
- * When you browse to any view within your application using a fresh session, you'll be re-directed to the sign-in page
139
- * After you authenticate, you'll be re-directed back to the page you browsed to
140
- * When you click the Logout link, your session will end, and the browser will be re-directed back to the login page
264
+ * When you browse to any protected endpoint within your application using a fresh session, you'll be re-directed to the sign-in page
265
+ * After you authenticate, you'll be re-directed back to the page you browsed to, after which you'll have access to all endpoints
266
+ * When you click the __Logout__ link or restart your browser, your session will end; and should you now attempt to access
267
+ a protected enpoint, you'll be prompted to log in once again
141
268
 
142
269
  ## Credits
143
270
 
@@ -0,0 +1,22 @@
1
+ ##
2
+ # Augments the Rails application class.
3
+
4
+ class Rails::Application < Rails::Engine
5
+
6
+ ##
7
+ # Gives the Rails::Application class a read-only class attribute to point to the CAS server URL. The URL in turn is then
8
+ # settable using @cas_server_url at the class level.
9
+
10
+ class << self
11
+ attr_reader :cas_server_url
12
+ end
13
+
14
+ ##
15
+ # Gets the CAS server root URL. Provides a convenience method at the instance level to fetch it.
16
+ # @return [String] Cas server's root URL.
17
+
18
+ def cas_server_url
19
+ self.class.cas_server_url
20
+ end
21
+
22
+ end
@@ -10,7 +10,12 @@ class ApplicationController < ActionController::Base
10
10
  # When invoked, will force authenticate. Most likely to be invoked as a before_action.
11
11
 
12
12
  def authenticate!
13
- authenticated? or render(:file => "public/401.html", :status => :unauthorized) # HTTP 401
13
+ return if authenticated?
14
+ if File.exists?("public/401.html")
15
+ render(:file => "public/401.html", :status => :unauthorized)
16
+ else
17
+ render(:plain => "Unauthorized!", :status => :unauthorized)
18
+ end
14
19
  end
15
20
 
16
21
  ##
@@ -27,7 +32,7 @@ class ApplicationController < ActionController::Base
27
32
  # @return [String] The CAS login URL.
28
33
 
29
34
  def login_url(service_url=request.url)
30
- url = URI(Rails.application.config.rack_cas.server_url)
35
+ url = URI(Rails.application.cas_server_url)
31
36
  url.path = "/login"
32
37
  url.query = "service=#{service_url || request.url}"
33
38
  url.to_s
@@ -1,3 +1,3 @@
1
1
  module RackCASRails
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,3 @@
1
+ require "rack_cas_rails/application"
2
+ require "rack_cas_rails/controllers"
3
+ require "rack_cas_rails/version"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-cas-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Brazil
@@ -44,6 +44,48 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 4.2.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: byebug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: sqlite3
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: yard
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
47
89
  description: Provides the integration glue between a Rails application and biola/rack-cas
48
90
  so that a CAS-compliant server (only tested with CASinoApp) can be used for authentication
49
91
  by the application.
@@ -54,9 +96,10 @@ extra_rdoc_files: []
54
96
  files:
55
97
  - LICENSE
56
98
  - README.md
57
- - lib/rack-cas-rails.rb
58
- - lib/rack-cas-rails/controllers.rb
59
- - lib/rack-cas-rails/version.rb
99
+ - lib/rack_cas_rails.rb
100
+ - lib/rack_cas_rails/application.rb
101
+ - lib/rack_cas_rails/controllers.rb
102
+ - lib/rack_cas_rails/version.rb
60
103
  homepage: https://github.com/bitaxis/rack-cas-rails.git
61
104
  licenses:
62
105
  - MIT
@@ -1 +0,0 @@
1
- require "rack-cas-rails/controllers"