Commit d09c5df540181267cc6d2a71a7bf8465f43b33f5

Authored by Eduardo Tourinho Edington
1 parent ce0d03ab

Allow admins to set and reset admin role on environment users.

Allow admins to activate and deactivate environment users.
app/controllers/admin/environment_users_controller.rb 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +class EnvironmentUsersController < AdminController
  2 +
  3 + protect 'manage_environment_users', :environment
  4 +
  5 + def per_page
  6 + 10
  7 + end
  8 +
  9 + def index
  10 + @q = params[:q]
  11 + if @q.blank?
  12 + @collection = environment.people.no_templates(environment).paginate(
  13 + :per_page => per_page,
  14 + :page => params[:npage]
  15 + )
  16 + else
  17 + @collection = find_by_contents(:people, environment.people.no_templates(environment), @q, {:per_page => per_page, :page => params[:npage]})[:results]
  18 + end
  19 + end
  20 +
  21 + def set_admin_role
  22 + @person = environment.people.find(params[:id])
  23 + environment.add_admin(@person)
  24 + redirect_to :action => :index, :q => params[:q]
  25 + end
  26 +
  27 + def reset_admin_role
  28 + @person = environment.people.find(params[:id])
  29 + environment.remove_admin(@person)
  30 + redirect_to :action => :index, :q => params[:q]
  31 + end
  32 +
  33 + def activate
  34 + @person = environment.people.find(params[:id])
  35 + @person.user.activate
  36 + redirect_to :action => :index, :q => params[:q]
  37 + end
  38 +
  39 + def deactivate
  40 + @person = environment.people.find(params[:id])
  41 + @person.user.deactivate
  42 + redirect_to :action => :index, :q => params[:q]
  43 + end
  44 +end
... ...
app/models/profile.rb
... ... @@ -79,6 +79,7 @@ class Profile &lt; ActiveRecord::Base
79 79 named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
80 80 named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
81 81 named_scope :templates, lambda { |environment| { :conditions => {:is_template => true, :environment_id => environment.id} } }
  82 + named_scope :no_templates, lambda { |environment| { :conditions => {:is_template => false, :environment_id => environment.id} } }
82 83  
83 84 def members
84 85 scopes = plugins.dispatch_scopes(:organization_members, self)
... ...
app/models/user.rb
... ... @@ -143,6 +143,21 @@ class User &lt; ActiveRecord::Base
143 143 end
144 144 end
145 145  
  146 + # Deactivates the user in the database.
  147 + def deactivate
  148 + return false unless self.person
  149 + self.activated_at = nil
  150 + self.person.visible = false
  151 + begin
  152 + self.person.save! && self.save!
  153 + rescue Exception => exception
  154 + logger.error(exception.to_s)
  155 + false
  156 + else
  157 + true
  158 + end
  159 + end
  160 +
146 161 def activated?
147 162 self.activation_code.nil? && !self.activated_at.nil?
148 163 end
... ...
app/views/environment_users/_environment_users_search_form.rhtml 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<% form_tag( { :controller => 'environment_users', :action => 'index' }, :method => 'get', :class => 'environment-users-search' ) do %>
  2 + <div class="search-field">
  3 + <span class="formfield">
  4 + <%= text_field_tag 'q', @q, :title => _("Find users") %>
  5 + </span>
  6 + <%= submit_button(:search, _('Search')) %>
  7 + </div>
  8 +<% end %>
... ...
app/views/environment_users/_index_buttons.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<% button_bar do %>
  2 + <%= button :back, _('Back'), :controller => 'users' %>
  3 +<% end %>
... ...
app/views/environment_users/_users_list.rhtml 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +<% title = _('All Users') %>
  2 +
  3 +<h3><%= title %></h3>
  4 +<table>
  5 + <tr>
  6 + <th><%= _('Member') %></th>
  7 + <th><%= _('Actions') %></th>
  8 + </tr>
  9 + <% @collection.each do |p| %>
  10 + <tr title="<%= p.name %>">
  11 + <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  12 + <td>
  13 + <div class="members-buttons-cell">
  14 + <% if p.is_admin? %>
  15 + <%= button_without_text :'reset-admin-role', _('Reset admin role'), :action => 'reset_admin_role', :id => p, :q => @q %>
  16 + <% else %>
  17 + <%= button_without_text :'set-admin-role', _('Set admin role'), :action => 'set_admin_role', :id => p, :q => @q %>
  18 + <% end %>
  19 + <% if !p.user.activated? %>
  20 + <%= button_without_text :'activate-user', _('Activate user'), :action => 'activate', :id => p, :q => @q %>
  21 + <% else %>
  22 + <%= button_without_text :'deactivate-user', _('Deactivate user'), :action => 'deactivate', :id => p, :q => @q %>
  23 + <% end %>
  24 + </div>
  25 + </td>
  26 + </tr>
  27 + <% end %>
  28 +</table>
  29 +
  30 +<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
0 31 \ No newline at end of file
... ...
app/views/environment_users/index.rhtml 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<h1><%= _('Edit Users')%></h1>
  2 +
  3 +<%= render :partial => 'index_buttons' %>
  4 +
  5 +<div id="search-users">
  6 + <%= render :partial => 'environment_users_search_form' %>
  7 +</div>
  8 +<div id="users-list">
  9 + <%= render :partial => 'users_list' %>
  10 +</div>
  11 +
  12 +<%= render :partial => 'index_buttons' %>
... ...
app/views/users/index.rhtml
... ... @@ -9,6 +9,9 @@
9 9 <li>
10 10 <%= link_to _('Send e-mail to users'), :action => 'send_mail' %>
11 11 </li>
  12 + <li>
  13 + <%= link_to _('Edit users'), :controller => 'environment_users' %>
  14 + </li>
12 15 </ul>
13 16  
14 17 <% button_bar do %>
... ...
public/designs/icons/tango/style.css
... ... @@ -101,6 +101,11 @@
101 101 .icon-user-unknown { background-image: url(Tango/16x16/status/dialog-error.png) }
102 102 .icon-alert { background-image: url(Tango/16x16/status/dialog-warning.png) }
103 103  
  104 +.icon-activate-user { background-image: url(Tango/16x16/emblems/emblem-system.png) }
  105 +.icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) }
  106 +.icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
  107 +.icon-reset-admin-role { background-image: url(/images/icons-app/person-icon.png) }
  108 +
104 109 /******************LARGE ICONS********************/
105 110 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
106 111 .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) }
... ...
public/stylesheets/application.css
... ... @@ -4137,6 +4137,20 @@ h1#agenda-title {
4137 4137 -webkit-border-radius:10px;
4138 4138 }
4139 4139  
  4140 +/* ==> public/stylesheets/controller_environment_users.css <== */
  4141 +.controller-environment_users table {
  4142 + text-align: left;
  4143 +}
  4144 +
  4145 +#environment-users-search form {
  4146 + padding: 10px;
  4147 + margin-bottom: 15px;
  4148 + background-color: #E6E6E6;
  4149 + -moz-border-radius: 5px;
  4150 + -webkit-border-radius: 5px;
  4151 +}
  4152 +
  4153 +
4140 4154 /* * * Profile search * * * * * * * */
4141 4155  
4142 4156 #public-profile-search, #profile-search-results form, .profile-search-block form {
... ...
test/functional/environment_users_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,103 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +require 'environment_users_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class EnvironmentUsersController; def rescue_action(e) raise e end; end
  6 +
  7 +class EnvironmentUsersControllerTest < ActionController::TestCase
  8 +
  9 + # all_fixtures
  10 + def setup
  11 + @controller = EnvironmentUsersController.new
  12 + @request = ActionController::TestRequest.new
  13 + @response = ActionController::TestResponse.new
  14 +
  15 + admin_user = create_user_with_permission('adminuser', 'manage_environment_users', Environment.default)
  16 + login_as('adminuser')
  17 + end
  18 +
  19 + should 'not access without right permission' do
  20 + guest = create_user('guest')
  21 + login_as 'guest'
  22 +
  23 + get :index
  24 + assert_response 403 # forbidden
  25 + end
  26 +
  27 + should 'grant access with right permission' do
  28 + get :index
  29 + assert_response :success
  30 + end
  31 +
  32 + should 'blank search results include activated and deactivated users' do
  33 + deactivated = create_user('deactivated')
  34 + deactivated.activated_at = nil
  35 + deactivated.person.visible = false
  36 + deactivated.save!
  37 + get :index, :q => ''
  38 + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /adminuser/}}
  39 + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /deactivated/}}
  40 + end
  41 +
  42 + should 'blank search include all users' do
  43 + (1..5).each {|i|
  44 + u = create_user('user'+i.to_s)
  45 + }
  46 + get :index, :q => '' # blank search
  47 + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /adminuser/}}
  48 + (1..5).each {|i|
  49 + u = 'user'+i.to_s
  50 + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => u}}
  51 + }
  52 + end
  53 +
  54 + should 'search not include all users' do
  55 + (1..5).each {|i|
  56 + u = create_user('user'+i.to_s)
  57 + }
  58 + get :index, :q => 'er5' # search
  59 + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /user5/}}
  60 + (1..4).each {|i|
  61 + u = 'user'+i.to_s
  62 + assert_no_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => u}}
  63 + }
  64 + end
  65 +
  66 + should 'set admin role' do
  67 + u = create_user()
  68 + assert_equal false, u.person.is_admin?
  69 + post :set_admin_role, :id => u.person.id, :q => ''
  70 + u.reload
  71 + assert u.person.is_admin?
  72 + end
  73 +
  74 + should 'reset admin role' do
  75 + u = create_user()
  76 + e = Environment.default
  77 + e.add_admin(u.person)
  78 + u.reload
  79 + assert u.person.is_admin?
  80 + post :reset_admin_role, :id => u.person.id, :q => ''
  81 + u.reload
  82 + assert_equal false, u.person.is_admin?
  83 + end
  84 +
  85 + should 'activate user' do
  86 + u = create_user()
  87 + assert_equal false, u.activated?
  88 + post :activate, :id => u.person.id, :q => ''
  89 + u.reload
  90 + assert u.activated?
  91 + end
  92 +
  93 + should 'deactivate user' do
  94 + u = create_user()
  95 + u.activated_at = Time.now.utc
  96 + u.activation_code = nil
  97 + u.person.visible = true
  98 + assert u.activated?
  99 + post :deactivate, :id => u.person.id, :q => ''
  100 + u.reload
  101 + assert_equal false, u.activated?
  102 + end
  103 +end
... ...
test/unit/profile_test.rb
... ... @@ -1379,6 +1379,18 @@ class ProfileTest &lt; ActiveSupport::TestCase
1379 1379 assert_not_includes Profile.templates(Environment.default), profile
1380 1380 end
1381 1381  
  1382 + should 'return a list of profiles that are not templates' do
  1383 + p1 = fast_create(Profile, :is_template => false)
  1384 + p2 = fast_create(Profile, :is_template => false)
  1385 + t1 = fast_create(Profile, :is_template => true)
  1386 + t2 = fast_create(Profile, :is_template => true)
  1387 +
  1388 + assert_includes Profile.no_templates(Environment.default), p1
  1389 + assert_includes Profile.no_templates(Environment.default), p2
  1390 + assert_not_includes Profile.no_templates(Environment.default), t1
  1391 + assert_not_includes Profile.no_templates(Environment.default), t2
  1392 + end
  1393 +
1382 1394 should 'not crash on a profile update with a destroyed template' do
1383 1395 template = fast_create(Profile, :is_template => true)
1384 1396 profile = fast_create(Profile, :template_id => template.id)
... ...
test/unit/user_test.rb
... ... @@ -518,6 +518,25 @@ class UserTest &lt; ActiveSupport::TestCase
518 518 end
519 519 end
520 520  
  521 + should 'deactivate an user' do
  522 + user = new_user
  523 + user.activated_at = Time.now.utc
  524 + user.person.visible = true
  525 + assert user.deactivate
  526 + assert_nil user.activated_at
  527 + assert !user.person.visible
  528 + end
  529 +
  530 + should 'return if the user is deactivated' do
  531 + user = new_user
  532 + user.activated_at = Time.now.utc
  533 + user.activation_code = nil
  534 + user.person.visible = true
  535 + assert user.activated?
  536 + user.deactivate
  537 + assert !user.activated?
  538 + end
  539 +
521 540 should 'activate right after creation when confirmation is not required' do
522 541 e = Environment.default
523 542 e.enable('skip_new_user_email_confirmation')
... ...