github phax/phoss-smp phoss-smp-parent-pom-8.3.0
v8.3.0

4 hours ago
  • Updated to Flyway 13.4.0
  • Updated to the MongoDB driver 5.10.0
  • Updated to protobuf 4.36.0
  • Updated to ph-commons 12.4.0, ph-oton 10.4.0 and ph-oton-bootstrap5 0.9.3
  • Improved the Content Security Policy of the management UI.
    Removed 'self' from script-src, because with 'strict-dynamic' present all host and scheme sources are ignored by the browser anyway, and removed it from style-src-attr, where only 'unsafe-inline' and hashes are meaningful. Both were inert and only implied a fallback that does not exist.
    Added base-uri 'self', form-action 'self', frame-ancestors 'none' and object-src 'none'. Note that form-action and frame-ancestors do not fall back to default-src, so they were previously not set at all.
  • The CSP violation reporting now also uses the Reporting API next to the deprecated report-uri: the policy contains a report-to directive and the new Reporting-Endpoints HTTP response header names the very same endpoint.
    The report URI now carries the menu item ID of the page and the SMP build version as query parameters, so that a report can be attributed to a page without having to guess from the report body. Both values are non-sensitive - the policy is readable by everybody loading the page and is echoed back in every report.
    Reports that are caused by browser internal code or by browser extensions - recognizable by a "source-file" that is not an http(s) URL - are now classified as noise. They are still logged, but no longer raise an internal error, so that real violations are not drowned out any more.
  • (SQL) Added the new database migration V35 that adds the nullable column job_type varchar(100) and the index IX_smp_long_running_job_jt to the table smp_long_running_job, for MySQL, PostgreSQL, Oracle, DB2 and SQL Server.
    The column is written by the LongRunningJobResultManagerJDBC of ph-oton 10.4.0 - without it, storing a long running job result fails. Job results created before this version keep an empty job type and therefore never match a job type filter
  • Fixed that in the public URL mode forwarded-header a non-default port contained in the host parameter of the Forwarded HTTP header was dropped from all created URLs, because the port number was taken from the wrong offset of the host value.
    Additionally IPv6 host literals like [2001:db8::1]:8443 are now split into host and port correctly.
    See #514 - thx @vinit-thummar
  • Fixed that in the public URL mode x-forwarded-header the port of the incoming request was never used as a fallback, because the internal fallback flag was initialized to false and could never become true.
    If none of the X-Forwarded-* HTTP headers is present, the port of the incoming request is used again - previously the port was dropped from all created URLs in that case. If at least one of X-Forwarded-Proto or X-Forwarded-Host is present, but X-Forwarded-Port is not, the default port of the scheme is still used.
    See #518 - thx @vinit-thummar
  • Fixed that in the public URL mode x-forwarded-header the port was contained twice in all created URLs (as in https://example.com:8443:8443/...), if the X-Forwarded-Host HTTP header already contained a port and the X-Forwarded-Port HTTP header was present as well.
    An optional port is now split off the X-Forwarded-Host value before the URL is created - taking bracketed IPv6 literals like [::1]:8443 into account. The X-Forwarded-Port header still takes precedence; if it is absent, the port contained in X-Forwarded-Host is used instead of the default port of the scheme.
    See #528 - thx @vinit-thummar
  • The relaxed SML hostname verification (accepting all TLS hostnames) is now only applied, if the host of the SML management service URL is exactly localhost or 127.0.0.1.
    Previously a substring check on the whole URL was performed, so that e.g. https://localhost.example.org/..., https://localhost@example.org/... or https://example.org//localhost also disabled the TLS hostname verification.
    See #522 - thx @vinit-thummar
  • The Bearer scheme of the REST API Authorization HTTP header is now matched case-insensitively (e.g. bearer or BEARER), because HTTP authentication schemes are case-insensitive according to RFC 9110 section 11.1. The token value itself is used unchanged.
    See #521 - thx @vinit-thummar
  • Fixed that the Font Awesome 6 icon resources were not registered on the public start page and on the secure pages "Business Cards", "Endpoints" (List and Tree view), "Redirects" and "Service Groups", so that the respective icons were not displayed. This was a leftover of the Bootstrap 5 migration of v8.2.0
  • Only a single Service Group export can run at a time now. Previously every click on the "Export" button in the management UI, and every call of the REST APIs GET /exchange/export/all/xml/v1 and GET /exchange/export/byowner/{UserId}/xml/v1, started another full export - several parallel exports of a large SMP could exhaust the heap and render the server unresponsive.
    A second export is now rejected: the REST API returns HTTP 503 (Service Unavailable) with a Retry-After HTTP header, and the management UI disables the button and shows since when the running export is active. The export of a single Service Group (GET /exchange/export/specific/{ServiceGroupId}/xml/v1) and the outbound migration export are not affected, because their size is bounded.
    The lock is the new ph-oton class SingleRunLock, exposed as ServiceGroupExportJob.LOCK. Added the new exception class SMPServiceUnavailableException.
    See #525 - thx @basileHalaweh
  • The Service Group export data is no longer built as a single in-memory XML document. It is now serialized Service Group by Service Group, so that the memory consumption no longer depends on the total number of exported Service Groups. The created XML is unchanged.
    Added the new method ServiceGroupExport.createExportDataXMLVer10 (ICommonsList, boolean, OutputStream), the new constant ServiceGroupExport.XML_WRITER_SETTINGS and the new method ServiceGroupExport.getExportMimeType ().
    See #525 - thx @basileHalaweh
  • The Service Group export of the management UI is now executed as a background job instead of being a direct download. Clicking "Export all Service Groups" returns immediately, the export is written to a file in the new directory servicegroup-export below the configured webapp.datapath, and neither an HTTP thread nor the created data is held for the duration of the export.
    The state and the result of the export are visible on the new ph-oton page "Administration / Application Information / Long running jobs", from where finished results can also be deleted.
    Added the new class ServiceGroupExportJob.
    Note: the REST export APIs are unchanged and still return the export data directly in the HTTP response.
    See #525 - thx @basileHalaweh
  • Added the new secure page "Service Groups / Export data" that lists the previously created Service Group exports and allows to download them.
    The download is addressed by the ID of the long running job that created the export - never by a file name or a path. The resolved file must additionally be an existing regular file located directly in the servicegroup-export directory and follow the export file naming, so that no other file of the server can be retrieved through this page. The check is done on the canonical paths, so .. path elements and symbolic links cannot be used to escape the export directory.
    Added the new method ServiceGroupExportJob.getValidExportFile (File) and the new menu item ID CMenuSecure.MENU_SERVICE_GROUPS_EXPORT_DATA.
    See #525 - thx @basileHalaweh
  • Created Service Group export files are now deleted after a configurable retention period. The new configuration property smp.export.retention.days defaults to 30 days; 0 or a negative value keeps the files forever. Outdated files - and the long running job results referring to them - are removed by a new scheduled job that runs once a day at 02:00, and additionally whenever a new export is started.
    Added the new class ServiceGroupExportPurgeJob, the new method ServiceGroupExportJob.purgeOldExportFiles () and the new method SMPServerConfiguration.getExportRetentionDays ().
    This is the first scheduled job of phoss SMP - it shows up on the page "Administration / Application Information / Scheduled Actions".
    See #525 - thx @basileHalaweh
  • Fixed that the action "Update all Business Cards in the Directory" could be started an arbitrary number of times in parallel, because only a hint was shown but the button was never disabled. Only a single push may run at a time now, guarded by the same SingleRunLock class.
  • Fixed that the bulk changes of the endpoint certificate ("Endpoints / Change Certificate") and of the endpoint URL ("Endpoints / Change URL") could be started an arbitrary number of times in parallel. Both write to all matching endpoints, so parallel runs could interfere with each other. Only a single bulk change of each kind may run at a time now, guarded by SingleRunLock as well.
  • (MongoDB) Fixed that replacing an existing Service Information with a different object instance (as done by the REST API) invoked the onSMPServiceInformationCreated callback instead of onSMPServiceInformationUpdated. This now matches the behaviour of the XML backend.
    See #519 - thx @vinit-thummar
  • (MongoDB) Fixed that ISMPServiceGroupManager.getAllSMPServiceGroupIDs () returned the owner IDs instead of the Service Group IDs, because the wrong BSON field (ownerid instead of id) was read.
    This affected the REST API GET /servicegroupids/all, the Service Group Import (UI and REST API PUT /exchange/import/xml/v1/{UserId}) and the pages "Endpoints (Tree view)" and "Tasks/Problems" in the management UI.
    See #524 - thx @vinit-thummar
  • (MongoDB) Fixed that updating a Transport Profile stored the deprecation flag in the obsolete BSON field deprecated instead of the field state used since v6.0.7, so that a changed state was silently lost when the Transport Profile was read again.
    Reading still falls back to the deprecated field, if no state field is present, so that data written by older versions is still interpreted correctly.
    See #524 - thx @vinit-thummar
  • (MongoDB) Fixed that the audit entries created when deleting a Transport Profile used the object type smpredirect instead of smp.transport.profile.
    See #523 - thx @vinit-thummar
  • (MongoDB) Fixed that security operations that don't change anything reported EChange.CHANGED instead of EChange.UNCHANGED, because the last-modification fields were always written and therefore MongoDB always reported a modified document.
    This affected deleting an already deleted object, undeleting a non-deleted object, assigning a User or a Role to a User Group it is already assigned to, and unassigning a User or a Role that is not assigned. Besides the wrong return value, the modification metadata was rewritten and the success callbacks were invoked for these no-ops. The behaviour now matches the XML and SQL backends.
    Added the new protected method AbstractBusinessObjectManagerMongoDB.genericUpdateOne (String, Bson, Bson) taking an additional filter, so that each state transition stays atomic.
    See #530 - thx @vinit-thummar
  • (MongoDB) Added LongRunningJobResultManagerMongoDB.deleteResult (String) and forEachJobResult (String, Consumer), implementing the new methods of the ph-oton interface ILongRunningJobResultManager.
    The job type of a long running job is now stored in the new BSON field job_type (incl. an index on it), so that job results can be queried per job type. Documents written by previous versions have no job_type field and therefore never match a job type filter - they are still returned when querying without a filter.
  • (MongoDB) The endpoint usage evaluation of the Endpoint "Change URL" and "Change Certificate" pages now happens inside MongoDB. getEndpointCount (), getEndpointURLUsageMap () and getEndpointCertificateUsageMap () use an aggregation pipeline that unwinds all endpoints and groups them, so that only a scalar count respectively one small document per group is transferred, instead of transferring and deserializing every complete Service Information document - including the unrelated process, description, contact and extension data - into Java.
    Based on #533 - thx @vinit-thummar. See #333.
    The URL filtering and the certificate normalization are unchanged: the grouping happens on the stored certificate, and the different spellings of one certificate - with and without PEM header - are merged afterwards, as before.
    The two grouping pipelines allow disk usage, so that a large SMP no longer risks an out of memory error in the SMP itself; the spilling happens in the MongoDB server instead. Note that MongoDB Atlas shared tier clusters (M0, M2 and M5) may not support that option.
    Note that the Endpoint list page still reads all Service Information objects, so #333 is only partially solved by this.
  • (MongoDB) The collection smp-serviceinfo now creates the indexes id, sgid, processes.endpoints.endpointreference and processes.endpoints.transportprofile on startup, as all the other MongoDB managers already did for their ID field.
    Next to the endpoint queries, the index on id also speeds up updateAllEndpointURLs (...) and updateAllEndpointCertificates (...), which replace the matching documents by ID one by one.
  • Added the new method EndpointUsageInfo.addForServiceGroupID (String, int) as the bulk version of incrementForServiceGroupID (String), so that a backend that lets the database do the counting does not need to increment one endpoint at a time. incrementForServiceGroupID (String) is unchanged and now delegates to it.
  • Added the new constant AbstractManagerMongoDB.BSON_MONGO_ID for the MongoDB internal _id field, because the MongoDB Java driver has no public constant for it - the only one it has is package private.
  • (Docker) The discarded first build stage of the Dockerfile-release-binary-* files no longer runs apt-get upgrade and installs only ca-certificates, wget and unzip with --no-install-recommends. The runtime image stays tomcat:10.1-jre25.
    See #517 - thx @gregjotau
  • (Docker) The Docker README now mentions, that the SQL image contains the JDBC drivers of all supported databases (roughly 20 MB in WEB-INF/lib) and that the unused drivers may be deleted in downstream images
  • (CI) The GitHub Actions build matrix now also builds with Java 26 (in addition to Java 17, 21 and 25). The Java source and target compatibility remains at Java 17.
    See #516 - thx @gregjotau
  • (Development) The JettyStopSMPSERVER_* classes now use the stop port 1090 instead of 8090, so that they match the stop port used by the respective RunInJettySMPSERVER_* classes.
    See #513 - thx @vinit-thummar

What's Changed

New Contributors

Full Changelog: phoss-smp-parent-pom-8.2.0...phoss-smp-parent-pom-8.3.0

Don't miss a new phoss-smp release

NewReleases is sending notifications on new releases.