technoweenie / restful-authentication

Generates common user authentication code for Rails/Merb, with a full test/unit and rspec suite and optional Acts as State Machine support built-in.

This URL has Read+Write access

restful-authentication / CHANGELOG
100644 185 lines (136 sloc) 8.443 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
As always, the most up-to-date version of the CHANGELOG file is in the source
code tree, not the wiki. The git log is even better than either.
 
********************************************************************************
 
Changes for v2.0b0
 
********************************************************************************
 
The system has been split up to give a clear distinction between authentication
(who are you?), authorization (is he allowed to just take the plutonium like
that?), policy (note to staff: no one is allowed to take plutonium) and access
control (step away from the reactor, bubba).
 
The plugin now generates *much* less app-space code: the controllers are super
skinny now, and if any security flaws are discovered it should be less painful
to stay current.
 
Out of the box, the plugin will stay the heck out of your way, implementing the
popular "users can do stuff and no-one else can" security model. But if your
security needs extend beyond that, there are clear hooks for you to add security
components that play nice with restful-authentication. It should also be easy
to *decouple* components such as login-by-password or remember-me-tokens if you
don't want that.
 
There is a robust rspec test suite with near-100% coverage, along with a
framework for building RSpec stories.
 
Finally, there have been several minor security fixes, largely centered around
implementing best practices recommended in the "Open Web Application Security
Project":http://www.owasp.org/index.php/Guide_Table_of_Contents and other
references (see notes/ for more).
 
 
********************************************************************************
 
The abstract implementation is divided among lib/authentication.rb and
lib/access_control.rb, with concrete code (Authentication::ByPassword,
AccessControl::LoginRequired, &c) in subdirectories.
 
* logged_in?, current_user, current_user= are basically the same. current_user's
  passive login behaviour now happens through the try_login_chain. Cookie_token
  & basic_auth hook in automagically when included, restoring the old behaviour.
 
* A session login is 'passive' -- it's meant to mimic the presence of state, and
  implies no change in logged-in status. All other login methods should call
  become_logged_in_as!, and should not set current_user= directly. (The old
  version of restful_authentication will let a non-activated user log in by HTTP
  basic).
 
* authorize? now has a bossy friend, demand_authorization! -- where authorize
  returns false, demand_authorization! raises an exception. Both now take a
  params hash of the form
    :for => subject, :to => action, :on => resource, :extra => whatever
  and hand it off to the #get_authorization stub. get_authorization returns
  something that is_denial? (false or a SecurityError exception) to say 'deny',
  and any other true value to say 'allow'.
 
* Most of the routines 'Fail-closed' (aka Positive Authentication; see
  http://owasp.org/index.php/Guide_to_Authentication#Positive_Authentication) --
  use exception handling to route authentication/access control violations, and
  commit no resources until all conditions pass (or rollback on
  failure). handle_signin_error shows one reasonable response chain.
 
* access_denied is now named handle_access_denied as is automatically installed
  as a rescue_from handler.
 
* Cookie handling (controller & model) is all in authentication/by_cookie_token.
  Password handling (controller & model) is all in authentication/by_password. I
  know the MVC-pattern violation will make some squirm, but this code *should*
  be opaque to the model at large, and security code should be compartmentalized
  -- this is all properly controller code, even the parts within the model.
 
* The logout routine calls a logout_chain for any resources that need to be
  destroyed on logout. (Clearing the server&client cookie token, for example).
 
--------------------------------------------------------------------------------
 
Model, controllers
 
* are much skinnier, by handing almost everything off to library code. They
  route by exception handling and not conditional branching.
 
* password and password_confirmation now have filter_parameter_logging by default.
 
* User#authenticate now **only** checks the password. User activation & other
  authorization is handled by the demand_authorization! chain -- specifically, by
  demand_authorization :for => user, :to => :login
 
* Much stricter validation by default:
** logins can only be /[\w\.\+@\-]+/
** email has to look liken an email
** password between 6, 40
* salt and remember_token now much less predictability
 
Stateful Roles and Email Validation will get their own generator.
 
********************************************************************************
 
Things that might make you sad:
 
* The old-skool Test::Unit &c are still present but won't be maintained (there
  are a couple dozen tests vs. a couple hundred specs).
 
* If you have existing users, make sure to use the --old-passwords flag.
 
* You have to manually include the modules into your controller, and the
  authentication_test_helper into your spec_helper/test_helper -- we don't fake
  it for you any more.
 
* You can name your SessionsController anything you like, as long as it's
  "SessionsController", and you can name your User resource anything you like,
  as long as you enjoy doing a search/replace through the code in lib/. A
  review of google hits for restful_authentication showed almost no-one using
  alternate names, so it's now more Opinionated, for maintainability and Playing
  Nicely with Others.
 
* The specs and stories will explode if you generate a nested (Admin::User)
  resource. If you actually use this, please fix it and send back a patch.
 
 
********************************************************************************
 
Changes from the svn version
 
********************************************************************************
 
h2. Changes for the v1.1 version of restful-authentication
 
h3. Changes to session_controller
 
* use uniform logout function
* use uniform remember_cookie functions
* avoid calling logged_in? which will auto-log-you-in (safe in the face of
  logout! call, but idiot-proof)
* Moved reset_session into only the "now logged in" branch
** wherever it goes, it has to be in front of the current_user= call
** See more in README-Tradeoffs.txt
* made a place to take action on failed login attempt
* recycle login and remember_me setting on failed login
* nil'ed out the password field in 'new' view
 
h3. Changes to users_controller
 
* use uniform logout function
* use uniform remember_cookie functions
* Moved reset_session into only the "now logged in" branch
** wherever it goes, it has to be in front of the current_user= call
** See more in README-Tradeoffs.txt
* made the implicit login only happen for non-activationed sites
* On a failed signup, kick you back to the signin screen (but strip out the password & confirmation)
* more descriptive error messages in activate()
* recently_activated? belongs only if stateful
* migration has 40-char limit on remember_token & an index on users by login
 
h3. users_helper
 
* link_to_user, link_to_current_user, link_to_signin_with_IP
* if_authorized(action, resource, &block) view function (with appropriate
  warning)
 
h3. authenticated_system
 
* Made authorized? take optional arguments action=nil, resource=nil, *args
  This makes its signature better match traditional approaches to access control
  eg Reference Monitor in "Security Patterns":http://www.securitypatterns.org/patterns.html)
* authorized? should be a helper too
* added uniform logout! methods
* format.any (as found in access_denied) doesn't work until
  http://dev.rubyonrails.org/changeset/8987 lands.
* cookies are now refreshed each time we cross the logged out/in barrier, as
  "best":http://palisade.plynt.com/issues/2004Jul/safe-auth-practices/
  "practice":http://www.owasp.org/index.php/Session_Management#Regeneration_of_Session_Tokens
 
h3. Other
 
* Used escapes <%= %> in email templates (among other reasons, so courtenay's
  "'dumbass' test":http://tinyurl.com/684g9t doesn't complain)
* Added site key to generator, users.yml.
* Made site key generation idempotent in the most crude and hackish way
* 100% coverage apart from the stateful code. (needed some access_control
  checks, and the http_auth stuff)
* Stories!