devisable 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.
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>