[freeside-commits] branch master updated. 7efd35e863da5de4bbfcad24ad73da7ec7385f62

Ivan ivan at 420.am
Mon Jul 20 19:09:35 PDT 2015


The branch, master has been updated
       via  7efd35e863da5de4bbfcad24ad73da7ec7385f62 (commit)
       via  6419542b10f8ebb0dada9dcb1a48cf78151ca82a (commit)
      from  86b44a7897af8265bcd87603fbf2632489ca10b8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7efd35e863da5de4bbfcad24ad73da7ec7385f62
Merge: 6419542 86b44a7
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Jul 20 19:09:28 2015 -0700

    Merge branch 'master' of git.freeside.biz:/home/git/freeside


commit 6419542b10f8ebb0dada9dcb1a48cf78151ca82a
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Jul 20 19:09:17 2015 -0700

    contact self-service pw changes, RT#37023

diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 420ed06..824ff67 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -50,7 +50,9 @@ use FS::cust_contact;
 use FS::cust_location;
 use FS::cust_payby;
 
-use FS::ClientAPI::MyAccount::quotation; # just for code organization
+# for code organization
+use FS::ClientAPI::MyAccount::contact;
+use FS::ClientAPI::MyAccount::quotation;
 
 $DEBUG = 0;
 $me = '[FS::ClientAPI::MyAccount]';
@@ -243,6 +245,8 @@ sub login {
     return { error => 'Incorrect contact password.' }
       unless $contact->authenticate_password($p->{'password'});
 
+    $session->{'contactnum'} = $contact->contactnum;
+
     my @cust_contact = grep $_->selfservice_access, $contact->cust_contact;
     if ( scalar(@cust_contact) == 1 ) {
       $session->{'custnum'} = $cust_contact[0]->custnum;
@@ -3002,53 +3006,6 @@ sub myaccount_passwd {
 
 }
 
-#  sub contact_passwd {
-#    my $p = shift;
-#    my($context, $session, $custnum) = _custoragent_session_custnum($p);
-#    return { 'error' => $session } if $context eq 'error';
-#  
-#    return { 'error' => 'Not logged in as a contact.' }
-#      unless $session->{'contactnum'};
-#  
-#    return { 'error' => "New passwords don't match." }
-#      if $p->{'new_password'} ne $p->{'new_password2'};
-#  
-#    return { 'error' => 'Enter new password' }
-#      unless length($p->{'new_password'});
-#  
-#    #my $search = { 'custnum' => $custnum };
-#    #$search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
-#    $custnum =~ /^(\d+)$/ or die "illegal custnum";
-#    my $search = " AND selfservice_access IS NOT NULL ".
-#                 " AND selfservice_access = 'Y' ".
-#                 " AND ( disabled IS NULL OR disabled = '' )".
-#                 " AND custnum IS NOT NULL AND custnum = $1";
-#    $search .= " AND agentnum = ". $session->{'agentnum'} if $context eq 'agent';
-#  
-#    my $contact = qsearchs( {
-#      'table'     => 'contact',
-#      'addl_from' => 'LEFT JOIN cust_main USING ( custnum ) ',
-#      'hashref'   => { 'contactnum' => $session->{'contactnum'}, },
-#      'extra_sql' => $search, #important
-#    } )
-#      or return { 'error' => "Email not found" }; #?  how did we get logged in?
-#                                                  # deleted since then?
-#  
-#    my $error = '';
-#  
-#    # use these svc_acct length restrictions??
-#    my $conf = new FS::Conf;
-#    $error = 'Password too short.'
-#      if length($p->{'new_password'}) < ($conf->config('passwordmin') || 6);
-#    $error = 'Password too long.'
-#      if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8);
-#  
-#    $error ||= $contact->change_password($p->{'new_password'});
-#  
-#    return { 'error' => $error, };
-#  
-#  }
-
 sub reset_passwd {
   my $p = shift;
 
diff --git a/FS/FS/ClientAPI/MyAccount/contact.pm b/FS/FS/ClientAPI/MyAccount/contact.pm
new file mode 100644
index 0000000..72226e2
--- /dev/null
+++ b/FS/FS/ClientAPI/MyAccount/contact.pm
@@ -0,0 +1,148 @@
+package FS::ClientAPI::MyAccount::contact;
+
+use strict;
+use FS::Record qw( qsearchs );
+use FS::cust_main;
+use FS::cust_contact;
+use FS::contact;
+
+sub _custoragent_session_custnum {
+  FS::ClientAPI::MyAccount::_custoragent_session_custnum(@_);
+}
+
+sub contact_passwd {
+  my $p = shift;
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  return { 'error' => 'Not logged in as a contact.' }
+    unless $session->{'contactnum'};
+
+  return { 'error' => 'Enter new password' }
+    unless length($p->{'new_password'});
+
+  my $contact = _contact( $session->{'contactnum'}, $custnum )
+    or return { 'error' => "Email not found" };
+
+  my $error = '';
+
+  # use these svc_acct length restrictions??
+  my $conf = new FS::Conf;
+  $error = 'Password too short.'
+    if length($p->{'new_password'}) < ($conf->config('passwordmin') || 6);
+  $error = 'Password too long.'
+    if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8);
+
+  $error ||= $contact->change_password($p->{'new_password'});
+
+  return { 'error' => $error };
+
+}
+
+sub _contact {
+  my( $contactnum, $custnum ) = @_;
+
+  #my $search = { 'custnum' => $custnum };
+  #$search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
+  $custnum =~ /^(\d+)$/ or die "illegal custnum";
+  my $search = " AND cust_contact.selfservice_access IS NOT NULL ".
+               " AND cust_contact.selfservice_access = 'Y' ".
+               " AND ( disabled IS NULL OR disabled = '' )".
+               " AND cust_contact.custnum IS NOT NULL AND cust_contact.custnum = $1";
+#  $search .= " AND agentnum = ". $session->{'agentnum'} if $context eq 'agent';
+
+  qsearchs( {
+    'table'     => 'contact',
+    #'addl_from' => 'LEFT JOIN cust_main USING ( custnum ) ',
+    'addl_from' => ' LEFT JOIN cust_contact USING ( contactnum ) '.
+                   ' LEFT JOIN cust_main ON ( cust_contact.custnum = cust_main.custnum ) ',
+    'hashref'   => { 'contactnum' => $contactnum, },
+    'extra_sql' => $search, #important
+  } );
+
+}
+
+sub list_contacts {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  my $cust_main = qsearchs('cust_main', { custnum=>$custnum } );
+
+  my @contacts = ( map {
+    my $contact = $_->contact;
+    my @contact_email = $contact->contact_email;
+    { 'contactnum'         => $contact->contactnum,
+      'class'              => $_->contact_classname,
+      'first'              => $contact->first,
+      'last'               => $contact->get('last'),
+      'title'              => $contact->title,
+      'emailaddress'       => join(',', map $_->emailaddress, @contact_email),
+      #TODO: contact phone numbers
+      'comment'            => $_->comment,
+      'selfservice_access' => $_->selfservice_access,
+      'disabled'           => $contact->disabled,
+    };
+  } $cust_main->cust_contact );
+
+  return { 'error'    => '',
+           'contacts' => \@contacts,
+         };
+}
+
+sub edit_contact {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  #shortcut: logged in as a contact?  that must be the one you want to edit
+  my $contactnum = $p->{contactnum} || $session->{'contactnum'};
+
+  my $contact = _contact( $contactnum, $custnum )
+    or return { 'error' => "Email not found" };
+
+  return { error => "Can't edit a multi-customer contact unless logged in as that contact" }
+    if $contactnum != $session->{'contactnum'}
+    && scalar( $contact->cust_contact ) > 1;
+
+  #my $cust_contact = qsearchs('cust_contact', { contactnum => $contactnum,
+  #                                              custnum    => $custnum,    } )
+  #  or die "guru meditation #4200";
+
+  #TODO: change more fields besides just these
+
+  foreach (qw( first last title emailaddress )) {
+    $contact->$_( $p->{$_} ) if length( $p->{$_} );
+  }
+
+  my $error = $contact->replace;
+
+  return { 'error' => $error, };
+
+}
+
+sub delete_contact {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  my $cust_contact = qsearchs('cust_contact', { contactnum => $p->{contactnum},
+                                                custnum    => $custnum,       })
+    or return { 'error' => 'Unknown contactnum' };
+
+  my $contact = $cust_contact->contact;
+
+  my $error = $cust_contact->delete;
+  return { 'error' => $error } if $error;
+
+  unless ( $contact->cust_contact ) {
+    $contact->delete;
+  }
+
+  return { 'error' => '', };
+}
+
+1;
diff --git a/FS/FS/ClientAPI_XMLRPC.pm b/FS/FS/ClientAPI_XMLRPC.pm
index 04aee29..8f02b09 100644
--- a/FS/FS/ClientAPI_XMLRPC.pm
+++ b/FS/FS/ClientAPI_XMLRPC.pm
@@ -106,6 +106,12 @@ sub ss2clientapi {
   'switch_cust'               => 'MyAccount/switch_cust',
   'customer_info'             => 'MyAccount/customer_info',
   'customer_info_short'       => 'MyAccount/customer_info_short',
+
+  'contact_passwd'            => 'MyAccount/contact/contact_passwd',
+  'list_contacts'             => 'MyAccount/contact/list_contacts',
+  'edit_contact'              => 'MyAccount/contact/edit_contact',
+  'delete_contact'            => 'MyAccount/contact/delete_contact',
+
   'billing_history'           => 'MyAccount/billing_history',
   'edit_info'                 => 'MyAccount/edit_info',     #add to ss cgi!
   'invoice'                   => 'MyAccount/invoice',
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 899270b..5b73b72 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -39,6 +39,8 @@ FS/ClientAPI/passwd.pm
 FS/ClientAPI/Agent.pm
 FS/ClientAPI/MasonComponent.pm
 FS/ClientAPI/MyAccount.pm
+FS/ClientAPI/MyAccount/contact.pm
+FS/ClientAPI/MyAccount/quotation.pm
 FS/ClientAPI/PrepaidPhone.pm
 FS/ClientAPI/Signup.pm
 FS/Conf.pm
diff --git a/bin/xmlrpc-contact_passwd b/bin/xmlrpc-contact_passwd
new file mode 100755
index 0000000..1a89d42
--- /dev/null
+++ b/bin/xmlrpc-contact_passwd
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use strict;
+use Frontier::Client;
+use Data::Dumper;
+
+my( $email, $current_pw, $new_pw ) = @ARGV;
+
+my $uri = new URI 'http://localhost:8080/';
+
+my $server = new Frontier::Client ( 'url' => $uri );
+
+my $login_result = $server->call(
+  'FS.ClientAPI_XMLRPC.login',
+    'email'    => $email,
+    'password' => $current_pw,
+);
+die $login_result->{'error'}."\n" if $login_result->{'error'};
+
+my $passwd_result = $server->call(
+  'FS.ClientAPI_XMLRPC.contact_passwd',
+    'session_id'   => $login_result->{'session_id'},
+    'new_password' => $new_pw,
+);
+die $passwd_result->{'error'}."\n" if $passwd_result->{'error'};
+
+warn "Password changed.\n";
+
+1;
diff --git a/bin/xmlrpc-edit_contact b/bin/xmlrpc-edit_contact
new file mode 100755
index 0000000..574284b
--- /dev/null
+++ b/bin/xmlrpc-edit_contact
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+
+use strict;
+use Frontier::Client;
+use Data::Dumper;
+
+my( $email, $password, $new_email ) = @ARGV;
+
+my $uri = new URI 'http://localhost:8080/';
+
+my $server = new Frontier::Client ( 'url' => $uri );
+
+my $login_result = $server->call(
+  'FS.ClientAPI_XMLRPC.login',
+    'email'    => $email,
+    'password' => $password,
+);
+die $login_result->{'error'}."\n" if $login_result->{'error'};
+
+my $passwd_result = $server->call(
+  'FS.ClientAPI_XMLRPC.edit_contact',
+    'session_id'   => $login_result->{'session_id'},
+    'emailaddress' => $new_email,
+);
+die $passwd_result->{'error'}."\n" if $passwd_result->{'error'};
+
+warn "Email changed.\n";
+
+1;
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index 847222d..0b65417 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -33,6 +33,12 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'switch_cust'               => 'MyAccount/switch_cust',
   'customer_info'             => 'MyAccount/customer_info',
   'customer_info_short'       => 'MyAccount/customer_info_short',
+
+  'contact_passwd'            => 'MyAccount/contact/contact_passwd',
+  'list_contacts'             => 'MyAccount/contact/list_contacts',
+  'edit_contact'              => 'MyAccount/contact/edit_contact',
+  'delete_contact'            => 'MyAccount/contact/delete_contact',
+
   'billing_history'           => 'MyAccount/billing_history',
   'edit_info'                 => 'MyAccount/edit_info',     #add to ss cgi!
   'invoice'                   => 'MyAccount/invoice',
@@ -531,7 +537,7 @@ Invoice text
 
 =item list_invoices HASHREF
 
-Returns a list of all customer invoices.  Takes a hash references with a single
+Returns a list of all customer invoices.  Takes a hash reference with a single
 key, session_id.
 
 Returns a hash reference with the following keys:
@@ -1219,7 +1225,7 @@ error message on errors.
 
 Provisions an account (svc_acct).
 
-Takes a hash references as parameter with the following keys:
+Takes a hash reference as parameter with the following keys:
 
 =over 4
 
@@ -1247,7 +1253,7 @@ svcpart or service definition to provision
 
 Provisions a phone number (svc_phone).
 
-Takes a hash references as parameter with the following keys:
+Takes a hash reference as parameter with the following keys:
 
 =over 4
 
@@ -1289,7 +1295,7 @@ E911 Address (optional)
 
 Provisions a customer PBX (svc_pbx).
 
-Takes a hash references as parameter with the following keys:
+Takes a hash reference as parameter with the following keys:
 
 =over 4
 
@@ -1321,7 +1327,7 @@ svcpart or service definition to provision
 
 Provisions an external service (svc_external).
 
-Takes a hash references as parameter with the following keys:
+Takes a hash reference as parameter with the following keys:
 
 =over 4
 
@@ -1345,6 +1351,57 @@ svcpart or service definition to provision
 
 =back
 
+=head2 "MY ACCOUNT" CONTACT FUNCTIONS
+
+=over 4
+
+=item contact_passwd
+
+Changes the password for the currently-logged in contact.
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item new_password
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=item list_contacts
+
+=item edit_contact
+
+Updates information for the currently-logged in contact, or (optionally) the
+specified contact
+
+Takes a hash reference as parameter with the following keys:
+
+=over 4
+
+=item session_id
+
+=item contactnum
+
+If already logged in as a contact, this is optional.
+
+=item first
+
+=item last
+
+=item emailaddress
+
+=back
+
+Returns a hash reference with a single parameter, B<error>, which contains an
+error message, or empty on success.
+
+=item delete_contact
+
 =head2 "MY ACCOUNT" QUOTATION FUNCTIONS
 
 All of these functions require the user to be logged in, and the 'session_id'
@@ -1357,12 +1414,33 @@ key to be included in the argument hashref.`
 Returns a hashref listing this customer's active self-service quotations.
 Contents are:
 
-- 'quotations', an arrayref containing an element for each quotation.
-  - quotationnum, the primary key
-  - _date, the date it was started
-  - num_pkgs, the number of packages
-  - total_setup, the sum of setup fees
-  - total_recur, the sum of recurring charges
+=over 4
+
+=item quotations
+
+an arrayref containing an element for each quotation.
+
+=item quotationnum
+
+the primary key
+
+=item _date
+
+the date it was started
+
+=item num_pkgs
+
+the number of packages
+
+=item total_setup
+
+the sum of setup fees
+
+=item total_recur
+
+the sum of recurring charges
+
+=back
 
 =item quotation_new HASHREF
 

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

Summary of changes:
 FS/FS/ClientAPI/MyAccount.pm                 |   53 +--------
 FS/FS/ClientAPI/MyAccount/contact.pm         |  148 ++++++++++++++++++++++++++
 FS/FS/ClientAPI_XMLRPC.pm                    |    6 ++
 FS/MANIFEST                                  |    2 +
 bin/xmlrpc-contact_passwd                    |   29 +++++
 bin/xmlrpc-edit_contact                      |   29 +++++
 fs_selfservice/FS-SelfService/SelfService.pm |  100 +++++++++++++++--
 7 files changed, 308 insertions(+), 59 deletions(-)
 create mode 100644 FS/FS/ClientAPI/MyAccount/contact.pm
 create mode 100755 bin/xmlrpc-contact_passwd
 create mode 100755 bin/xmlrpc-edit_contact




More information about the freeside-commits mailing list