From: Ivan Kohler Date: Tue, 21 Jul 2015 02:09:17 +0000 (-0700) Subject: contact self-service pw changes, RT#37023 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=6419542b10f8ebb0dada9dcb1a48cf78151ca82a contact self-service pw changes, RT#37023 --- diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 420ed0688..824ff67cb 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 000000000..72226e2dc --- /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 04aee290b..8f02b0925 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 899270bf2..5b73b728c 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 000000000..1a89d4260 --- /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 000000000..574284bbc --- /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 847222d72..0b65417ed 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, 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, 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