diff --git a/app/controllers/admin/managers_controller.rb b/app/controllers/admin/managers_controller.rb
new file mode 100644
index 000000000..5023a1380
--- /dev/null
+++ b/app/controllers/admin/managers_controller.rb
@@ -0,0 +1,32 @@
+class Admin::ManagersController < Admin::BaseController
+ load_and_authorize_resource
+
+ def index
+ @managers = @managers.page(params[:page])
+ end
+
+ def search
+ @user = User.find_by(email: params[:email])
+
+ respond_to do |format|
+ if @user
+ @manager = Manager.find_or_initialize_by(user: @user)
+ format.js
+ else
+ format.js { render "user_not_found" }
+ end
+ end
+ end
+
+ def create
+ @manager.user_id = params[:user_id]
+ @manager.save
+
+ redirect_to admin_managers_path
+ end
+
+ def destroy
+ @manager.destroy
+ redirect_to admin_managers_path
+ end
+end
diff --git a/app/controllers/admin/moderators_controller.rb b/app/controllers/admin/moderators_controller.rb
index e15e9273f..2566c0c02 100644
--- a/app/controllers/admin/moderators_controller.rb
+++ b/app/controllers/admin/moderators_controller.rb
@@ -18,15 +18,15 @@ class Admin::ModeratorsController < Admin::BaseController
end
end
- def destroy
- @moderator.destroy
- redirect_to admin_moderators_path
- end
-
def create
@moderator.user_id = params[:user_id]
@moderator.save
redirect_to admin_moderators_path
end
+
+ def destroy
+ @moderator.destroy
+ redirect_to admin_moderators_path
+ end
end
diff --git a/app/controllers/management/sessions_controller.rb b/app/controllers/management/sessions_controller.rb
index d3a85402b..bca17bf4c 100644
--- a/app/controllers/management/sessions_controller.rb
+++ b/app/controllers/management/sessions_controller.rb
@@ -4,7 +4,7 @@ class Management::SessionsController < ActionController::Base
def create
destroy_session
- if admin? || manager?
+ if admin? || manager? || authenticated_manager?
redirect_to management_root_path
else
raise CanCan::AccessDenied
@@ -31,6 +31,12 @@ class Management::SessionsController < ActionController::Base
end
def manager?
+ if current_user.try(:manager?)
+ session[:manager] = {login: "manager_user_#{current_user.id}"}
+ end
+ end
+
+ def authenticated_manager?
if manager = ManagerAuthenticator.new(params).auth
session[:manager] = manager
end
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 587b4954b..6b77c130d 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -37,6 +37,7 @@ module Abilities
can [:search, :create, :index, :destroy], ::Moderator
can [:search, :create, :index, :summary], ::Valuator
+ can [:search, :create, :index, :destroy], ::Manager
can :manage, Annotation
diff --git a/app/models/manager.rb b/app/models/manager.rb
new file mode 100644
index 000000000..d9c1aff07
--- /dev/null
+++ b/app/models/manager.rb
@@ -0,0 +1,6 @@
+class Manager < ActiveRecord::Base
+ belongs_to :user, touch: true
+ delegate :name, :email, :name_and_email, to: :user
+
+ validates :user_id, presence: true, uniqueness: true
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 7da80b6fb..4839d3ced 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,7 @@ class User < ActiveRecord::Base
has_one :administrator
has_one :moderator
has_one :valuator
+ has_one :manager
has_one :organization
has_one :lock
has_many :flags
@@ -104,6 +105,10 @@ class User < ActiveRecord::Base
valuator.present?
end
+ def manager?
+ manager.present?
+ end
+
def organization?
organization.present?
end
diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb
index f435c5511..bf0382dbd 100644
--- a/app/views/admin/_menu.html.erb
+++ b/app/views/admin/_menu.html.erb
@@ -85,6 +85,13 @@
<% end %>
+
>
+ <%= link_to admin_managers_path do %>
+
+ <%= t('admin.menu.managers') %>
+ <% end %>
+
+
>
<%= link_to admin_activity_path do %>
diff --git a/app/views/admin/managers/_manager.html.erb b/app/views/admin/managers/_manager.html.erb
new file mode 100644
index 000000000..24dd1565c
--- /dev/null
+++ b/app/views/admin/managers/_manager.html.erb
@@ -0,0 +1,13 @@
+<%= manager.name %>
+ •
+<%= manager.email %>
+<% if manager.persisted? %>
+ <%= link_to t('admin.managers.manager.delete'),
+ admin_manager_path(manager),
+ method: :delete,
+ class: "button small alert float-right"
+ %>
+<% else %>
+ <%= link_to t('admin.managers.manager.add'),{ controller: "admin/managers", action: :create, user_id: manager.user_id },
+ method: :post, class: "button small success float-right" %>
+<% end %>
diff --git a/app/views/admin/managers/index.html.erb b/app/views/admin/managers/index.html.erb
new file mode 100644
index 000000000..3113907a4
--- /dev/null
+++ b/app/views/admin/managers/index.html.erb
@@ -0,0 +1,24 @@
+<%= t("admin.managers.index.title") %>
+
+
+ <%= form_tag search_admin_managers_path, method: :get, remote: true do %>
+
+ <%= text_field_tag :email, '', placeholder: t('admin.managers.search.email_placeholder') %>
+
+
+ <%= submit_tag t('admin.managers.search.search'), class: 'button' %>
+
+ <% end %>
+
+
+
+<%= page_entries_info @managers %>
+
+ <% @managers.each do |manager| %>
+ -
+ <%= render 'manager', manager: manager %>
+
+ <% end %>
+
+
+<%= paginate @managers %>
diff --git a/app/views/admin/managers/search.js.erb b/app/views/admin/managers/search.js.erb
new file mode 100644
index 000000000..0f0fd09cd
--- /dev/null
+++ b/app/views/admin/managers/search.js.erb
@@ -0,0 +1 @@
+$("#search-result").html("<%= j render 'manager', manager: @manager %>
");
diff --git a/app/views/admin/managers/user_not_found.js.erb b/app/views/admin/managers/user_not_found.js.erb
new file mode 100644
index 000000000..0116de21d
--- /dev/null
+++ b/app/views/admin/managers/user_not_found.js.erb
@@ -0,0 +1 @@
+$("#search-result").html("<%= j t('admin.managers.search.user_not_found') %>
");
diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb
index 3625432a8..6ba10bbca 100644
--- a/app/views/shared/_admin_login_items.html.erb
+++ b/app/views/shared/_admin_login_items.html.erb
@@ -17,7 +17,7 @@
<% end %>
- <% if current_user.administrator? %>
+ <% if current_user.administrator? || current_user.manager? %>
<%= link_to t("layouts.header.management"), management_sign_in_path %>
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 15b3870d8..282e72d27 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -47,6 +47,16 @@ en:
with_confirmed_hide: Confirmed
without_confirmed_hide: Pending
title: Hidden debates
+ managers:
+ index:
+ title: Managers
+ manager:
+ add: Add
+ delete: Delete
+ search:
+ email_placeholder: Search user by email
+ search: Search
+ user_not_found: User not found
menu:
activity: Moderator activity
debate_topics: Debate topics
@@ -55,6 +65,7 @@ en:
hidden_proposals: Hidden proposals
hidden_users: Hidden users
incomplete_verifications: Incomplete verifications
+ managers: Managers
moderators: Moderators
valuators: Valuators
officials: Officials
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 803073b2d..66b419d26 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -47,6 +47,16 @@ es:
with_confirmed_hide: Confirmados
without_confirmed_hide: Pendientes
title: Debates ocultos
+ managers:
+ index:
+ title: Gestores
+ manager:
+ add: Añadir como Gestor
+ delete: Borrar
+ search:
+ email_placeholder: Buscar usuario por email
+ search: Buscar
+ user_not_found: Usuario no encontrado
menu:
activity: Actividad de moderadores
debate_topics: Temas de debate
@@ -55,6 +65,7 @@ es:
hidden_proposals: Propuestas ocultas
hidden_users: Usuarios bloqueados
incomplete_verifications: Verificaciones incompletas
+ managers: Gestores
moderators: Moderadores
valuators: Evaluadores
officials: Cargos públicos
@@ -66,7 +77,7 @@ es:
index:
title: Moderadores
moderator:
- add: Añadir
+ add: Añadir como Moderador
delete: Borrar
search:
email_placeholder: Buscar usuario por email
diff --git a/config/routes.rb b/config/routes.rb
index 1c7af6800..a2035a0b7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -165,6 +165,10 @@ Rails.application.routes.draw do
get :summary, on: :collection
end
+ resources :managers, only: [:index, :create, :destroy] do
+ get :search, on: :collection
+ end
+
resources :verifications, controller: :verifications, only: :index do
get :search, on: :collection
end
diff --git a/db/migrate/20160510161858_create_manager_role.rb b/db/migrate/20160510161858_create_manager_role.rb
new file mode 100644
index 000000000..48ceb7e20
--- /dev/null
+++ b/db/migrate/20160510161858_create_manager_role.rb
@@ -0,0 +1,7 @@
+class CreateManagerRole < ActiveRecord::Migration
+ def change
+ create_table :managers do |t|
+ t.belongs_to :user, index: true, foreign_key: true
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b105a2b2c..78a3ffd45 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160426211658) do
+ActiveRecord::Schema.define(version: 20160510161858) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -214,6 +214,12 @@ ActiveRecord::Schema.define(version: 20160426211658) do
add_index "locks", ["user_id"], name: "index_locks_on_user_id", using: :btree
+ create_table "managers", force: :cascade do |t|
+ t.integer "user_id"
+ end
+
+ add_index "managers", ["user_id"], name: "index_managers_on_user_id", using: :btree
+
create_table "moderators", force: :cascade do |t|
t.integer "user_id"
end
@@ -510,6 +516,7 @@ ActiveRecord::Schema.define(version: 20160426211658) do
add_foreign_key "flags", "users"
add_foreign_key "identities", "users"
add_foreign_key "locks", "users"
+ add_foreign_key "managers", "users"
add_foreign_key "moderators", "users"
add_foreign_key "notifications", "users"
add_foreign_key "organizations", "users"
diff --git a/spec/controllers/management/sessions_controller_spec.rb b/spec/controllers/management/sessions_controller_spec.rb
index a07067ed9..d2d6b5f8b 100644
--- a/spec/controllers/management/sessions_controller_spec.rb
+++ b/spec/controllers/management/sessions_controller_spec.rb
@@ -6,31 +6,44 @@ describe Management::SessionsController do
it "should deny access if wrong manager credentials" do
allow_any_instance_of(ManagerAuthenticator).to receive(:auth).and_return(false)
expect { get :create, login: "nonexistent" , clave_usuario: "wrong"}.to raise_error CanCan::AccessDenied
+ expect(session[:manager]).to be_nil
end
- it "should redirect to management root path if right credentials" do
+ it "should redirect to management root path if authorized manager with right credentials" do
manager = {login: "JJB033", user_key: "31415926" , date: "20151031135905"}
allow_any_instance_of(ManagerAuthenticator).to receive(:auth).and_return(manager)
get :create, login: "JJB033" , clave_usuario: "31415926", fecha_conexion: "20151031135905"
expect(response).to be_redirect
+ expect(session[:manager][:login]).to eq "JJB033"
end
it "should redirect to management root path if user is admin" do
- sign_in create(:administrator).user
+ user = create(:administrator).user
+ sign_in user
get :create
expect(response).to be_redirect
+ expect(session[:manager][:login]).to eq "admin_user_#{user.id}"
end
- it "should deny access if user is not admin" do
+ it "should redirect to management root path if user is manager" do
+ user = create(:manager).user
+ sign_in user
+ get :create
+ expect(response).to be_redirect
+ expect(session[:manager][:login]).to eq "manager_user_#{user.id}"
+ end
+
+ it "should deny access if user is not admin or manager" do
sign_in create(:user)
expect { get :create}.to raise_error CanCan::AccessDenied
+ expect(session[:manager]).to be_nil
end
end
describe 'Sign out' do
it "should destroy the session data and redirect" do
- session[:manager] = {user_key: "31415926" , date: "20151031135905", login: "JJB033"}
+ session[:manager] = {user_key: "31415926", date: "20151031135905", login: "JJB033"}
session[:document_type] = "1"
session[:document_number] = "12345678Z"
diff --git a/spec/factories.rb b/spec/factories.rb
index 20a0b2b51..67c2e2c07 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -256,6 +256,10 @@ FactoryGirl.define do
user
end
+ factory :manager do
+ user
+ end
+
factory :organization do
user
responsible_name "Johnny Utah"
diff --git a/spec/features/admin/managers_spec.rb b/spec/features/admin/managers_spec.rb
new file mode 100644
index 000000000..100781446
--- /dev/null
+++ b/spec/features/admin/managers_spec.rb
@@ -0,0 +1,37 @@
+require 'rails_helper'
+
+feature 'Admin managers' do
+ background do
+ @admin = create(:administrator)
+ @user = create(:user)
+ @manager = create(:manager)
+ login_as(@admin.user)
+ visit admin_managers_path
+ end
+
+ scenario 'Index' do
+ expect(page).to have_content @manager.name
+ expect(page).to have_content @manager.email
+ expect(page).to_not have_content @user.name
+ end
+
+ scenario 'Create Manager', :js do
+ fill_in 'email', with: @user.email
+ click_button 'Search'
+
+ expect(page).to have_content @user.name
+ click_link 'Add'
+ within("#managers") do
+ expect(page).to have_content @user.name
+ end
+ end
+
+ scenario 'Delete Manager' do
+ click_link 'Delete'
+
+ within("#managers") do
+ expect(page).to_not have_content @manager.name
+ end
+ end
+end
+
diff --git a/spec/features/admin_spec.rb b/spec/features/admin_spec.rb
index 87c60355b..9ef1b334e 100644
--- a/spec/features/admin_spec.rb
+++ b/spec/features/admin_spec.rb
@@ -36,6 +36,16 @@ feature 'Admin' do
expect(page).to have_content "You do not have permission to access this page"
end
+ scenario 'Access as a manager is not authorized' do
+ create(:manager, user: user)
+ login_as(user)
+ visit admin_root_path
+
+ expect(current_path).not_to eq(admin_root_path)
+ expect(current_path).to eq(proposals_path)
+ expect(page).to have_content "You do not have permission to access this page"
+ end
+
scenario 'Access as an administrator is authorized' do
login_as(administrator)
visit admin_root_path
@@ -51,6 +61,7 @@ feature 'Admin' do
expect(page).to have_link('Administration')
expect(page).to have_link('Moderation')
expect(page).to have_link('Valuation')
+ expect(page).to have_link('Management')
end
scenario 'Admin dashboard' do
@@ -65,47 +76,4 @@ feature 'Admin' do
expect(page).to_not have_css('#valuation_menu')
end
- context 'Tags' do
- let(:unfeatured_tag) { create :tag, :unfeatured, name: 'Mi barrio' }
-
- background do
- login_as(administrator)
- end
-
- scenario 'adding a new tag' do
- visit admin_tags_path
-
- fill_in 'tag_name', with: 'Papeleras'
-
- click_on 'Create Topic'
-
- expect(page).to have_content 'Papeleras'
- end
-
- scenario 'deleting tag' do
- unfeatured_tag
-
- visit admin_tags_path
-
- expect(page).to have_content 'Mi barrio'
-
- click_link 'Destroy Topic'
-
- expect(page).not_to have_content 'Mi barrio'
- end
-
- scenario 'marking tags as featured / unfeatured' do
- expect(unfeatured_tag).not_to be_featured
-
- visit admin_tags_path
-
- expect(page).to have_content 'Mi barrio'
-
- check "tag_featured_#{unfeatured_tag.id}"
- click_button 'Update Topic'
-
- expect(page).to have_checked_field("tag_featured_#{unfeatured_tag.id}")
- end
- end
-
end
diff --git a/spec/features/management/account_spec.rb b/spec/features/management/account_spec.rb
index 3b9951d41..04a2e7213 100644
--- a/spec/features/management/account_spec.rb
+++ b/spec/features/management/account_spec.rb
@@ -26,7 +26,7 @@ feature 'Account' do
expect(page).to have_content "User account deleted."
- expect(user.reload.erase_reason).to eq "Deleted by manager: JJB042"
+ expect(user.reload.erase_reason).to eq "Deleted by manager: manager_user_#{Manager.last.user_id}"
end
end
\ No newline at end of file
diff --git a/spec/features/management/users_spec.rb b/spec/features/management/users_spec.rb
index 021edaaad..1a0618e60 100644
--- a/spec/features/management/users_spec.rb
+++ b/spec/features/management/users_spec.rb
@@ -59,7 +59,7 @@ feature 'Users' do
expect(page).to have_content "User account deleted."
- expect(level_2_user.reload.erase_reason).to eq "Deleted by manager: JJB042"
+ expect(level_2_user.reload.erase_reason).to eq "Deleted by manager: manager_user_#{Manager.last.user_id}"
visit management_document_verifications_path
fill_in 'document_verification_document_number', with: '13579'
diff --git a/spec/features/moderation_spec.rb b/spec/features/moderation_spec.rb
index 12eb07358..6607ec48a 100644
--- a/spec/features/moderation_spec.rb
+++ b/spec/features/moderation_spec.rb
@@ -29,6 +29,20 @@ feature 'Moderation' do
expect(page).to have_content "You do not have permission to access this page"
end
+ scenario 'Access as manager is not authorized' do
+ create(:manager, user: user)
+
+ login_as(user)
+ visit root_path
+
+ expect(page).to_not have_link("Moderation")
+ visit moderation_root_path
+
+ expect(current_path).not_to eq(moderation_root_path)
+ expect(current_path).to eq(proposals_path)
+ expect(page).to have_content "You do not have permission to access this page"
+ end
+
scenario 'Access as a moderator is authorized' do
create(:moderator, user: user)
diff --git a/spec/features/valuation_spec.rb b/spec/features/valuation_spec.rb
index 571a4323f..fab16027a 100644
--- a/spec/features/valuation_spec.rb
+++ b/spec/features/valuation_spec.rb
@@ -28,6 +28,19 @@ feature 'Valuation' do
expect(page).to have_content "You do not have permission to access this page"
end
+ scenario 'Access as manager is not authorized' do
+ create(:manager, user: user)
+ login_as(user)
+ visit root_path
+
+ expect(page).to_not have_link("Valuation")
+ visit valuation_root_path
+
+ expect(current_path).not_to eq(valuation_root_path)
+ expect(current_path).to eq(proposals_path)
+ expect(page).to have_content "You do not have permission to access this page"
+ end
+
scenario 'Access as a valuator is authorized' do
create(:valuator, user: user)
login_as(user)
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index b49e3cc6b..054e043f9 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -121,6 +121,18 @@ describe User do
end
end
+ describe "manager?" do
+ it "is false when the user is not a manager" do
+ expect(subject.manager?).to be false
+ end
+
+ it "is true when the user is a manager" do
+ subject.save
+ create(:manager, user: subject)
+ expect(subject.manager?).to be true
+ end
+ end
+
describe "organization?" do
it "is false when the user is not an organization" do
expect(subject.organization?).to be false
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index bba79441b..18a3f9499 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -24,12 +24,18 @@ module CommonActions
click_button 'Enter'
end
- def login_as_manager
+ def login_as_authenticated_manager
login, user_key, date = "JJB042", "31415926", Time.now.strftime("%Y%m%d%H%M%S")
allow_any_instance_of(ManagerAuthenticator).to receive(:auth).and_return({login: login, user_key: user_key, date: date}.with_indifferent_access)
visit management_sign_in_path(login: login, clave_usuario: user_key, fecha_conexion: date)
end
+ def login_as_manager
+ manager = create(:manager)
+ login_as(manager.user)
+ visit management_sign_in_path
+ end
+
def login_managed_user(user)
allow_any_instance_of(Management::BaseController).to receive(:managed_user).and_return(user)
end