Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-66173

Add hooks to extend all forms with /login/

    XMLWordPrintable

    Details

    • Testing Instructions:
      Hide

      Requirements

      • Either an SMTP server configured, or mailcatcher/mailhog configured.
      • A Moodle mobile app connection to the Moodle instance.

      Setup Instructions

      1) Enable the Moodle Mobile app support on the Moodle instance. Visit Site Administration-> Mobile App-> Mobile Settings and enable 'enablemobilewebservice' to allow testing of the Mobile interactions.

      2) On the Mobile app, visit Settings, and enable 'Display Debug Messages'. This will ensure any interactions with the Webservices layer can be seen.

      3) Edit config.php in the main moodle directory, and add the line:

      $CFG->pwresettime = 14400;
      

      This ensures that any password reset request will remain active for a long enough period to correctly test.

      4)

      1. While not logged in to any user account, submit a password reset request for an account that has an active email address, such as the admin account.
      2. Do not visit the page in the URL yet. It is sent now, as the forgot_password form will later always fail validation, and you will be unable to submit password reset requests after the plugin below is installed.

      5) Install a tester plugin that uses the hooks to inject form elements. In the Moodle installation directory, open a terminal and run:

      git clone https://github.com/Peterburnett/MDL-66173_tester.git admin/tool/loginhooktester
      

      This will clone a tester plugin into the correct directory.

      Once the plugin has been cloned, visit the main admin page to ensure that the install plugin script runs and installs the plugin.

      6) Visit Site Administration->Debugging and set Debug Messages to DEVELOPER, and ensure Display Debug Messages is ticked. This ensures that any debugging messages being emitted are displayed.

      Testing Instructions

      To test this change, all of the pages that have injection calls can be added, and using a plugin that takes advantage of the hooks, all of the hook functionality can be observed.

      1) change_password_form: 

      1. Visit Preferences->Change Password. There will be two extra injected form elements.
      2.  The first will be a static text that displays the current account's username, e.g. 'admin'. This verifies that the form extension hook is passing the correct user account to the plugin.
      3. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form.
      4.  The second element will be a text box labelled 'Injected form extension element'. This is used for validation of the form.
      5. Enter 'tester string' into the box, and fill in the required fields with dummy data.
      6. Submit the form, and verify that the error text underneath the box matches the text that was submitted.  The username of the current account will also be displayed in the string. This shows that the validation can correctly interact with injected form elements,  and that the correct account is being passed into the validation.
      7. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'.
      8. Set the text in the box to be 'test', and set the new password to valid values, and submit the form again. This string allows the validation to pass.
      9. You will be presented with a popup showing the originating callback, and the string entered into the box.
      10. Ensure the popup shows post_change_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in.
      11. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'.

      2) Ensure that users have a way to self-sign up, such as email-based self signup, by visiting Site Administration->Plugins->Authentication->Manage Authentication and set the control 'Self Registration' to Email-based self-registration.

      3) signup_form Now log out of the Moodle instance, and visit the login page.

      1. Click "Create new account" at the bottom /login/signup.php
      2. In the signup form, there will only be the text box labelled 'Injected form extension element'.
      3. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form.
      4. Submit the form with dummy data in any all the fields marked required.
      5. You should see validation errors for the new extra field that just says "Input:".
      6. Enter any text into the box, such as 'tester string'.
      7. Submit the form, and verify that the error text underneath the box matches the text that was submitted. This shows that the form injection works, and that validation can correctly interact with the form elements.
      8. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'.
      9. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass.
      10. You will be presented with a popup showing the originating callback, and the string entered into the box.
      11. Ensure the popup shows post_signup_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in.
      12. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'.

      4) forgot_password_form

      1.  While still logged out, on the login page, click 'Forgotten your username or password?' to get the the forgot_password_form.
      2. At the top of the form, there will be a text box labelled 'Injected form extension element'. Enter any text into the box, such as 'tester string', and click either of the submit buttons.
      3. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form.
      4. Verify that the validation returns the text entered into the box. This shows that the injection is working, and that the validation can correctly interact with form elements.
      5. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'.
      6. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass.
      7. You will be presented with a popup showing the originating callback, and the string entered into the box.
      8. Ensure the popup shows post_forgot_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in.
      9. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'.

      5) set_password_form Now follow the link to password reset that was emailed out, to get to the set_password_form. There will be two extra injected form elements:

      1.  The first will be a static text that displays the current account's username, e.g. 'admin'. This verifies that the form extension hook is passing the correct user account to the plugin.
      2.  The second element will be a text box labelled 'Injected form extension element'. This is used for validation of the form. Enter any text into the box, such as 'tester string', and set the new password fields to dummy data.
      3. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form.
      4. Submit the form, and verify that the error text underneath the box matches the text that was submitted.  The username of the current account will also be displayed in the string. This shows that the validation can correctly interact with injected form elements,  and that the correct account is being passed into the validation.
      5. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'.
      6. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass.
      7. You will be presented with a popup showing the originating callback, and the string entered into the box.
      8. Ensure the popup shows post_set_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in.
      9. After clicking OK on the javascript popup, the page will die. This is intended behaviour, to ensure the Javascript popup correctly appears once validation is successful.
      10. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'.

      6) Mobile App: forgot_password_form

      1. On the mobile app, connect to the Moodle instance.
      2. Press 'Forgotten your username or password?'.
      3. Verify that there are no injected form elements present on this page.
      4. Verify that there are no debugging messages being displayed on the page.
      5. Fill in data in the username field  e.g. 'testuser', and press Search.
      6. Verify that no debugging messages are present, and that the success modal window appeared.
      7. This ensures that no form extensions, validation, or post requests are being fired, or impacting upon the webservices layer.

      7) Mobile App: signup_form

      1. From the login page, now press 'Create new account'.
      2. Fill in the form with valid data in all required fields.
      3. Verify that there are no injected form elements present on this page.
      4. Verify that there are no debugging messages being displayed on the page.
      5. Press 'Create my new account'.
      6. Verify that the request went through, showing that there is no additional validation being called.
      7. Verify that the success modal appeared, and that an email arrived from the Moodle instance for the new user.
      Show
      Requirements Either an SMTP server configured, or mailcatcher/mailhog configured. A Moodle mobile app connection to the Moodle instance. Setup Instructions 1) Enable the Moodle Mobile app support on the Moodle instance. Visit Site Administration-> Mobile App-> Mobile Settings and enable 'enablemobilewebservice' to allow testing of the Mobile interactions. 2) On the Mobile app, visit Settings, and enable 'Display Debug Messages'. This will ensure any interactions with the Webservices layer can be seen. 3) Edit config.php in the main moodle directory, and add the line: $CFG->pwresettime = 14400 ; This ensures that any password reset request will remain active for a long enough period to correctly test. 4) While not logged in to any user account, submit a password reset request for an account that has an active email address, such as the admin account. Do not visit the page in the URL yet. It is sent now, as the forgot_password form will later always fail validation, and you will be unable to submit password reset requests after the plugin below is installed. 5) Install a tester plugin that uses the hooks to inject form elements. In the Moodle installation directory, open a terminal and run: git clone https: //github.com/Peterburnett/MDL-66173_tester.git admin/tool/loginhooktester This will clone a tester plugin into the correct directory. Once the plugin has been cloned, visit the main admin page to ensure that the install plugin script runs and installs the plugin. 6) Visit Site Administration->Debugging and set Debug Messages to DEVELOPER, and ensure Display Debug Messages is ticked. This ensures that any debugging messages being emitted are displayed. Testing Instructions To test this change, all of the pages that have injection calls can be added, and using a plugin that takes advantage of the hooks, all of the hook functionality can be observed. 1) change_password_form:   Visit Preferences->Change Password. There will be two extra injected form elements.  The first will be a static text that displays the current account's username, e.g. 'admin'. This verifies that the form extension hook is passing the correct user account to the plugin. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form.  The second element will be a text box labelled 'Injected form extension element'. This is used for validation of the form. Enter 'tester string' into the box, and fill in the required fields with dummy data. Submit the form, and verify that the error text underneath the box matches the text that was submitted.  The username of the current account will also be displayed in the string. This shows that the validation can correctly interact with injected form elements,  and that the correct account is being passed into the validation. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'. Set the text in the box to be 'test', and set the new password to valid values, and submit the form again. This string allows the validation to pass. You will be presented with a popup showing the originating callback, and the string entered into the box. Ensure the popup shows post_change_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'. 2) Ensure that users have a way to self-sign up, such as email-based self signup, by visiting Site Administration->Plugins->Authentication->Manage Authentication and set the control 'Self Registration' to Email-based self-registration. 3) signup_form Now log out of the Moodle instance, and visit the login page. Click "Create new account" at the bottom /login/signup.php In the signup form, there will only be the text box labelled 'Injected form extension element'. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form. Submit the form with dummy data in any all the fields marked required. You should see validation errors for the new extra field that just says "Input:". Enter any text into the box, such as 'tester string'. Submit the form, and verify that the error text underneath the box matches the text that was submitted. This shows that the form injection works, and that validation can correctly interact with the form elements. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass. You will be presented with a popup showing the originating callback, and the string entered into the box. Ensure the popup shows post_signup_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'. 4) forgot_password_form  While still logged out, on the login page, click 'Forgotten your username or password?' to get the the forgot_password_form. At the top of the form, there will be a text box labelled 'Injected form extension element'. Enter any text into the box, such as 'tester string', and click either of the submit buttons. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form. Verify that the validation returns the text entered into the box. This shows that the injection is working, and that the validation can correctly interact with form elements. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass. You will be presented with a popup showing the originating callback, and the string entered into the box. Ensure the popup shows post_forgot_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'. 5) set_password_form Now follow the link to password reset that was emailed out, to get to the set_password_form. There will be two extra injected form elements:  The first will be a static text that displays the current account's username, e.g. 'admin'. This verifies that the form extension hook is passing the correct user account to the plugin.  The second element will be a text box labelled 'Injected form extension element'. This is used for validation of the form. Enter any text into the box, such as 'tester string', and set the new password fields to dummy data. Verify that at the top of the page, debugging messages can be seen labelled 'extendform'. This is present to ensure that they are NOT present on mobile variants of this form. Submit the form, and verify that the error text underneath the box matches the text that was submitted.  The username of the current account will also be displayed in the string. This shows that the validation can correctly interact with injected form elements,  and that the correct account is being passed into the validation. Ensure after submitting the form for validation, that there are two debug messages now present, 'extendform' and 'extendvalidation'. Set the text in the box to be 'test', and set the form data to valid values, and submit the form again. This string allows the validation to pass. You will be presented with a popup showing the originating callback, and the string entered into the box. Ensure the popup shows post_set_password_request, the correct callback, and that the string passed is correct, showing the correct data is being passed in. After clicking OK on the javascript popup, the page will die. This is intended behaviour, to ensure the Javascript popup correctly appears once validation is successful. Ensure that there are three debugging messages displayed on the page behind the popup, labelled 'extendform', 'extendvalidation', and 'postrequest'. 6) Mobile App: forgot_password_form On the mobile app, connect to the Moodle instance. Press 'Forgotten your username or password?'. Verify that there are no injected form elements present on this page. Verify that there are no debugging messages being displayed on the page. Fill in data in the username field  e.g. 'testuser', and press Search. Verify that no debugging messages are present, and that the success modal window appeared. This ensures that no form extensions, validation, or post requests are being fired, or impacting upon the webservices layer. 7) Mobile App: signup_form From the login page, now press 'Create new account'. Fill in the form with valid data in all required fields. Verify that there are no injected form elements present on this page. Verify that there are no debugging messages being displayed on the page. Press 'Create my new account'. Verify that the request went through, showing that there is no additional validation being called. Verify that the success modal appeared, and that an email arrived from the Moodle instance for the new user.
    • Affected Branches:
      MOODLE_38_STABLE
    • Fixed Branches:
      MOODLE_38_STABLE
    • Pull Master Branch:
      mdl-66173

      Description

      At present there are a bunch of auth plugins which augment the login flow but this has never been a clean architecture. eg an alternative to recapture to the login page, adding an enrolkey, or adding 2 factor auth of various kinds. None of these should be considered a new auth method or auth source. These should instead be like a 'mixin' that you apply on top of other auth methods.

      https://github.com/catalyst/moodle-auth_enrolkey

      https://moodle.org/plugins/auth_a2fa

      I've considered adding more methods to the auth plugin but this doesn't seem clean to me, these things just shouldn't be auth plugins at all.

      So I'm proposing two alternate solutions:

      A) add this as new methods to auth_plugin_base including a new method which says 'this is not a real auth source'. can_be_manually_set() is close but I don't think strong enough, something like is_auth_type()

      or

      B) we just implement a series of new callback hooks or classes which can be implemented in any plugin eg an admin tools

      Either way the hooks / methods would enable us to add fields to all of these forms:

      change_password_form.php
      forgot_password_form.php
      set_password_form.php
      signup_form.php

      And also the new form which I intend to introduce in MDL-66172

       

      Webservices status:

      The proposed hooks currently have no interaction with the Webservices API or the Moodle app. Any injected elements, validation, or post actions will not be fired from any Moodle app session that touches the forgot_password_form or signup_form. This means that while there is no current implementation of these hooks on Mobile, any mobile functionality remains untouched by these hooks, and no current implementations are broken

       

       

       

        Attachments

        1. change_password_form.png
          change_password_form.png
          78 kB
        2. image-2019-08-06-16-32-23-581.png
          image-2019-08-06-16-32-23-581.png
          172 kB
        3. Screenshot_1.png
          Screenshot_1.png
          232 kB
        4. Screenshot_2.png
          Screenshot_2.png
          123 kB
        5. Screenshot_3.png
          Screenshot_3.png
          330 kB
        6. Screenshot_4.png
          Screenshot_4.png
          273 kB
        7. Screenshot_5.png
          Screenshot_5.png
          163 kB

          Issue Links

            Activity

              People

              • Votes:
                4 Vote for this issue
                Watchers:
                13 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Fix Release Date:
                  18/Nov/19

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 7 hours
                  7h