diff --git a/htdocs/auth/lib.php b/htdocs/auth/lib.php index 10a1d14af9517bfb7a80b8ebd11fd14245cc3dd1..c3b614050b53d834026ca150090455fdd2e5edf7 100644 --- a/htdocs/auth/lib.php +++ b/htdocs/auth/lib.php @@ -750,72 +750,66 @@ function auth_get_available_auth_types($institution=null) { */ function auth_check_required_fields() { global $USER, $SESSION; - $refused = param_boolean('refuseprivacy', false); - // Privacy statement. - if (get_config('institutionstrictprivacy') && !$USER->has_latest_agreement()) { - if ($refused) { - $elements['refused'] = array( + // for the case we are mascarading as the user and we want to return to be admin user + $restoreadmin = param_integer('restore', 0); + $loginanyway = false; + if ($USER->get('parentuser') && param_exists('loginanyway')) { + $USER->loginanyway = true; + } + if ($USER->get('loginanyway')) { + $loginanyway = true; + } + // Privacy statement. + if (get_config('institutionstrictprivacy') && !$USER->has_latest_agreement() && !$restoreadmin && !$loginanyway) { + // Get all institutions of a user. + $userinstitutions = array_keys($USER->get('institutions')); + // Include the 'mahara' institution so that we may show the site privacy statement as well. + array_push($userinstitutions, 'mahara'); + + // Check if there are new privacies that need to be accepted. + $latestversions = get_latest_privacy_versions($userinstitutions, true); + + foreach ($latestversions as $privacy) { + $elements[$privacy->institution . 'text'] = array( + 'type' => 'markup', + 'value' => '

' . ($privacy->institution == 'mahara' ? get_string('siteprivacystatement', 'admin') : get_string('institutionprivacystatement', 'admin')) . '

' . $privacy->content, + ); + $elements[$privacy->institution . 'id'] = array( 'type' => 'hidden', - 'value' => 1 + 'value' => $privacy->id, ); - $elements['submit'] = array( - 'type' => 'submitcancel', - 'class' => 'btn-default', - 'value' => array(get_string('yes'), get_string('no')), - 'goto' => get_config('wwwroot'), + $elements[$privacy->institution] = array( + 'type' => 'switchbox', + 'title' => get_string('privacyagreement', 'admin'), + 'description' => $privacy->agreed ? get_string('privacyagreedto', 'admin', format_date(strtotime($privacy->agreedtime))) : '', + 'defaultvalue' => $privacy->agreed ? true : false, + 'disabled' => $privacy->agreed ? true : false, + 'required' => true, ); - $form = pieform(array( - 'name' => 'refuseprivacy', - 'elements' => $elements, - )); - } - else { - // Get all institutions of a user. - $userinstitutions = array_keys($USER->get('institutions')); - // Include the 'mahara' institution so that we may show the site privacy statement as well. - array_push($userinstitutions, 'mahara'); - - // Check if there are new privacies that need to be accepted. - $latestversions = get_latest_privacy_versions($userinstitutions, true); - - foreach ($latestversions as $privacy) { - $elements[$privacy->institution . 'text'] = array( - 'type' => 'markup', - 'value' => '

' . ($privacy->institution == 'mahara' ? get_string('siteprivacystatement', 'admin') : get_string('institutionprivacystatement', 'admin')) . '

' . $privacy->content, - ); - $elements[$privacy->institution . 'id'] = array( - 'type' => 'hidden', - 'value' => $privacy->id, - ); - $elements[$privacy->institution] = array( - 'type' => 'switchbox', - 'title' => get_string('privacyagreement', 'admin'), - 'description' => $privacy->agreed ? get_string('privacyagreedto', 'admin', format_date(strtotime($privacy->agreedtime))) : '', - 'defaultvalue' => $privacy->agreed ? true : false, - 'disabled' => $privacy->agreed ? true : false, - 'required' => true, - ); - $elements[$privacy->institution . 'switch'] = array( - 'type' => 'hidden', - 'value' => $privacy->agreed ? 'disabled' : 'enabled', - ); - } - $elements['submit'] = array( - 'class' => 'btn-primary', - 'type' => 'submit', - 'value' => get_string('savechanges', 'admin') + $elements[$privacy->institution . 'switch'] = array( + 'type' => 'hidden', + 'value' => $privacy->agreed ? 'disabled' : 'enabled', ); - $form = pieform(array( - 'name' => 'agreetoprivacy', - 'elements' => $elements, - )); } + $elements['submit'] = array( + 'class' => 'btn-primary', + 'type' => 'submit', + 'value' => get_string('savechanges', 'admin') + ); + $form = pieform(array( + 'name' => 'agreetoprivacy', + 'elements' => $elements, + )); define('TITLE', get_string('privacy', 'admin')); $smarty = smarty(); setpageicon($smarty, 'icon-umbrella'); + if ($USER->get('parentuser')) { + $smarty->assign('loginanyway', + get_string('loginasoverrideprivacyaccept', 'admin', + '', '')); + } $smarty->assign('form', $form); - $smarty->assign('refused', $refused); $smarty->display('account/useracceptprivacy.tpl'); exit; } @@ -835,8 +829,7 @@ function auth_check_required_fields() { } // Check if the user wants to log in anyway - if ($USER->get('passwordchange') && $USER->get('parentuser') && param_exists('loginanyway')) { - $USER->loginanyway = true; + if ($USER->get('passwordchange') && $loginanyway) { $changepassword = false; } @@ -1212,7 +1205,8 @@ function agreetoprivacy_submit(Pieform $form, $values) { $userinstitutions = array_keys($USER->get('institutions')); array_push($userinstitutions, 'mahara'); - $hasrefused = false; + $hasrefused = param_integer('hasrefused', 0); + foreach ($userinstitutions as $institution) { // check if the institution has a privacy statement // if not, it depends on the site one and we can skip it @@ -1223,32 +1217,20 @@ function agreetoprivacy_submit(Pieform $form, $values) { try { $agreed = (empty($values[$institution]) ? 0 : $values[$institution]); save_user_reply_to_agreement($USER->get('id'), $values[$institution . 'id'], $agreed); - if ($values[$institution]) { - $SESSION->add_ok_msg(get_string('agreementsaved', 'admin')); - } - else { - $hasrefused = true; + $SESSION->add_ok_msg(get_string('agreementsaved', 'admin')); + if ($hasrefused) { + suspend_user($USER->get('id'), 'privacyrefusal'); + $SESSION->add_ok_msg(get_string('usersuspended', 'admin')); + $USER->logout(); + redirect(); } } catch (SQLException $e) { $SESSION->add_ok_msg(get_string('savefailed', 'admin')); } } - if ($hasrefused) { - redirect(get_config('wwwroot') . '?refuseprivacy=true'); - } - $SESSION->set('nocheckrequiredfields', true); - redirect(); -} - -function refuseprivacy_submit(Pieform $form, $values) { - global $USER, $SESSION; - - suspend_user($USER->get('id'), 'privacyrefusal'); - $SESSION->add_ok_msg(get_string('usersuspended', 'admin')); - $SESSION->set('nocheckrequiredfields', true); - $USER->logout(); + $USER->renew(); redirect(); } /** diff --git a/htdocs/js/mahara.js b/htdocs/js/mahara.js index 1a8a7ca58bd76a081bb6ec745cde130f88d4f1c9..fb375af8b15c9b19dc2e52d8c641b9c6e339c5e3 100644 --- a/htdocs/js/mahara.js +++ b/htdocs/js/mahara.js @@ -139,8 +139,6 @@ function formStartProcessing(form, btn) { processingStart(); var button = jQuery(btn); if (button.length) { - button.text(get_string('processing') + ' ...'); - // we add a hidden input field so the "disabled" button still gets to // pass its value through var node = jQuery('').attr({ @@ -148,6 +146,12 @@ function formStartProcessing(form, btn) { 'name': button.attr('name') }); button.after(node); + if (button.prop("tagName").toLowerCase() == 'input') { + button.prop('value', get_string('processing') + ' ...'); + } + else { + button.text(get_string('processing') + ' ...'); + } button.prop('disabled', true); button.blur(); @@ -174,6 +178,22 @@ function formStopProcessing(form, btn) { processingStop(); } +// This is to style the in processing button back to it's original state +// Takes a jQuery object +function formAbortProcessing(jbtn) { + processingStop(); + var button = jbtn; + var buttonnext = button.next('input'); + if (button.length) { + // reset the form button back to it's pre-submitted state + button.prop('disabled', false); + if (buttonnext.attr('name') == button.attr('name')) { + button.prop('value', buttonnext.prop('value')); + buttonnext.remove(); + } + } +} + function formError(form, data) { displayMessage(data.message, 'error', true); scrollTo(0, 0); diff --git a/htdocs/lang/en.utf8/admin.php b/htdocs/lang/en.utf8/admin.php index 45e8519f0b77aeb855ce1315e090e8e8d065f187..248fce19225f004303e5a024c3a4a12b1384062d 100644 --- a/htdocs/lang/en.utf8/admin.php +++ b/htdocs/lang/en.utf8/admin.php @@ -894,6 +894,7 @@ $string['loginasdenied'] = 'Attempt to log in as another user without permission $string['loginastwice'] = 'Attempt to log in as another user when already logged in as another user'; $string['loginasrestorenodata'] = 'No user data to restore'; $string['loginasoverridepasswordchange'] = 'As you are masquerading as another user, you may choose to %slog in anyway%s ignoring the password change screen.'; +$string['loginasoverrideprivacyaccept'] = 'As you are masquerading as another user, you may choose to %slog in anyway%s ignoring the accept privacy statement screen.'; // Institutions $string['Add'] = 'Add'; diff --git a/htdocs/theme/raw/templates/account/useracceptprivacy.tpl b/htdocs/theme/raw/templates/account/useracceptprivacy.tpl index 8ae7cf401972a9e3cc681faab35d718422c71303..b16798c95b7c1ba7d85e67079cd5bb503122f0e8 100644 --- a/htdocs/theme/raw/templates/account/useracceptprivacy.tpl +++ b/htdocs/theme/raw/templates/account/useracceptprivacy.tpl @@ -1,17 +1,75 @@ {include file="header.tpl"} -{if $refused} -
-

{str tag="refuseprivacy" section="admin"}

-
-
{str tag="privacyrefusaldetails" section="admin"}
-

{str tag="confirmprivacyrefusal" section="admin"}

- {$form|safe} +{if $loginanyway} +

+ {$loginanyway|safe} +

+{/if} +
{str tag="newprivacy" section="admin"}
+
{$form|safe}
+ +{* Modal form *} + -{else} -
{str tag="newprivacy" section="admin"}
-
{$form|safe}
-{/if} + + {include file="footer.tpl"} diff --git a/test/behat/features/site_features/strict_privacy.feature b/test/behat/features/site_features/strict_privacy.feature new file mode 100644 index 0000000000000000000000000000000000000000..b156d42b4cc9c3491264ab965522530c3240e8c3 --- /dev/null +++ b/test/behat/features/site_features/strict_privacy.feature @@ -0,0 +1,48 @@ +@javascript @core @gdpr + +Feature: Strict privacy switch + As a new user logging in for the first time + When strict privacy is enabled + I should be required to accept the privacy statement + +Background: + + # And the following site settings are set: + #| 'usersallowedmultipleinstitutions' | 0 | + # | 'institutionstrictprivacy' | 1 | + +Scenario: Create user who logs in with strict privacy enabled + Given I log in as "admin" with password "Kupuhipa1" + And I choose "Site options" in "Configure site" from administration menu + And I expand "Institution settings" node + # Need to disable multiple inst first, or set strict privacy doesn't work. + And I disable the switch "Users allowed multiple institutions" + And I enable the switch "Strict privacy" + # Check this worked as otherwise there is no point in continuing + And the field "Strict privacy" matches value "1" + And I press "Update site options" + # Background adding of user doesn't work for this test + And I choose "Add user" in "Users" from administration menu + And I set the following fields to these values: + | First name | Bob | + | Last name | One | + | Email | UserB@example.com | + | Username | bob | + | password | Kupuhipa1 | + And I press "Create user" + And I disable the switch "Force password change on next login" + And I enable the switch "Disable email" + And I press "Save changes" + And I log out + Given I log in as "bob" with password "Kupuhipa1" + Then I should see "Before entering your account, please read the privacy statement displayed below." + # Try to ignore privacy statement + And I choose "Pages and collections" in "Portfolio" from main menu + Then I should see "Before entering your account, please read the privacy statement displayed below." + And I press "Save changes" + Then I should see "If you do not consent to the privacy statement, your account will be suspended." + Then I press "No" + # consent to privacy statement + And I enable the switch "I consent to this privacy statement" + And I press "Save changes" + Then I should see "Welcome"