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 %>
+
+
+ <%= _('Member') %> |
+ <%= _('Actions') %> |
+
+ <% @collection.each do |p| %>
+
+ <%= 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 %>
+
+ |
+
+ <% 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