package FS::part_export::aradial; use base qw( FS::part_export ); use LWP::UserAgent; use HTTP::Request; use Tie::IxHash; use XML::LibXML; use URI; use Date::Format 'time2str'; use Data::Dumper; use vars qw( %options %info $me $DEBUG ); use strict; $me = '[FS::part_export::aradial]'; $DEBUG = 2; tie %options, 'Tie::IxHash', 'port' => { label => 'HTTP port', default => 8000 }, 'login' => { label => 'Admin username' }, 'pass' => { label => 'Admin password' }, 'realm' => { label => 'Admin authentication realm' }, 'group' => { label => 'Group name' }, ; %info = ( 'svc' => 'svc_acct', 'desc' => 'Export accounts to Aradial RADIUS HTTP interface', 'options' => \%options, 'nodomain' => 'Y', 'notes' => '
This export maintains user accounts on an Aradial Technologies access control server, via the HTTP interface. The export hostname and the HTTP port option determine the location of the server.
Admin username, password, authentication realm are the settings for the HTTP interface, set in the "Admin Web Interface Security" options for your Aradial server.
Group name is the user group to assign to new users, and must already exist on the Aradial server. Currently this export will assign all users to a single group; if you want multiple groups for different service types, create another export instance.
' ); sub _export_insert { my ($self, $svc) = @_; my $result = $self->request_user_edit( 'Add' => 1, $self->svc_acct_params($svc), 'db_$N$Users.Status' => 0, ); if ($svc->cust_svc->cust_pkg->susp > 0 ) { $result ||= $self->export_suspend($svc); } $result; } sub _export_replace { my ($self, $new, $old) = @_; if ($new->email ne $old->email) { return $old->export_delete || $new->export_insert; } my $Status = 0; $Status = 3 if $new->cust_svc->cust_pkg->susp > 0; $self->request_user_edit( 'Page' => 'UserEdit', 'Modify' => 1, 'UserID' => $old->email, $self->svc_acct_params($new), 'db_$N$Users.Status' => $Status, ); } sub _export_suspend { my ($self, $svc) = @_; $self->request_user_edit( 'Modify' => 1, 'UserID' => $svc->email, 'db_$N$Users.Status' => '3', ); } sub _export_unsuspend { my ($self, $svc) = @_; $self->request_user_edit( 'Modify' => 1, 'UserID' => $svc->email, 'db_$N$Users.Status' => 0, ); } sub _export_delete { my ($self, $svc) = @_; $self->request_user_edit( 'ConfirmDelete' => 1, ('$Checked$' . $svc->email) => 1, ); } # Send a request to the 'UserEdit' interface, and process the response into # an error string (empty on success, per Freeside convention). sub request_user_edit { my ($self, @params) = @_; my $result = eval { $self->request( Page => 'UserEdit', @params ) }; return $result unless ref($result); my $status = $result->findvalue('Result/Status/@value'); # XPath if ($status eq 'Success') { return ''; } else { my $error = $result->findvalue('Result/Reason/@value') || 'unknown error'; return "updating Aradial user database: $error"; } } # Send a request to any interface, parse the response (from XML), and # return it (as an XML::LibXML::Document). Returns a string if there's an # HTTP error. sub request { my $self = shift; my @params = @_; my $path = '/ArdWeb/ARDAdminIs.dll'; # I think this is always right my $url = URI->new('http://' . $self->host . $path); warn "$me request: \n".Dumper(\@params)."\n\n" if $DEBUG >= 2; my $response = $self->ua->post($url, \@params); if ( $response->is_success ) { my $content = $response->decoded_content; warn "$me response: \n$content\n\n" if $DEBUG >= 2; return $self->parser->parse_string($content); # the formats of these are _variable_. # Some of them have a