<%# Do not allow a user to change their own permissions or a super admin's permissions if they are not a super admin %>
- <% unless current_user == user ||
- !current_user.can_super_admin? && user.can_super_admin? %>
- <% b_label = _('Edit') %>
- <%= link_to( b_label, admin_grant_permissions_user_path(user)) %>
+ <% unless current_user == user || !is_super_admin && user.can_super_admin? %>
+ <%= link_to( _('Edit'), admin_grant_permissions_user_path(user)) %>
<% end %>
<%= user.name(false) %><%= _(' current user privileges are: ') %>
<%= label_tag :organisational_admin_privileges %>
diff --git a/config/locales/devise/devise.de.yml b/config/locales/devise/devise.de.yml
index 72df6c7..d968088 100644
--- a/config/locales/devise/devise.de.yml
+++ b/config/locales/devise/devise.de.yml
@@ -10,7 +10,7 @@
send_paranoid_instructions: "Falls Ihre E-Mail-Adresse in unserer Datenbank existiert, erhalten Sie in wenigen Minuten eine E-Mail mit einer Anleitung zur Bestätigung Ihres Zugangs."
failure:
already_authenticated: "Sie sind bereits angemeldet."
- inactive: "Ihr Zugang ist noch nicht aktiviert worden."
+ inactive: "Ihr Konto ist nicht mehr aktiv. Bitte kontaktieren Sie uns, um Ihr Konto zu reaktivieren."
invalid: "E-Mail-Adresse oder Passwort ungültig."
invalid_token: "Ungültiges Authentifizierungs-Token."
locked: "Ihr Zugang ist gesperrt."
diff --git a/config/locales/devise/devise.en_GB.yml b/config/locales/devise/devise.en_GB.yml
index 3961e3b..f6e8719 100644
--- a/config/locales/devise/devise.en_GB.yml
+++ b/config/locales/devise/devise.en_GB.yml
@@ -8,7 +8,7 @@
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
failure:
already_authenticated: "You are already signed in."
- inactive: "Your account was not activated yet."
+ inactive: "Your account is no longer active. Please contact us to reactivate your account."
invalid: "Invalid email or password."
invalid_token: "Invalid authentication token."
invited: "You have a pending invitation, accept it to finish creating your account."
diff --git a/config/locales/devise/devise.en_US.yml b/config/locales/devise/devise.en_US.yml
index 826ae0f..db03c5d 100644
--- a/config/locales/devise/devise.en_US.yml
+++ b/config/locales/devise/devise.en_US.yml
@@ -8,7 +8,7 @@
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
failure:
already_authenticated: "You are already signed in."
- inactive: "Your account was not activated yet."
+ inactive: "Your account is no longer active. Please contact us to reactivate your account."
invalid: "Invalid email or password."
invalid_token: "Invalid authentication token."
invited: "You have a pending invitation, accept it to finish creating your account."
diff --git a/config/locales/devise/devise.es.yml b/config/locales/devise/devise.es.yml
index c664f5a..d1ac440 100644
--- a/config/locales/devise/devise.es.yml
+++ b/config/locales/devise/devise.es.yml
@@ -8,7 +8,7 @@
send_paranoid_instructions: "Si su correo electrónico existe en nuestra base de datos recibirás un correo electrónico en unos minutos con instrucciones sobre cómo reiniciar su contraseña."
failure:
already_authenticated: "Ya ha sido identificado."
- inactive: "su cuenta aún no ha sido activada."
+ inactive: "Su cuenta ya no está activa. Por favor contáctenos para reactivar su cuenta."
invalid: "Correo o contraseña inválidos."
invalid_token: "Cadena de autenticación invalida."
locked: "Su cuenta ha sido bloqueada."
diff --git a/config/locales/devise/devise.fr.yml b/config/locales/devise/devise.fr.yml
index 59c4f02..e968038 100644
--- a/config/locales/devise/devise.fr.yml
+++ b/config/locales/devise/devise.fr.yml
@@ -9,7 +9,7 @@
send_paranoid_instructions: "Si votre adresse électronique existe dans notre base de données, vous recevrez dans quelques minutes un courriel contenant les directives pour valider votre compte."
failure:
already_authenticated: "Vous êtes déjà connecté(e)."
- inactive: "Votre compte n'est pas encore activé."
+ inactive: "Votre compte n'est plus actif. Merci de nous contacter pour réactiver votre compte."
invalid: "Courriel ou mot de passe incorrect."
invalid_token: "Jeton d'authentification incorrect."
locked: "Votre compte est verrouillé."
diff --git a/config/routes.rb b/config/routes.rb
index 4de6205..5e2376b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -71,6 +71,7 @@
member do
get 'admin_grant_permissions'
put 'admin_update_permissions'
+ put 'activate'
end
end
@@ -313,5 +314,6 @@
namespace :super_admin do
resources :orgs, only: [:index, :new, :create, :edit, :update, :destroy]
resources :themes, only: [:index, :new, :create, :edit, :update, :destroy]
+ resources :users, only: [:edit, :update]
end
end
diff --git a/db/migrate/20180315161757_add_active_to_users.rb b/db/migrate/20180315161757_add_active_to_users.rb
new file mode 100644
index 0000000..8a5fd16
--- /dev/null
+++ b/db/migrate/20180315161757_add_active_to_users.rb
@@ -0,0 +1,8 @@
+class AddActiveToUsers < ActiveRecord::Migration
+ def up
+ add_column :users, :active, :boolean, default: true
+ end
+ def down
+ remove_column :users, :active
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b38c962..ca41822 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: 20180313120831) do
+ActiveRecord::Schema.define(version: 20180315161757) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -413,6 +413,7 @@
t.string "invited_by_type"
t.integer "language_id"
t.string "recovery_email"
+ t.boolean "active", default: true
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js
index f0c99af..8f6ef35 100644
--- a/lib/assets/javascripts/application.js
+++ b/lib/assets/javascripts/application.js
@@ -45,6 +45,7 @@
import './views/shared/my_org';
import './views/shared/sign_in_form';
import './views/super_admin/themes/new_edit';
+import './views/super_admin/users/edit';
import './views/usage/index';
import './views/users/notification_preferences';
import './views/users/admin_grant_permissions';
diff --git a/lib/assets/javascripts/utils/autoComplete.js b/lib/assets/javascripts/utils/autoComplete.js
index ff0628f..1e735ec 100644
--- a/lib/assets/javascripts/utils/autoComplete.js
+++ b/lib/assets/javascripts/utils/autoComplete.js
@@ -11,7 +11,6 @@
const updateIdField = (el) => {
const crosswalk = $(`#${$(el).attr('id')}_crosswalk`);
const idField = $(el).attr('id').replace(/_name/, '_id');
-
if (isObject(crosswalk) && isObject($(idField))) {
const json = JSON.parse(`${$(crosswalk).val().replace(/\\"/g, '"').replace(/\\'/g, '\'')}`);
const selection = (json[$(el).val()] === undefined ? '' : json[$(el).val()]);
diff --git a/lib/assets/javascripts/views/super_admin/users/edit.js b/lib/assets/javascripts/views/super_admin/users/edit.js
new file mode 100644
index 0000000..00b14e4
--- /dev/null
+++ b/lib/assets/javascripts/views/super_admin/users/edit.js
@@ -0,0 +1,5 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+
+$(() => {
+ ariatiseForm({ selector: '#super_admin_user_edit' });
+});
diff --git a/lib/assets/javascripts/views/users/admin_grant_permissions.js b/lib/assets/javascripts/views/users/admin_grant_permissions.js
index bb32354..95b0155 100644
--- a/lib/assets/javascripts/views/users/admin_grant_permissions.js
+++ b/lib/assets/javascripts/views/users/admin_grant_permissions.js
@@ -1,9 +1,26 @@
import { paginableSelector } from '../../utils/paginable';
import { isObject, isString } from '../../utils/isType';
-import { renderNotice, renderAlert } from '../../utils/notificationHelper';
+import { renderNotice, renderAlert, hideNotifications } from '../../utils/notificationHelper';
import { scrollTo } from '../../utils/scrollTo';
$(() => {
+ // Activate/Deactivate user account
+ $(paginableSelector).on('click, change', '.activate-user input[type="checkbox"]', (e) => {
+ const form = $(e.target).closest('form');
+ hideNotifications();
+ form.submit();
+ });
+ $(paginableSelector).on('ajax:success', '.activate-user', (e, data) => {
+ if (data.code === 1 && data.msg && data.msg !== '') {
+ renderNotice(data.msg);
+ } else {
+ renderAlert(data.msg);
+ }
+ });
+ $(paginableSelector).on('ajax:error', '.activate-user', () => {
+ renderAlert('Unexpected error');
+ });
+
let currentPrivileges = null;
$(paginableSelector).on('click', 'a[href$="admin_grant_permissions"]', (e) => {
e.preventDefault();
diff --git a/lib/assets/stylesheets/overrides.scss b/lib/assets/stylesheets/overrides.scss
index d8a3e33..a833b18 100644
--- a/lib/assets/stylesheets/overrides.scss
+++ b/lib/assets/stylesheets/overrides.scss
@@ -49,6 +49,9 @@
.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
background-color: #CCC;
}
+th.date-column {
+ min-width: 120px;
+}
// Fix issues with dropdwon within tables being cut off
.table-responsive > .table {
@@ -84,6 +87,12 @@
}
}
+/* MODAL DIALOG STYLING */
+.modal-dialog {
+ background-color: $white;
+}
+
+
/* nav-tabs and nav-pills styling */
.nav-tabs, .nav-pills {
background-color: $grey;
diff --git a/test/functional/super_admin/orgs_controller_test.rb b/test/functional/super_admin/orgs_controller_test.rb
index b7c2f5f..0a8d623 100644
--- a/test/functional/super_admin/orgs_controller_test.rb
+++ b/test/functional/super_admin/orgs_controller_test.rb
@@ -51,6 +51,7 @@
test 'super admin can create an org' do
params = {name: 'Test Org create', abbreviation: 'ABCD'}
sign_in @super_admin
+
post super_admin_orgs_path, {org: params}
assert_response :redirect
end
diff --git a/test/functional/super_admin/users_controller_test.rb b/test/functional/super_admin/users_controller_test.rb
new file mode 100644
index 0000000..36a7c1a
--- /dev/null
+++ b/test/functional/super_admin/users_controller_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+class UsersControllerTest < ActionDispatch::IntegrationTest
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @user = User.create!(email: "super-admin-user-test@example.com",
+ firstname: "Testing", surname: "User",
+ password: "password123", password_confirmation: "password123",
+ org: Org.last, accept_terms: true, confirmed_at: Time.zone.now)
+ @super_admin = User.find_by(email: 'super_admin@example.com')
+ end
+
+ test 'unauthorized user cannot access edit user page' do
+ get edit_super_admin_user_path(@user)
+ assert_unauthorized_redirect_to_root_path
+
+ sign_in @user
+ get edit_super_admin_user_path(@user)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'super admin can access edit user page' do
+ sign_in @super_admin
+ get edit_super_admin_user_path(@user)
+ assert_response :success
+ end
+
+ test 'unauthorized user cannot edit a user' do
+ params = { firstname: 'Foo', surname: 'Bar' }
+ put super_admin_user_path(@user), { super_admin_user: params }
+ assert_unauthorized_redirect_to_root_path
+
+ sign_in @user
+ put super_admin_user_path(@user), { super_admin_user: params }
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'super admin can edit a user' do
+ params = { firstname: 'Foo', surname: 'Bar' }
+ sign_in @super_admin
+ put super_admin_user_path(@user), { super_admin_user: params }
+ assert_response :redirect
+ @user.reload
+ assert_equal 'Foo', @user.firstname, "expected the User's firstname to have been updated"
+ end
+
+end
diff --git a/test/integration/user_activation_test.rb b/test/integration/user_activation_test.rb
new file mode 100644
index 0000000..89aaaf0
--- /dev/null
+++ b/test/integration/user_activation_test.rb
@@ -0,0 +1,39 @@
+require 'test_helper'
+
+class AnswerLockingTest < ActionDispatch::IntegrationTest
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @user = User.create!(email: "super-admin-user-test@example.com",
+ firstname: "Testing", surname: "User",
+ password: "password123", password_confirmation: "password123",
+ org: Org.last, accept_terms: true, confirmed_at: Time.zone.now)
+ end
+
+ test 'user can login when their account is active' do
+ sign_in @user
+ get root_path
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'user cannot login when their account is inactive' do
+ @user.active = false
+ @user.save!
+
+ sign_in @user
+ # Sign in throws an Exception when the user is inactive
+ assert_raise do
+ get root_path
+ end
+ end
+
+ test 'logged in user is logged out when their account is deactivated' do
+ sign_in @user
+ get root_path
+ assert_authorized_redirect_to_plans_page
+ @user.active = false
+ @user.save!
+ get root_path
+ assert_unauthorized_redirect_to_root_path
+ end
+end
\ No newline at end of file
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index 73d966f..0fa96b6 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -139,6 +139,11 @@
end
# ---------------------------------------------------
+ test "new user is active by default" do
+ assert @user.active?
+ end
+
+ # ---------------------------------------------------
test "can only have one identifier per IdentifierScheme" do
@scheme = IdentifierScheme.first