[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.3-51-g9090f4b32

? sunnavy sunnavy at bestpractical.com
Fri Sep 28 17:32:49 EDT 2018


The branch, 4.4-trunk has been updated
       via  9090f4b322d9c7e7fbf2eae73b90ae61f173585b (commit)
       via  3a72f6ea87341da3251dccf8c49d6780c47bc35c (commit)
       via  c909bd1a4ceb034b4baa4341118005ec0cf505d2 (commit)
       via  5dd6043ffc8d8eb07c77777e4d8038e04062b675 (commit)
       via  7465813765407a4e0c72e5d3456574456239d852 (commit)
       via  3c5f6c30408f0afa856598e4478c97183b8972f1 (commit)
      from  ade968bfd5ef25ad8a986fef336b8d1d148b9633 (commit)

Summary of changes:
 etc/RT_Config.pm.in                                |  48 +++++++
 share/html/Elements/Tabs                           |   3 +-
 share/html/Prefs/AboutMe.html                      | 147 +-------------------
 .../Prefs/{AboutMe.html => Elements/EditAboutMe}   | 138 ++----------------
 share/html/Prefs/Elements/ShowAboutMe              | 154 +++++++++++++++++++++
 .../Elements/RequestUpdate}                        |  63 +++++----
 share/html/SelfService/Prefs.html                  |  95 ++++++++-----
 t/web/self_service.t                               |  40 +++++-
 8 files changed, 355 insertions(+), 333 deletions(-)
 copy share/html/Prefs/{AboutMe.html => Elements/EditAboutMe} (70%)
 create mode 100644 share/html/Prefs/Elements/ShowAboutMe
 copy share/html/{Ticket/Elements/DelayShowHistory => SelfService/Elements/RequestUpdate} (60%)

- Log -----------------------------------------------------------------
commit 7465813765407a4e0c72e5d3456574456239d852
Author: Maureen E. Mirville <maureen at bestpractical.com>
Date:   Wed May 9 10:46:03 2018 -0400

    Allow self service users varied access to their stored RT user information
    
    The self service user preferences page now has configurable displays
    using the config option, $SelfServiceUserPrefs. The default display,
    'edit-prefs', remains the same (user can update locale and password).
    The full access viewing option, 'view-info', allows the user to view
    all of their stored RT information (read only). The full access
    editing option, 'full-edit', allows users to make updates to all of
    their RT information. The 'edit-prefs-view-info' option allows
    selfservice users the option to both update their locale and password,
    and also view all of their stored RT information in a read only format.

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 6fe7bc7a2..f705f3e20 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1798,6 +1798,42 @@ access ticked displays.
 
 Set($SelfServiceRegex, qr!^(?:/+SelfService/)!x );
 
+=item C<$SelfServiceUserPrefs>
+
+This option controls how the SelfService user preferences page is
+displayed. It accepts a string from one of the four possible modes
+below.
+
+=over
+
+=item C<edit-prefs> (the default)
+
+When set to C<edit-prefs>, self service users will be able to update
+their Timezone and Language preference and update their password.
+This is the default behavior of RT.
+
+=item C<view-info>
+
+When set to C<view-info>, users will have full access to all their
+user information stored in RT on a read-only page.
+
+=item C<edit-prefs-view-info>
+
+When set to C<edit-prefs-view-info>, users will have full access as in
+the C<view-info> option, but also will be able to update their Locale
+and password as in the default C<edit-prefs> option.
+
+=item C<full-edit>
+
+When set to C<full-edit>, users will be able to fully view and update
+all of their stored RT user information.
+
+=back
+
+=cut
+
+Set($SelfServiceUserPrefs, 'edit-prefs');
+
 =back
 
 =head2 Articles
diff --git a/share/html/Prefs/AboutMe.html b/share/html/Prefs/AboutMe.html
index 7eaf36755..4082396c6 100644
--- a/share/html/Prefs/AboutMe.html
+++ b/share/html/Prefs/AboutMe.html
@@ -50,152 +50,7 @@
 
 <& /Elements/ListActions, actions => \@results &>
 
-<form action="<%RT->Config->Get('WebPath')%>/Prefs/AboutMe.html" method="post">
-<input type="hidden" class="hidden" name="id" value="<%$UserObj->Id%>" />
-
-<table width="100%" border="0">
-<tr>
-
-<td valign="top" class="boxcontainer">
-<&| /Widgets/TitleBox, title => loc('Identity'), id => "user-prefs-identity" &>
-
-<input type="hidden" class="hidden" name="Name" value="<%$UserObj->Name%>" />
-<table cellspacing="0" cellpadding="0">
-  <tr>
-    <td class="label"><&|/l&>Email</&>: </td>
-    <td class="value"><input name="EmailAddress" value="<%$UserObj->EmailAddress%>" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Real Name</&>:</td>
-    <td class="value"><input name="RealName" value="<%$UserObj->RealName%>" /></td>  </tr>
-  <tr>
-    <td class="label"><&|/l&>Nickname</&>:</td>
-    <td class="value"><input name="NickName" value="<%$UserObj->NickName || ''%>" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Language</&>:</td>
-    <td class="value"><& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang &></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Timezone</&>:</td>
-    <td class="value"><& /Elements/SelectTimezone, Name => 'Timezone', Default => $UserObj->Timezone &></td>
-  </tr>
-<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Identity', InTable => 1 &>
-</table>
-</&>
-<&| /Widgets/TitleBox, title => loc('Phone numbers'), id => "user-prefs-phone" &>
-<table cellspacing="0" cellpadding="0">
-  <tr>
-    <td class="label"><&|/l&>Residence</&>:</td>
-    <td class="value"><input name="HomePhone" value="<%$UserObj->HomePhone || ''%>" size="13" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Work</&>:</td>
-    <td class="value"><input name="WorkPhone" value="<%$UserObj->WorkPhone || ''%>" size="13" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Mobile</&>:</td>
-    <td class="value"><input name="MobilePhone" value="<%$UserObj->MobilePhone || ''%>" size="13" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Pager</&>:</td>
-    <td class="value"><input name="PagerPhone" value="<%$UserObj->PagerPhone || ''%>" size="13" /></td>
-  </tr>
-<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Phones', InTable => 1 &>
-</table>
-</&>
-
-%if ($UserObj->Privileged) {
-<&| /Widgets/TitleBox, title => loc('Signature'), id => "user-prefs-signature" &>
-<textarea cols="80" rows="5" name="Signature" class="signature" wrap="hard">
-<%$UserObj->Signature || ''%></textarea>
-</&>
-% }
-
-% $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormLeftColumn' );
-</td>
-<td valign="top" class="boxcontainer">
-
-<&| /Widgets/TitleBox, title => loc('Access control'), id => "user-prefs-password" &>
-% if ( $UserObj->__Value('Password') ne '*NO-PASSWORD*' ) {
-<& /Elements/EditPassword,
-    User => $UserObj,
-    Name => [qw(CurrentPass Pass1 Pass2)],
-&>
-% }
-
-<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Access control' &>
-
-</&>
-
-<&| /Widgets/TitleBox, title => loc('Location'), id => "user-prefs-location" &>
-<table cellspacing="0" cellpadding="0">
-  <tr>
-    <td class="label"><&|/l&>Organization</&>:</td>
-    <td class="value"><input name="Organization" value="<%$UserObj->Organization || ''%>" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Address1</&>:</td>
-    <td class="value"><input name="Address1" value="<%$UserObj->Address1 || ''%>" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Address2</&>:</td>
-    <td class="value"><input name="Address2" value="<%$UserObj->Address2 || ''%>" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>City</&>:</td>
-    <td><input name="City" value="<%$UserObj->City || ''%>" size="14" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>State</&>:</td>
-    <td class="value"><input name="State" value="<%$UserObj->State || ''%>" size="3" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Zip</&>:</td>
-    <td class="value"><input name="Zip" value="<%$UserObj->Zip || ''%>" size="9" /></td>
-  </tr>
-  <tr>
-    <td class="label"><&|/l&>Country</&>:</td>
-    <td class="value"><input name="Country" value="<%$UserObj->Country || ''%>" /></td>
-  </tr>
-<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Location', InTable => 1 &>
-</table>
-</&>
-
-
-
-<& /Elements/EditCustomFieldCustomGroupings, Object => $UserObj &>
-
-
-
-<& /Elements/Submit, Label => loc('Save Preferences') &>
-
-<&| /Widgets/TitleBox, title => loc('Secret authentication token'), id => "user-prefs-feeds" &>
-
-<&|/l&>All iCal feeds embed a secret token which authorizes you.  If the URL for one of your iCal feeds was exposed to the outside world, you can get a new secret, <b>breaking all existing iCal feeds</b>, below.</&>
-
-<a href="#" id="ResetAuthTokenPrompt" style="display: none">
-  <&|/l&>I want to reset my secret token.</&>
-</a>
-<& /Elements/Submit,
-    Label       => loc('Reset secret authentication token'),
-    Name        => "ResetAuthToken",
-    id          => "ResetAuthTokenContainer" &>
-<script>
-    jQuery("#ResetAuthTokenContainer").hide();
-    jQuery("#ResetAuthTokenPrompt").show().click(function(ev){
-        jQuery(this).slideUp();
-        jQuery("#ResetAuthTokenContainer").slideDown();
-        ev.preventDefault();
-    });
-</script>
-</&>
-
-% $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormRightColumn' );
-</td>
-</tr>
-
-</table>
+<& Elements/EditAboutMe, UserObj => $UserObj, PasswordName => [ qw(CurrentPass Pass1 Pass2) ] &>
 
 % $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormEnd' );
 
diff --git a/share/html/Prefs/AboutMe.html b/share/html/Prefs/Elements/EditAboutMe
similarity index 70%
copy from share/html/Prefs/AboutMe.html
copy to share/html/Prefs/Elements/EditAboutMe
index 7eaf36755..603b46cbb 100644
--- a/share/html/Prefs/AboutMe.html
+++ b/share/html/Prefs/Elements/EditAboutMe
@@ -45,20 +45,14 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title=>loc("Preferences") &>
-<& /Elements/Tabs &>
 
-<& /Elements/ListActions, actions => \@results &>
-
-<form action="<%RT->Config->Get('WebPath')%>/Prefs/AboutMe.html" method="post">
+<form name="EditAboutMe" action="" method="post">
 <input type="hidden" class="hidden" name="id" value="<%$UserObj->Id%>" />
 
 <table width="100%" border="0">
 <tr>
-
 <td valign="top" class="boxcontainer">
 <&| /Widgets/TitleBox, title => loc('Identity'), id => "user-prefs-identity" &>
-
 <input type="hidden" class="hidden" name="Name" value="<%$UserObj->Name%>" />
 <table cellspacing="0" cellpadding="0">
   <tr>
@@ -104,7 +98,6 @@
 <& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Phones', InTable => 1 &>
 </table>
 </&>
-
 %if ($UserObj->Privileged) {
 <&| /Widgets/TitleBox, title => loc('Signature'), id => "user-prefs-signature" &>
 <textarea cols="80" rows="5" name="Signature" class="signature" wrap="hard">
@@ -113,26 +106,29 @@
 % }
 
 % $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormLeftColumn' );
+
 </td>
 <td valign="top" class="boxcontainer">
-
-<&| /Widgets/TitleBox, title => loc('Access control'), id => "user-prefs-password" &>
+<&| /Widgets/TitleBox, title => loc( $AccessControlName ), id => "user-prefs-password" &>
 % if ( $UserObj->__Value('Password') ne '*NO-PASSWORD*' ) {
 <& /Elements/EditPassword,
     User => $UserObj,
-    Name => [qw(CurrentPass Pass1 Pass2)],
+    Name => $PasswordName,
 &>
 % }
-
 <& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Access control' &>
-
 </&>
 
+%my $AdminUser = $session{'CurrentUser'}->HasRight( Object => RT->System, Right => 'AdminUsers' );
 <&| /Widgets/TitleBox, title => loc('Location'), id => "user-prefs-location" &>
 <table cellspacing="0" cellpadding="0">
   <tr>
     <td class="label"><&|/l&>Organization</&>:</td>
+%if ( $AdminUser ) {
     <td class="value"><input name="Organization" value="<%$UserObj->Organization || ''%>" /></td>
+%} else {
+    <td class="value"><%$UserObj->Organization || ''%></td>
+%}
   </tr>
   <tr>
     <td class="label"><&|/l&>Address1</&>:</td>
@@ -161,15 +157,11 @@
 <& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Location', InTable => 1 &>
 </table>
 </&>
-
-
-
 <& /Elements/EditCustomFieldCustomGroupings, Object => $UserObj &>
 
-
-
 <& /Elements/Submit, Label => loc('Save Preferences') &>
 
+%if ( $AdminUser ) {
 <&| /Widgets/TitleBox, title => loc('Secret authentication token'), id => "user-prefs-feeds" &>
 
 <&|/l&>All iCal feeds embed a secret token which authorizes you.  If the URL for one of your iCal feeds was exposed to the outside world, you can get a new secret, <b>breaking all existing iCal feeds</b>, below.</&>
@@ -190,117 +182,15 @@
     });
 </script>
 </&>
+%}
 
 % $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormRightColumn' );
 </td>
 </tr>
-
 </table>
 
-% $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormEnd' );
-
-</form>
-
-
-<%INIT>
-
-my $UserObj = RT::User->new( $session{'CurrentUser'} );
-$UserObj->Load($id) if $id;
-$UserObj->Load($Name) if $Name && !$UserObj->id;
-unless ( $UserObj->id ) {
-    Abort(loc("Couldn't load user #[_1] or user '[_2]'", $id, $Name))
-        if $id && $Name;
-    Abort(loc("Couldn't load user #[_1]", $id))
-        if $id;
-    Abort(loc("Couldn't load user '[_1]'", $Name))
-        if $Name;
-    Abort(loc("Couldn't load user"));
-}
-$id = $UserObj->id;
-
-my @results;
-
-if ( $ARGS{'ResetAuthToken'} ) {
-    my ($status, $msg) = $UserObj->GenerateAuthToken;
-    push @results, $msg;
-}
-else {
-    my @fields = qw(
-        Name Comments Signature EmailAddress FreeformContactInfo 
-        Organization RealName NickName Lang Gecos HomePhone WorkPhone
-        MobilePhone PagerPhone Address1 Address2 City State Zip Country
-        Timezone
-    );
-
-    $m->callback(
-        CallbackName => 'UpdateLogic',
-        fields       => \@fields,
-        results      => \@results,
-        UserObj      => $UserObj,
-        ARGSRef      => \%ARGS,
-    );
-
-    push @results, UpdateRecordObject (
-        AttributesRef => \@fields,
-        Object => $UserObj,
-        ARGSRef => \%ARGS,
-    );
-
-    push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj );
-
-    # Deal with special fields: Privileged, Enabled, and Password
-    if  ( $SetPrivileged and $Privileged != $UserObj->Privileged ) {
-        my ($code, $msg) = $UserObj->SetPrivileged( $Privileged );
-        push @results, loc('Privileged status: [_1]', loc_fuzzy($msg));
-    }
-
-    my %password_cond = $UserObj->CurrentUserRequireToSetPassword;
-    if (defined $Pass1 && length $Pass1 ) {
-        my ($status, $msg) = $UserObj->SafeSetPassword(
-            Current      => $CurrentPass,
-            New          => $Pass1,
-            Confirmation => $Pass2,
-        );
-        push @results, loc("Password: [_1]", $msg);
-    }
-}
-
-
-MaybeRedirectForResults(
-    Actions   => \@results,
-);
-
-</%INIT>
-
-
 <%ARGS>
-$id => $session{'CurrentUser'}->Id
-$Name  => undef
-$Comments  => undef
-$Signature  => undef
-$EmailAddress  => undef
-$FreeformContactInfo => undef
-$Organization  => undef
-$RealName  => undef
-$NickName  => undef
-$Privileged => undef
-$SetPrivileged => undef
-$Enabled => undef
-$SetEnabled => undef
-$Lang  => undef
-$Gecos => undef
-$HomePhone => undef
-$WorkPhone  => undef
-$MobilePhone  => undef
-$PagerPhone  => undef
-$Address1 => undef
-$Address2  => undef
-$City  => undef
-$State  => undef
-$Zip  => undef
-$Country => undef
-$CurrentPass => undef
-$Pass1 => undef
-$Pass2 => undef
-$Create=> undef
+$UserObj
+$PasswordName
+$AccessControlName => 'Access control'
 </%ARGS>
diff --git a/share/html/Prefs/Elements/ShowAboutMe b/share/html/Prefs/Elements/ShowAboutMe
new file mode 100644
index 000000000..268eb3a5a
--- /dev/null
+++ b/share/html/Prefs/Elements/ShowAboutMe
@@ -0,0 +1,154 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+
+<table width="100%" border="0">
+  <tr>
+    <td valign="top" class="boxcontainer">
+      <&| /Widgets/TitleBox, title => loc('Identity'), id => "user-prefs-identity" &>
+      <input type="hidden" class="hidden" name="Name" value="<%$UserObj->Name%>" />
+      <table cellspacing="0" cellpadding="0">
+        <tr>
+          <td class="label"><&|/l&>Email</&>:</td>
+          <td class="value"><%$UserObj->EmailAddress%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Real Name</&>:</td>
+          <td class="value"><%$UserObj->RealName%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Nickname</&>:</td>
+          <td class="value"><%$UserObj->NickName || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Language</&>:</td>
+% if ( $UserObj->Lang ) {
+          <td class="value"><&|/l, $lang &>[_1]</&></td>
+% } else {
+          <td class="value"><&|/l&>System Default</&></td>
+% }
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Timezone</&>:</td>
+% if ( $UserObj->Timezone ) {
+          <td class="value"><%$UserObj->Timezone%></td>
+% } else {
+          <td class="value"><&|/l&>System Default</&></td>
+% }
+        </tr>
+      <& /Elements/ShowCustomFields, Object => $UserObj, Grouping => 'Identity', InTable => 1 &>
+      </table>
+      </&>
+      <&| /Widgets/TitleBox, title => loc('Phone numbers'), id => "user-prefs-phone" &>
+      <table cellspacing="0" cellpadding="0">
+        <tr>
+          <td class="label"><&|/l&>Residence</&>:</td>
+          <td class="value"><%$UserObj->HomePhone || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Work</&>:</td>
+          <td class="value"><%$UserObj->WorkPhone || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Mobile</&>:</td>
+          <td class="value"><%$UserObj->MobilePhone || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Pager</&>:</td>
+          <td class="value"><%$UserObj->PagerPhone || ''%></td>
+        </tr>
+      <& /Elements/ShowCustomFields, Object => $UserObj, Grouping => 'Phones', InTable => 1 &>
+      </table>
+      </&>
+    </td>
+    <td valign="top" class="boxcontainer">
+      <&| /Widgets/TitleBox, title => loc('Location'), id => "user-prefs-location" &>
+      <table cellspacing="0" cellpadding="0">
+        <tr>
+          <td class="label"><&|/l&>Organization</&>:</td>
+          <td class="value"><%$UserObj->Organization || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Address1</&>:</td>
+          <td class="value"><%$UserObj->Address1 || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Address2</&>:</td>
+          <td class="value"><%$UserObj->Address2 || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>City</&>:</td>
+          <td class="value"><%$UserObj->City || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>State</&>:</td>
+          <td class="value"><%$UserObj->State || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Zip</&>:</td>
+          <td class="value"><%$UserObj->Zip || ''%></td>
+        </tr>
+        <tr>
+          <td class="label"><&|/l&>Country</&>:</td>
+          <td class="value"><%$UserObj->Country || ''%></td>
+        </tr>
+      <& /Elements/ShowCustomFields, Object => $UserObj, Grouping => 'Location', InTable => 1 &>
+      </table>
+      </&>
+      <& /Elements/ShowCustomFieldCustomGroupings, Object => $UserObj &>
+    </td>
+  </tr>
+</table>
+
+<%INIT>
+use I18N::LangTags::List;
+my $lang = I18N::LangTags::List::name( $UserObj->Lang );
+</%INIT>
+
+<%ARGS>
+$UserObj
+</%ARGS>
diff --git a/share/html/SelfService/Prefs.html b/share/html/SelfService/Prefs.html
index 0c6736446..a3c1c8ea8 100644
--- a/share/html/SelfService/Prefs.html
+++ b/share/html/SelfService/Prefs.html
@@ -48,6 +48,10 @@
 <& /SelfService/Elements/Header, Title => loc('Preferences') &>
 
 <& /Elements/ListActions, actions => \@results &>
+% if ( $pref eq 'full-edit' ) {
+<& /Prefs/Elements/EditAboutMe, UserObj => $user, PasswordName => $password, AccessControlName => 'Change Password' &>
+% }
+% if ( $pref eq 'edit-prefs' || $pref eq 'edit-prefs-view-info' ) {
 <form method="post">
 
 <table width="100%" border="0">
@@ -71,7 +75,7 @@
 % if ( $user->__Value('Password') ne '*NO-PASSWORD*' ) {
 <& /Elements/EditPassword,
     User => $user,
-    Name => [qw(CurrentPass NewPass1 NewPass2)],
+    Name => $password,
 &>
 % }
 </&>
@@ -81,46 +85,70 @@
 <& /Elements/Submit, Label => loc('Save Changes') &>
 </form>
 
+% }
+% if ( $pref eq 'view-info' || $pref eq 'edit-prefs-view-info' ) {
+<& /Prefs/Elements/ShowAboutMe, UserObj => $user &>
+% }
 
 <%INIT>
 my @results;
 
 my $user = $session{'CurrentUser'}->UserObj;
+my $password = [ qw(CurrentPass NewPass1 NewPass2) ];
+
+my $pref = RT->Config->Get( 'SelfServiceUserPrefs' ) || '';
+
+if ( $pref eq 'edit-prefs' || $pref eq 'edit-prefs-view-info' || $pref eq 'full-edit' ) {
+
+    if ( defined $NewPass1 && length $NewPass1 ) {
+        my ($status, $msg) = $user->SafeSetPassword(
+            Current      => $CurrentPass,
+            New          => $NewPass1,
+            Confirmation => $NewPass2,
+        );
+        push @results, loc("Password: [_1]", $msg);
+    }
+
+    my @fields;
 
-if (defined $NewPass1 && length $NewPass1 ) {
-    my ($status, $msg) = $user->SafeSetPassword(
-        Current      => $CurrentPass,
-        New          => $NewPass1,
-        Confirmation => $NewPass2,
+    if ( $pref eq 'edit-prefs' || $pref eq 'edit-prefs-view-info' ) {
+        @fields = qw( Lang Timezone );
+    } else {
+        @fields = qw(
+            Name Comments EmailAddress FreeformContactInfo Organization RealName
+            NickName Lang Gecos HomePhone WorkPhone MobilePhone PagerPhone Address1
+            Address2 City State Zip Country Timezone
+        );
+    }
+
+    $m->callback(
+        CallbackName => 'UpdateLogic',
+        fields       => \@fields,
+        results      => \@results,
+        UserObj      => $user,
+        ARGSRef      => \%ARGS,
     );
-    push @results, loc("Password: [_1]", $msg);
-}
 
-my @fields = qw(
-        Lang Timezone
+    push @results, UpdateRecordObject (
+        AttributesRef => \@fields,
+        Object => $user,
+        ARGSRef => \%ARGS,
     );
 
-$m->callback(
-    CallbackName => 'UpdateLogic',
-    fields       => \@fields,
-    results      => \@results,
-    UserObj      => $user,
-    ARGSRef      => \%ARGS,
-);
-
-push @results, UpdateRecordObject (
-    AttributesRef => \@fields,
-    Object => $user,
-    ARGSRef => \%ARGS,
-);
-
-if ( $Lang ) {
-    $session{'CurrentUser'}->LanguageHandle($Lang);
-    $session{'CurrentUser'} = $session{'CurrentUser'}; # force writeback
-}
+    push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $user ) if $pref eq 'full-edit';
+
+    if ( $Lang ) {
+        $session{'CurrentUser'}->LanguageHandle($Lang);
+        $session{'CurrentUser'} = $session{'CurrentUser'}; # force writeback
+    }
 
-#A hack to make sure that session gets rewritten.
-$session{'i'}++;
+    #A hack to make sure that session gets rewritten.
+    $session{'i'}++;
+
+    MaybeRedirectForResults(
+        Actions   => \@results,
+    );
+}
 </%INIT>
 
 <%ARGS>

commit 5dd6043ffc8d8eb07c77777e4d8038e04062b675
Author: Maureen E. Mirville <maureen at bestpractical.com>
Date:   Tue Jun 26 10:16:38 2018 -0400

    Update ModifySelf rights check for Preferences tab in SelfService
    
    With the additional display options added with the SelfServiceUserPrefs
    config, a new condition has also been added to this rights check.
    Now if a user does not have the ModifySelf right, the Preferences
    tab will stil display as long as the SelfServiceUserPrefs config
    is set to 'view-info'.

diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index 40cb43e7c..08b05705d 100644
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -1219,7 +1219,8 @@ my $build_selfservice_nav = sub {
         sort_order   => 99,
     );
 
-    if ( $session{'CurrentUser'}->HasRight( Right => 'ModifySelf', Object => RT->System ) ) {
+    if ( ( RT->Config->Get('SelfServiceUserPrefs') || '' ) eq 'view-info' ||
+       $session{'CurrentUser'}->HasRight( Right => 'ModifySelf', Object => RT->System ) ) {
         $about_me->child( prefs => title => loc('Preferences'), path => '/SelfService/Prefs.html' );
     }
 

commit c909bd1a4ceb034b4baa4341118005ec0cf505d2
Author: Maureen E. Mirville <maureen at bestpractical.com>
Date:   Fri Jun 8 12:05:02 2018 -0400

    Add $SelfServiceUserPrefs config tests to verify SelfService display

diff --git a/t/web/self_service.t b/t/web/self_service.t
index 7afc008c6..abe9f2724 100644
--- a/t/web/self_service.t
+++ b/t/web/self_service.t
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 
 use RT::Test
-  tests  => 17,
+  tests  => undef,
   config => 'Set( $ShowUnreadMessageNotifications, 1 );'
 ;
 
@@ -51,4 +51,42 @@ $m->follow_link_ok(
 $m->content_contains( "<h1>$title</h1>", "contains <h1>$title</h1>" );
 $m->content_lacks( "There are unread messages on this ticket." );
 
+diag 'Test $SelfServiceUserPrefs config';
+{
+  # Verify the $SelfServiceUserPrefs config option renders the correct display at
+  # /SelfService/Prefs.html for each of the available options
+
+  is( RT->Config->Get( 'SelfServiceUserPrefs' ), 'edit-prefs', '$SelfServiceUserPrefs is set to "edit-prefs" by default' );
+
+  for my $config ( 'edit-prefs', 'view-info', 'edit-prefs-view-info', 'full-edit' ) {
+    RT::Test->stop_server;
+    RT->Config->Set( SelfServiceUserPrefs => $config );
+    ( $url, $m ) = RT::Test->started_ok;
+    ok( $m->login('user_a' => 'password'), 'unprivileged user logged in' );
+    $m->get_ok( '/SelfService/Prefs.html');
+
+    if ( $config eq 'edit-prefs' ) {
+      $m->content_lacks( 'Nickname', "'Edit-Prefs' option does not contain full user info" );
+      $m->content_contains( '<td class="value"><input type="password" name="CurrentPass"', "'Edit-Prefs' option contains default user info" );
+    } elsif ( $config eq 'view-info' ) {
+      $m->content_lacks( '<td class="value"><input name="NickName" value="" /></td>', "'View-Info' option contains no input fields for full user info" );
+      $m->content_contains( '<td class="label">Nickname:</td>', "'View-Info' option contains full user info" );
+    } elsif ( $config eq 'edit-prefs-view-info' ) {
+      $m->content_contains( '<td class="value"><input type="password" name="CurrentPass"', "'Edit-Prefs-View-Info' option contains default user info" );
+      $m->content_contains( '<td class="label">Nickname:</td>', "'Edit-Prefs-View-Info' option contains full user info" );
+      $m->content_lacks( '<td class="value"><input name="NickName" value="" /></td>', "'Edit-Prefs-View-Info' option contains no input fields for full user info" );
+    } else {
+      RT::Test->add_rights( { Principal => $user_a, Right => ['ModifySelf'] } );
+      my $nickname = 'user_a_nickname';
+      $m->submit_form_ok({
+        form_name  => 'EditAboutMe',
+        with_fields     => { NickName => $nickname,}
+      }, 'Form submitted');
+      $m->text_contains("NickName changed from (no value) to '$nickname'", "NickName updated");
+    }
+  }
+}
+
 # TODO need more SelfService tests
+
+done_testing();

commit 3a72f6ea87341da3251dccf8c49d6780c47bc35c
Author: Maureen E. Mirville <maureen at bestpractical.com>
Date:   Thu Sep 6 10:36:03 2018 -0400

    Add config to allow SelfService users to request user info updates

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index f705f3e20..4c38d555c 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1834,6 +1834,18 @@ all of their stored RT user information.
 
 Set($SelfServiceUserPrefs, 'edit-prefs');
 
+=item C<$SelfServiceRequestUpdatePortlet>
+
+Set this to 1 to allow Self Service users to request updates to
+their RT user information. When enabled, this portlet adds a quick
+ticket create portlet to the Self Service preferences page. This
+option is only available when $SelfServiceUserPrefs is set to
+'view-info' or 'edit-prefs-view-info'.
+
+=cut
+
+Set($SelfServiceRequestUpdatePortlet, 0);
+
 =back
 
 =head2 Articles
diff --git a/share/html/SelfService/Elements/RequestUpdate b/share/html/SelfService/Elements/RequestUpdate
new file mode 100644
index 000000000..538c417d5
--- /dev/null
+++ b/share/html/SelfService/Elements/RequestUpdate
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="quick-create">
+<&| /Widgets/TitleBox, title => loc('Update my user information request') &>
+<div><&|/l&>Please indicate which user fields you would like updated</&></div>
+<form method="post"
+action="<%RT->Config->Get('WebPath')%><% $r->path_info %>"
+% $m->callback(CallbackName => 'InFormElement');
+>
+    <input type="hidden" class="hidden" name="QuickCreate" value="1" />
+    <table>
+        <tr class="input-row">
+            <td class="label"><&|/l&>Subject</&>:</td>
+            <td colspan="3" class="value"><input type="text" size="50" name="Subject" value="<% $args->{Subject} || '' %>" /></td>
+        </tr>
+        <tr class="input-row">
+            <td class="label"><&|/l&>Queue</&>:</td>
+            <td class="value"><& /Elements/SelectNewTicketQueue, Name => 'Queue', Default => $args->{Queue} &></td>
+        </tr>
+        <tr>
+            <td class="label"><&|/l&>Requestors</&>:</td>
+            <td colspan="3" class="value"><& /Elements/EmailInput, Name => 'Requestors', Size => '40', Default => $args->{Requestors} || $session{CurrentUser}->EmailAddress &></td>
+        </tr>
+        <tr class="input-row">
+            <td class="labeltop"><&|/l&>Description</&>:</td>
+            <td colspan="3" class="value"><textarea name="Content" cols="50" rows="3"><% $args->{Content} || ''%></textarea></td>
+        </tr>
+    </table>
+<& /Elements/Submit, Label => loc('Submit') &>
+</form>
+</&>
+</div>
+
+<%INIT>
+my $args = delete $session{QuickCreate} || {};
+</%INIT>
+
+<%ARGS>
+$User
+</%ARGS>
diff --git a/share/html/SelfService/Prefs.html b/share/html/SelfService/Prefs.html
index a3c1c8ea8..d53c6a8e6 100644
--- a/share/html/SelfService/Prefs.html
+++ b/share/html/SelfService/Prefs.html
@@ -88,6 +88,9 @@
 % }
 % if ( $pref eq 'view-info' || $pref eq 'edit-prefs-view-info' ) {
 <& /Prefs/Elements/ShowAboutMe, UserObj => $user &>
+%    if ( $request_portlet ) {
+<& Elements/RequestUpdate, User=> $user &>
+%    }
 % }
 
 <%INIT>
@@ -97,6 +100,7 @@ my $user = $session{'CurrentUser'}->UserObj;
 my $password = [ qw(CurrentPass NewPass1 NewPass2) ];
 
 my $pref = RT->Config->Get( 'SelfServiceUserPrefs' ) || '';
+my $request_portlet = RT->Config->Get( 'SelfServiceRequestUpdatePortlet' );
 
 if ( $pref eq 'edit-prefs' || $pref eq 'edit-prefs-view-info' || $pref eq 'full-edit' ) {
 
@@ -141,14 +145,20 @@ if ( $pref eq 'edit-prefs' || $pref eq 'edit-prefs-view-info' || $pref eq 'full-
         $session{'CurrentUser'}->LanguageHandle($Lang);
         $session{'CurrentUser'} = $session{'CurrentUser'}; # force writeback
     }
+}
 
-    #A hack to make sure that session gets rewritten.
-    $session{'i'}++;
-
-    MaybeRedirectForResults(
-        Actions   => \@results,
-    );
+if ( $request_portlet ) {
+    my $path = RT->Config->Get('WebPath') . '/SelfService/Prefs.html';
+    push @results, ProcessQuickCreate( Path => $path, ARGSRef => \%ARGS );
 }
+
+#A hack to make sure that session gets rewritten.
+$session{'i'}++;
+
+MaybeRedirectForResults(
+    Actions   => \@results,
+);
+
 </%INIT>
 
 <%ARGS>

commit 9090f4b322d9c7e7fbf2eae73b90ae61f173585b
Merge: ade968bfd 3a72f6ea8
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Sep 29 03:21:14 2018 +0800

    Merge branch '4.4/selfservice-user-info-display-options' into 4.4-trunk


-----------------------------------------------------------------------


More information about the rt-commit mailing list