diff --git a/app/controllers/admin/environment_users_controller.rb b/app/controllers/admin/environment_users_controller.rb new file mode 100644 index 0000000..1302cf1 --- /dev/null +++ b/app/controllers/admin/environment_users_controller.rb @@ -0,0 +1,44 @@ +class EnvironmentUsersController < AdminController + + protect 'manage_environment_users', :environment + + def per_page + 10 + end + + def index + @q = params[:q] + if @q.blank? + @collection = environment.people.no_templates(environment).paginate( + :per_page => per_page, + :page => params[:npage] + ) + else + @collection = find_by_contents(:people, environment.people.no_templates(environment), @q, {:per_page => per_page, :page => params[:npage]})[:results] + end + end + + def set_admin_role + @person = environment.people.find(params[:id]) + environment.add_admin(@person) + redirect_to :action => :index, :q => params[:q] + end + + def reset_admin_role + @person = environment.people.find(params[:id]) + environment.remove_admin(@person) + redirect_to :action => :index, :q => params[:q] + end + + def activate + @person = environment.people.find(params[:id]) + @person.user.activate + redirect_to :action => :index, :q => params[:q] + end + + def deactivate + @person = environment.people.find(params[:id]) + @person.user.deactivate + redirect_to :action => :index, :q => params[:q] + end +end diff --git a/app/models/profile.rb b/app/models/profile.rb index 525df3d..faf790a 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -79,6 +79,7 @@ class Profile < ActiveRecord::Base named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } named_scope :templates, lambda { |environment| { :conditions => {:is_template => true, :environment_id => environment.id} } } + named_scope :no_templates, lambda { |environment| { :conditions => {:is_template => false, :environment_id => environment.id} } } def members scopes = plugins.dispatch_scopes(:organization_members, self) diff --git a/app/models/user.rb b/app/models/user.rb index fd5d7aa..6eb55cd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -143,6 +143,21 @@ class User < ActiveRecord::Base end end + # Deactivates the user in the database. + def deactivate + return false unless self.person + self.activated_at = nil + self.person.visible = false + begin + self.person.save! && self.save! + rescue Exception => exception + logger.error(exception.to_s) + false + else + true + end + end + def activated? self.activation_code.nil? && !self.activated_at.nil? end diff --git a/app/views/environment_users/_environment_users_search_form.rhtml b/app/views/environment_users/_environment_users_search_form.rhtml new file mode 100644 index 0000000..79747a0 --- /dev/null +++ b/app/views/environment_users/_environment_users_search_form.rhtml @@ -0,0 +1,8 @@ +<% form_tag( { :controller => 'environment_users', :action => 'index' }, :method => 'get', :class => 'environment-users-search' ) do %> +
+ + <%= text_field_tag 'q', @q, :title => _("Find users") %> + + <%= submit_button(:search, _('Search')) %> +
+<% end %> diff --git a/app/views/environment_users/_index_buttons.rhtml b/app/views/environment_users/_index_buttons.rhtml new file mode 100644 index 0000000..fe3d97e --- /dev/null +++ b/app/views/environment_users/_index_buttons.rhtml @@ -0,0 +1,3 @@ +<% button_bar do %> + <%= button :back, _('Back'), :controller => 'users' %> +<% end %> diff --git a/app/views/environment_users/_users_list.rhtml b/app/views/environment_users/_users_list.rhtml new file mode 100644 index 0000000..f31f553 --- /dev/null +++ b/app/views/environment_users/_users_list.rhtml @@ -0,0 +1,30 @@ +<% title = _('All Users') %> + +

<%= title %>

+ + + + + + <% @collection.each do |p| %> + + + + + <% end %> +
<%= _('Member') %><%= _('Actions') %>
<%= link_to_profile p.short_name, p.identifier, :title => p.name %> +
+ <% if p.is_admin? %> + <%= button_without_text :'reset-admin-role', _('Reset admin role'), :action => 'reset_admin_role', :id => p, :q => @q %> + <% else %> + <%= button_without_text :'set-admin-role', _('Set admin role'), :action => 'set_admin_role', :id => p, :q => @q %> + <% end %> + <% if !p.user.activated? %> + <%= button_without_text :'activate-user', _('Activate user'), :action => 'activate', :id => p, :q => @q %> + <% else %> + <%= button_without_text :'deactivate-user', _('Deactivate user'), :action => 'deactivate', :id => p, :q => @q %> + <% end %> +
+
+ +<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %> \ No newline at end of file diff --git a/app/views/environment_users/index.rhtml b/app/views/environment_users/index.rhtml new file mode 100644 index 0000000..b6d15f1 --- /dev/null +++ b/app/views/environment_users/index.rhtml @@ -0,0 +1,12 @@ +

<%= _('Edit Users')%>

+ +<%= render :partial => 'index_buttons' %> + +
+ <%= render :partial => 'environment_users_search_form' %> +
+
+ <%= render :partial => 'users_list' %> +
+ +<%= render :partial => 'index_buttons' %> diff --git a/app/views/users/index.rhtml b/app/views/users/index.rhtml index f40f241..f41c280 100644 --- a/app/views/users/index.rhtml +++ b/app/views/users/index.rhtml @@ -9,6 +9,9 @@
  • <%= link_to _('Send e-mail to users'), :action => 'send_mail' %>
  • +
  • + <%= link_to _('Edit users'), :controller => 'environment_users' %> +
  • <% button_bar do %> diff --git a/public/designs/icons/tango/style.css b/public/designs/icons/tango/style.css index 1881f0c..ab08744 100644 --- a/public/designs/icons/tango/style.css +++ b/public/designs/icons/tango/style.css @@ -101,6 +101,11 @@ .icon-user-unknown { background-image: url(Tango/16x16/status/dialog-error.png) } .icon-alert { background-image: url(Tango/16x16/status/dialog-warning.png) } +.icon-activate-user { background-image: url(Tango/16x16/emblems/emblem-system.png) } +.icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) } +.icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) } +.icon-reset-admin-role { background-image: url(/images/icons-app/person-icon.png) } + /******************LARGE ICONS********************/ .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) } diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 07d075b..f29b69f 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -4137,6 +4137,20 @@ h1#agenda-title { -webkit-border-radius:10px; } +/* ==> public/stylesheets/controller_environment_users.css <== */ +.controller-environment_users table { + text-align: left; +} + +#environment-users-search form { + padding: 10px; + margin-bottom: 15px; + background-color: #E6E6E6; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + + /* * * Profile search * * * * * * * */ #public-profile-search, #profile-search-results form, .profile-search-block form { diff --git a/test/functional/environment_users_controller_test.rb b/test/functional/environment_users_controller_test.rb new file mode 100644 index 0000000..0bb6c36 --- /dev/null +++ b/test/functional/environment_users_controller_test.rb @@ -0,0 +1,103 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'environment_users_controller' + +# Re-raise errors caught by the controller. +class EnvironmentUsersController; def rescue_action(e) raise e end; end + +class EnvironmentUsersControllerTest < ActionController::TestCase + + # all_fixtures + def setup + @controller = EnvironmentUsersController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + admin_user = create_user_with_permission('adminuser', 'manage_environment_users', Environment.default) + login_as('adminuser') + end + + should 'not access without right permission' do + guest = create_user('guest') + login_as 'guest' + + get :index + assert_response 403 # forbidden + end + + should 'grant access with right permission' do + get :index + assert_response :success + end + + should 'blank search results include activated and deactivated users' do + deactivated = create_user('deactivated') + deactivated.activated_at = nil + deactivated.person.visible = false + deactivated.save! + get :index, :q => '' + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /adminuser/}} + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /deactivated/}} + end + + should 'blank search include all users' do + (1..5).each {|i| + u = create_user('user'+i.to_s) + } + get :index, :q => '' # blank search + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /adminuser/}} + (1..5).each {|i| + u = 'user'+i.to_s + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => u}} + } + end + + should 'search not include all users' do + (1..5).each {|i| + u = create_user('user'+i.to_s) + } + get :index, :q => 'er5' # search + assert_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => /user5/}} + (1..4).each {|i| + u = 'user'+i.to_s + assert_no_tag :tag => 'div', :attributes => { :id => /users-list/ }, :descendant => {:tag => 'a', :attributes => {:title => u}} + } + end + + should 'set admin role' do + u = create_user() + assert_equal false, u.person.is_admin? + post :set_admin_role, :id => u.person.id, :q => '' + u.reload + assert u.person.is_admin? + end + + should 'reset admin role' do + u = create_user() + e = Environment.default + e.add_admin(u.person) + u.reload + assert u.person.is_admin? + post :reset_admin_role, :id => u.person.id, :q => '' + u.reload + assert_equal false, u.person.is_admin? + end + + should 'activate user' do + u = create_user() + assert_equal false, u.activated? + post :activate, :id => u.person.id, :q => '' + u.reload + assert u.activated? + end + + should 'deactivate user' do + u = create_user() + u.activated_at = Time.now.utc + u.activation_code = nil + u.person.visible = true + assert u.activated? + post :deactivate, :id => u.person.id, :q => '' + u.reload + assert_equal false, u.activated? + end +end diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index 5da1312..139fa48 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -1379,6 +1379,18 @@ class ProfileTest < ActiveSupport::TestCase assert_not_includes Profile.templates(Environment.default), profile end + should 'return a list of profiles that are not templates' do + p1 = fast_create(Profile, :is_template => false) + p2 = fast_create(Profile, :is_template => false) + t1 = fast_create(Profile, :is_template => true) + t2 = fast_create(Profile, :is_template => true) + + assert_includes Profile.no_templates(Environment.default), p1 + assert_includes Profile.no_templates(Environment.default), p2 + assert_not_includes Profile.no_templates(Environment.default), t1 + assert_not_includes Profile.no_templates(Environment.default), t2 + end + should 'not crash on a profile update with a destroyed template' do template = fast_create(Profile, :is_template => true) profile = fast_create(Profile, :template_id => template.id) diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index d69fcc4..6b49ffe 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -518,6 +518,25 @@ class UserTest < ActiveSupport::TestCase end end + should 'deactivate an user' do + user = new_user + user.activated_at = Time.now.utc + user.person.visible = true + assert user.deactivate + assert_nil user.activated_at + assert !user.person.visible + end + + should 'return if the user is deactivated' do + user = new_user + user.activated_at = Time.now.utc + user.activation_code = nil + user.person.visible = true + assert user.activated? + user.deactivate + assert !user.activated? + end + should 'activate right after creation when confirmation is not required' do e = Environment.default e.enable('skip_new_user_email_confirmation') -- libgit2 0.21.2