authcan_easyroller 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.swp
2
+ *.swo
3
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Topher Fangio
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,217 @@
1
+ == Rails 3 Notes
2
+
3
+ I wanted to put this at the top so that nobody misses it. There are currently some bugs due to
4
+ Rails 3 still being in beta. As I come across these bugs, I will add them below and any workaround
5
+ if available.
6
+
7
+ * Bug #3928[https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3928] - process_parameter_filter throws an exception on array parameters
8
+
9
+ [Status:] Resolved in source control, awaiting next beta release.
10
+ [Workaround:] The code to enable parameter filtering in `lib/authcan_easyroller.rb` has been commented out until the next beta release.
11
+
12
+
13
+
14
+ == authcan_easyroller
15
+
16
+ This is a basic Rails engine utilizing Authlogic[http://github.com/binarylogic/authlogic],
17
+ CanCan[http://github.com/ryanb/cancan] and Easy Roles[http://github.com/platform45/easy_roles]
18
+ for simple Rails 3.x applications that need authentication and authorization.
19
+
20
+
21
+
22
+ == Basis for Creation
23
+
24
+ As a Rails developer, I find myself needing an elegant and easy-to-use solution for authentication
25
+ and authorization in the small web-apps that I create. They generally aren't linked together since
26
+ they are separate clients with completely different ideas and business models, but they both need
27
+ the same underlying code to manage their users.
28
+
29
+ I have used Authlogic for quite a while now and have found it to be very useful and a complete
30
+ solution for authentication. Adding a dash of functionality here and there is fairly easy and the
31
+ ability to extend it really drew me in (in fact, I helped develop some of the code behind
32
+ authlogic_ldap[http://github.com/topherfangio/authlogic_ldap] which I never got to finish but
33
+ still intend to do).
34
+
35
+ After watching the screencast[http://railscasts.com/episodes/192-authorization-with-cancan] by
36
+ Ryan Bates, I decided that CanCan was a great addition to my applications since it was easy to
37
+ use and cleanly separated the authorization from the model and view logic. The only other piece
38
+ was an easy way to manage roles soley in code, yet while storing the assignments in the database;
39
+ and I found this in Easy Roles.
40
+
41
+ Putting the three together, I now have a complete (albeit simple) authentication and authorization
42
+ solution that I can easily plugin into existing or new applications (and update in one spot).
43
+
44
+
45
+
46
+ == Future Enhancements
47
+
48
+ Before we get into the nitty-gritty of how to use it, I wanted to go ahead and mention the
49
+ planned enhancements so you can get a feel of where this project will go.
50
+
51
+ * Authlogic supports many different types of authentication without you needing to change
52
+ hardly anything, so I plan on modifying the code to allow for all of the possible authentication
53
+ schemes. Thus, I definitely plan on integrating OpenID, LDAP, Facebook Connect and OAuth. I may
54
+ or may not implement PAM, but we'll see.
55
+ * I plan on adding an easy password reset mechanism for users provided that you use an email column.
56
+ * I also plan to add the configuration option to turn on e-mail verification before users are granted
57
+ access to the system.
58
+
59
+
60
+
61
+ == Installation/Setup
62
+
63
+ Now that the code is a Rails 3 engine, installation is very simple; just install the gem and it's dependencies!
64
+
65
+ gem install rails authlogic cancan easy_roles authcan_easyroller
66
+
67
+ Next, create a migration for the users:
68
+
69
+ rails generate migration CreateUsers
70
+
71
+ Then, copy the following contents into that file making any changes you see fit:
72
+
73
+ class CreateUsers < ActiveRecord::Migration
74
+ def self.up
75
+ create_table :users do |t|
76
+ # Necessary Columns - These are required for AuthcanEasyroller to function properly
77
+ t.string :email, :null => false
78
+ t.string :crypted_password, :null => false
79
+ t.string :password_salt, :null => false
80
+ t.string :persistence_token, :null => false
81
+ t.string :single_access_token, :null => false
82
+ t.string :perishable_token, :null => false
83
+ t.integer :roles_mask, :null => false, :default => 0
84
+
85
+ # Magic Columns - You may leave any of the following out if you wish
86
+ t.integer :login_count, :null => false, :default => 0
87
+ t.integer :failed_login_count, :null => false, :default => 0
88
+ t.datetime :last_request_at
89
+ t.datetime :current_login_at
90
+ t.datetime :last_login_at
91
+ t.string :current_login_ip
92
+ t.string :last_login_ip
93
+
94
+ # Timestamp Columns - You should have these on every database table you create
95
+ t.timestamps
96
+ end
97
+ end
98
+
99
+ def self.down
100
+ drop_table :users
101
+ end
102
+ end
103
+
104
+ Once saved, migrate your database by running
105
+
106
+ rake db:migrate
107
+
108
+ Next, copy the following files to their proper locations (feel free to edit them, these are just some basics to
109
+ help get you started). The <tt>rails.js</tt> file at the bottom of the list is the official Rails jQuery file available
110
+ at http://github.com/rails/jquery-ujs .
111
+
112
+ * ability.rb[http://github.com/topherfangio/authcan_easyroller/raw/master/examples/ability.rb] -> <<APPLICATION>>/app/models/ability.rb
113
+ * application.html.erb[http://github.com/topherfangio/authcan_easyroller/raw/master/examples/application.html.erb] -> <<APPLICATION>>/app/view/layouts/application.html.erb
114
+ * main.css[http://github.com/topherfangio/authcan_easyroller/raw/master/examples/main.css] -> <<APPLICATION>/public/stylesheets/main.css
115
+ * rails.js[http://github.com/rails/jquery-ujs/raw/master/src/rails.js] -> <<APPLICATION>/public/javascripts/rails.js
116
+
117
+
118
+
119
+ == Starting Your Engine
120
+
121
+ Once you have everything setup correctly, simply run the following to start your application, then visit http://localhost:3000
122
+
123
+ rails server
124
+
125
+ The application realizes that it has no users, and forces you to create one before you can continue
126
+ to any page. The first user is always created as an administrator and thus has privileges to create
127
+ new users, give themselves the "developer" role (or any/all roles) and do other adminy things. All
128
+ users created after this will be given the default role of "user".
129
+
130
+ Currently, the available roles are
131
+
132
+ 1. Developer
133
+ 2. Admin
134
+ 3. Moderator
135
+ 4. User
136
+
137
+ I'm working on a way to extend this functionality as a configuration option, or perhaps give it an
138
+ API so that you can create your own roles or modify the existing ones without having to delve into
139
+ the gem's code. Check back often to see where that stands if it is something you need.
140
+
141
+
142
+
143
+ == Usage
144
+
145
+ You can find out more by checking each specific project's documentation, but here is the gist:
146
+
147
+ A user's abilities are defined in <tt>app/models/ability.rb</tt>. I generally prefer to specify what
148
+ each role is allowed to do and then give a user all of the roles that they need instead of
149
+ saying that an admin can do everything that a moderator can do. This tends to keep the ability
150
+ model cleaner and your views don't change either. In addition, this allows you to assign roles
151
+ to a user for special circumstances. For instance, if you are writing a help desk app, you may
152
+ decide that one particular customer is really superb and should also have status update abilities
153
+ even though he has the customer role.
154
+
155
+ You define your abilities in each role's section. For instance, the moderator's role currently looks
156
+ like so:
157
+
158
+ # Moderator role abilities
159
+ if current_user.is_moderator?
160
+ end
161
+
162
+ If you wanted to let moderators manage users, you would simply call <tt>can</tt>
163
+
164
+ # Moderator role abilities
165
+ if current_user.is_moderator?
166
+ can :manage, User
167
+ end
168
+
169
+ You can also define your own abilities if they don't tie to a particular object, but you must pass a
170
+ <tt>nil</tt> object as the second argument to <tt>can?</tt> and you must specify all object types when
171
+ defining the ability. I'll get in touch with the developer to see if this can be a tad bit more streamlined.
172
+
173
+ # ability.rb
174
+
175
+ # Moderator role abilities
176
+ if current_user.is_moderator?
177
+ can :visit_woot_all_day, :all
178
+ end
179
+
180
+
181
+ # application.html.erb
182
+
183
+ <% if can? :visit_woot_all_day, nil %>
184
+ <%= link_to "Woot", "http://www.woot.com" %>
185
+ <% end %>
186
+
187
+ Once you have the roles and abilities setup, your views can check who has access by simply calling <tt>can?</tt>
188
+
189
+ if can? :create, Comment
190
+ ...
191
+ end
192
+
193
+ You can also use <tt>cannot?</tt>
194
+
195
+ link_to "Export", export_users_url unless cannot? :create, Export
196
+
197
+ Using <tt>can?</tt> and <tt>cannot?</tt> is the preferred method of checking authorization privileges, however,
198
+ if you find a rare case that you need to limit access based on the role(s) that a user has, you can
199
+ always do the following:
200
+
201
+ if current_user.is_moderator? || current_user.is_admin?
202
+ ...
203
+ end
204
+
205
+ However, the beauty of authcan_easyroller (more specifically the CanCan integration) is that you
206
+ don't have to. That is the exact purpose of the <tt>Ability</tt> class! Use it to your advantage and
207
+ make your life easier.
208
+
209
+
210
+
211
+ == Special Thanks
212
+
213
+ I would like to thank the creators of Authlogic, CanCan and Easy Roles for the effort that they put
214
+ into these plugins. Adding them together was relatively straightforward and easy and I hope that they
215
+ realize how much time this saves other developers!
216
+
217
+ Copyright (c) 2010 Topher Fangio, released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "authcan_easyroller"
8
+ gem.summary = %Q{Rails 3 engine for user authentication/authorization utilizing Authlogic, CanCan and EasyRoles}
9
+ gem.description = %Q{This is a basic Rails engine utilizing Authlogic, CanCan and Easy Roles to create a starting point for simple Rails-based applications that need authentication and authorization. }
10
+ gem.email = "fangiotophia@gmail.com"
11
+ gem.homepage = "http://github.com/topherfangio/authcan_easyroller"
12
+ gem.authors = ["Topher Fangio"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "authcan_easyroller #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,79 @@
1
+ class AuthcanEasyrollerController < ApplicationController
2
+ helper :all # include all helpers, all the time
3
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
4
+
5
+ # Scrub sensitive parameters from your log
6
+ helper_method :current_user_session, :current_user
7
+
8
+ rescue_from CanCan::AccessDenied do |exception|
9
+ flash[:error] = exception.message
10
+ redirect_back_or_default(root_url)
11
+ end
12
+
13
+ # Ensure there is at least one user in the system before trying to do anything
14
+ before_filter :require_one_user
15
+ after_filter :store_location
16
+
17
+ private
18
+ def current_user_session
19
+ return @current_user_session if defined?(@current_user_session)
20
+ @current_user_session = UserSession.find
21
+ end
22
+
23
+ def current_user
24
+ if defined?(@current_user)
25
+ return @current_user
26
+ end
27
+
28
+ @current_user = current_user_session && current_user_session.user
29
+
30
+ if @current_user_session and @current_user_session.stale?
31
+ flash[:warning] = "You have been logged out due to an extended period of inactivity."
32
+ @current_user_session.destroy
33
+ end
34
+
35
+ return @current_user
36
+ end
37
+
38
+ def require_one_user
39
+ if User.count == 0 and not users_url.match(/#{request.request_uri}$/) and not new_user_url.match(/#{request.request_uri}$/)
40
+ flash[:error] = "No users yet, must create one to access the site."
41
+
42
+ redirect_to new_user_url
43
+ return false
44
+ end
45
+ end
46
+
47
+ def require_user
48
+ unless current_user
49
+ store_location
50
+
51
+ flash[:notice] = "You must be logged in to access this page."
52
+ redirect_to new_user_session_url
53
+
54
+ return false
55
+ end
56
+ end
57
+
58
+ def require_no_user
59
+ if current_user
60
+ store_location
61
+
62
+ flash[:notice] = "You must be logged out to access this page."
63
+ redirect_to user_url(current_user)
64
+
65
+ return false
66
+ end
67
+ end
68
+
69
+ def store_location
70
+ unless new_user_url.match(/#{request.request_uri}$/) or new_user_session_url.match(/#{request.request_uri}$/)
71
+ session[:return_to] = request.request_uri
72
+ end
73
+ end
74
+
75
+ def redirect_back_or_default(default)
76
+ redirect_to(session[:return_to] || default)
77
+ session[:return_to] = nil
78
+ end
79
+ end
@@ -0,0 +1,35 @@
1
+ class UserSessionsController < AuthcanEasyrollerController
2
+ before_filter :require_no_user, :only => [:new, :create]
3
+ before_filter :require_user, :only => :destroy
4
+
5
+ load_and_authorize_resource
6
+
7
+ def new
8
+ respond_to do |format|
9
+ if current_user
10
+ redirect_to :controll => 'users', :action => 'show', :id => current_user
11
+ else
12
+ @user_session = UserSession.new
13
+
14
+ format.html # new.html.erb
15
+ format.xml { render :xml => @user_session }
16
+ end
17
+ end
18
+ end
19
+
20
+ def create
21
+ @user_session = UserSession.new(params[:user_session])
22
+ if @user_session.save
23
+ flash[:notice] = "Login successful!"
24
+ redirect_back_or_default user_url(@user_session.user)
25
+ else
26
+ render :action => :new
27
+ end
28
+ end
29
+
30
+ def destroy
31
+ current_user_session.destroy
32
+ flash[:notice] = "Logout successful!"
33
+ redirect_back_or_default '/'
34
+ end
35
+ end
@@ -0,0 +1,60 @@
1
+ class UsersController < AuthcanEasyrollerController
2
+
3
+ before_filter :load_correct_user, :only => [:show, :edit, :update]
4
+ before_filter :require_user, :only => [:edit, :update]
5
+
6
+ load_and_authorize_resource
7
+
8
+ def index
9
+ @users = User.all
10
+ end
11
+
12
+ def new
13
+ @user = User.new
14
+ end
15
+
16
+ def create
17
+ @user = User.new(params[:user])
18
+ if @user.save
19
+ flash[:notice] = "Account registered!"
20
+ redirect_back_or_default user_url(@user)
21
+ else
22
+ render :action => :new
23
+ end
24
+ end
25
+
26
+ def show
27
+ require_user if @user.nil?
28
+ end
29
+
30
+ def edit
31
+ end
32
+
33
+ def update
34
+ if @user.update_attributes(params[:user])
35
+ flash[:notice] = "Account updated!"
36
+ redirect_to user_url(@user)
37
+ else
38
+ render :action => :edit
39
+ end
40
+ end
41
+
42
+ def destroy
43
+ @user = User.find(params[:id])
44
+ @user.destroy
45
+
46
+ respond_to do |format|
47
+ format.html { redirect_to(users_url) }
48
+ format.xml { head :ok }
49
+ end
50
+ end
51
+
52
+ private
53
+ def load_correct_user
54
+ if params[:id]
55
+ @user = User.find(params[:id])
56
+ else
57
+ @user = current_user
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ module AuthcanEasyrollerHelper
2
+ def namify(object)
3
+ if object.present? and object.respond_to? :name
4
+ object.send(:name)
5
+ else
6
+ ""
7
+ end
8
+ end
9
+
10
+ def datify(object, format = :long)
11
+ object.to_s(format) unless object.nil?
12
+ end
13
+
14
+ def phonify(object)
15
+ if object.respond_to? :gsub
16
+ s = object.gsub(/[^0-9]/, '')
17
+
18
+ case s.length
19
+ when 11 then "#{s[0..0]} (#{s[1..3]}) #{s[4..6]}-#{s[7..10]}"
20
+ when 10 then "(#{s[0..2]}) #{s[3..5]}-#{s[6..9]}"
21
+ when 7 then "#{s[0..2]}-#{s[3..6]}"
22
+ else s
23
+ end
24
+ else
25
+ object.to_s
26
+ end
27
+ end
28
+
29
+ def form_descriptor(message = nil)
30
+ raw "<br /><span class='form-descriptor-element'>#{message}</span>"
31
+ end
32
+
33
+ def link_separator
34
+ raw "&nbsp;|&nbsp;"
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(current_user)
5
+ can :read, :all
6
+ can :manage, UserSession
7
+
8
+ if current_user
9
+ # Abilities for someone with an account (does not necessarily have a "user" role)
10
+ can [:update, :destroy], User do |user|
11
+ user == current_user
12
+ end
13
+
14
+
15
+ # User role abilities
16
+ if current_user.is_user?
17
+ end
18
+
19
+
20
+ # Moderator role abilities
21
+ if current_user.is_moderator?
22
+ end
23
+
24
+
25
+ # Admin role abilities
26
+ if current_user.is_admin?
27
+ can :manage, :all
28
+ end
29
+
30
+
31
+ # Developer role abilities
32
+ if current_user.is_developer?
33
+ can :manage, :all
34
+ end
35
+ else
36
+ can :create, User
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,54 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ # Constant variable storing roles in the system
4
+ ROLES_MASK = %w[developer admin moderator user]
5
+
6
+ HUMANIZED_COLUMNS = {
7
+ :email => 'E-mail'
8
+ }
9
+
10
+
11
+ # Authentication and Authorization
12
+ acts_as_authentic do |config|
13
+ config.logged_in_timeout = 1.hour
14
+ end
15
+
16
+ easy_roles :roles_mask, :method => :bitmask
17
+
18
+
19
+ # Ensure the user has the proper roles
20
+ before_create :assign_user_roles
21
+
22
+
23
+ # Validations
24
+ validates_each :roles do |record, attr, value|
25
+ begin
26
+ # If the roles changed, and it's not a new record whose only role is "user" and there is at least 1 user already in the system...
27
+ if record.roles_mask_changed? and not (record.new_record? and record.roles == ["user"]) and User.count > 0
28
+ session = UserSession.find
29
+ current_user = session.user unless session.nil?
30
+
31
+ record.errors.add attr, ' can only be modified by an administrator.' if (not current_user.is_developer? and not current_user.is_admin?)
32
+ end
33
+ rescue Authlogic::Session::Activation::NotActivatedError
34
+ # Do nothing, we are in a console session
35
+ end
36
+ end
37
+
38
+
39
+ # Allows us to easily humanize our attributes in one location
40
+ # so we don't have to do it in every view
41
+ def self.human_attribute_name(attribute)
42
+ HUMANIZED_COLUMNS[attribute.to_sym] || super
43
+ end
44
+
45
+ private
46
+ def assign_user_roles
47
+ self.roles += ["user"]
48
+
49
+ if User.count == 0
50
+ self.roles += ["admin"]
51
+ self.roles += ["moderator"]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ class UserSession < Authlogic::Session::Base
2
+ logout_on_timeout true
3
+ end
@@ -0,0 +1,27 @@
1
+ <h1>Login</h1>
2
+
3
+ <% form_for @user_session, :url => user_session_path do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <p>
7
+ <%= f.label :email %>
8
+ <%= f.text_field :email %>
9
+ </p>
10
+
11
+ <p>
12
+ <%= f.label :password %>
13
+ <%= f.password_field :password %>
14
+ </p>
15
+
16
+ <p>
17
+ <%= f.check_box :remember_me %><%= f.label :remember_me %>
18
+ </p>
19
+
20
+ <p>
21
+ <%= f.submit "Login" %>
22
+ </p>
23
+
24
+ <p>
25
+ Don't have an account yet? Why not <%= link_to "sign up", new_user_path %>!
26
+ </p>
27
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <%= form.hidden_field :id unless form.object.new_record? %>
2
+
3
+ <p>
4
+ <%= form.label :email, "E-mail" %>
5
+ <%= form.text_field :email %>
6
+ </p>
7
+
8
+ <p>
9
+ <%= form.label :password, form.object.new_record? ? "Password" : "Change Password" %>
10
+ <%= form.password_field :password %>
11
+ </p>
12
+
13
+ <p>
14
+ <%= form.label :password_confirmation, "Password Confirmation" %>
15
+ <%= form.password_field :password_confirmation %>
16
+ </p>
17
+
18
+ <% if can? :manage, :roles %>
19
+ <p>
20
+ <%= form.label :roles %>
21
+ <%= form.select :roles, User::ROLES_MASK, {}, { :multiple => true, :size => 4 } %>
22
+ </p>
23
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <h3>Edit My Account</h3>
2
+
3
+ <% form_for @user do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <%= render :partial => "form", :object => f %>
7
+
8
+ <p>
9
+ <%= f.submit "Update" %>&nbsp;or&nbsp;<%= link_to 'return to list', users_path %>
10
+ </p>
11
+ <% end %>
12
+
13
+ <br /><%= link_to "My Profile", user_path(@user) %>
@@ -0,0 +1,35 @@
1
+ <h3>Listing Users</h3>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Email</th>
6
+ <th>Last Seen</th>
7
+ <th>Action</th>
8
+ </tr>
9
+
10
+ <% @users.each do |user| %>
11
+ <tr>
12
+ <td><%= user.email %></td>
13
+ <td><%= time_ago_in_words user.last_request_at %> ago</td>
14
+
15
+ <td>
16
+ <%= link_to 'Show', user %>
17
+
18
+ <% if can? :update, user %>
19
+ <%= link_separator %>
20
+ <%= link_to 'Edit', edit_user_path(user) %>
21
+ <% end %>
22
+
23
+ <% if can? :destroy, user %>
24
+ <%= link_separator %>
25
+ <%= link_to 'Delete', user, :confirm => 'Are you sure?', :method => :delete %>
26
+ <% end %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+
31
+ </table>
32
+
33
+ <br />
34
+
35
+ Not signed up? <%= link_to 'Register', new_user_path %> now!
@@ -0,0 +1,11 @@
1
+ <h3>Register New User</h3>
2
+
3
+ <% form_for @user do |f| %>
4
+ <%= f.error_messages %>
5
+
6
+ <%= render :partial => "form", :object => f %>
7
+
8
+ <p>
9
+ <%= f.submit "Register" %>&nbsp;or&nbsp;<%= link_to 'return to list', users_path %>
10
+ </p>
11
+ <% end %>
@@ -0,0 +1,39 @@
1
+ <h3>Showing User Information</h3>
2
+
3
+ <p>
4
+ <b>E-mail:</b>
5
+ <%=h @user.email %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Login Count:</b>
10
+ <%=h @user.login_count %>
11
+ </p>
12
+
13
+ <p>
14
+ <b>Last Request at:</b>
15
+ <%= datify @user.last_request_at %>
16
+ </p>
17
+
18
+ <p>
19
+ <b>Last Login at:</b>
20
+ <%= datify @user.last_login_at %>
21
+ </p>
22
+
23
+ <p>
24
+ <b>Current Login at:</b>
25
+ <%= datify @user.current_login_at %>
26
+ </p>
27
+
28
+ <p>
29
+ <b>Last Login IP:</b>
30
+ <%=h @user.last_login_ip %>
31
+ </p>
32
+
33
+ <p>
34
+ <b>Current Login IP:</b>
35
+ <%=h @user.current_login_ip %>
36
+ </p>
37
+
38
+
39
+ <%= link_to 'Edit', edit_user_path(@user) %> or <%= link_to 'return to list', users_path %>
@@ -0,0 +1,70 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{authcan_easyroller}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Topher Fangio"]
12
+ s.date = %q{2010-03-31}
13
+ s.description = %q{This is a basic Rails engine utilizing Authlogic, CanCan and Easy Roles to create a starting point for simple Rails-based applications that need authentication and authorization. }
14
+ s.email = %q{fangiotophia@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "app/controllers/authcan_easyroller_controller.rb",
26
+ "app/controllers/user_sessions_controller.rb",
27
+ "app/controllers/users_controller.rb",
28
+ "app/helpers/authcan_easyroller_helper.rb",
29
+ "app/models/ability.rb",
30
+ "app/models/user.rb",
31
+ "app/models/user_session.rb",
32
+ "app/views/user_sessions/new.html.erb",
33
+ "app/views/users/_form.html.erb",
34
+ "app/views/users/edit.html.erb",
35
+ "app/views/users/index.html.erb",
36
+ "app/views/users/new.html.erb",
37
+ "app/views/users/show.html.erb",
38
+ "authcan_easyroller.gemspec",
39
+ "config/routes.rb",
40
+ "example/ability.rb",
41
+ "example/application.html.erb",
42
+ "example/main.css",
43
+ "lib/authcan_easyroller.rb",
44
+ "test/helper.rb",
45
+ "test/test_authcan_easyroller.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/topherfangio/authcan_easyroller}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.6}
51
+ s.summary = %q{Rails 3 engine for user authentication/authorization utilizing Authlogic, CanCan and EasyRoles}
52
+ s.test_files = [
53
+ "test/helper.rb",
54
+ "test/test_authcan_easyroller.rb"
55
+ ]
56
+
57
+ if s.respond_to? :specification_version then
58
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
59
+ s.specification_version = 3
60
+
61
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
62
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
63
+ else
64
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
68
+ end
69
+ end
70
+
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ Rails::Application.routes.draw do |map|
2
+ resources :users
3
+ resource :user_session
4
+ end
@@ -0,0 +1,41 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(current_user)
5
+ can :read, :all
6
+ can :manage, UserSession
7
+
8
+ if current_user
9
+ # Abilities for someone with an account (does not necessarily have a "user" role)
10
+ can [:update, :destroy], User do |user|
11
+ user == current_user
12
+ end
13
+
14
+
15
+ # User role abilities
16
+ if current_user.is_user?
17
+ end
18
+
19
+
20
+ # Moderator role abilities
21
+ if current_user.is_moderator?
22
+ end
23
+
24
+
25
+ # Admin role abilities
26
+ if current_user.is_admin?
27
+ can :manage, :all
28
+ end
29
+
30
+
31
+ # Developer role abilities
32
+ if current_user.is_developer?
33
+ can :manage, :all
34
+ end
35
+ else
36
+ can :create, User
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,40 @@
1
+ <html>
2
+ <head>
3
+ <script src="http://www.google.com/jsapi"></script>
4
+ <script>google.load("jquery", "1.4");</script>
5
+
6
+ <%= stylesheet_link_tag 'main' %>
7
+ </head>
8
+
9
+ <body>
10
+ <div id='navigation'>
11
+ <%= link_to "Users", users_path %>
12
+ </div>
13
+
14
+ <div id='userland'>
15
+ <% if current_user %>
16
+ Welcome <%= current_user.email %>!
17
+
18
+ <%= link_to "My Account", user_path(current_user) %>
19
+ <%= link_separator %>
20
+ <%= link_to "Logout", '/user_sessions/destroy' %>
21
+ <% else %>
22
+ You are not currently
23
+ <%= link_to "logged in", new_user_session_path %>.
24
+ <% end %>
25
+ </div>
26
+
27
+ <div id='flashes'>
28
+ <%= raw "<h5 class='flash error'>#{flash[:error]}</h5>" unless flash[:error].blank? %>
29
+ <%= raw "<h5 class='flash notice'>#{flash[:notice]}</h5>" unless flash[:notice].blank? %>
30
+ </div>
31
+
32
+ <div id='content'>
33
+ <%= yield %>
34
+ </div>
35
+
36
+ <div id='copyright'>
37
+ Copyright &copy; 2010, MyCompany. All rights reserved.
38
+ </div>
39
+ </body>
40
+ </html>
data/example/main.css ADDED
@@ -0,0 +1,41 @@
1
+ #navigation {
2
+ float: left;
3
+ margin-bottom: 10px;
4
+ }
5
+
6
+ #userland {
7
+ float: right;
8
+ margin-bottom: 10px;
9
+ }
10
+
11
+ #flashes {
12
+ clear: both;
13
+ }
14
+
15
+ #content {
16
+ margin: 10px;
17
+ }
18
+
19
+ #copyright {
20
+ text-align: center;
21
+ }
22
+
23
+ .flash {
24
+ border: 1px solid #000000;
25
+ padding: 10px;
26
+ }
27
+
28
+ .flash.error {
29
+ }
30
+
31
+ .flash.notice {
32
+ }
33
+
34
+ label {
35
+ font-weight: bold;
36
+ }
37
+
38
+ input[type=text],input[type=password],select,textarea {
39
+ clear: both;
40
+ display: block;
41
+ }
@@ -0,0 +1,20 @@
1
+ require 'authcan_easyroller'
2
+ require 'rails'
3
+
4
+ # AuthcanEasyroller
5
+ module AuthcanEasyroller
6
+ class Engine < Rails::Engine
7
+ engine_name :authcan_easyroller
8
+
9
+ initializer "authcan_easyroller.configure_rails_initilization" do |app|
10
+ # NOTE: The following has been commented out to bypass bug #3928 which will be fixed with the next release.
11
+ #
12
+ # Please comment these back in when Rails 3.0.0.beta2 or later version is used.
13
+ #
14
+ # Bug here: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3928
15
+ #
16
+ app.config.filter_parameters << :password
17
+ app.config.filter_parameters << :password_confirmation
18
+ end
19
+ end
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'authcan_easyroller'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestAuthcanEasyroller < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authcan_easyroller
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Topher Fangio
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-31 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thoughtbot-shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: "This is a basic Rails engine utilizing Authlogic, CanCan and Easy Roles to create a starting point for simple Rails-based applications that need authentication and authorization. "
33
+ email: fangiotophia@gmail.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.rdoc
41
+ files:
42
+ - .gitignore
43
+ - LICENSE
44
+ - README.rdoc
45
+ - Rakefile
46
+ - VERSION
47
+ - app/controllers/authcan_easyroller_controller.rb
48
+ - app/controllers/user_sessions_controller.rb
49
+ - app/controllers/users_controller.rb
50
+ - app/helpers/authcan_easyroller_helper.rb
51
+ - app/models/ability.rb
52
+ - app/models/user.rb
53
+ - app/models/user_session.rb
54
+ - app/views/user_sessions/new.html.erb
55
+ - app/views/users/_form.html.erb
56
+ - app/views/users/edit.html.erb
57
+ - app/views/users/index.html.erb
58
+ - app/views/users/new.html.erb
59
+ - app/views/users/show.html.erb
60
+ - authcan_easyroller.gemspec
61
+ - config/routes.rb
62
+ - example/ability.rb
63
+ - example/application.html.erb
64
+ - example/main.css
65
+ - lib/authcan_easyroller.rb
66
+ - test/helper.rb
67
+ - test/test_authcan_easyroller.rb
68
+ has_rdoc: true
69
+ homepage: http://github.com/topherfangio/authcan_easyroller
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options:
74
+ - --charset=UTF-8
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ requirements: []
92
+
93
+ rubyforge_project:
94
+ rubygems_version: 1.3.6
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Rails 3 engine for user authentication/authorization utilizing Authlogic, CanCan and EasyRoles
98
+ test_files:
99
+ - test/helper.rb
100
+ - test/test_authcan_easyroller.rb