From d58fcee103431cd355b71828f6abca15205db268 Mon Sep 17 00:00:00 2001 From: Guillaume Rousse <guillaume.rousse@renater.fr> Date: Fri, 3 Nov 2017 11:02:55 +0100 Subject: [PATCH] use a plain text file for configuration --- bin/account-manager-client.pl | 41 +++++---- bin/account-manager-web.pl | 11 ++- conf/Conf.pm | 113 ------------------------- conf/IdPAccountManager.conf | 77 +++++++++++++++++ lib/IdPAccountManager/Configuration.pm | 33 ++++++++ lib/IdPAccountManager/WebRequest.pm | 58 ++++++------- 6 files changed, 170 insertions(+), 163 deletions(-) delete mode 100644 conf/Conf.pm create mode 100644 conf/IdPAccountManager.conf create mode 100644 lib/IdPAccountManager/Configuration.pm diff --git a/bin/account-manager-client.pl b/bin/account-manager-client.pl index 2ae8709..2be941c 100755 --- a/bin/account-manager-client.pl +++ b/bin/account-manager-client.pl @@ -25,6 +25,7 @@ use IdPAccountManager::Data::TestAccount::Manager; use IdPAccountManager::Data::ServiceProvider; use IdPAccountManager::Data::ServiceProvider::Manager; use IdPAccountManager::SAMLMetadata; +use IdPAccountManager::Configuration; use IdPAccountManager::Logger; my %options; @@ -50,12 +51,16 @@ pod2usage( -verbose => 0 ) unless $action; +my $configuration = IdPAccountManager::Configuration->new( + file => 'conf/IdPAccountManager.conf' +); + IdPAccountManager::DB->register_db( - driver => $Conf::global{database_type}, - database => $Conf::global{database_name}, - host => $Conf::global{database_host}, - password => $Conf::global{database_password}, - username => $Conf::global{database_user} + driver => $configuration->{database_type}, + database => $configuration->{database_name}, + host => $configuration->{database_host}, + password => $configuration->{database_password}, + username => $configuration->{database_user} ); my $db = IdPAccountManager::DB->new(); @@ -100,7 +105,7 @@ sub add_test_account { die "Failed to save test account\n" unless $test_account->save( - accounts_validity_period => $Conf::global{'accounts_validity_period'} + accounts_validity_period => $configuration->{'accounts_validity_period'} ); printf "Account created:\n\tuserid: user%d\n\tpassword: %s\n", @@ -142,8 +147,8 @@ sub list_test_accounts { die "failed to update simpleSAMLphp configuration file\n" unless IdPAccountManager::Tools::update_ssp_authsources( - $Conf::global{'root_manager_dir'}, - \%Conf::global + $configuration->{'root_manager_dir'}, + $configuration ); printf "Update simpleSamlPhp configuration file...\n"; @@ -157,7 +162,7 @@ sub parse_federation_metadata { die "unable to load federation metadata\n" unless $federation_metadata->load( federation_metadata_file_path => - $Conf::global{'federation_metadata_file_path'} + $configuration->{'federation_metadata_file_path'} ); my %args; @@ -169,7 +174,7 @@ sub parse_federation_metadata { unless $federation_metadata->parse(%args); printf "Document %s parsed\n", - $Conf::global{'federation_metadata_file_path'}; + $configuration->{'federation_metadata_file_path'}; ## List SAML entities printf "Hashref representing the metadata:\n"; @@ -249,7 +254,7 @@ sub list_authentication_tokens { } if ($options{'filter_expired'}) { push @{ $args{'query'} }, 'creation_date' => - { lt => time - ($Conf::global{'tokens_validity_period'} * 3600) }; + { lt => time - ($configuration->{'tokens_validity_period'} * 3600) }; } my $tokens = @@ -346,8 +351,8 @@ sub send_notice { ) unless $options{'email_address'}; my $logger = IdPAccountManager::Logger->new( - file => $Conf::global{'log_file'}, - verbosity => $Conf::global{'log_level'} + file => $configuration->{'log_file'}, + verbosity => $configuration->{'log_level'} ); die "Failed to send mail notice to $options{'email_address'}\n" @@ -356,11 +361,11 @@ sub send_notice { 'data' => {}, 'to' => $options{'email_address'}, 'logger' => $logger, - 'conf' => \%Conf::global, - 'admin_email' => $Conf::global{'admin_email'}, - 'dev_no_mail_outside' => $Conf::global{'dev_no_mail_outside'}, - 'dev_sp_contact' => $Conf::global{'dev_sp_contact'}, - 'notice_from' => $Conf::global{'notice_from'} + 'conf' => $configuration, + 'admin_email' => $configuration->{'admin_email'}, + 'dev_no_mail_outside' => $configuration->{'dev_no_mail_outside'}, + 'dev_sp_contact' => $configuration->{'dev_sp_contact'}, + 'notice_from' => $configuration->{'notice_from'} ); printf "Mail notice sent to $options{'email_address'}\n"; diff --git a/bin/account-manager-web.pl b/bin/account-manager-web.pl index 3729cf9..631c80a 100755 --- a/bin/account-manager-web.pl +++ b/bin/account-manager-web.pl @@ -18,9 +18,9 @@ use CGI::Util; use Template; use Template::Constants qw( :debug ); -use Conf; use IdPAccountManager::SAMLMetadata; +use IdPAccountManager::Configuration; use IdPAccountManager::WebRequest; ## Defining parameters format @@ -48,9 +48,14 @@ umask 0002; chdir $Conf::global{'root_manager_dir'}; +my $configuration = IdPAccountManager::Configuration->new( + file => 'conf/IdPAccountManager.conf' +); + my $request = new IdPAccountManager::WebRequest( - actions => \%actions, - format => \%format + actions => \%actions, + format => \%format, + configuration => $configuration ); if (defined $request) { diff --git a/conf/Conf.pm b/conf/Conf.pm deleted file mode 100644 index 18ae1e0..0000000 --- a/conf/Conf.pm +++ /dev/null @@ -1,113 +0,0 @@ -package Conf; - -our %global = ( - - ## Code version - 'version' => 'open Beta 1', - - ## Name of the application used in web pages, mail notices - 'app_name' => 'eduGAIN Access Check', - - ## URL of the application - 'app_url' => 'https://my.fqdn/accountmanager', - - ## Validity period of test accounts, in days - 'accounts_validity_period' => 7, - - ## Token validity period, in hours - 'tokens_validity_period' => 2, - - ## Scope used by the associated IdP - 'idp_scope' => 'my.fqdn', - - ## EntityID of the IdP - 'idp_entityid' => 'https://my.fqdn/simplesaml/saml2/idp/metadata.php', - - ## Name of the IdP - 'idp_displayname' => 'eduGAIN Access Check', - - ## Root simpleSamlPhp directory - 'root_ssp_dir' => '/opt/testidp/simplesamlphp', - - ## Root test account manager directory - 'root_manager_dir' => '/opt/testidp/IdPAccountManager', - - ## Database type refers to a Perl Database Driver name - ## However only a subset of existing DBDs are supported by Rose::DB::Object: - ## Pg, mysql, SQLite, Informix, Oracle (DBD names are case sensitives) - 'database_type' => 'mysql', - - ## Database hostname - 'database_host' => 'localhost', - - ## Database_name - 'database_name' => 'idp_account_manager', - - ## Database username - 'database_user' => 'root', - - ## Database user password - 'database_password' => 'root', - - ## Log file for the manager - 'log_file' => '/opt/testidp/IdPAccountManager/log/manager.log', - - ## Log level : debug, info, trace, notice, error - 'log_level' => 'info', - - ## email address to contact admins - 'admin_email' => 'john@my.fqdn', - - ## email address to ask for support - 'support_email' => 'support@my.fqdn', - - ## Development feature - ## Protection to prevent notifications during test dev phases - ## Notify only admin_email above - 'dev_no_mail_outside' => 1, - - ## Development feature - ## hard-coded list of contactPersons - ## these email addresses will be added to the list of contacts for any SP - 'dev_sp_contact' => 'john@my.fqdn,sarah@my.fqdn', - - ## From field use by the account manager - 'notice_from' => 'edugain-access-check.fqdn', - - ## federation metadata local copy path - 'federation_metadata_file_path' => - '/opt/testidp/IdPAccountManager/conf/edugain-md.xml', - - ## Valid account profiles - 'account_profiles' => [ - 'fullset1', 'limitedset1', 'generic1', 'student1', - 'student2', 'teacher1', 'teacher2', 'alumni1', - 'librarywalkin1', 'employee1', 'researcher1' - ], -); - -1; # Magic true value required at end of module -__END__ - -=head1 NAME - -Conf - Configuration of the Test Account manager - -=head1 SYNOPSIS - -use Conf; - -printf "Version: %s\n", $Conf::global{'version'}; - -=head1 DESCRIPTION - -The Test Account manager instanciates test accounts associated to a SAML Identity Provider. This module is the main configuration file for the -software. - -=head1 CONFIGURATION OPTIONS - -See the code for the list of supported configuration options - -=head1 AUTHOR - -Olivier Salaün (olivier.salaun@renater.fr) diff --git a/conf/IdPAccountManager.conf b/conf/IdPAccountManager.conf new file mode 100644 index 0000000..8ed6bb6 --- /dev/null +++ b/conf/IdPAccountManager.conf @@ -0,0 +1,77 @@ +# Code version +version = open Beta 1 + +# Name of the application used in web pages, mail notices +app_name = eduGAIN Access Check + +# URL of the application +app_url = https://my.fqdn/accountmanager + +# Validity period of test accounts, in days +accounts_validity_period = 7 + +# Token validity period, in hours +tokens_validity_period = 2 + +# Scope used by the associated IdP +idp_scope = my.fqdn + +# EntityID of the IdP +idp_entityid = https://my.fqdn/simplesaml/saml2/idp/metadata.php + +# Name of the IdP +idp_displayname = eduGAIN Access Check + +# Root simpleSamlPhp directory +root_ssp_dir = /opt/testidp/simplesamlphp + +# Root test account manager directory +root_manager_dir = /opt/testidp/IdPAccountManager + +# Database type refers to a Perl Database Driver name +# However only a subset of existing DBDs are supported by Rose::DB::Object: +# Pg, mysql, SQLite, Informix, Oracle (DBD names are case sensitives) +database_type = mysql + +# Database hostname +database_host = localhost + +# Database_name +database_name = idp_account_manager + +# Database username +database_user = idpadmin + +# Database user password +database_password = secret + +# Log file for the manager +log_file = /opt/testidp/IdPAccountManager/log/manager.log + +# Log level : debug, info, trace, notice, error +log_level = info + +# email address to contact admins +admin_email = john@my.fqdn + +# email address to ask for support +support_email = support@my.fqdn + +# Development feature +# Protection to prevent notifications during test dev phases +# Notify only admin_email above +dev_no_mail_outside = 1 + +# Development feature +# hard-coded list of contactPersons +# these email addresses will be added to the list of contacts for any SP +dev_sp_contact = john@my.fqdn, sarah@my.fqdn + +# From field use by the account manager +notice_from = edugain-access-check.fqdn + +# federation metadata local copy path +federation_metadata_file_path = /opt/testidp/IdPAccountManager/conf/edugain-md.xml + +# Valid account profiles +account_profiles = fullset1, limitedset1, generic1, student1, student2, teacher1, teacher2, alumni1, librarywalkin1, employee1, researcher1 diff --git a/lib/IdPAccountManager/Configuration.pm b/lib/IdPAccountManager/Configuration.pm new file mode 100644 index 0000000..0e956b2 --- /dev/null +++ b/lib/IdPAccountManager/Configuration.pm @@ -0,0 +1,33 @@ +package IdPAccountManager::Configuration; + +use strict; +use warnings; + +use English qw(-no_match_vars); + +sub new { + my ($pkg) = shift; + my %args = @_; + + die "missing argument 'file'" unless $args{file}; + die "non-existing file $args{file}" unless -f $args{file}; + die "non-readable file $args{file}" unless -r $args{file}; + + my $self = {}; + my $handle; + open($handle, '<', $args{file}) or die "Failed to open $args{file}: $ERRNO"; + + while (my $line = <$handle>) { + next unless $line =~ /^(\S+)\s*=\s*(.+)$/; + my $key = $1; + my $val = $2; + $self->{$1} = $2; + } + close $handle; + + bless $self, $pkg; + + return $self; +} + +1; diff --git a/lib/IdPAccountManager/WebRequest.pm b/lib/IdPAccountManager/WebRequest.pm index e1c5bf1..943b9a4 100755 --- a/lib/IdPAccountManager/WebRequest.pm +++ b/lib/IdPAccountManager/WebRequest.pm @@ -8,20 +8,20 @@ use IdPAccountManager::Logger; use IdPAccountManager::Data::TestAccount; use IdPAccountManager::Data::AuthenticationToken; use IdPAccountManager::Data::ServiceProvider; -use Conf; ## New web request sub new { my ($pkg, %args) = @_; my $self = { - format => $args{format}, - actions => $args{actions}, + format => $args{format}, + actions => $args{actions}, + configuration => $args{configuration}, }; $self->{logger} = IdPAccountManager::Logger->new( - file => $Conf::global{'log_file'}, - verbosity => $Conf::global{'log_level'} + file => $self->{configuration}->{'log_file'}, + verbosity => $self->{configuration}->{'log_level'} ); $self->{logger}->log( level => LOG_INFO, @@ -29,11 +29,11 @@ sub new { ); IdPAccountManager::DB->register_db( - driver => $Conf::global{database_type}, - database => $Conf::global{database_name}, - host => $Conf::global{database_host}, - password => $Conf::global{database_password}, - username => $Conf::global{database_user} + driver => $self->{configuration}->{database_type}, + database => $self->{configuration}->{database_name}, + host => $self->{configuration}->{database_host}, + password => $self->{configuration}->{database_password}, + username => $self->{configuration}->{database_user} ); $self->{db} = IdPAccountManager::DB->new(); @@ -56,7 +56,7 @@ sub new { $self->{'param_out'}{'url_cgi'} = $ENV{'SCRIPT_NAME'}; $self->{'param_out'}{'env'} = \%ENV; $self->{'param_out'}{'actions'} = $args{actions}; - $self->{'param_out'}{'conf'} = \%Conf::global; + $self->{'param_out'}{'conf'} = $self->{configuration}; ## Clean input vars foreach my $key (keys %{ $self->{'param_in'} }) { @@ -169,8 +169,8 @@ sub respond { 'escape_quotes' => [ \&IdPAccountManager::Tools::escape_quotes, 0 ] }, - INCLUDE_PATH => $Conf::global{'root_manager_dir'} . ':' - . $Conf::global{'root_manager_dir'} + INCLUDE_PATH => $self->{configuration}->{'root_manager_dir'} . ':' + . $self->{configuration}->{'root_manager_dir'} . '/templates/accountProfiles', #DEBUG => 'all', @@ -209,14 +209,14 @@ sub respond { if (@errors_admin) { $self->{'param_out'}{'subject'} = 'Error notification - web interface'; IdPAccountManager::Tools::mail_notice( - 'template' => 'templates/mail/notification_generic_error.tt2.eml', - 'data' => $self->{'param_out'}, - 'logger' => $self->{'logger'}, - 'conf' => \%Conf::global, - 'admin_email' => $Conf::global{'admin_email'}, - 'dev_no_mail_outside' => $Conf::global{'dev_no_mail_outside'}, - 'dev_sp_contact' => $Conf::global{'dev_sp_contact'}, - 'notice_from' => $Conf::global{'notice_from'} + 'template' => 'templates/mail/notification_generic_error.tt2.eml', + 'data' => $self->{'param_out'}, + 'logger' => $self->{'logger'}, + 'conf' => $self->{configuration}, + 'admin_email' => $self->{configuration}->{'admin_email'}, + 'dev_no_mail_outside' => $self->{configuration}->{'dev_no_mail_outside'}, + 'dev_sp_contact' => $self->{configuration}->{'dev_sp_contact'}, + 'notice_from' => $self->{configuration}->{'notice_from'} ); } } @@ -233,7 +233,7 @@ sub req_account_wizard { unless ( $federation_metadata->load( federation_metadata_file_path => - $Conf::global{'federation_metadata_file_path'} + $self->{configuration}->{'federation_metadata_file_path'} ) ) { @@ -280,7 +280,7 @@ sub req_select_sp { unless ( $federation_metadata->load( federation_metadata_file_path => - $Conf::global{'federation_metadata_file_path'} + $self->{configuration}->{'federation_metadata_file_path'} ) ) { @@ -310,7 +310,7 @@ sub req_select_sp { my $service_provider = IdPAccountManager::Data::ServiceProvider->new( db => $self->{db}, entityid => $self->{'param_in'}{'sp_entityid'}, - dev_sp_contact => $Conf::global{'dev_sp_contact'} + dev_sp_contact => $self->{configuration}->{'dev_sp_contact'} ); ## Prepare data @@ -353,7 +353,7 @@ sub req_select_sp { entityid => $self->{'param_in'}{'sp_entityid'}, contacts => join(',', @contacts), displayname => $display_name, - dev_sp_contact => $Conf::global{'dev_sp_contact'} + dev_sp_contact => $self->{configuration}->{'dev_sp_contact'} ); unless (defined $service_provider) { push @{ $self->{'param_out'}{'errors'} }, "internal"; @@ -407,7 +407,7 @@ sub req_generate_token { my $service_provider = IdPAccountManager::Data::ServiceProvider->new( db => $self->{db}, entityid => $self->{'param_in'}{'sp_entityid'}, - dev_sp_contact => $Conf::global{'dev_sp_contact'} + dev_sp_contact => $self->{configuration}->{'dev_sp_contact'} ); # Try loading DB object first @@ -579,7 +579,7 @@ sub req_validate_token { ## create test accounts my @test_accounts; - foreach my $profile ($Conf::global{'account_profiles'}) { + foreach my $profile ($self->{configuration}->{'account_profiles'}) { my $test_account = IdPAccountManager::Data::TestAccount->new( db => $self->{db}, account_profile => $profile, @@ -602,8 +602,8 @@ sub req_validate_token { ## Update simpleSAMLphp configuration to enable test accounts unless (IdPAccountManager::Tools::update_ssp_authsources( - $Conf::global{'root_manager_dir'}, - \%Conf::global + $self->{configuration}->{'root_manager_dir'}, + $self->{configuration} )) { push @{ $self->{'param_out'}{'errors'} }, "accounts_creation_failed"; $self->{logger}->log( -- GitLab