diff --git a/Koha/REST/V1/SIP2/ServerParams.pm b/Koha/REST/V1/SIP2/ServerParams.pm new file mode 100644 index 0000000000..eeeb33ef91 --- /dev/null +++ b/Koha/REST/V1/SIP2/ServerParams.pm @@ -0,0 +1,111 @@ +package Koha::REST::V1::SIP2::ServerParams; + +# 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 Mojo::Base 'Mojolicious::Controller'; + +use Koha::SIP2::ServerParam; +use Koha::SIP2::ServerParams; + +use Try::Tiny qw( catch try ); + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $server_params = $c->objects->search( Koha::SIP2::ServerParams->new ); + return $c->render( status => 200, openapi => $server_params ); + } catch { + $c->unhandled_exception($_); + }; + +} + +sub update_server_params { + my ($c) = @_; + + my $body = $c->req->json; + + unless ( $body && ref $body eq 'ARRAY' ) { + return $c->render( + status => 400, + openapi => { error => "Invalid request body" } + ); + } + + foreach my $server_param (@$body) { + my $server_param_id = $server_param->{key}; + my $server_param_obj = Koha::SIP2::ServerParams->search( { key => $server_param->{key} } )->last; + + if ( !$server_param_obj ) { + try { + Koha::Database->new->schema->txn_do( + sub { + $server_param_obj = Koha::SIP2::ServerParam->new_from_api($server_param)->store; + } + ); + } catch { + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + json => { message => 'Some error occurred' } + ); + } + } + + $c->unhandled_exception($_); + } + } else { + try { + Koha::Database->new->schema->txn_do( + sub { + $server_param_obj->set_from_api($server_param)->store; + } + ); + } catch { + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + json => { message => 'Some error occurred' } + ); + } + } + + $c->unhandled_exception($_); + } + } + } + + $c->res->headers->location( $c->req->url->to_string ); + return $c->render( + status => 200, + json => { message => 'Server params updated successfully' }, + ); +} + +1; diff --git a/Koha/SIP2/ServerParam.pm b/Koha/SIP2/ServerParam.pm new file mode 100644 index 0000000000..b39c277cfb --- /dev/null +++ b/Koha/SIP2/ServerParam.pm @@ -0,0 +1,40 @@ +package Koha::SIP2::ServerParam; + +# 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 base qw(Koha::Object); + +=head1 NAME + +Koha::SIP2::ServerParam- Koha Sip Server Param Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'SipServerParam'; +} + +1; diff --git a/Koha/SIP2/ServerParams.pm b/Koha/SIP2/ServerParams.pm new file mode 100644 index 0000000000..ad8c0a2cef --- /dev/null +++ b/Koha/SIP2/ServerParams.pm @@ -0,0 +1,69 @@ +package Koha::SIP2::ServerParams; + +# 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::SIP2::ServerParam; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::SIP2::ServerParams- Koha Sip Server Param Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 get_for_config + +Returns the server params hashref as expected by C4/SIP/Sip/Configuration->new; + +=cut + +sub get_for_config { + my ($self) = @_; + + my $server_params = $self->search(); + my $return_hash; + + while ( my $server_param = $server_params->next() ) { + next if $server_param->key eq 'config_timestamp'; + $return_hash->{ $server_param->key } = $server_param->value; + } + return $return_hash; +} + +=head3 type + +=cut + +sub _type { + return 'SipServerParam'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::SIP2::ServerParam'; +} + +1; diff --git a/Koha/Schema/Result/SipServerParam.pm b/Koha/Schema/Result/SipServerParam.pm new file mode 100644 index 0000000000..9f5387ff77 --- /dev/null +++ b/Koha/Schema/Result/SipServerParam.pm @@ -0,0 +1,87 @@ +use utf8; +package Koha::Schema::Result::SipServerParam; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +=head1 NAME + +Koha::Schema::Result::SipServerParam + +=cut + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +=head1 TABLE: C + +=cut + +__PACKAGE__->table("sip_server_params"); + +=head1 ACCESSORS + +=head2 sip_server_param_id + + data_type: 'integer' + is_auto_increment: 1 + is_nullable: 0 + +=head2 key + + data_type: 'varchar' + is_nullable: 1 + size: 80 + +=head2 value + + data_type: 'varchar' + is_nullable: 0 + size: 255 + +=cut + +__PACKAGE__->add_columns( + "sip_server_param_id", + { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, + "key", + { data_type => "varchar", is_nullable => 1, size => 80 }, + "value", + { data_type => "varchar", is_nullable => 0, size => 255 }, +); + +=head1 PRIMARY KEY + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->set_primary_key("sip_server_param_id"); + +=head1 UNIQUE CONSTRAINTS + +=head2 C + +=over 4 + +=item * L + +=back + +=cut + +__PACKAGE__->add_unique_constraint("server_param_key", ["key"]); + + +# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-02-07 16:23:07 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VU5dn7xlVS8ZZKB1i2V6oQ + + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/api/v1/swagger/definitions/sip2_server_param.yaml b/api/v1/swagger/definitions/sip2_server_param.yaml new file mode 100644 index 0000000000..cc3fbc0906 --- /dev/null +++ b/api/v1/swagger/definitions/sip2_server_param.yaml @@ -0,0 +1,19 @@ +--- +type: object +properties: + sip_server_param_id: + type: integer + description: unique identifier + readOnly: true + key: + description: port + type: string + value: + description: protocol + type: + - string + - number + - "null" +additionalProperties: false +required: + - sip_server_param_id \ No newline at end of file diff --git a/api/v1/swagger/paths/sip2_server_params.yaml b/api/v1/swagger/paths/sip2_server_params.yaml new file mode 100644 index 0000000000..35872ab33d --- /dev/null +++ b/api/v1/swagger/paths/sip2_server_params.yaml @@ -0,0 +1,114 @@ +--- +/sip2/server_params: + get: + x-mojo-to: SIP2::ServerParams#list + operationId: listSip2ServerParams + tags: + - sip2_server_params + summary: List server params + produces: + - application/json + parameters: + - description: Case insensitive search on server_param sip_server_param_id + in: query + name: sip_server_param_id + required: false + type: string + collectionFormat: csv + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + responses: + 200: + description: A list of SIP2 server params + schema: + items: + $ref: "../swagger.yaml#/definitions/sip2_server_param" + type: array + "400": + description: | + Bad request. Possible `error_code` attribute values: + + * `invalid_query` + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + superlibrarian: 1 # TODO: Fix this, currently for superlibrarians only + patch: + x-mojo-to: SIP2::ServerParams#update_server_params + operationId: updateSip2ServerParams + tags: + - sip2_server_params + summary: Update server params + consumes: + - application/json + produces: + - application/json + parameters: + - description: A JSON object containing information about the server params updates + in: body + name: body + required: true + schema: + $ref: "../swagger.yaml#/definitions/sip2_server_param" + responses: + 201: + description: A successfully created listener + schema: + items: + $ref: "../swagger.yaml#/definitions/sip2_listener" + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 401: + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: Ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 409: + description: Conflict in creating resource + schema: + $ref: "../swagger.yaml#/definitions/error" + 413: + description: Payload too large + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + superlibrarian: 1 # TODO: Fix this, currently for superlibrarians only \ No newline at end of file diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 1da40dcd46..d25b1d501c 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -186,6 +186,8 @@ definitions: $ref: ./definitions/sip2_institution.yaml sip2_listener: $ref: ./definitions/sip2_listener.yaml + sip2_server_param: + $ref: ./definitions/sip2_server_param.yaml smtp_server: $ref: ./definitions/smtp_server.yaml file_transport: @@ -615,6 +617,8 @@ paths: $ref: ./paths/sip2_listeners.yaml#/~1sip2~1listeners "/sip2/listeners/{sip_listener_id}": $ref: "./paths/sip2_listeners.yaml#/~1sip2~1listeners~1{sip_listener_id}" + /sip2/serverparams: + $ref: "./paths/sip2_server_params.yaml#/~1sip2~1server_params" /suggestions: $ref: ./paths/suggestions.yaml#/~1suggestions "/suggestions/{suggestion_id}": diff --git a/installer/data/mysql/atomicupdate/bug_37893.pl b/installer/data/mysql/atomicupdate/bug_37893.pl index de6ca4d910..ad680139a8 100755 --- a/installer/data/mysql/atomicupdate/bug_37893.pl +++ b/installer/data/mysql/atomicupdate/bug_37893.pl @@ -306,5 +306,24 @@ return { $SIPconfig->{listeners}->{$listener_key}->{transport} ); } + + # Server params # + my @server_params_keys = keys %{ $SIPconfig->{'server-params'} }; + foreach my $server_params_key (@server_params_keys) { + my $insert_listeners = $dbh->prepare( + q{INSERT IGNORE INTO sip_server_params (`key`, value) VALUES (?, ?) } + ); + + $insert_listeners->execute( + $server_params_key, + $SIPconfig->{'server-params'}->{$server_params_key} + ); + } + + my $delete_config_timestamp = $dbh->prepare(q{DELETE FROM sip_server_params WHERE `key` = 'config_timestamp' }); + $delete_config_timestamp->execute(); + my $timestamp = DateTime->now; + my $insert_config_timestamp = $dbh->prepare(q{INSERT INTO sip_server_params (`key`, value) VALUES (?, ?) }); + $insert_config_timestamp->execute( 'config_timestamp', $timestamp->epoch ); }, }; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 559fc3711b..46742acd80 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -6303,6 +6303,21 @@ CREATE TABLE `sip_listeners` ( UNIQUE KEY `listener_port` (`port`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- +-- Table structure for table `sip_listeners` +-- + +DROP TABLE IF EXISTS `sip_server_params`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `sip_server_params` ( + `sip_server_param_id` int(11) NOT NULL AUTO_INCREMENT, + `key` varchar(80) DEFAULT NULL, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`sip_server_param_id`), + UNIQUE KEY `server_param_key` (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + -- -- Table structure for table `sms_providers` -- diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/sip2-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/sip2-api-client.js index 4f8464727c..451b58d8c1 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/fetch/sip2-api-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/sip2-api-client.js @@ -119,6 +119,20 @@ export class SIP2APIClient { }), }; } + + get serverparams() { + return { + getAll: params => + this.getAll({ + endpoint: "serverparams", + }), + updateAll: (body) => + this.patch({ + endpoint: "serverparams", + body: body, + }), + }; + } } export default SIP2APIClient; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2ServerParams.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2ServerParams.vue new file mode 100644 index 0000000000..c76f36c4c8 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/SIP2/SIP2ServerParams.vue @@ -0,0 +1,182 @@ + + + + + \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/sip2.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/sip2.js index b659ddf39b..f2f130a567 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/sip2.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/sip2.js @@ -2,6 +2,7 @@ import { markRaw } from "vue"; import Home from "../components/SIP2/Home.vue"; import ResourceWrapper from "../components/ResourceWrapper.vue"; +import ServerParams from "../components/SIP2/SIP2ServerParams.vue"; import { $__ } from "../i18n"; export const routes = [ @@ -113,6 +114,19 @@ export const routes = [ }, ], }, + { + path: "/cgi-bin/koha/sip2/serverparams", + title: $__("Server params"), + icon: "fa fa-cog", + is_end_node: true, + children: [ + { + path: "", + name: "SIP2ServerParams", + component: markRaw(ServerParams), + }, + ] + }, ], }, ];