"Edit password" ACL, #21178, part 2
authorMark Wells <mark@freeside.biz>
Wed, 27 Feb 2013 20:47:34 +0000 (12:47 -0800)
committerMark Wells <mark@freeside.biz>
Wed, 27 Feb 2013 20:47:34 +0000 (12:47 -0800)
13 files changed:
FS/FS/AccessRight.pm
FS/FS/Schema.pm
FS/FS/access_right.pm
FS/FS/part_svc.pm
httemplate/browse/part_svc.cgi
httemplate/edit/part_svc.cgi
httemplate/edit/process/cust_svc.cgi
httemplate/edit/svc_acct.cgi
httemplate/misc/process/change-password.html
httemplate/view/elements/svc_Common.html
httemplate/view/elements/svc_edit_link.html
httemplate/view/svc_acct.cgi
httemplate/view/svc_acct/basics.html

index 50fb0e3..a60d033 100644 (file)
@@ -162,6 +162,7 @@ tie my %rights, 'Tie::IxHash',
     'Recharge customer service', #NEW
     'Unprovision customer service',
     'Change customer service', #NEWNEW
+    'Edit password',
     'Edit usage', #NEW
     'Edit home dir', #NEW
     'Edit www config', #NEW
index 774dcd2..eff4878 100644 (file)
@@ -2112,7 +2112,8 @@ sub tables_hashref {
         'preserve',              'char', 'NULL',         1, '', '',
         'selfservice_access', 'varchar', 'NULL',   $char_d, '', '',
         'classnum',               'int', 'NULL',        '', '', '',
-      ],
+        'restrict_edit_password','char', 'NULL',         1, '', '',
+],
       'primary_key' => 'svcpart',
       'unique' => [],
       'index' => [ [ 'disabled' ] ],
@@ -2260,6 +2261,7 @@ sub tables_hashref {
         'cgp_sendmdnmode',    'varchar', 'NULL', $char_d, '', '',#SendMDNMode
         #mail
         #XXX RPOP settings
+        #
       ],
       'primary_key' => 'svcnum',
       #'unique' => [ [ 'username', 'domsvc' ] ],
index 0c61896..0e8bf45 100644 (file)
@@ -228,7 +228,9 @@ sub _upgrade_data { # class method
                             'Usage: Call Detail Records (CDRs)',
                             'Usage: Unrateable CDRs',
                           ],
-  ;
+    'Provision customer service' => [ 'Edit password' ],
+
+;
 
   foreach my $old_acl ( keys %onetime ) {
 
index c471771..6ca4889 100644 (file)
@@ -58,6 +58,13 @@ L<FS::svc_domain>, and L<FS::svc_forward>, among others.
 
 =item preserve - Preserve after cancellation, empty or 'Y'
 
+=item selfservice_access - Access allowed to the service via self-service:
+empty for full access, "readonly" for read-only, "hidden" to hide it entirely
+
+=item restrict_edit_password - Require the "Provision customer service" access
+right to change the password field, rather than just "Edit password".  Only
+relevant to svc_acct for now.
+
 =back
 
 =head1 METHODS
@@ -391,7 +398,8 @@ sub check {
     || $self->ut_enum('preserve', [ '', 'Y' ] )
     || $self->ut_enum('selfservice_access', [ '', 'hidden', 'readonly' ] )
     || $self->ut_foreign_keyn('classnum', 'part_svc_class', 'classnum' )
-  ;
+    || $self->ut_enum('restrict_edit_password', [ '', 'Y' ] )
+;
   return $error if $error;
 
   my @fields = eval { fields( $self->svcdb ) }; #might die
index a8f4a7c..f941ae5 100755 (executable)
@@ -82,6 +82,7 @@ function part_export_areyousure(href) {
 %            }
 %            @dfields ;
 %     my $rowspan = scalar(@fields) || 1;
+%     $rowspan++ if $part_svc->restrict_edit_password;
 %     my $url = "${p}edit/part_svc.cgi?". $part_svc->svcpart;
 %
 %     if ( $bgcolor eq $bgcolor1 ) {
@@ -183,15 +184,21 @@ function part_export_areyousure(href) {
 % } else { 
 
             <% $value %>
-% } 
+% }
 
      </TD>
 %     $n1="</TR><TR>";
-%     }
-%
+%     } #foreach $field
+%   if ( $part_svc->restrict_edit_password ) {
+   <TR>
+     <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" COLSPAN=4 ALIGN="left">
+      <B><% emt('Password editing restricted.') %></B>
+     </TD>
+   </TR>
+%   }
 
   </TR>
-% } 
+% }  #foreach $part_svc
 
 </TABLE>
 </BODY>
index 007c246..8a84b20 100755 (executable)
 %
 %      } #foreach my $field (@fields) {
 %
+%      if ( $layer eq 'svc_acct' ) {
+%        # eww, more ugly special-caseyness
+%        $html .= 
+%          '<TR><TD COLSPAN=3 ALIGN="right">'.
+%          emt('Require "Provision" access right to edit password').
+%          '</TD><TD>'.
+%          '<INPUT TYPE="checkbox" NAME="restrict_edit_password" VALUE="Y"'.
+%          ($part_svc->restrict_edit_password ? ' CHECKED' : '').
+%          '></TD></TR>';
+%      } else {
+%        $html .= 
+%          '<INPUT TYPE="hidden" NAME="restrict_edit_password" VALUE="">';
+%      }
+%
 %      $part_svc->svcpart('') if $clone; #undone
 %      $html .= "</TABLE>";
 %
 %                         $layer, #form name
 %                         [ qw(svc svcpart classnum selfservice_access
 %                              disabled preserve
-%                              exportnum),
+%                              exportnum restrict_edit_password),
 %                           @fields ],
 %                         'process/part_svc.cgi',
 %                         $p.'browse/part_svc.cgi',
index e22cbb2..7cb1d6d 100644 (file)
@@ -6,7 +6,7 @@
 %}
 <%init>
 
-die 'access deined'
+die 'access denied'
  unless $FS::CurrentUser::CurrentUser->access_right('Change customer service');
 
 my $svcnum = $cgi->param('svcnum');
index c1f7455..627791b 100755 (executable)
@@ -9,19 +9,6 @@
   <BR>
 % } 
 
-<SCRIPT TYPE="text/javascript">
-function randomPass() {
-  var i=0;
-  var pw_set='<% join('', 'a'..'z', 'A'..'Z', '0'..'9' ) %>';
-  var pass='';
-  while(i < 8) {
-    i++;
-    pass += pw_set.charAt(Math.floor(Math.random() * pw_set.length));
-  }
-  document.OneTrueForm.clear_password.value = pass;
-}
-</SCRIPT>
-
 <FORM NAME="OneTrueForm" ACTION="<% $p1 %>process/svc_acct.cgi" METHOD=POST>
 <INPUT TYPE="hidden" NAME="svcnum" VALUE="<% $svcnum %>">
 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
@@ -57,10 +44,11 @@ function randomPass() {
 
 %if ( $part_svc->part_svc_column('_password')->columnflag ne 'F' ) {
 <TR>
+% #XXX eventually should require "Edit Password" ACL
   <TD ALIGN="right"><% mt('Password') |h %></TD>
   <TD>
-    <INPUT TYPE="text" NAME="clear_password" VALUE="<% $password %>" SIZE=<% $pmax2 %> MAXLENGTH=<% $pmax %>>
-    <INPUT TYPE="button" VALUE="<% mt('Generate') |h %>" onclick="randomPass();">
+    <INPUT TYPE="text" ID="clear_password" NAME="clear_password" VALUE="<% $password %>" SIZE=<% $pmax2 %> MAXLENGTH=<% $pmax %>>
+    <& /elements/random_pass.html, 'clear_password' &>
   </TD>
 </TR>
 %}else{
index 7005439..7cab9c4 100644 (file)
@@ -1,11 +1,16 @@
 <%init>
 my $curuser = $FS::CurrentUser::CurrentUser;
-die "access denied" unless $curuser->access_right('Edit password');
 
 $cgi->param('svcnum') =~ /^(\d+)$/ or die "illegal svcnum";
 my $svcnum = $1;
 my $svc_acct = FS::svc_acct->by_key($svcnum)
   or die "svc_acct $svcnum not found";
+my $part_svc = $svc_acct->part_svc;
+die "access denied" unless (
+  $curuser->access_right('Provision customer service') or
+  ( $curuser->access_right('Edit password') and 
+    ! $part_svc->restrict_edit_password )
+  );
 my $error = $svc_acct->set_password($cgi->param('password'))
         ||  $svc_acct->replace;
 
index f7c685c..46b9c28 100644 (file)
@@ -52,7 +52,7 @@ function areyousure(href) {
 
 <% mt('Service #') |h %><B><% $svcnum %></B>
 % my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?';
-<& /view/elements/svc_edit_link.html, 'svc' => $svc_x, 'edit_url' => $url &>
+<& /view/elements/svc_edit_link.html, 'svc' => $svc_x, 'edit_url' => $url &>
 <BR>
 
 <% ntable("#cccccc") %><TR><TD><% ntable("#cccccc",2) %>
index d65db0a..5438ed2 100644 (file)
@@ -7,8 +7,12 @@ function areyousure_delete() {
     window.location.href = '<% $cancel_url %>';
 }
 </SCRIPT>
-<A HREF="<% $edit_url %>"><% mt("Edit this [_1]", $label) |h %></A> | 
-<A HREF="javascript:areyousure_delete()"><% mt('Unprovision this Service') |h %></A>
+%   if ( $curuser->access_right('Provision customer service') ) {
+| <A HREF="<% $edit_url %>"><% mt("Edit this [_1]", $label) |h %></A>
+%   }
+%   if ( $curuser->access_right('Unprovision customer service') ) {
+| <A HREF="javascript:areyousure_delete()"><% mt('Unprovision this Service') |h %></A>
+%   }
 % }
 <%init>
 my %opt = @_;
@@ -20,4 +24,5 @@ my $cancel_url = $p . 'misc/unprovision.cgi?' . $svc_x->svcnum;
 my $cust_svc = $svc_x->cust_svc; # always exists
 my $cancel_date = $cust_svc->pkg_cancel_date;
 my ($label) = $cust_svc->label;
+my $curuser = $FS::CurrentUser::CurrentUser;
 </%init>
index 1995913..76631ba 100755 (executable)
@@ -37,7 +37,6 @@
 &>
 
 <% mt('Service #') |h %><B><% $svcnum %></B>
-|
 <& /view/elements/svc_edit_link.html, 'svc' => $svc_acct &>
 <& svc_acct/change_svc.html,
               'part_svc' => \@part_svc,
@@ -90,8 +89,12 @@ die "access denied"
 my $addl_from = ' LEFT JOIN cust_svc  USING ( svcnum  ) '.
                 ' LEFT JOIN cust_pkg  USING ( pkgnum  ) '.
                 ' LEFT JOIN cust_main USING ( custnum ) ';
-
-my($query) = $cgi->keywords;
+my $query;
+if ( $cgi->keywords ) {
+  ($query) = $cgi->keywords;
+} else {
+  $query = $cgi->param('svcnum');
+}
 $query =~ /^(\d+)$/;
 my $svcnum = $1;
 my $svc_acct = qsearchs({
index 2d9953f..04e7bcf 100644 (file)
@@ -20,7 +20,7 @@
 % if ( $password =~ /^\*\w+\* (.*)$/ ) {
 %   $password = $1;
 %   $show_pw .= '<I>('. mt('login disabled') .')</I> ';
-% } 
+% }
 % if ( ! $password
 %      && $svc_acct->_password_encryption ne 'plain'
 %      && $svc_acct->_password
 % {
 %   $show_pw .= '<I>('. uc($svc_acct->_password_encryption). ' '.mt('encrypted').')</I>';
 % } elsif ( $conf->exists('showpasswords') ) { 
-%   $show_pw .= '<PRE>'. encode_entities($password). '</PRE>';
+%   $show_pw .= '<SPAN >'. encode_entities($password). '</PRE>';
 % } else { 
+%   $password = '';
 %   $show_pw .= '<I>('. mt('hidden') .')</I>';
-% } 
-% $password = ''; 
-<& /view/elements/tr.html, label=>mt('Password'), value=>$show_pw &>
-
+% }
+<TR>
+  <TD ALIGN="right"><% mt('Password') %></TD>
+  <TD STYLE="background-color: #ffffff; white-space: nowrap">
+  <% $show_pw %>
+% my $curuser = $FS::CurrentUser::CurrentUser;
+% if ( $curuser->access_right('Provision customer service') or
+%     ($curuser->access_right('Edit password') and
+%      ! $part_svc->restrict_edit_password) )
+% {
+  <& /elements/change_password.html,
+      'svc_acct'    => $svc_acct,
+      'curr_value'  => $password,
+  &>
+% }
+  </TD>
+</TR>
 
 % if ( $conf->exists('security_phrase') ) {
   <& /view/elements/tr.html, label=>mt('Security phrase'), value=>$svc_acct->sec_phrase &>