Closed jsperhac closed 4 months ago
I've addressed your blocking change requests:
com_reply
migration files that had dates prior to 2023 in their names (commit b1b0538)While doing this I saw a couple of things that needed to be addressed:
I've tested all this stuff on my AWS instance.
Dependencies
This work is part of Epic NCN-434, whose PRs are as follows:
1693, NCN-633
plgUserHubzero
(on user login, ensure user has a secret in the DB)1683 NCN-439
com_members
(manage user secret)1676 NCN-437
com_newsletter
(manage campaign secret)1675 NCN-438
com_config
(manage hub secret)1704 NCN-702, NCN-440:
com_newsletter
(The current PR: update verification, after porting functionality from custom com_reply)Summary
Move and adapt custom code from Nanohub (
com_reply
) into the core CMS component,com_newsletter
.Then, update access validation for one-click links to use the secrets (hub, user, and campaign) created in the Epic mentioned above, NCN-434.
NOTE that all PRs mentioned above are already merged into this branch. All of them have been reviewed and tested.
Jira cards (for this PR):
What's the point again?
Nanohub team wants to be able to send emails to their users with secure, unique links that enable users one-click access to their editable profile details or to a survey. This work ensures that we can selectively reset or expire codes for individual users or for a campaign. In order to provide access we maintain unique secret codes for each user; for each "campaign"; and for the Hub. The three of these must be hashed together and the expiration date validated for access to be granted.
If this solution seems weirdly incomplete, it is. The Nanohub team uses a Salesforce instance to do their mailings. This requires only that they hit a replica of the Nanohub database to query for the needed campaign id, username, and hashed access code. Those are pulled into Salesforce, which handles the mailing part.
However, it was thought that this functionality might be generally useful so this work moves it into core.
Previous PRs provide admin user interfaces for Hub-side management of:
secret
codesUse
The one-click access code is generated by a call to stored procedure
hash_access_code
as follows:SELECT hash_access_code(campaignId, username);
Here's a partial example of what that looks like:
Page access
Example format of the secure page-access URLs provided to users:
https://hub.hubzero.org/newsletter/pages/2?campaign=CAMPAIGNID&user=USERNAME&code=CODE_FROM_hash_access_code
Subscription access
https://hub.hubzero.org/newsletter/email-subscriptions?campaign=CAMPAIGNID&user=USERNAME&code=CODE_FROM_hash_access_code
Management of the one-click pages, subscriptions, and related tables is no different than it was on nanoHUB, except that any hardcoding of the Hub name was replaced. Management of pages is largely manual and no change to that was scoped in this work (see README section below).
This is an example of the one-click "email subscription" page following successful validation:
Testing
This work was tested on a developer AWS instance. At the stage of this PR, testing concentrated on behavior when different URLs were provided. In particular:
Generation of codes via the stored procedure was also tested.
The README
The following is the updated README taken from the custom
com_reply
component. I reproduce it here to provide context on the work that was done.Reply functionality: single-click validation
Use Case
"Reply" functionality allows users to submit survey responses or update their preferences without first completing the primary hub authentication procedure.
This feature provides user authentication via hashes of randomly-generated codes that are associated with the user's CMS record, the campaign, and the Hub.
This functionality is now part of the
com_newsletter
core component. It was originally found in custom componentcom_reply
.Related features:
All management of these features is found under the Hub's administrator interface.
Install
muse migration run ...
Adding a Page
It is assumed that all users providing correct credentials will have access to all pages.
To add a form-based page:
jos_reply_pages
site/views/pages
Adding an Email Subscription Option
jos_email_subscriptions
secrets/code.php
, usingsecrets/code_example.php
as a model.validateEmailSubscriptionsCode()
.Gotchas
jos_email_subscriptions.profile_field_name
must correspond with ajos_user_profile_fields.name
jos_user_profile_options
must be populated for the user profile fields.jos_user_profile_options.field_id
must correspond with id fromjos_user_profile_fields.id
jos_users
user codes are provided at login time by the core Hubzero members plugin.campaign
.id
andjos_users
.username
Component-Specific Tables
jos_reply_pages
- pages for collecting datajos_reply_replies
- user-submitted responsesjos_email_subscriptions
- email subscription optionsAccess-Related Tables
jos_users
- contains asecret
for each usercampaign
- contains asecret
for each campaign, with expiration datejos_config
- thevalue
column forscope
='hub' andkey
='secret' contains the overall secret for the HubIntegrations
The email subscription update functionality integrates with the core user profile data.
jos_user_profile_fields
- profile fieldsjos_user_profile_options
- profile field response optionsjos_user_profiles
- associates user data with profile fieldsGenerating Access Codes
The stored procedure
hash_access_code
is used to generate and verify codes for page access. Codes are used in URLs as shown below.Example URLs
Here:
pages
Format of links for page access:
https://jsperhac.aws.hubzero.org/newsletter/pages/2?campaign=CAMPAIGNID&user=USERNAME&code=CODE_FROM_hash_access_code
subscriptions
Format of links for so-called subscription access:
https://jsperhac.aws.hubzero.org/newsletter/email-subscriptions?campaign=CAMPAIGNID&user=USERNAME&code=CODE_FROM_hash_access_code