From 8aa6c0bc6a224994182a78e56ec9db61db691d33 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Tue, 28 Jul 2020 12:35:26 -0300 Subject: [PATCH] Bug 22343: Add classes for handling SMTP servers This patch introduces classes to handle SMTP servers. It is done in a way that a default server can be set, and then per-library ones can be set. All should be done with Koha::SMTP::Servers methods, that take care of overwriting library-specific configs, and handle the defaults retrieval and setting correctly. To test: 1. Apply this patches 2. Run: $ kshell $ perl installer/data/mysql/updatedatabase.pl => SUCCESS: Atomic update is ok, smtp_servers table created 3. Run: k$ prove t/db_dependent/Koha/SMTP/ => SUCCESS: Tests pass! 4. Sign off :-D Signed-off-by: Martin Renvoize --- Koha/SMTP/Server.pm | 128 ++++++++++++++ Koha/SMTP/Servers.pm | 191 +++++++++++++++++++++ t/db_dependent/Koha/SMTP/Server.t | 120 ++++++++++++++ t/db_dependent/Koha/SMTP/Servers.t | 258 +++++++++++++++++++++++++++++ 4 files changed, 697 insertions(+) create mode 100644 Koha/SMTP/Server.pm create mode 100644 Koha/SMTP/Servers.pm create mode 100644 t/db_dependent/Koha/SMTP/Server.t create mode 100644 t/db_dependent/Koha/SMTP/Servers.t diff --git a/Koha/SMTP/Server.pm b/Koha/SMTP/Server.pm new file mode 100644 index 0000000000..5a078941c1 --- /dev/null +++ b/Koha/SMTP/Server.pm @@ -0,0 +1,128 @@ +package Koha::SMTP::Server; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; +use Koha::Exceptions::Object; +use Koha::SMTP::Servers; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::SMTP::Server - Koha SMTP Server Object class + +=head1 API + +=head2 Class methods + +=head3 store + + my $server = Koha::SMTP::Server->new({...})->store; + $server->set({...})->store; + +Overloaded I method that takes care of checking unicity of the +default server (i.e. when library_id IS NULL). + +FIXME: Replace with a CHECK constraint when the feature is available. + +=cut + +sub store { + my ( $self, $params ) = @_; + + if ( $self->in_storage ) { + + # update + if ( !defined $self->library_id ) { + + # trying to set a default, check manually + # until the DB can handle it + Koha::Exceptions::Object::DuplicateID->throw( duplicate_id => 'library_id' ) + if Koha::SMTP::Servers->search( + { library_id => undef, id => { '!=' => $self->id } } )->count > 0; + } + } + else { + # new + if ( !defined $self->library_id ) { + + # trying to set a default, check manually + # until the DB can handle it + Koha::Exceptions::Object::DuplicateID->throw( duplicate_id => 'library_id' ) + if Koha::SMTP::Servers->search( { library_id => undef } )->count > 0; + } + } + + return $self->SUPER::store; +} + +=head3 is_default + + my $is_default = $server->is_default + +Helper method to determine if the server is the default one + +=cut + +sub is_default { + my ($self) = @_; + + return (defined $self->library_id) ? 0 : 1; +} + +=head3 library + +Returns the Koha::Library object linked to the SMTP server. + +=cut + +sub library { + my ( $self ) = @_; + + my $library_rs = $self->_result->library; + return unless $library_rs; + return Koha::Library->_new_from_dbic($self->_result->library); +} + +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::SMTP::Server object +on the API. + +=cut + +sub to_api_mapping { + return { + id => 'smtp_server_id' + }; +} + +=head2 Internal methods + +=head3 _type + +Return type of Object relating to Schema ResultSet + +=cut + +sub _type { + return 'SmtpServer'; +} + +1; diff --git a/Koha/SMTP/Servers.pm b/Koha/SMTP/Servers.pm new file mode 100644 index 0000000000..eee40e4e11 --- /dev/null +++ b/Koha/SMTP/Servers.pm @@ -0,0 +1,191 @@ +package Koha::SMTP::Servers; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Database; +use Koha::Exceptions; + +use Koha::SMTP::Server; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::SMTP::Servers - Koha SMTP Server Object set class + +=head1 API + +=head2 Class methods + +=head3 get_effective_server + + my $server = Koha::SMTP::Servers->get_effective_server({ library => $library }); + +Returns a I representing the effective configured SMTP for the library. + +=cut + +sub get_effective_server { + my ($self, $args) = @_; + + my $library = $args->{library}; + + Koha::Exceptions::MissingParameter->throw('Mandatory parameter missing: library') + unless $library; + + my $servers_rs = Koha::SMTP::Servers->search({ library_id => $library->branchcode }); + if ( $servers_rs->count > 0 ) { + return $servers_rs->next; + } + + return $self->get_default; +} + +=head3 get_default + + my $server = Koha::SMTP::Servers->new->get_default; + +Returns the default I object. + +=cut + +sub get_default { + my ($self) = @_; + + my $servers_rs = $self->search({ library_id => undef }); + + my $server; + if ($servers_rs->count > 0) { + $server = $servers_rs->next; + } + else { + $server = Koha::SMTP::Server->new( $self->default_setting ); + } + + return $server; +} + +=head3 set_default + + my $server = Koha::SMTP::Servers->new->set_default; + +Set the default I server, and returns it. + +=cut + +sub set_default { + my ($self, $params) = @_; + + Koha::Exceptions::BadParameter->throw( 'library_id must be undef when setting the default SMTP server' ) + if defined $params->{library_id}; + + my $smtp_server; + $self->_resultset()->result_source->schema->txn_do( sub { + + # Delete existing default + $self->search({ library_id => undef })->delete; + + $smtp_server = Koha::SMTP::Server->new($params)->store; + }); + + return $smtp_server; +} + +=head3 set_library_server + + my $server = Koha::SMTP::Servers->new->set_library_server( + { + name => $name, + library_id => $library->id, + host => $smtp_host, + port => $smtp_port, + timeout => $smtp_timeout, + ssl => 1, + user_name => $user_name, + password => $password + } + ); + +Set the I server for a library, and return it. + +=cut + +sub set_library_server { + my ( $self, $params ) = @_; + + Koha::Exceptions::MissingParameter->throw( + 'Mandatory parameter missing: library_id') + unless $params->{library_id}; + + my $smtp_server; + $self->_resultset()->result_source->schema->txn_do( sub { + # Delete existing default + $self->search({ library_id => $params->{library_id} })->delete; + + $smtp_server = Koha::SMTP::Server->new($params)->store; + }); + + return $smtp_server; +} + +=head2 Internal methods + +=head3 _type + +Return type of object, relating to Schema ResultSet + +=cut + +sub _type { + return 'SmtpServer'; +} + +=head3 default_setting + + my $hash = Koha::SMTP::Servers::default_setting; + +Returns the default setting that is to be used when no user-defined default +SMTP server is provided + +=cut + +sub default_setting { + return { + name => 'localhost', + library_id => undef, + host => 'localhost', + port => 25, + timeout => 120, + ssl_mode => 'disabled', + user_name => undef, + password => undef, + debug => 0 + }; +} + +=head3 object_class + +Return object class + +=cut + +sub object_class { + return 'Koha::SMTP::Server'; +} + +1; diff --git a/t/db_dependent/Koha/SMTP/Server.t b/t/db_dependent/Koha/SMTP/Server.t new file mode 100644 index 0000000000..db7b1f65af --- /dev/null +++ b/t/db_dependent/Koha/SMTP/Server.t @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 2; +use Test::Exception; +use Test::Warn; + +use Koha::SMTP::Servers; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +subtest 'is_default() tests' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $default_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => undef + } + } + ); + + my $library = $builder->build_object( { class => 'Koha::Libraries' } ); + my $library_specific_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => $library->branchcode + } + } + ); + + ok( $default_server->is_default, 'Server is the default one' ); + ok( !$library_specific_server->is_default, + 'Server is not the default one' ); + + $schema->storage->txn_rollback; +}; + +subtest 'store() tests' => sub { + + plan tests => 4; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $default_server = Koha::SMTP::Server->new( + { + library_id => undef, + name => 'Default SMTP server' + } + )->store; + + my $library = $builder->build_object( { class => 'Koha::Libraries' } ); + my $library_specific_server = Koha::SMTP::Server->new( + { + library_id => $library->id, + name => 'Library-specific SMTP server' + } + )->store; + + warning_like + { + throws_ok + { Koha::SMTP::Server->new( + { + library_id => $library->id, + name => 'Some fake name' + } + )->store; } + 'Koha::Exceptions::Object::DuplicateID', + 'Cannot define two servers for the same library'; + } + qr/DBI Exception: DBD::mysql::st execute failed: Duplicate entry/, + 'Warning is printed'; + + throws_ok + { Koha::SMTP::Server->new( + { + library_id => undef, + name => 'Some fake name' + } + )->store; } + 'Koha::Exceptions::Object::DuplicateID', + 'Cannot define two default SMTP servers'; + + $default_server->set({ name => 'New name' })->store; + $default_server->discard_changes; + + is( $default_server->name, 'New name', 'Default server updated correctly' ); + + $schema->storage->txn_rollback; +}; diff --git a/t/db_dependent/Koha/SMTP/Servers.t b/t/db_dependent/Koha/SMTP/Servers.t new file mode 100644 index 0000000000..f306178f73 --- /dev/null +++ b/t/db_dependent/Koha/SMTP/Servers.t @@ -0,0 +1,258 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 4; +use Test::Exception; + +use Koha::SMTP::Servers; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +subtest 'get_default() tests' => sub { + + plan tests => 3; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $default_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => undef + } + } + ); + + my $library = $builder->build_object( { class => 'Koha::Libraries' } ); + my $library_specific_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => $library->branchcode + } + } + ); + + my $servers = Koha::SMTP::Servers->new; + my $server = $servers->get_default; + is( $server->id, $default_server->id, + 'The default server is correctly retrieved' ); + + # Delete the default server + $server->delete; + + # Get the default + $default_server = $servers->get_default; + is( ref($default_server), 'Koha::SMTP::Server', + 'An object of the right type is returned' ); + + my $unblessed_server = $default_server->unblessed; + delete $unblessed_server->{id}; + is_deeply( + $unblessed_server, + Koha::SMTP::Servers::default_setting, + 'The default setting is returned if no user-defined default' + ); + + $schema->storage->txn_rollback; +}; + +subtest 'set_default() tests' => sub { + + plan tests => 4; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $default_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => undef + } + } + ); + + throws_ok { + Koha::SMTP::Servers->new->set_default( + { + name => 'A new default', + library_id => 'Whatever', + } + ); + } + 'Koha::Exceptions::BadParameter', +'Exception thrown when trying to set default SMTP server with a library_id'; + + is( + "$@", + 'library_id must be undef when setting the default SMTP server', + 'Exception message is clear' + ); + + my $new_default = Koha::SMTP::Servers->new->set_default( + { + name => 'A new default', + library_id => undef, + } + ); + + is( ref($new_default), 'Koha::SMTP::Server', 'Type is correct' ); + is( + $new_default->id, + Koha::SMTP::Servers->get_default->id, + 'Default SMTP server is correctly set' + ); + + $schema->storage->txn_rollback; +}; + +subtest 'get_effective_server() tests' => sub { + + plan tests => 4; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $library = $builder->build_object( { class => 'Koha::Libraries' } ); + + my $default_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => undef + } + } + ); + + throws_ok { Koha::SMTP::Servers->new->get_effective_server() } + 'Koha::Exceptions::MissingParameter', 'Exception thrown'; + + is( "$@", 'Mandatory parameter missing: library' ); + + is( + Koha::SMTP::Servers->new->get_effective_server( + { library => $library } + )->id, + $default_server->id, + 'Fallback default server retrieved' + ); + + my $specific_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => $library->branchcode + } + } + ); + + is( + Koha::SMTP::Servers->new->get_effective_server( + { library => $library } + )->id, + $specific_server->id, + 'Library specific server retrieved' + ); + + $schema->storage->txn_rollback; +}; + +subtest 'set_library_server() tests' => sub { + + plan tests => 6; + + $schema->storage->txn_begin; + + Koha::SMTP::Servers->search->delete; + + my $library = $builder->build_object( { class => 'Koha::Libraries' } ); + + my $default_server = $builder->build_object( + { + class => 'Koha::SMTP::Servers', + value => { + library_id => undef + } + } + ); + + is( + Koha::SMTP::Servers->new->get_effective_server( + { library => $library } + )->id, + $default_server->id, + 'Fallback default server retrieved' + ); + + my $specific_server = Koha::SMTP::Servers->new->set_library_server( + { + name => 'Specific server 1', + library_id => $library->id + } + ); + + is( + Koha::SMTP::Servers->new->get_effective_server( + { library => $library } + )->id, + $specific_server->id, + 'Library specific server retrieved' + ); + + throws_ok { + Koha::SMTP::Servers->new->set_library_server( + { + name => 'Specific server 2' + } + ); + } + 'Koha::Exceptions::MissingParameter', + 'Exception thrown on missing parameter'; + + is( "$@", 'Mandatory parameter missing: library_id' ); + + $specific_server = Koha::SMTP::Servers->new->set_library_server( + { + name => 'Specific server 2', + library_id => $library->id + } + ); + + is( + Koha::SMTP::Servers->new->get_effective_server( + { library => $library } + )->id, + $specific_server->id, + 'New library specific server retrieved' + ); + + is( Koha::SMTP::Servers->search( { library_id => $library->id } )->count, + 1, 'Only one SMTP server set' ); + + $schema->storage->txn_rollback; +}; -- 2.20.1