Skip to content

Commit

Permalink
Item9790: Modernized BulkRegistration
Browse files Browse the repository at this point in the history
 - Support multiple New User Templates
 - Generate the UnprocessedRegistrations topic
 - Build a reset form to reset the new users passwords.
  • Loading branch information
gac410 committed Feb 23, 2017
1 parent c793404 commit 2583081
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 85 deletions.
149 changes: 95 additions & 54 deletions TopicUserMappingContrib/data/System/BulkRegistration.txt
@@ -1,5 +1,12 @@
%META:TOPICINFO{author="ProjectContributor" comment="" date="1460853933" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" comment="" date="1487815547" format="1.1" version="1"}%
%META:TOPICPARENT{name="AdminToolsCategory"}%
%ADDTOZONE{"head" text="<style type='text/css'>
#bulkReg .col1 {float:left; width:30%; margin:0 3% 0 0;}
#bulkReg .col2 {float:left; width:66%;}
#bulkReg .col1 .foswikiInputField,
#bulkReg .col1 .foswikiSelect {width:90%;}
#bulkReg .required {font-size:80%; color:#aaa;}
</style>"}%
---+ Bulk Registration

Administrators can use this topic to register (i.e. create logins and user topics) for a group of people in one batch.
Expand All @@ -14,11 +21,9 @@ Note: this is an administrator job - only admistrators can run this.

If you are administrator, you will take these actions:
1 (First time use) Create new bulk registration topics (see [[#Settings][Settings]] below).
1 In the REGISTERTOPIC (%REGISTERTOPIC%) topic: create a table of new users. An example table is provided below to copy.
1 Return to this topic and press the [[#RegisterForm]["Bulk Register" button]] to create the new topics.
1 Read %LOGTOPIC% to verify if all has gone well.
1 Visit %USERSWEB%.WikiGroups if the new users need to be added to any groups.
1 When you are ready, use the [[BulkResetPassword]] page to assign passwords and notify the users of their new accounts.
1 In the REGISTERTOPIC (%REGISTERTOPIC%) topic: create a table of new users. You can include a list of groups that the new user will automatically join.
1 After saving the table changes, press the button to register the users.
1 Read %LOGTOPIC% to verify if all has gone well. A form to reset the passwords of the new users is provided at the end of the log topic.

Below are the details.

Expand All @@ -30,30 +35,97 @@ Below are the details.

---++ The user table

This table is a template for user data that will be written to the new user topics. If you stick to these basic fields you can just use the first example below.
If you want to write more data (like phone number or country) read the section [[#CustomizingUserData][Customizing user data]] as well.
The user table is a template for user data that will be written to the new user topics. Each column should correspond to a field name captured in the UserForm.
Any field not included in the form will be written to the user topic in bullet format. Add new row for each user to be registered.

If the =Password= field is not included, then use the BulkResetPassword topic to assign new passwords. For convenience, the log of user registrations generated
when bulk registration is run will include a password reset form. Note that
the form is not generated if all users have been provided with passwords.

If the =Password= field is not included, then use the BulkResetPassword topic to assign new passwords.
If a password is included, it must be a valid password (&gt; minimum length, etc.)

%IF{"{Register}{AllowLoginName}" then="*Your system is configured to use Login Names. Be sure to include the !LoginName column in your table*"}%

---+++ Example format

The following should be inserted into your %REGISTERTOPIC% as a table. This is the most simple format:

<verbatim class='tml'>
Use the following form to create a new Unprocessed Registration topic.
* Enter a new topic name. You can use %REGISTERTOPIC% or any other new topic in the %USERSWEB%
* Select one or more optional fieldnames.
* Click "Create the topic" - you will be redirected to the new topic.

<div id="bulkReg" class="foswikiFormSteps">
<form name="picker" action="%SCRIPTURL{view}%/%WEB%/%TOPIC%#BuildTopic">
<div class="foswikiFormStep">
<h3>Choose the user template</h3>
<div class="col1">
<select name="usertemplate" onchange="picker.submit()">
<option>%URLPARAM{"usertemplate" default="%SYSTEMWEB%.NewUserTemplate"}%</option>
%SEARCH{"%VALUE%%SPLIT%" scope="all" topic="*Template" web="%USERSWEB%" type="literal" nonoise="on" format="<option value=\"%USERSWEB%.$topic\">%USERSWEB%.$topic</option>"}%</select>
</select>
</div><!--//col1-->
<div class="col2">
<p>
Select the template used when creating user topics. On most sites,
this is the NewUserTemplate. Note that this selection will reload the
page to refresh the field names used by that template.
</p>
</div><!--//col2-->
</div>
</form>
#BuildTopic
<noautolink>
%EDITTABLE{}%
| FirstName | LastName | Email | WikiName |
| Test | User | you@your.domain | TestUser |
</noautolink></verbatim>
<form name="savebulk" action="%SCRIPTURLPATH{save}%/%USERSWEB%" method="post"> \
<input type="hidden" name="onlynewtopic" value="1" />

<div class="foswikiFormStep">
<h3>Name of the new bulk registration topic <span class="required">Required</span></h3>
<div class="col1">
<p>
<input type="text" name="topic" />
</p>
</div><!--//col1-->
<div class="col2">
<p>
Enter a new topic name. This topic must not exist in the %USERSWEB% web.
</p>
</div><!--//col2-->
<div class="foswikiClear"></div>
</div><!--//foswikiFormStep-->

<div class="foswikiFormStep">
<h3>Fields to include in the registration</h3>
<div class="col1">
<p>
<select multiple='on' name='fields'>
%FORMAT{"%CALCULATE{$LISTUNIQUE(%QUERY{"'%URLPARAM{"usertemplate" default="System.NewUserTemplate"}%'/fields.name"}%)}%" type="string" format="<option value='$item'>$item</option>"}%
</select>
</p>
</div><!--//col1-->
<div class="col2">
Use Ctrl-click to select multiple fields. (LastName and FirstName
will be included even if not selected. They are required for registration.)
</div><!--//col2-->
<div class="foswikiClear"></div>
</div> <!-- foswikiFormStep -->

<div class="foswikiFormStep">
<div class="col1">
<h3>Create the topic</h3>
</div><!--//col1-->
<div class="col2">
<p>
Create the topic in the %USERSWEB% Web
</p>
</div> <!-- col2 -->
<div class="foswikiClear"></div>
</div> <!-- foswikkFormStep -->
<input type="hidden" name="usertemplate" value="%URLPARAM{"usertemplate" default="NewUserTemplate"}%" />
<input type="hidden" name="action" value="save" />
<input type="hidden" name="topicparent" value="BulkRegistration" />
<input type="hidden" name="templatetopic" value="%SYSTEMWEB%.BulkRegistrationInputTemplate" />
<input type="submit" class="foswikiSubmit" value="Create the topic" />
</div><!-- foswikiFormSteps -->
</form>
</noautolink>

*Usage:*
1 Copy this text to your clipboard
1 Click through and paste this on %REGISTERTOPIC%.
1 Add and customize entries, save table.
1 Return here

#CustomizingUserData
---+++ Customizing user data
Expand All @@ -62,12 +134,8 @@ You can write additional data to the new user topics. Do this by enhancing the u

Any fields you define in this table will end up in the User's topic. If a form (such as %SYSTEMWEB%.UserForm) is attached to NewUserTemplate then the data will go in as META:FIELDS, meaning that you can use SEARCH formfield constructs to search.

If you use the %SYSTEMWEB%.UserForm then ensure that it contains all the fields you define here. Otherwise they will disappear when the user edits their home topic!

---++++ Mandatory fields
* =WikiName=
* =FirstName=
* =LastName=

---++++ Optional fields
* =LoginName= - __Required if the system is configured to__ ==AllowLoginName== (Commonly referred to as the UserName).
Expand All @@ -77,17 +145,6 @@ If you use the %SYSTEMWEB%.UserForm then ensure that it contains all the fields
* =templatetopic= - Template used when creating the User topic. If not provided, defaults to [[%USERSWEB%.NewUserTemplate]], or [[%SYSTEMWEB%.NewUserTemplate]].
* =AddToGroups= - A comma-separated list of groups. When user is registered, they will be added to the listed groups. The groups must exist.

---++++ Customized table example

Make sure that the extra fields also appear on the %SYSTEMWEB%.UserForm.

<verbatim class='tml'>
<noautolink>
%EDITTABLE{}%
| FirstName | LastName | Email | WikiName | AddToGroups | CustomFieldThis | SomeOtherRandomField | WhateverYouLike |
| Test | User | you@example.com | TestUser | MyGroup, DocGroup | A | B | C |
</noautolink></verbatim>

---

%IF{
Expand All @@ -99,21 +156,5 @@ Make sure that the extra fields also appear on the %SYSTEMWEB%.UserForm.
<!--
%JQREQUIRE{"chili"}%
-->
#RegisterForm
<form name="bulkRegister" action="%SCRIPTURLPATH{"manage"}%/%REGISTERTOPIC%" method="post">
<input type="hidden" name="action" value="bulkRegister" /><sticky>&nbsp;</sticky>
<input type="submit" class="foswikiSubmit" value="Bulk Register these people" />
<input type="hidden" name="LogTopic" value="%LOGTOPIC%" />
</form>

---++ <nop>%REGISTERTOPIC%

%INCLUDE{"%REGISTERTOPIC%" warn="Topic does not exist"}%

---++ <nop>%LOGTOPIC%

%INCLUDE{"%LOGTOPIC%" warn="Topic will be created during registration run."}%

---

*%MAKETEXT{"Related topics:"}%* AdminToolsCategory
@@ -1,8 +1,18 @@
%META:TOPICINFO{author="ProjectContributor" date="1456871285" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1487815547" format="1.1" version="1"}%
%META:TOPICPARENT{name="WikiUsers"}%
%EDITTABLE{ headerrows="1" }%%STARTSECTION{type="expandvariables"}%
| *WikiName* |%IF{"{Register}{AllowLoginName}" then=" *LoginName* |"}% *Email* | *Password* | *AddToGroups* |\
*%CALCULATE{"$LISTJOIN(* | *, $LISTIF($NOT($EXACT($item,Email)),%QUERY{"'%URLPARAM{"usertemplate" default="%SYSTEMWEB%.NewUserTemplate"}%'/fields.name"}%))"}%* |

%IF{
"context passwords_modifyable"
then=""
else='<div class="foswikiHelp">%X% <strong>%MAKETEXT{"Caution: The password system is currently read only. Users will not be added to the Password file."}%</strong>%BR%
%MAKETEXT{"If your wiki uses an external password manager, and the users you want to register are known to the password manager, then bulk registration may still be useful. Please contact [_1] if you are unsure." args="%WIKIWEBMASTER%"}%</strong></div>'
}%


%EDITTABLE{ headerrows="1" format="text,20,%URLPARAM{"usertemplate" default="NewUserTemplate"}%" }%%STARTSECTION{type="expandvariables"}%
| *TemplateTopic* | *WikiName* |%IF{"{Register}{AllowLoginName}" then=" *LoginName* |"}% *Password* | *AddToGroups* \
%FORMAT{"%CALCULATE{$LISTUNIQUE(Email,LastName,FirstName,%URLPARAM{"fields" multiple="on" separator=","}%)}%" type="text" format=" | *$item* " separator="" type="string"}% |

%ENDSECTION%

%META:PREFERENCE{name="ALLOWTOPICVIEW" title="ALLOWTOPICVIEW" type="Set" value="AdminGroup"}%
Expand Down
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="ProjectContributor" date="1456982088" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" date="1487815547" format="1.1" version="1"}%
%META:TOPICPARENT{name="BulkRegister"}%
%{<verbatim class="tml">
===================================================
Expand All @@ -23,6 +23,7 @@ _Be sure to remember to save any table changes!_
<form name='bulkRegister' action='%SCRIPTURLPATH{"manage"}%/%TOPIC%' method='post'>
<input type='hidden' name='action' value='bulkRegister' /><sticky>&nbsp;</sticky>
<input type='submit' class='foswikiSubmit' value='Bulk Register these people' />
<input type='hidden' name='topic' value='%USERSWEB%.%TOPIC%' />
<input type='hidden' name='redirectto' value='%TOPIC%' />
<input type='hidden' name='LogTopic' value='%TOPIC%Log' />
<input type='hidden' name='templatetopic' value='%USER_TEMPLATE{default=""}%' />
Expand Down
37 changes: 18 additions & 19 deletions TopicUserMappingContrib/data/System/NewUserTemplate.txt
@@ -1,6 +1,6 @@
%META:TOPICINFO{author="ProjectContributor" date="1418937051" format="1.1" version="1"}%
%META:TOPICINFO{author="ProjectContributor" comment="" date="1487815547" format="1.1" version="1"}%
%META:TOPICPARENT{name="WikiUsers"}%
---+ <nop>%TOPIC%
---+ %TOPIC%

%SPLIT%
* %KEY%: %VALUE%%SPLIT%
Expand All @@ -9,20 +9,19 @@
* Set ALLOWTOPICCHANGE = %WIKIUSERNAME%
-->


%META:FORM{name="%25SYSTEMWEB%25.UserForm"}%
%META:FIELD{name="FirstName" attributes="" title="<nop>FirstName" value=""}%
%META:FIELD{name="LastName" attributes="" title="<nop>LastName" value=""}%
%META:FIELD{name="OrganisationName" attributes="" title="<nop>OrganisationName" value=""}%
%META:FIELD{name="OrganisationURL" attributes="" title="<nop>OrganisationURL" value=""}%
%META:FIELD{name="Profession" attributes="" title="Profession" value=""}%
%META:FIELD{name="Country" attributes="" title="Country" value=""}%
%META:FIELD{name="State" attributes="" title="State" value=""}%
%META:FIELD{name="Address" attributes="" title="Address" value=""}%
%META:FIELD{name="Location" attributes="" title="Location" value=""}%
%META:FIELD{name="Telephone" attributes="" title="Telephone" value=""}%
%META:FIELD{name="VoIP" attributes="" title="<nop>VoIP" value=""}%
%META:FIELD{name="InstantMessagingIM" attributes="" title="<nop>InstantMessaging (IM)" value=""}%
%META:FIELD{name="Email" attributes="" title="Email" value=""}%
%META:FIELD{name="HomePage" attributes="" title="<nop>HomePage" value=""}%
%META:FIELD{name="Comment" attributes="" title="Comment" value=""}%
%META:FORM{name="UserForm"}%
%META:FIELD{name="FirstName" title="<nop>FirstName" value=""}%
%META:FIELD{name="LastName" title="<nop>LastName" value=""}%
%META:FIELD{name="OrganisationName" title="<nop>OrganisationName" value=""}%
%META:FIELD{name="OrganisationURL" title="<nop>OrganisationURL" value=""}%
%META:FIELD{name="Profession" title="Profession" value=""}%
%META:FIELD{name="Country" title="[[System.CountryList][Country]]" value=""}%
%META:FIELD{name="State" title="State" value=""}%
%META:FIELD{name="Address" title="Address" value=""}%
%META:FIELD{name="Location" title="Location" value=""}%
%META:FIELD{name="Telephone" title="Telephone" value=""}%
%META:FIELD{name="VoIP" title="<nop>VoIP" value=""}%
%META:FIELD{name="InstantMessagingIM" title="<nop>InstantMessaging (IM)" value=""}%
%META:FIELD{name="Email" title="Email" value=""}%
%META:FIELD{name="HomePage" title="<nop>HomePage" value=""}%
%META:FIELD{name="Comment" title="Comment" value=""}%
27 changes: 20 additions & 7 deletions core/lib/Foswiki/UI/Register.pm
Expand Up @@ -400,10 +400,20 @@ sub bulkRegister {
#-- Read the topic containing the table of people to be registered
my $meta = Foswiki::Meta->load( $session, $web, $topic );

unless ( $meta->getLoadedRev() ) {
throw Foswiki::OopsException(
'register',
def => 'bulk_reg_topic_missing',
web => $web,
topic => $topic,
params => ["!$web.$topic"]
);
}

my @fields;
my @data;
my $gotHdr = 0;
foreach my $line ( split( /\r?\n/, $meta->text ) ) {
foreach my $line ( split( /\r?\n/, $meta->text() ) ) {

# unchecked implicit untaint OK - this function is for admins only
if ( $line =~ m/^\s*\|\s*(.*?)\s*\|\s*$/ ) {
Expand Down Expand Up @@ -441,6 +451,7 @@ sub bulkRegister {
$row->{webName} = $userweb;

unless ( $row->{WikiName} ) {
$row->{WikiName} |= '';
$row->{errors} .= " Not registered: WikiName not entered.";
$row->{FAIL} = 1;
$log .= "---++ Failed to register user on row $n: no !WikiName\n";
Expand All @@ -462,8 +473,6 @@ sub bulkRegister {
}
}

#$row->{LoginName} = $row->{WikiName} unless $row->{LoginName};

$log .= _registerSingleBulkUser( $session, \@fields, $row, $settings );
$genReset = 1 unless ( $row->{Password} || $row->{FAIL} );
}
Expand Down Expand Up @@ -608,12 +617,13 @@ sub _registerSingleBulkUser {
}
catch Error with {
my $e = shift;
$row->{errors} = " Failed to create user topic! " . $e->{def};
$row->{FAIL} = 1;
$row->{errors} =
" Failed to create user topic! " . ( $e->{def} || 'unknown error' );
$row->{FAIL} = 1;
$log .= "$b1 Failed to add user: " . $e->stringify() . "\n";
};

if ( $cUID && $row->{AddToGroups} ) {
if ( $cUID && $row->{AddToGroups} && !$row->{FAIL} ) {
my @addedTo;
foreach my $groupName ( split( /\s*,\s*/, $row->{AddToGroups} ) ) {
try {
Expand Down Expand Up @@ -1541,7 +1551,10 @@ sub _populateUserTopicForm {
}
my $leftoverText = '';
foreach my $fd ( sort { $a->{name} cmp $b->{name} } @{ $data->{form} } ) {
unless ( $inform{ $fd->{name} } || $SKIPKEYS{ $fd->{name} } ) {
unless ( $inform{ $fd->{name} }
|| $SKIPKEYS{ $fd->{name} }
|| !defined $fd->{value} )
{
$leftoverText .= " * $fd->{name}: $fd->{value}\n";
}
}
Expand Down
7 changes: 7 additions & 0 deletions core/templates/registermessages.tmpl
Expand Up @@ -453,6 +453,13 @@

%MAKETEXT{"See %MAINWEB%.WikiGroups to see the result."}%%TMPL:END%
%{==============================================================================}%
%TMPL:DEF{"bulk_reg_topic_missing"}%
---+++ %MAKETEXT{"Requested bulk registration topic not found."}%

%MAKETEXT{"[_1] topic not found. No users registered." args="%PARAM1%"}%

%MAKETEXT{"Please go back in your browser and try again."}%
%{==============================================================================}%
%TMPL:DEF{"bulkreg_pwreset_form"}%
<form action='%SCRIPTURLPATH{"manage"}%/%BASEWEB%/%BASETOPIC%' method='post' />
<input type="hidden" name="action" value="resetPassword" />
Expand Down

0 comments on commit 2583081

Please sign in to comment.