diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 701c46cbf..8f7f220eb 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11"] module: [Api, Core] # We want to run on external PRs, but not on our own internal PRs as they'll be run @@ -56,6 +56,7 @@ jobs: MODULE: ${{ matrix.module }} - name: Upload coverage to Codecov + if: false # Disable temporarily uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -84,7 +85,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: "3.10" - name: Install Apt Packages run: | @@ -104,6 +105,7 @@ jobs: run: tox -e "migration-docker" - name: Upload coverage to Codecov + if: false # Disable temporarily uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -119,7 +121,8 @@ jobs: # Only build docker containers on a push event. Otherwise, we won't have # permissions to push the built containers into registry. - if: github.event_name == 'push' + # if: github.event_name == 'push' + if: false # Disable temporarily outputs: baseimage-changed: ${{ steps.changes.outputs.baseimage }} @@ -231,6 +234,7 @@ jobs: BASE_IMAGE=${{ steps.baseimage.outputs.tag }} docker-image-test: + if: false # Disable temporarily name: Docker test circ-${{ matrix.image }} (${{ matrix.platform }}) runs-on: ubuntu-latest needs: [docker-image-build] @@ -301,6 +305,7 @@ jobs: run: docker stop test_container docker-image-push: + if: false # Disable temporarily name: Push circ-${{ matrix.image }} runs-on: ubuntu-latest needs: [test, test-migrations, docker-image-build, docker-image-test] @@ -331,7 +336,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: "3.10" - name: Install Poetry uses: ./.github/actions/poetry diff --git a/api/admin/config.py b/api/admin/config.py index b20b987a2..4d4f60337 100644 --- a/api/admin/config.py +++ b/api/admin/config.py @@ -17,7 +17,7 @@ class OperationalMode(str, Enum): class Configuration(LoggerMixin): APP_NAME = "E-kirjasto Collection Manager" PACKAGE_NAME = "@natlibfi/ekirjasto-circulation-admin" - PACKAGE_VERSION = "1.11.0" + PACKAGE_VERSION = "0.0.1" STATIC_ASSETS = { "admin_js": "circulation-admin.js", diff --git a/api/authenticator.py b/api/authenticator.py index bbad8c069..a73c145ea 100644 --- a/api/authenticator.py +++ b/api/authenticator.py @@ -215,7 +215,6 @@ def from_config( # Finland if authenticator.ekirjasto_provider: authenticator.ekirjasto_provider.set_secrets(_db) - authenticator.assert_ready_for_token_signing() return authenticator @@ -499,7 +498,7 @@ def authenticated_patron( provider_token = provider.validate_ekirjasto_delegate_token(auth.token) if isinstance(provider_token, ProblemDetail): return provider_token - elif self.saml_providers_by_name and auth.type.lower() == "bearer": + elif auth.type.lower() == "bearer": # The patron wants to use an # SAMLAuthenticationProvider. Figure out which one. if auth.token is None: diff --git a/api/controller.py b/api/controller.py index a19ff260b..2599e5a24 100644 --- a/api/controller.py +++ b/api/controller.py @@ -31,7 +31,7 @@ from api.circulation_exceptions import * from api.config import CannotLoadConfiguration, Configuration from api.ekirjasto_controller import EkirjastoController # Finland -from api.opensearch_analytics_search import OpenSearchAnalyticsSearch +from api.opensearch_analytics_search import OpenSearchAnalyticsSearch # Finland from api.custom_index import CustomIndexView from api.lanes import ( ContributorFacets, @@ -84,8 +84,6 @@ DeliveryMechanism, Hold, Identifier, - IntegrationConfiguration, - IntegrationLibraryConfiguration, Library, LicensePool, LicensePoolDeliveryMechanism, @@ -180,7 +178,6 @@ class CirculationManager: odl_notification_controller: ODLNotificationController static_files: StaticFileController playtime_entries: PlaytimeEntriesController - catalog_descriptions: CatalogDescriptionsController # Admin controllers admin_sign_in_controller: SignInController @@ -450,7 +447,6 @@ def setup_one_time_controllers(self): self.static_files = StaticFileController(self) self.patron_auth_token = PatronAuthTokenController(self) self.playtime_entries = PlaytimeEntriesController(self) - self.catalog_descriptions = CatalogDescriptionsController(self) def setup_configuration_dependent_controllers(self): """Set up all the controllers that depend on the @@ -689,27 +685,13 @@ def load_licensepools(self, library, identifier_type, identifier): """ _db = Session.object_session(library) pools = ( - _db.scalars( - select(LicensePool) - .join(Collection, LicensePool.collection_id == Collection.id) - .join(Identifier, LicensePool.identifier_id == Identifier.id) - .join( - IntegrationConfiguration, - Collection.integration_configuration_id - == IntegrationConfiguration.id, - ) - .join( - IntegrationLibraryConfiguration, - IntegrationConfiguration.id - == IntegrationLibraryConfiguration.parent_id, - ) - .where( - Identifier.type == identifier_type, - Identifier.identifier == identifier, - IntegrationLibraryConfiguration.library_id == library.id, - ) - ) - .unique() + _db.query(LicensePool) + .join(LicensePool.collection) + .join(LicensePool.identifier) + .join(Collection.libraries) + .filter(Identifier.type == identifier_type) + .filter(Identifier.identifier == identifier) + .filter(Library.id == library.id) .all() ) if not pools: @@ -1024,7 +1006,7 @@ def crawlable_collection_feed(self, collection_name): """Build or retrieve a crawlable acquisition feed for the requested collection. """ - collection = Collection.by_name(self._db, collection_name) + collection = get_one(self._db, Collection, name=collection_name) if not collection: return NO_SUCH_COLLECTION title = collection.name @@ -1437,7 +1419,7 @@ def borrow(self, identifier_type, identifier, mechanism_id=None): """ patron = flask.request.patron library = flask.request.library - + header = self.authorization_header() credential = self.manager.auth.get_credential_from_header(header) @@ -2443,13 +2425,13 @@ def image(self, filename): ) return self.static_file(directory, filename) + # Finland class CatalogDescriptionsController(CirculationManagerController): def get_catalogs(self, library_uuid=None): catalogs = [] libraries = [] - - + if library_uuid != None: try: libraries = [ @@ -2468,23 +2450,23 @@ def get_catalogs(self, library_uuid=None): { "rel": "http://opds-spec.org/image/thumbnail", "href": library.logo.data_url, - "type": "image/png" + "type": "image/png", } ] authentication_document_url = url_for( "authentication_document", - library_short_name=library.short_name, - _external=True + library_short_name=library.short_name, + _external=True, ) catalog_url = url_for( "acquisition_groups", - library_short_name=library.short_name, - _external=True + library_short_name=library.short_name, + _external=True, ) - - timenow = utc_now().strftime('%Y-%m-%dT%H:%M:%SZ') + + timenow = utc_now().strftime("%Y-%m-%dT%H:%M:%SZ") metadata = { "id": "urn:uuid:" + library.uuid, @@ -2492,9 +2474,9 @@ def get_catalogs(self, library_uuid=None): "short_name": library.short_name, "modified": timenow, "updated": timenow, - "isAutomatic": False + "isAutomatic": False, } - + if "library_description" in settings: metadata["description"] = settings["library_description"] @@ -2502,53 +2484,40 @@ def get_catalogs(self, library_uuid=None): { "rel": "http://opds-spec.org/catalog", "href": catalog_url, - "type": "application/atom+xml;profile=opds-catalog;kind=acquisition" + "type": "application/atom+xml;profile=opds-catalog;kind=acquisition", }, { "href": authentication_document_url, - "type": "application/vnd.opds.authentication.v1.0+json" - } + "type": "application/vnd.opds.authentication.v1.0+json", + }, ] - + if "help_web" in settings: - links += [{ - "href": settings["help_web"], - "rel": "help" - }] + links += [{"href": settings["help_web"], "rel": "help"}] elif "help_email" in settings: - links += [{ - "href": "mailto:"+settings["help_email"], - "rel": "help" - }] + links += [{"href": "mailto:" + settings["help_email"], "rel": "help"}] + + catalogs += [{"metadata": metadata, "links": links, "images": images}] - catalogs += [ - { - "metadata": metadata, - "links": links, - "images": images - } - ] - response_json = { - "metadata": { - "title": "Libraries" - }, + "metadata": {"title": "Libraries"}, "catalogs": catalogs, "links": [ { "rel": "self", "href": url_for("client_libraries", _external=True), - "type": "application/opds+json" + "type": "application/opds+json", } - ] + ], } - + return Response( json_serializer(response_json), status=200, mimetype="application/json", ) + class PatronAuthTokenController(CirculationManagerController): def get_token(self): """Create a Patron Auth access token for an authenticated patron""" diff --git a/api/opensearch_analytics_provider.py b/api/opensearch_analytics_provider.py index eba83997b..5825e7df2 100644 --- a/api/opensearch_analytics_provider.py +++ b/api/opensearch_analytics_provider.py @@ -204,17 +204,23 @@ def _create_event_object( "authors": [ contribution.contributor.sort_name for contribution in edition.contributions - if contribution.role == Contributor.AUTHOR_ROLE + if getattr(contribution.contributor, "role", None) + == Contributor.AUTHOR_ROLE ] if edition else None, "contributions": [ ": ".join( - contribution.contributor.role, - contribution.contributor.sort_name, + [ + getattr(contribution.contributor, "role", ""), + contribution.contributor.sort_name, + ] ) for contribution in edition.contributions - if contribution.role != Contributor.AUTHOR_ROLE + if ( + not getattr(contribution.contributor, "role", None) + or contribution.contributor.role != Contributor.AUTHOR_ROLE + ) ] if edition else None, diff --git a/docker-compose.yml b/docker-compose.yml index 11c30e56f..258847373 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,8 +56,3 @@ services: environment: discovery.type: single-node DISABLE_SECURITY_PLUGIN: true - - admin: - build: - dockerfile: docker/Dockerfile.admin - target: admin diff --git a/docker/Dockerfile b/docker/Dockerfile index 4a47975a3..c7c2bbb29 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -6,7 +6,7 @@ # The only difference are what services are enabled. ############################################################################### -ARG BASE_IMAGE=ghcr.io/natlibfi/ekirjasto-circ-baseimage:latest +ARG BASE_IMAGE=ghcr.io/thepalaceproject/circ-baseimage:latest FROM ${BASE_IMAGE} AS common @@ -66,20 +66,13 @@ ENV TZ=Europe/Helsinki # Setup nginx COPY docker/services/nginx /etc/nginx/ -COPY docker/admin_dist.tar.gz /mnt/admin_dist.tar.gz # Setup uwsgi COPY docker/services/uwsgi /etc/ RUN mkdir -p /var/log/uwsgi && \ chown -RHh simplified:simplified /var/log/uwsgi && \ mkdir /var/run/uwsgi && \ - chown simplified:simplified /var/run/uwsgi && \ - cd /var/www/circulation/api/admin && \ - tar xf /mnt/admin_dist.tar.gz && \ - chown -R simplified:simplified dist && \ - rm /mnt/admin_dist.tar.gz - -COPY --chown=simplified:simplified docker/config.py_admin /var/www/circulation/api/admin/config.py + chown simplified:simplified /var/run/uwsgi # Setup runit COPY docker/runit /etc/service/ @@ -89,4 +82,3 @@ WORKDIR /home/simplified/circulation EXPOSE 80 CMD ["/sbin/my_init"] - diff --git a/docker/Dockerfile.admin b/docker/Dockerfile.admin deleted file mode 100755 index a1359b9cc..000000000 --- a/docker/Dockerfile.admin +++ /dev/null @@ -1,83 +0,0 @@ -FROM ubuntu:22.04 as admin - -LABEL maintainer="Joe Random " - -ARG BUILDENV=devz - -#RUN if [ "${BUILDENV}" != "lfapi" -a "${BUILDENV}" != "lsstest" -a "${BUILDENV}" != "lfapi2" -a "${BUILDENV}" != "ltstest" -a "${BUILDENV}" != "prod" ]; \ -# then exit 1 ; \ -# fi - -RUN sed -i 's/http:\/\/archive\.ubuntu\.com\/ubuntu/http:\/\/mirrors.nic.funet.fi\/ubuntu\//' \ - /etc/apt/sources.list - -ENV DEBIAN_FRONTEND noninteractive -ENV TERM linux - -#ENV TINI_VERSION v0.19.0 -#ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini - -RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends \ - apt-utils \ - apt-transport-https \ - ca-certificates \ - curl \ - debconf-utils \ - gnupg \ - gzip \ - net-tools \ - software-properties-common \ - tar \ - telnet \ - tzdata \ - wget && \ - mkdir -p /etc/apt/keyrings && \ - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | \ - tee /etc/apt/sources.list.d/nodesource.list && \ - echo Europe/Helsinki >/etc/timezone && \ - ln -sf /usr/share/zoneinfo/Europe/Helsinki /etc/localtime && \ - dpkg-reconfigure -f noninteractive tzdata && \ - apt-get update && apt-get install -y --allow-unauthenticated --no-install-recommends \ - less \ - nodejs && \ - npm update -g npm && \ - rm -f /etc/cron.daily/* && \ - rm -rf /var/lib/apt/lists/* && \ - groupadd -g 1000 node && \ - useradd -u 1000 -r -g node -d /home/node -s /bin/bash -c "Node image user" node && \ - apt-get remove -y \ - apt-transport-https \ - apt-utils \ - debconf-utils \ - gnupg \ - software-properties-common \ - wget && \ - apt-get autoremove -y - -COPY palace_circulation_admin_ui /opt/circulation/admin - -RUN cd /opt/circulation/admin && \ - npm install && \ - npm run test-finland && \ - retval=$? && \ - if [ $retval -ne 0 ]; then \ - echo "Admin UI test failed" && \ - exit $retval ; \ - fi && \ - mkdir -p /mnt/tarball && \ - tar czvf /mnt/tarball/admin_dist.tar.gz dist - -# Specify the port number the container should expose -#EXPOSE 8080 - -# Set up working dir -#WORKDIR /opt/circulation/admin - -# Entrypoint is run prior to CMD -#ENTRYPOINT ["/tini", "--"] - -# Actual command to start, can be overridden to start e.g. ASR API -#CMD ["npm", "run", "dev-server", "--", "--env=backend=webapp:6500"] - - diff --git a/tests/api/admin/test_config.py b/tests/api/admin/test_config.py index e336cfc73..1780cc698 100644 --- a/tests/api/admin/test_config.py +++ b/tests/api/admin/test_config.py @@ -132,12 +132,12 @@ def test_package_url( [ None, None, - "/my-base-dir/node_modules/@natlibfi/circulation-admin", + "/my-base-dir/node_modules/@natlibfi/ekirjasto-circulation-admin", ], [ None, "1.0.0", - "/my-base-dir/node_modules/@natlibfi/circulation-admin", + "/my-base-dir/node_modules/@natlibfi/ekirjasto-circulation-admin", ], ["some-package", "1.0.0", "/my-base-dir/node_modules/some-package"], ],