authcan_easyroller 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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