devisable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Devisable.gemspec +117 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.rdoc +111 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/lib/generators/devisable/USAGE +57 -0
  8. data/lib/generators/devisable/devisable_generator.rb +484 -0
  9. data/lib/generators/devisable/templates/app/controllers/registrations_controller.erb +19 -0
  10. data/lib/generators/devisable/templates/app/controllers/users_controller.erb +152 -0
  11. data/lib/generators/devisable/templates/app/controllers/welcome_controller.erb +11 -0
  12. data/lib/generators/devisable/templates/app/helpers/roles_helper.erb +63 -0
  13. data/lib/generators/devisable/templates/app/models/permission.erb +12 -0
  14. data/lib/generators/devisable/templates/app/models/role.erb +5 -0
  15. data/lib/generators/devisable/templates/app/views/roles/_form.erb +29 -0
  16. data/lib/generators/devisable/templates/app/views/roles/edit.erb +6 -0
  17. data/lib/generators/devisable/templates/app/views/roles/index.erb +28 -0
  18. data/lib/generators/devisable/templates/app/views/roles/new.erb +5 -0
  19. data/lib/generators/devisable/templates/app/views/roles/show.erb +10 -0
  20. data/lib/generators/devisable/templates/app/views/shared/_admin_nav.erb +7 -0
  21. data/lib/generators/devisable/templates/app/views/users/_form.erb +23 -0
  22. data/lib/generators/devisable/templates/app/views/users/edit.erb +6 -0
  23. data/lib/generators/devisable/templates/app/views/users/index.erb +27 -0
  24. data/lib/generators/devisable/templates/app/views/users/new.erb +5 -0
  25. data/lib/generators/devisable/templates/app/views/users/show.erb +55 -0
  26. data/lib/generators/devisable/templates/app/views/welcome/welcome_index.erb +3 -0
  27. data/lib/generators/devisable/templates/config/initializers/devise_initializer.erb +239 -0
  28. data/lib/generators/devisable/templates/cucumber/_rake_partial.rb +19 -0
  29. data/lib/generators/devisable/templates/cucumber/devise.feature +78 -0
  30. data/lib/generators/devisable/templates/cucumber/role.feature +79 -0
  31. data/lib/generators/devisable/templates/cucumber/step_definitions/authentication_steps.rb +33 -0
  32. data/lib/generators/devisable/templates/cucumber/step_definitions/generic_steps.rb +23 -0
  33. data/lib/generators/devisable/templates/cucumber/step_definitions/role_steps.rb +32 -0
  34. data/lib/generators/devisable/templates/cucumber/step_definitions/user_steps.rb +30 -0
  35. data/lib/generators/devisable/templates/cucumber/support/_env_partial.rb +57 -0
  36. data/lib/generators/devisable/templates/cucumber/support/_paths_partial.rb +20 -0
  37. data/lib/generators/devisable/templates/cucumber/user.feature +45 -0
  38. data/lib/generators/devisable/templates/partials/_ability_class.rb +53 -0
  39. data/lib/generators/devisable/templates/partials/_access_denied_flash.rb +4 -0
  40. data/lib/generators/devisable/templates/partials/_accessible_permissions_controller.rb +8 -0
  41. data/lib/generators/devisable/templates/partials/_accessible_permissions_model.rb +43 -0
  42. data/lib/generators/devisable/templates/partials/_application_controller_methods.erb +3 -0
  43. data/lib/generators/devisable/templates/partials/_application_controller_methods2.erb +11 -0
  44. data/lib/generators/devisable/templates/partials/_application_current_tab.rb +8 -0
  45. data/lib/generators/devisable/templates/partials/_application_flash.html.erb +4 -0
  46. data/lib/generators/devisable/templates/partials/_environments_development.erb +10 -0
  47. data/lib/generators/devisable/templates/partials/_login_links.erb +18 -0
  48. data/lib/generators/devisable/templates/partials/_migration_down.rb +2 -0
  49. data/lib/generators/devisable/templates/partials/_migration_up.rb +7 -0
  50. data/lib/generators/devisable/templates/partials/_oauth_user_table_fields.erb +1 -0
  51. data/lib/generators/devisable/templates/partials/_permission_equals.rb +8 -0
  52. data/lib/generators/devisable/templates/partials/_permission_manage.js +18 -0
  53. data/lib/generators/devisable/templates/partials/_role_permission.rb +72 -0
  54. data/lib/generators/devisable/templates/partials/_roles_index_delete.erb +7 -0
  55. data/lib/generators/devisable/templates/partials/_user_model_methods.erb +21 -0
  56. data/lib/generators/devisable/templates/partials/_user_role.rb +7 -0
  57. data/lib/generators/devisable/templates/spec/helpers/roles_helper_spec.erb +50 -0
  58. data/lib/generators/devisable/templates/spec/models/ability_spec.erb +69 -0
  59. data/lib/generators/devisable/templates/spec/models/permission_spec.erb +22 -0
  60. data/lib/generators/devisable/templates/spec/models/role_spec.erb +45 -0
  61. data/lib/generators/devisable/templates/spec/models/user_spec.erb +65 -0
  62. data/pkg/devisable-0.1.0.gem +0 -0
  63. data/pkg/devise_generator-0.1.0.gem +0 -0
  64. data/test/helper.rb +18 -0
  65. data/test/test_devise_generator.rb +7 -0
  66. metadata +169 -0
@@ -0,0 +1,19 @@
1
+ class RegistrationsController < Devise::RegistrationsController
2
+ self.view_paths = ['app/views/devise','app/views']
3
+
4
+ # Overiding the create controller because we are assigning the General User role to every user
5
+ # POST /resource/sign_up
6
+ def create
7
+ build_resource
8
+
9
+ if resource.save
10
+ resource.roles << Role.find_by_name('GeneralUser') unless User.count() == 1
11
+ resource.save
12
+ set_flash_message :notice, :signed_up
13
+ sign_in_and_redirect(resource_name, resource)
14
+ else
15
+ clean_up_passwords(resource)
16
+ render_with_scope :new
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,152 @@
1
+ class UsersController < ApplicationController
2
+ before_filter :get_user, :only => [:index,:new,:edit]
3
+ before_filter :accessible_roles, :only => [:new, :edit, :show, :update, :create]
4
+ #load and authorize resource is cancan's way of filtering controllers.
5
+ load_and_authorize_resource
6
+
7
+ # GET /users
8
+ # GET /users.xml
9
+ # GET /users.json HTML and AJAX
10
+ #-----------------------------------------------------------------------
11
+ def index
12
+ @super_admins = User.superadmins
13
+ @super_admin_role = Role.find_by_name('SuperAdmin');
14
+ @users = User.accessible_by(current_ability, :index).limit(20)
15
+ respond_to do |format|
16
+ format.json { render :json => @users }
17
+ format.xml { render :xml => @users }
18
+ format.html
19
+ end
20
+ end
21
+
22
+ # GET /users/new
23
+ # GET /users/new.xml
24
+ # GET /users/new.json HTML AND AJAX
25
+ #-------------------------------------------------------------------
26
+ def new
27
+ respond_to do |format|
28
+ format.json { render :json => @user }
29
+ format.xml { render :xml => @user }
30
+ format.html
31
+ end
32
+ end
33
+
34
+ # GET /users/1
35
+ # GET /users/1.xml
36
+ # GET /users/1.json HTML AND AJAX
37
+ #-------------------------------------------------------------------
38
+ def show
39
+ respond_to do |format|
40
+ format.json { render :json => @user }
41
+ format.xml { render :xml => @user }
42
+ format.html
43
+ end
44
+
45
+ rescue ActiveRecord::RecordNotFound
46
+ respond_to_not_found(:json, :xml, :html)
47
+ end
48
+
49
+ # GET /users/1/edit
50
+ # GET /users/1/edit.xml
51
+ # GET /users/1/edit.json HTML AND AJAX
52
+ #-------------------------------------------------------------------
53
+ def edit
54
+ respond_to do |format|
55
+ format.json { render :json => @user }
56
+ format.xml { render :xml => @user }
57
+ format.html
58
+ end
59
+
60
+ rescue ActiveRecord::RecordNotFound
61
+ respond_to_not_found(:json, :xml, :html)
62
+ end
63
+
64
+ # DELETE /users/1
65
+ # DELETE /users/1.xml
66
+ # DELETE /users/1.json HTML AND AJAX
67
+ #-------------------------------------------------------------------
68
+ def destroy
69
+ @user.destroy
70
+
71
+ respond_to do |format|
72
+ format.json { render :json => "Ok" }
73
+ format.xml { head :ok }
74
+ format.html { redirect_to( users_path, :notice => "The account has been deleted." ) }
75
+ end
76
+
77
+ rescue ActiveRecord::RecordNotFound
78
+ respond_to_not_found(:json, :xml, :html)
79
+ end
80
+
81
+ # POST /users
82
+ # POST /users.xml
83
+ # POST /users.json HTML AND AJAX
84
+ #-----------------------------------------------------------------
85
+ def create
86
+ @user = User.new(params[:user])
87
+
88
+ if @user.save
89
+ respond_to do |format|
90
+ format.json { render :json => @user.to_json, :status => 200 }
91
+ format.xml { head :ok }
92
+ format.html { redirect_to :action => :index }
93
+ end
94
+ else
95
+ respond_to do |format|
96
+ format.json { render :text => "Could not create user", :status => :unprocessable_entity } # placeholder
97
+ format.xml { head :ok }
98
+ format.html { render :action => :new, :status => :unprocessable_entity }
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ # Get roles accessible by the current user
105
+ #----------------------------------------------------
106
+ def accessible_roles
107
+ @accessible_roles = Role.accessible_by(current_ability,:read)
108
+ end
109
+
110
+ # Make the current user object available to views
111
+ #----------------------------------------
112
+ def get_user
113
+ @current_user = current_user
114
+ end
115
+
116
+ # PUT /users/1
117
+ # PUT /users/1.xml
118
+ # PUT /users/1.json HTML AND AJAX
119
+ #----------------------------------------------------------------------------
120
+ def update
121
+ if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
122
+ [:password,:password_confirmation,:current_password].collect{|p| params[:user].delete(p) }
123
+ else
124
+ @user.errors[:base] << "Your passwords don't match" unless params[:user][:password] == params[:user][:password_confirmation]
125
+ #the following can be used if you have an update profile page.
126
+ #@user.errors[:base] << "The password you entered is incorrect" unless @user.valid_password?(params[:user][:current_password])
127
+ end
128
+
129
+ respond_to do |format|
130
+ if @user.errors[:base].empty? and @user.update_attributes(params[:user])
131
+ @user.roles = []
132
+ params[:user]['role_ids'].each do |role_id|
133
+ if role_id != ''
134
+ @user.roles << Role.find_by_id(role_id)
135
+ end
136
+ end
137
+ @user.save
138
+ flash[:notice] = "The account has been updated"
139
+ format.json { render :json => @user.to_json, :status => 200 }
140
+ format.xml { head :ok }
141
+ format.html { render :action => :show }
142
+ else
143
+ format.json { render :text => "Could not update user", :status => :unprocessable_entity } #placeholder
144
+ format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
145
+ format.html { render :action => :edit, :status => :unprocessable_entity }
146
+ end
147
+ end
148
+
149
+ rescue ActiveRecord::RecordNotFound
150
+ respond_to_not_found(:js, :xml, :html)
151
+ end
152
+ end
@@ -0,0 +1,11 @@
1
+ class WelcomeController < ApplicationController
2
+ before_filter :authenticate_user!, :except => [:index]
3
+
4
+ # GET /
5
+ # GET /welcome.html
6
+ # GET /welcome.xml
7
+ # GET /welcome.json HTML and AJAX
8
+ #-----------------------------------------------------------------------
9
+ def index
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ module RolesHelper
2
+ def habtm_checkboxes(obj, column, assignment_objects, assignment_object_display_column)
3
+ obj_to_s = obj.class.to_s.split("::").last.underscore
4
+ field_name = "#{obj_to_s}[#{column}][]"
5
+
6
+ html = hidden_field_tag(field_name, "")
7
+ assignment_objects.each do |assignment_obj|
8
+ cbx_id = "#{obj_to_s}_#{column}_#{assignment_obj.id}"
9
+ html += check_box_tag field_name, assignment_obj.id, obj.send(column).include?(assignment_obj.id), :id => cbx_id
10
+ html += label_tag cbx_id, h(assignment_obj.send(assignment_object_display_column))
11
+ html += content_tag(:br)
12
+ end
13
+ html
14
+ end
15
+
16
+
17
+ def permissions_checkboxes(obj, column, controllers, role_id)
18
+ perms = obj.permissions
19
+ html = ""
20
+ abilities = ['manage','read','create','update','destroy']
21
+ html += content_tag(:table) do
22
+ html_table = ""
23
+ controllers.each do |controller|
24
+ controller.strip!
25
+ html_table += content_tag(:tr) do
26
+ html_tr = ""
27
+ html_tr += content_tag(:th, controller)
28
+ html_tr += content_tag(:th, "Use")
29
+ html_tr += content_tag(:th, "View")
30
+ html_tr += content_tag(:th, "Add")
31
+ html_tr += content_tag(:th, "Edit")
32
+ html_tr += content_tag(:th, "Delete")
33
+ end
34
+ html_table += content_tag(:tr) do
35
+ html_tr = ""
36
+ html_tr += content_tag(:td," ")
37
+ abilities.each do |ability|
38
+ # p = Permission.new
39
+ #
40
+ # p.role_id = role_id
41
+ # p.controller = controller
42
+ # p.ability = ability
43
+ p = {
44
+ :role_id => role_id,
45
+ :controller => controller.singularize,
46
+ :ability => ability
47
+ }
48
+
49
+ perm = Permission.new(p)
50
+ checked = perms.include?(perm)
51
+ #checked = false
52
+ html_tr += content_tag(:td) do
53
+ check_box_tag 'role_ids[]',p.to_json,checked, {:id => "permission_#{controller}_#{ability}", :class => "permission_#{ability}"}
54
+ end
55
+ end
56
+ html_tr
57
+ end
58
+ end
59
+ html_table
60
+ end
61
+ html.html_safe
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ # Stores all Cancan permissions
2
+ class Permission < ActiveRecord::Base
3
+ belongs_to :role
4
+
5
+ # Equality check based on the role id, controller, and ability
6
+ #
7
+ # @param another_permission The permission to compare against
8
+ # @return [Boolean] True if the permissions match role id, controller and ability
9
+ def ==(another_permission)
10
+ self.role_id == another_permission.role_id && self.controller == another_permission.controller && self.ability == another_permission.ability ? true : false
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ # Stores groups of permissions and their relationships to users
2
+ class Role < ActiveRecord::Base
3
+ has_and_belongs_to_many :users
4
+ has_many :permissions
5
+ end
@@ -0,0 +1,29 @@
1
+ <%= form_for(@role) do |f| %>
2
+ <% if @role.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@role.errors.count, "error") %> prohibited this role from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @role.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+
19
+ <% if can? :read, Permission %>
20
+ <p><%= f.label :permission %></p>
21
+ <ul class="no-pad no-bullets">
22
+ <%= permissions_checkboxes(@role, :permission_ids, @accessible_permissions, @role.id) %>
23
+ </ul>
24
+ <% end %>
25
+
26
+ <div class="actions">
27
+ <%= f.submit %>
28
+ </div>
29
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing role</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @role %> |
6
+ <%= link_to 'Back', roles_path %>
@@ -0,0 +1,28 @@
1
+ <h1>Listing roles</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th></th>
7
+ <th></th>
8
+ <th></th>
9
+ </tr>
10
+
11
+ <% @roles.each do |role| %>
12
+ <tr>
13
+ <td><%= role.name %></td>
14
+ <td><%= link_to 'Show', role %></td>
15
+ <td><%= link_to_if(can?(:edit, Role), 'Edit', edit_role_path(role)) %></td>
16
+ <td>
17
+ <% if role.users.length > 0 %>
18
+ <span title="Roles with associated users cannot be deleted">Delete</span>
19
+ <% else %>
20
+ <%= link_to_if(can?(:delete, Role), 'Destroy', role, :confirm => 'Are you sure?', :method => :delete) %></td>
21
+ <% end %>
22
+ </tr>
23
+ <% end %>
24
+ </table>
25
+
26
+ <br />
27
+
28
+ <%= link_to 'New Role', new_role_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New role</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', roles_path %>
@@ -0,0 +1,10 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Name:</b>
5
+ <%= @role.name %>
6
+ </p>
7
+
8
+
9
+ <%= link_to_if(can?(:edit, Role), 'Edit', edit_role_path(@role)) %> |
10
+ <%= link_to 'Back', roles_path %>
@@ -0,0 +1,7 @@
1
+ <ul id="navigation">
2
+ <%% if can?(:view, Role) || can?(:view, User) %>
3
+ <li><%%= link_to_if(can?(:view, User), 'Users', users_path, :class => ( "on" if current_tab?('users') )) %></li>
4
+ <li><%%= link_to_if(can?(:view, Role), 'Roles', roles_path, :class => ( "on" if current_tab?('roles') )) %></li>
5
+ <%% end %>
6
+ </ul>
7
+ <div class="clear">&nbsp;</div>
@@ -0,0 +1,23 @@
1
+ <%%= form_for(@user) do |f| %>
2
+
3
+ <!-- extra fields go here -->
4
+
5
+ <p><%%= f.label :email %></p>
6
+ <p><%%= f.text_field :email %></p>
7
+
8
+ <%% if can? :read, Role %>
9
+ <p><%%= f.label :role %></p>
10
+ <ul class="no-pad no-bullets">
11
+ <%%= habtm_checkboxes(@user, :role_ids, @accessible_roles, :name) %>
12
+ </ul>
13
+ <%% end %>
14
+
15
+ <% if @show_password %>
16
+ <p><%%= f.label :password %> <i>(leave blank if you don't want to change it)</i></p>
17
+ <p><%%= f.password_field :password %></p>
18
+
19
+ <p><%%= f.label :password_confirmation %></p>
20
+ <p><%%= f.password_field :password_confirmation %></p>
21
+ <% end %>
22
+ <p><%%= f.submit "Submit" %></p>
23
+ <%% end %>
@@ -0,0 +1,6 @@
1
+ <h3><%%= @user == @current_user ? "Your Account Settings" : "Edit User" %></h3>
2
+
3
+ <%%= render 'form' %>
4
+
5
+ <%%= link_to 'Show', @user %> |
6
+ <%%= link_to 'Back', user_path %>
@@ -0,0 +1,27 @@
1
+ <h1>Listing Users</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Email</th>
6
+ <th>Roles</th>
7
+ <th></th>
8
+ <th></th>
9
+ </tr>
10
+
11
+ <!-- table header stuff here -->
12
+ <%% @users.each do |u| %>
13
+ <tr>
14
+ <td><%%= "#{u.email}" %></td>
15
+ <td><%%= "#{u.roles.collect{|r| r.name}}" %></td>
16
+ <td><%%= link_to 'Show', user_path(u.id) %></td>
17
+ <td><%%= link_to_if(can?(:edit, User), 'Edit', edit_user_path(u.id)) {} %></td>
18
+ <%% if !(@super_admins.count == 1 && u.roles.include?(@super_admin_role)) %>
19
+ <td><%%= link_to_if(can?(:delete, u), 'Delete', u, :confirm => "Are you sure?", :method => :delete) {} %></td>
20
+ <%% else %>
21
+ <td><span title="Can NOT delete the last SuperAdmin user">Delete</span></td>
22
+ <%% end %>
23
+ </tr>
24
+ <%% end %>
25
+ </table>
26
+
27
+ <br />
@@ -0,0 +1,5 @@
1
+ <h1>New User</h1>
2
+
3
+ <%%= render 'form' %>
4
+
5
+ <%%= link_to 'Back', user_index_path %>
@@ -0,0 +1,55 @@
1
+ <h3><%%= @user.email %></h3>
2
+
3
+ <%%= link_to_if(can?(:update,@user), "Edit", edit_user_path(@user)) %> |
4
+ <%%= link_to_if(can?(:delete, @user), "Delete", user_path(@user), :confirm => "Are you sure?", :method => :delete) {} %>
5
+
6
+ <table class="one-column-emphasis">
7
+ <tbody>
8
+ <tr>
9
+ <td class="oce-first">Email:</td>
10
+ <td><%%= @user.email %></td>
11
+ </tr>
12
+ <tr>
13
+ <td class="oce-first">Username:</td>
14
+ <td><%%= @user.username %></td>
15
+ </tr>
16
+ <tr>
17
+ <td class="oce-first">Role:</td>
18
+ <td><%%= @user.roles.first.name %></td>
19
+ </tr>
20
+ <%% if can?(:see_timestamps,User) %>
21
+ <tr>
22
+ <td class="oce-first">Created at:</td>
23
+ <td><%%= @user.created_at %></td>
24
+ </tr>
25
+ <tr>
26
+ <td class="oce-first">Last Sign In:</td>
27
+ <td><%%= @user.last_sign_in_at %></td>
28
+ </tr>
29
+ <tr>
30
+ <td class="oce-first">Sign In Count:</td>
31
+ <td><%%= @user.sign_in_count %></td>
32
+ </tr>
33
+ <%% end %>
34
+ <%% if @user.respond_to?(:oauth_profiles) %>
35
+ <%% @user.oauth_profiles.each do |profile| %>
36
+ <tr>
37
+ <td class="oce-first"><%%= profile.provider %> username:</td>
38
+ <td><%%= profile.username %></td>
39
+ </tr>
40
+ <tr>
41
+ <td class="oce-first"><%%= profile.provider %> email:</td>
42
+ <td><%%= profile.email %></td>
43
+ </tr>
44
+ <tr>
45
+ <td class="oce-first"><%%= profile.provider %> name:</td>
46
+ <td><%%= profile.name %></td>
47
+ </tr>
48
+ <tr>
49
+ <td class="oce-first"><%%= profile.provider %> image:</td>
50
+ <td><img src='<%%= profile.img_url %>' /></td>
51
+ </tr>
52
+ <%% end %>
53
+ <%% end %>
54
+ </tbody>
55
+ </table>