diff --git a/doc/en/developer/source/cite-test-guide/index.rst b/doc/en/developer/source/cite-test-guide/index.rst index b8ef61d8c6f..8b45d2dbb63 100644 --- a/doc/en/developer/source/cite-test-guide/index.rst +++ b/doc/en/developer/source/cite-test-guide/index.rst @@ -10,177 +10,170 @@ A step by step guide to the GeoServer Compliance Interoperability Test Engine (C ~~~~~~~~~~~~~ -Check out CITE suite tests --------------------------- +Check out OGC CITE suite tests +------------------------------ .. note:: The CITE suite tests are available at `Open Geospatial Consortium`_. .. _Open Geospatial Consortium: https://github.com/opengeospatial Requirements: -------------- -- `GeoServer instance `_. +- `GeoServer instance `_. - `Teamengine Web Application `_, with a set of CITE suite tests. -- make +- ``make`` CITE automation tests with docker -================================= +--------------------------------- How to run the CITE Test suites with `docker `_. Requirements: -------------- -- Running the tests requires a linux system with `docker `_, `docker-compose `_, and git installed on it. +- Running the tests requires a Linux system with `docker `_, `docker-compose `_, and Git installed on it. .. note:: The CITE tools are available in the build/cite folder of the `GeoServer Git repository `_: -Steps: ------- +Set-up the environment +^^^^^^^^^^^^^^^^^^^^^^ -Set-up the environment. -~~~~~~~~~~~~~~~~~~~~~~~ +#. Clone the repository. - #. Clone the repository. + .. code:: shell - .. code:: shell + git clone https://github.com/geoserver/geoserver.git - git clone https://github.com/geoserver/geoserver.git +#. Go to the cite directory. - #. Go to cite directory. + .. code:: shell - .. code:: shell + cd geoserver/build/cite - cd geoserver/build/cite +#. Inside you will find a structure, like below, with a list of directories which contains the name of the suites to run. - #. Inside you will find a structure, like below, with a list of directories which contains the name of the suites to run. + .. code:: shell - .. code:: shell + cite + |-- forms + |-- geoserver + |-- run-test.sh + |-- wcs10 + |-- wcs11 + |-- wfs10 + |-- wms11 + |-- wms13 + |-- wfs11 + |-- interactive + |-- logs + |-- docker-compose.yml + |-- postgres + |-- README.md + `-- Makefile - cite - |-- forms - |-- geoserver - |-- run-test.sh - |-- wcs10 - |-- wcs11 - |-- wfs10 - |-- wms11 - |-- wms13 - |-- wfs11 - |-- interactive - |-- logs - |-- docker-compose.yml - |-- postgres - |-- README.md - `-- Makefile +Running the suite tests +^^^^^^^^^^^^^^^^^^^^^^^ -Running the suite tests. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There are 2 ways to run the suites. One is running with ``make`` that will +automate all the commands, and the second one is running the test through WebUI: - There are 2 ways to run the suites. One is running with ``make`` that will - automate all the commands, and the second one is running the test through WebUI: +1. Running it through ``Makefile``: - 1. Running it through ``Makefile``: + - run ``make`` in the console, it will give you the list of commands + to run. - - run ``make`` in the console, it will give you the list of commands - to run. + .. code:: shell - .. code:: shell + make - make + - the output will look like this: - - the output will like this: + .. code:: makefile - .. code:: makefile + clean: $(suite) This will clean the Environment of previous runs. + build: $(suite) This will build the GeoServer Docker Image for the Environment. + test: $(suite) This will run the Suite test with teamengine. + webUI: $(suite) This will run the Suite test with teamengine. - clean: $(suite) Will Clean the Environment of previous runs. - build: $(suite) Will Build the GeoServer Docker Image for the Environment. - test: $(suite) Will running the Suite test with teamengine. - webUI: $(suite) Will running the Suite test with teamengine. + - Choose which test to run, this is an example: - - Choose which test to run, this is an example: + .. warning:: - .. warning:: + The first Docker build may take a long time. - The first Docker build may take a long time. + .. code:: SHELL - .. code:: SHELL + suite=wcs10 - suite=wcs10 - - .. note:: - - Valid values for the suite parameter are: - * wcs10 - * wcs11 - * wfs10 - * wfs11 - * wms11 - * wms13 + .. note:: - - Choose which GeoServer war file to test by setting the ``war_url`` environment variable inside the ``Makefile``, ex: + Valid values for the suite parameter are: + * wcs10 + * wcs11 + * wfs10 + * wfs11 + * wms11 + * wms13 - .. code:: C + - Choose which GeoServer war file to test by setting the ``war_url`` environment variable inside the ``Makefile``, ex: - war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" + .. code:: C - .. note:: + war_url = "https://build.geoserver.org/geoserver/main/geoserver-main-latest-war.zip" - if you don't want to do it inside the ``Makefile`` you have the option of adding the variable in the command when you build the docker images. +2. If you don't want to do it inside the ``Makefile`` you have the option of adding the variable in the command when you build the docker images. - - To clean the local environment. + - To clean the local environment. - .. code:: shell + .. code:: shell - make clean + make clean - - To build the geoserver docker image locally. + - To build the GeoServer Docker image locally. - .. code:: shell + .. code:: shell - make build suite= + make build suite= - - Alternative, with the ``war_url`` variable include: + - Alternative, with the ``war_url`` variable include: - .. code:: + .. code:: - make build suite= war_url= + make build suite= war_url= - - To run the suite test. + - To run the suite test. - .. code:: shell + .. code:: shell - make test suite= + make test suite= - - To run the full automate workflow. + - To run the full automate workflow. - .. code:: shell + .. code:: shell - make clean build test suite= + make clean build test suite= -Run CITE Test Suites in local pc -================================ +Run CITE Test Suites on a local PC +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: - I assume that you have a standalone geoserver running. + I assume that you have a standalone GeoServer running. .. important:: Details to consider when you are running the tests: - - The Default username/password for the teamengine webUI are **teamengine/teamengine**. + - The default username/password for the teamengine webUI are **teamengine/teamengine**. - - the default url for the teamengine webUI is http://localhost:8888/teamengine/ + - the default URL for the teamengine webUI is http://localhost:8888/teamengine/ - The output of the old suite tests might not appear in the Result page. So you should click on the link below **detailed old test report**, to get the full report. Ex. @@ -188,7 +181,7 @@ Run CITE Test Suites in local pc .. image:: ./image/full-report.png - - Since you are running teamengine inside a container, the localhost in the url of geoserver for the tests can't be used, for that, get the ip of host where the geoserver is running. You will use it later. + - Since you are running teamengine inside a container, the localhost in the URL of GeoServer for the tests can't be used, for that, get the IP address of the host where the GeoServer is running. You will use it later. - after you log in to teamengine webUI you have to create a session. @@ -199,10 +192,7 @@ Run CITE Test Suites in local pc .. image:: ./image/tewfs-1_0a.png - - Requirements: -------------- - GeoServer running. @@ -211,7 +201,6 @@ Requirements: - Teamengine Running in docker container. - #. Clone the repository: .. code:: shell @@ -237,21 +226,20 @@ Requirements: .. code:: makefile - clean: $(suite) Will Clean the Environment of previous runs. - build: $(suite) Will Build the GeoServer Docker Image for the Environment. - test: $(suite) Will running the Suite test with teamengine. - webUI: $(suite) Will running the Suite test with teamengine. + clean: $(suite) This will clean the Environment of previous runs. + build: $(suite) This will build the GeoServer Docker Image for the Environment. + test: $(suite) This will run the Suite test with teamengine. + webUI: $(suite) This will run the Suite test with teamengine. Run WFS 1.0 tests ------------------ +^^^^^^^^^^^^^^^^^ .. important:: Running WFS 1.0 tests require PostgreSQL with PostGIS extension installed in the system. Requirements: -~~~~~~~~~~~~~ - `GeoServer running` - teamengine @@ -260,7 +248,7 @@ Requirements: #. Prepare the environment: - - login to postgresql and create a user named "cite". + - login to PostgreSQL and create a user named "cite". .. code:: sql @@ -272,7 +260,7 @@ Requirements: createdb cite own by cite; - - enter to the database and enable the postgis extension: + - enter the database and enable the postgis extension: .. code:: sql @@ -282,23 +270,23 @@ Requirements: .. code-block:: shell - cd + cd psql -U cite cite < build/cite/wfs10/citewfs-1.0/cite_data_postgis2.sql - Start GeoServer with the citewfs-1.0 data directory. Example: .. important:: - If the postgresql server is not in the same host of the geoserver, you have to change the `localhost` in the `datastore.xml` file, located inside each workspace directory. ex. + If the PostgreSQL server is not on the same host as the GeoServer, you have to change the `localhost` in the `datastore.xml` file, located inside each workspace directory. ex. .. note:: - /build/cite/wfs10/citewfs-1.0/workspaces/cgf/cgf/datastore.xml + /build/cite/wfs10/citewfs-1.0/workspaces/cgf/cgf/datastore.xml .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wfs10/citewfs-1.0 + cd + export GEOSERVER_DATA_DIR=/build/cite/wfs10/citewfs-1.0 ./bin/startup.sh #. Start the test: @@ -313,29 +301,28 @@ Requirements: - after creating the session, and choosing the test, enter the following parameters: - #. ``Capabilities URL`` http://:8080/geoserver/wfs?request=getcapabilities&service=wfs&version=1.0.0 + #. ``Capabilities URL`` http://:8080/geoserver/wfs?request=getcapabilities&service=wfs&version=1.0.0 #. ``Enable tests with multiple namespaces`` tests included .. image:: ./image/tewfs-1_0.png Run WFS 1.1 tests ------------------ +^^^^^^^^^^^^^^^^^ .. important:: Running WFS 1.1 tests requires PostgreSQL with PostGIS extension installed in the system. Requirements: -~~~~~~~~~~~~~ - GeoServer - teamengine -- Posgresql +- PostgreSQL - PostGIS #. Prepare the environment: - - login to postgresql and create a user named "cite". + - login to PostgreSQL and create a user named "cite". .. code:: sql @@ -357,23 +344,23 @@ Requirements: .. code-block:: shell - cd + cd psql -U cite cite < build/cite/wfs11/citewfs-1.1/dataset-sf0-postgis2.sql - Start GeoServer with the citewfs-1.1 data directory. Example: .. important:: - If the postgresql server is not in the same host of the geoserver, you have to change the `localhost` in the `datastore.xml` file, located inside each workspace directory. ex. + If the PostgreSQL server is not on the same host as the GeoServer, you have to change the `localhost` in the `datastore.xml` file, located inside each workspace directory. ex. .. note:: - /build/cite/wfs11/citewfs-1.1/workspaces/cgf/cgf/datastore.xml + /build/cite/wfs11/citewfs-1.1/workspaces/cgf/cgf/datastore.xml .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wfs11/citewfs-1.1 + cd + export GEOSERVER_DATA_DIR=/build/cite/wfs11/citewfs-1.1 ./bin/startup.sh @@ -389,7 +376,7 @@ Requirements: - after creating the session, and choosing the test, enter the following parameters: - #. ``Capabilities URL`` http://:8080/geoserver/wfs?service=wfs&request=getcapabilities&version=1.1.0 + #. ``Capabilities URL`` http://:8080/geoserver/wfs?service=wfs&request=getcapabilities&version=1.1.0 #. ``Supported Conformance Classes``: @@ -404,7 +391,7 @@ Requirements: .. image:: ./image/tewfs-1_1b.png Run WMS 1.1 tests ------------------ +^^^^^^^^^^^^^^^^^ #. Prepare the environment: @@ -412,8 +399,8 @@ Run WMS 1.1 tests .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wms11/citewms-1.1 + cd + export GEOSERVER_DATA_DIR=/build/cite/wms11/citewms-1.1 ./bin/startup.sh #. Start the test: @@ -430,7 +417,7 @@ Run WMS 1.1 tests #. ``Capabilities URL`` - http://:8080/geoserver/wms?service=wms&request=getcapabilities&version=1.1.1 + http://:8080/geoserver/wms?service=wms&request=getcapabilities&version=1.1.1 #. ``UpdateSequence Values``: @@ -454,7 +441,7 @@ Run WMS 1.1 tests .. image:: ./image/tewms-1_1b.png Run WCS 1.0 tests ------------------ +^^^^^^^^^^^^^^^^^ #. Prepare the environment: @@ -462,8 +449,8 @@ Run WCS 1.0 tests .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wcs10/citewcs-1.0 + cd + export GEOSERVER_DATA_DIR=/build/cite/wcs10/citewcs-1.0 ./bin/startup.sh #. Start the test: @@ -480,7 +467,7 @@ Run WCS 1.0 tests #. ``Capabilities URL``: - http://:8080/geoserver/wcs?service=wcs&request=getcapabilities&version=1.0.0 + http://:8080/geoserver/wcs?service=wcs&request=getcapabilities&version=1.0.0 #. ``MIME Header Setup``: "image/tiff" @@ -513,7 +500,7 @@ Run WCS 1.0 tests Run WCS 1.1 tests ------------------ +^^^^^^^^^^^^^^^^^ #. Prepare the environment: @@ -521,8 +508,8 @@ Run WCS 1.1 tests .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wcs11/citewcs-1.1 + cd + export GEOSERVER_DATA_DIR=/build/cite/wcs11/citewcs-1.1 ./bin/startup.sh @@ -540,7 +527,7 @@ Run WCS 1.1 tests #. ``Capabilities URL``: - http://:8080/geoserver/wcs + http://:8080/geoserver/wcs Click ``Next`` @@ -548,7 +535,7 @@ Run WCS 1.1 tests Run WMS 1.3 tests ------------------ +^^^^^^^^^^^^^^^^^ #. Prepare the environment: @@ -556,8 +543,8 @@ Run WMS 1.3 tests .. code-block:: shell - cd - export GEOSERVER_DATA_DIR=/build/cite/wms13/citewms-1.3 + cd + export GEOSERVER_DATA_DIR=/build/cite/wms13/citewms-1.3 ./bin/startup.sh @@ -575,7 +562,7 @@ Run WMS 1.3 tests #. ``Capabilities URL``: - http://:8080/geoserver/wms?service=wms&request=getcapabilities&version=1.3.0 + http://:8080/geoserver/wms?service=wms&request=getcapabilities&version=1.3.0 #. ``UpdateSequence Values``: @@ -591,7 +578,6 @@ Run WMS 1.3 tests .. image:: ./image/tewms-1_3.png - .. _commandline: .. _teamengine: diff --git a/doc/en/developer/source/conf.py b/doc/en/developer/source/conf.py index d7f3231b8fd..2a42bf55bca 100644 --- a/doc/en/developer/source/conf.py +++ b/doc/en/developer/source/conf.py @@ -71,9 +71,7 @@ # List of directories, relative to source directories, that shouldn't be searched # for source files. -exclude_patterns = [ - 'release-guide/old.rst' -] +# exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None diff --git a/doc/en/developer/source/index.rst b/doc/en/developer/source/index.rst index 1c053c17c02..86f02f9489b 100644 --- a/doc/en/developer/source/index.rst +++ b/doc/en/developer/source/index.rst @@ -15,9 +15,7 @@ Welcome to the GeoServer Developer Manual. The manual is for those who want to eclipse-guide/index qa-guide/index programming-guide/index - release-schedule/index - release-guide/index - release-testing-checklist/index + release/index cite-test-guide/index translation policies/index diff --git a/doc/en/developer/source/policies/img/cve-disclosure.png b/doc/en/developer/source/policies/img/cve-disclosure.png new file mode 100644 index 00000000000..ed578ddb96c Binary files /dev/null and b/doc/en/developer/source/policies/img/cve-disclosure.png differ diff --git a/doc/en/developer/source/policies/img/cve-issue-public.png b/doc/en/developer/source/policies/img/cve-issue-public.png new file mode 100644 index 00000000000..f5ba4897055 Binary files /dev/null and b/doc/en/developer/source/policies/img/cve-issue-public.png differ diff --git a/doc/en/developer/source/policies/img/cve-issue.png b/doc/en/developer/source/policies/img/cve-issue.png new file mode 100644 index 00000000000..1cdc66a95b9 Binary files /dev/null and b/doc/en/developer/source/policies/img/cve-issue.png differ diff --git a/doc/en/developer/source/policies/img/cve-not-yet-published.png b/doc/en/developer/source/policies/img/cve-not-yet-published.png new file mode 100644 index 00000000000..c41fcabd532 Binary files /dev/null and b/doc/en/developer/source/policies/img/cve-not-yet-published.png differ diff --git a/doc/en/developer/source/policies/img/cve-version-range.png b/doc/en/developer/source/policies/img/cve-version-range.png new file mode 100644 index 00000000000..a546f4edf32 Binary files /dev/null and b/doc/en/developer/source/policies/img/cve-version-range.png differ diff --git a/doc/en/developer/source/policies/index.rst b/doc/en/developer/source/policies/index.rst index 24fd9201ce8..9d514d0164d 100644 --- a/doc/en/developer/source/policies/index.rst +++ b/doc/en/developer/source/policies/index.rst @@ -14,3 +14,4 @@ Policies and Procedures review community-modules service_providers + security diff --git a/doc/en/developer/source/policies/security.rst b/doc/en/developer/source/policies/security.rst new file mode 100644 index 00000000000..ed845886088 --- /dev/null +++ b/doc/en/developer/source/policies/security.rst @@ -0,0 +1,234 @@ +.. _security_procedure: + +Security Procedure +================== + +This page covers some of the lines of communication and tools available to enact our public security policy (see `SECURITY.md `__). + +Vulnerability reporting and discussion +-------------------------------------- + +Our security policy asks the community to take care in the reporting and discussion of security vulnerabilities: + + **Reporting a Vulnerability** + + If you encounter a security vulnerability in GeoServer, please take care to report it in a responsible fashion: + + 1. Keep exploit details out of public mailing lists and the Jira issue tracker. + + 2. There are two options to report a security vulnerability: + + * To report via email: + + Please send an email directly to the volunteers on the private `geoserver-security@lists.osgeo.org `__ mailing list. Provide information about the security vulnerability you might have found in your email. + + This is a moderated list: send directly to the address; your email will be moderated; and eventually shared with volunteers. + + * To report via GitHub: + + Navigate to `security `_ page, use link for Private vulnerability reporting. + + For more information see `GitHub documentation `_. + + 3. There is no expected response time. Please be prepared to work with geoserver-security email list volunteers on a solution. + + 4. Keep in mind participants are volunteering their time, an extensive fix may require fundraising/resources. + + For more information see `Community Support `_. + +Guidance on communication challenges +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Issue tracker: If an issue is opened with a security vulnerability, send the link to SECURITY.md to the reporter and close the issue. + +* Public Email: If a geoserver-devel or geoserver-user email comes in reporting the vulnerability (or discussing a vulnerability), link to the SECURITY.md file and invite parties to a discussion on the geoserver-security email list privately. + +* Private Email: If you are contacted directly, share the SECURITY.md, and link to commercial support providers (which may include your employer of course). + +* Social media: Ask parties to respect the coordinated vulnerability disclosure policy. + + Recognize that such communication is outside our control and do not further engage. + +* Public CVE: Most reliable response is to locate the CVE on advisory database and issue a pull-request clarification. + + * https://github.com/advisories?query=geoserver + * https://github.com/advisories?query=geotools + + You may also go through the steps of "disputing" a CVE, this involves contacting the original numbering authority (each of which have their own procedures). + + Keep in mind that security researchers may have obligations to report to their national numbering authority. + + Ask that they withhold details and work within our SECURITY.md policy (key phrase "coordinated vulnerability disclosure"). + +Kindness: + +* This is a long game, so prioritize sustainability and our geoserver-security volunteers. +* Recognize that the reporter is likely stressed, and may not have much flexibility due legal obligations around vulnerability disclosure. +* This is a sustainability challenge, so do not be shy about seeking sponsorship. + +geoserver-security list participation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Participation in the geoserver-security, like commit access, is volunteer based and reflects trust. + +* To volunteer, email geoserver-security@lists.osgeo.org stating your interest. + +* If you are unable to participate, send an email to step down. + + We understand that short term commitments can get in the way of sustainability initiatives – you are welcome to rejoin at any time. + + We will also retire inactive members as needed. + +When contacted by an external party on geoserver-security email list: + +1. Engage with the reporter as normal to determine if the issue is reproducible, and assess vulnerability. + + * For known issues we can add the reporter to an existing CVE, and indicate the assessment for their review. + + * For new issues we can work with the reporter, and create a CVE (as below), and assess the vulnerability with the reporter's input. + +2. The same approach is used for "triage" reports made directly to the security advisory list. + +3. The policy of the reporter working with the geoserver-security volunteers remains steadfast. + + Especially with respect to mitigation and scheduling a fix we need to gather interested parties, including the reporter, with time/resources to address the issue. + + Reporters expecting a vendor relationship are invited to contact our service providers (who are very nice). + +Coordinated vulnerability disclosure +------------------------------------ + +GeoServer has adopted a coordinated vulnerability disclosure model, as outlined in `SECURITY.md `__: + + + **Coordinated vulnerability disclosure** + + Disclosure policy: + + 1. The reported vulnerability has been verified by working with the geoserver-security list + 2. GitHub `security advisory `_ is used to reserve a CVE number + 3. A fix or documentation clarification is accepted and backported to both the "stable" and "maintenance" branches + 4. A fix is included for the "stable" and "maintenance" downloads (`released as scheduled `__, or issued via emergency update) + 5. The CVE vulnerability is published with mitigation and patch instructions + + This represents a balance between transparency and participation that does not overwhelm participants. Those seeking greater visibility are encouraged to volunteer with the geoserver-security list; or work with one of the `commercial support providers `__ who participate on behalf of their customers. + +Working with vulnerability reports +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. When working with a "triage" or "draft" vulnerability: + + * Invite reporter to participate, they are part of the team addressing the issue, + * Give credit to the reporter and anyone else involved using the allocated fields + * Do not immediately request a CVE, and be sure to confirm the vulnerability (for example with a proof of concept) first. + * A vulnerability flagged from a dependency scan does not automatically indicate that an exploit is available in GeoServer. + * For popular concerns (like spring-framework upgrade) add each reporter to same advisory. + + Be aware that a security researcher may only be tasked with reporting the issue, and might be unavailable + once you have created a CVE. + +2. Preparing report: + + * Package: Always report `org.geoserver.web:gs-web-app` as `geoserver.war` as a useful way to document that the `geoserver.war` includes other jars + * Affected versions: It is difficult to communicate version ranges, due to limitations in CVE advisory processing, requiring multiple lines. + + .. figure:: img/cve-version-range.png + + Package guidance and version range + +3. Work on providing a fix, mitigation instructions, or best-practice clarification for documentation. + + * The use of GitHub private repository associated with an advisory should be used with caution. + + If making extensive code changes keep in mind that automations, including QA automations, are not available to be run as part of the pull-request review process. + + This may be appropriate when updating documentation / best practice information. + + The key advantage is several pull-requests can be managed at once, and merged at the same time as disclosure (see below). + + * If you wish to work on a public pull-request (to take advantage of workflow automations) take care that test-cases, commit messages, and documentation updates do not immediately reveal the vulnerability. + + * Although not ideal, it is possible to resolve some security issues by documenting a best-practice in the production consideration of the user guide. + +4. Request a CVE from GitHub. + + This requires an external review as they check that the details provided are complete. + + .. note:: Example: The report "GHSA-cqpc-x2c6-2gmf" has been assigned CVE-2023-41339 and is shown as "not yet published". + + .. figure:: img/cve-not-yet-published.png + + CVE-2023-41339 Not Yet Published + +3. Assign a placeholder Jira issue with ``Vulnerability`` category. + + * Mentioning the CVE is fine, even if it is not yet public, it will still show up in the database as reserved. + + .. note:: Example: The Jira issue GEOS-11121 ticket is created for CVE-2023-41339. + + .. figure:: img/cve-issue.png + + Jira GEOS-11121 Placeholder + +4. During the release process list CVE in "Security Considerations" section of release announcements. + + * Initially this lists CVE numbers, indicating a fix is included but does not provide any details + + * An indication of the severity is provided to encourage community to update. + + * You may change the wording of the recommendation to "recommended" or "essential" or "urgent" as you see fit. + + .. note:: It is our policy not to provide details at this time. Any deeply concerned parties can volunteer on the geoserver-security email list, or arrange a vendor relationship with a service provider. + +5. Disclosure: + + * Wait until the vulnerability has been addressed, for BOTH the stable and maintenance versions, before publishing. + + * Update prior release announcements, and placeholder Jira issue, with the complete title of the vulnerability. + + .. note:: Example: Security considerations section showing a mix of disclosed and not yet disclosed (no hyperlink) vulnerabilities. + + .. figure:: img/cve-disclosure.png + + Release announcement communication + + * Publish the security advisory to make the vulnerability public + + * If you feel a statement is necessary, you may write an appropriate blog post. + + .. note:: Example: Statement on covering `Jiffle and GeoTools RCE vulnerabilities `__. + +Publicly reported issue +^^^^^^^^^^^^^^^^^^^^^^^ + +When a national agency or similar has already reported a vulnerability publicly, it can be found in the GitHub security advisory database: + +1. Locate the issue on https://github.com/advisories?query=geoserver + + .. note:: Example: Public reported CVE-2023-35042 is listed here https://github.com/advisories/GHSA-59x6-g4jr-4hxc + +2. Create a pull request to revise the issue with useful details such as: + + * maven + * org.geoserver + * version + + .. note:: Example: CVE-2023-35042 correction https://github.com/github/advisory-database/pull/2721 + +3. Optional: Work with original agency to try and revise their record. + + .. note:: Example: + + A request to mark `CVE-2023-35042 `__ as duplicate that had been fixed in all supported versions came out as: + + [DISPUTED] GeoServer 2, in some configurations, allows remote attackers to execute arbitrary code via java.lang.Runtime.getRuntime().exec in wps:LiteralData within a wps:Execute request, as exploited in the wild in June 2023. NOTE: the vendor states that they are unable to reproduce this in any version. + + This is the opposite of controlling the message, it now appears as if the issue being disputed - rather than accepted as already solved please update etc... + +4. Claim the ticket with a Jira issue, linking to the revised GitHub record, or national record as appropriate. + + .. note:: Example: CVE-2023-35042 reported to our issue tracker as GEOS-11027 + + .. figure:: img/cve-issue-public.png + + GEOS-11027 documenting state of CVE-2023-35042 diff --git a/doc/en/developer/source/release-guide/index.rst b/doc/en/developer/source/release/guide/index.rst similarity index 100% rename from doc/en/developer/source/release-guide/index.rst rename to doc/en/developer/source/release/guide/index.rst diff --git a/doc/en/developer/source/release-guide/jira1.png b/doc/en/developer/source/release/guide/jira1.png similarity index 100% rename from doc/en/developer/source/release-guide/jira1.png rename to doc/en/developer/source/release/guide/jira1.png diff --git a/doc/en/developer/source/release-guide/jira2.png b/doc/en/developer/source/release/guide/jira2.png similarity index 100% rename from doc/en/developer/source/release-guide/jira2.png rename to doc/en/developer/source/release/guide/jira2.png diff --git a/doc/en/developer/source/release-guide/jira3.png b/doc/en/developer/source/release/guide/jira3.png similarity index 100% rename from doc/en/developer/source/release-guide/jira3.png rename to doc/en/developer/source/release/guide/jira3.png diff --git a/doc/en/developer/source/release-guide/jira4.png b/doc/en/developer/source/release/guide/jira4.png similarity index 100% rename from doc/en/developer/source/release-guide/jira4.png rename to doc/en/developer/source/release/guide/jira4.png diff --git a/doc/en/developer/source/release-guide/old.rst b/doc/en/developer/source/release/guide/old.rst similarity index 100% rename from doc/en/developer/source/release-guide/old.rst rename to doc/en/developer/source/release/guide/old.rst diff --git a/doc/en/developer/source/release-guide/sf1.png b/doc/en/developer/source/release/guide/sf1.png similarity index 100% rename from doc/en/developer/source/release-guide/sf1.png rename to doc/en/developer/source/release/guide/sf1.png diff --git a/doc/en/developer/source/release-guide/sf2.png b/doc/en/developer/source/release/guide/sf2.png similarity index 100% rename from doc/en/developer/source/release-guide/sf2.png rename to doc/en/developer/source/release/guide/sf2.png diff --git a/doc/en/developer/source/release-guide/sf3.png b/doc/en/developer/source/release/guide/sf3.png similarity index 100% rename from doc/en/developer/source/release-guide/sf3.png rename to doc/en/developer/source/release/guide/sf3.png diff --git a/doc/en/developer/source/release-guide/sf4.png b/doc/en/developer/source/release/guide/sf4.png similarity index 100% rename from doc/en/developer/source/release-guide/sf4.png rename to doc/en/developer/source/release/guide/sf4.png diff --git a/doc/en/developer/source/release-guide/sf5.png b/doc/en/developer/source/release/guide/sf5.png similarity index 100% rename from doc/en/developer/source/release-guide/sf5.png rename to doc/en/developer/source/release/guide/sf5.png diff --git a/doc/en/developer/source/release-guide/sf6.png b/doc/en/developer/source/release/guide/sf6.png similarity index 100% rename from doc/en/developer/source/release-guide/sf6.png rename to doc/en/developer/source/release/guide/sf6.png diff --git a/doc/en/developer/source/release-guide/sfnotice.png b/doc/en/developer/source/release/guide/sfnotice.png similarity index 100% rename from doc/en/developer/source/release-guide/sfnotice.png rename to doc/en/developer/source/release/guide/sfnotice.png diff --git a/doc/en/developer/source/release-guide/wiki1.png b/doc/en/developer/source/release/guide/wiki1.png similarity index 100% rename from doc/en/developer/source/release-guide/wiki1.png rename to doc/en/developer/source/release/guide/wiki1.png diff --git a/doc/en/developer/source/release/index.rst b/doc/en/developer/source/release/index.rst new file mode 100644 index 00000000000..dd951c6a169 --- /dev/null +++ b/doc/en/developer/source/release/index.rst @@ -0,0 +1,18 @@ +.. _release: + +Release Process +=============== + +Public release process. + +.. toctree:: + :maxdepth: 1 + + schedule/index.rst + guide/index.rst + testing/index.rst + +.. toctree:: + :hidden: + + guide/old.rst \ No newline at end of file diff --git a/doc/en/developer/source/release-schedule/index.rst b/doc/en/developer/source/release/schedule/index.rst similarity index 100% rename from doc/en/developer/source/release-schedule/index.rst rename to doc/en/developer/source/release/schedule/index.rst diff --git a/doc/en/developer/source/release-schedule/timeboxed.png b/doc/en/developer/source/release/schedule/timeboxed.png similarity index 100% rename from doc/en/developer/source/release-schedule/timeboxed.png rename to doc/en/developer/source/release/schedule/timeboxed.png diff --git a/doc/en/developer/source/release-testing-checklist/arc_sample.png b/doc/en/developer/source/release/testing/arc_sample.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/arc_sample.png rename to doc/en/developer/source/release/testing/arc_sample.png diff --git a/doc/en/developer/source/release-testing-checklist/img_sample_kml.png b/doc/en/developer/source/release/testing/img_sample_kml.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/img_sample_kml.png rename to doc/en/developer/source/release/testing/img_sample_kml.png diff --git a/doc/en/developer/source/release-testing-checklist/index.rst b/doc/en/developer/source/release/testing/index.rst similarity index 100% rename from doc/en/developer/source/release-testing-checklist/index.rst rename to doc/en/developer/source/release/testing/index.rst diff --git a/doc/en/developer/source/release-testing-checklist/states_cql.png b/doc/en/developer/source/release/testing/states_cql.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_cql.png rename to doc/en/developer/source/release/testing/states_cql.png diff --git a/doc/en/developer/source/release-testing-checklist/states_georss.png b/doc/en/developer/source/release/testing/states_georss.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_georss.png rename to doc/en/developer/source/release/testing/states_georss.png diff --git a/doc/en/developer/source/release-testing-checklist/states_kml_bestguess.png b/doc/en/developer/source/release/testing/states_kml_bestguess.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_kml_bestguess.png rename to doc/en/developer/source/release/testing/states_kml_bestguess.png diff --git a/doc/en/developer/source/release-testing-checklist/states_kml_sort.png b/doc/en/developer/source/release/testing/states_kml_sort.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_kml_sort.png rename to doc/en/developer/source/release/testing/states_kml_sort.png diff --git a/doc/en/developer/source/release-testing-checklist/states_rasterized.png b/doc/en/developer/source/release/testing/states_rasterized.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_rasterized.png rename to doc/en/developer/source/release/testing/states_rasterized.png diff --git a/doc/en/developer/source/release-testing-checklist/states_template.png b/doc/en/developer/source/release/testing/states_template.png similarity index 100% rename from doc/en/developer/source/release-testing-checklist/states_template.png rename to doc/en/developer/source/release/testing/states_template.png diff --git a/src/extension/inspire/src/main/java/org/geoserver/inspire/LanguagesDispatcherCallback.java b/src/extension/inspire/src/main/java/org/geoserver/inspire/LanguagesDispatcherCallback.java index 0fb1df249d0..b70fedcbce5 100644 --- a/src/extension/inspire/src/main/java/org/geoserver/inspire/LanguagesDispatcherCallback.java +++ b/src/extension/inspire/src/main/java/org/geoserver/inspire/LanguagesDispatcherCallback.java @@ -7,10 +7,8 @@ import java.io.IOException; import java.util.Map; import java.util.Properties; -import java.util.stream.Collectors; import org.geoserver.ows.AbstractDispatcherCallback; import org.geoserver.ows.Request; -import org.geoserver.platform.ServiceException; public class LanguagesDispatcherCallback extends AbstractDispatcherCallback { @@ -29,21 +27,8 @@ public Request init(Request request) { try { Properties mappings = InspireDirectoryManager.get().getLanguagesMappings(); String isoLang = mappings.getProperty(value); - String supportedLanguages = - mappings.keySet().stream() - .map(s -> s.toString()) - .collect(Collectors.joining(",")); - if (isoLang == null) { - value = value == null || value.equals("") ? "empty" : value; - throw new ServiceException( - "A Language parameter was provided in the request but it cannot be resolved to an ISO lang code." - + " Parameter value is " - + value - + " while supported languages are " - + supportedLanguages); - } rawKvp.put(ACCEPT_LANGUAGES_PARAM, isoLang); - rawKvp.put(LANGUAGE_PARAM, isoLang); + rawKvp.put(LANGUAGE_PARAM, isoLang != null ? isoLang : ""); if (request.getKvp() != null) { request.getKvp().put(ACCEPT_LANGUAGES_PARAM, isoLang); request.getKvp().put(LANGUAGE_PARAM, isoLang); diff --git a/src/extension/inspire/src/main/java/org/geoserver/inspire/ServicesUtils.java b/src/extension/inspire/src/main/java/org/geoserver/inspire/ServicesUtils.java index c33b175660d..7524ecac694 100644 --- a/src/extension/inspire/src/main/java/org/geoserver/inspire/ServicesUtils.java +++ b/src/extension/inspire/src/main/java/org/geoserver/inspire/ServicesUtils.java @@ -116,7 +116,7 @@ private static String retrieveLanguageParameter( value = getIfSupported(reqLang, languages); } } - if (value == null) value = defaultLanguage; + if (value == null || value.isEmpty()) value = defaultLanguage; return value; } diff --git a/src/extension/inspire/src/test/java/org/geoserver/inspire/wcs/WCSExtendedCapabilitiesTest.java b/src/extension/inspire/src/test/java/org/geoserver/inspire/wcs/WCSExtendedCapabilitiesTest.java index 8fd9d82a011..72daa7c853d 100644 --- a/src/extension/inspire/src/test/java/org/geoserver/inspire/wcs/WCSExtendedCapabilitiesTest.java +++ b/src/extension/inspire/src/test/java/org/geoserver/inspire/wcs/WCSExtendedCapabilitiesTest.java @@ -372,4 +372,38 @@ public void testSupportedLanguages() throws Exception { nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); assertEquals("Number of Supported Languages", 2, nodeList.getLength()); } + + @Test + public void testUnSupportedLanguages() throws Exception { + final ServiceInfo serviceInfo = getGeoServer().getService(WCSInfo.class); + final MetadataMap metadata = serviceInfo.getMetadata(); + clearInspireMetadata(metadata); + metadata.put(CREATE_EXTENDED_CAPABILITIES.key, true); + metadata.put(SERVICE_METADATA_URL.key, "http://foo.com?bar=baz"); + metadata.put(SERVICE_METADATA_TYPE.key, "application/vnd.iso.19139+xml"); + metadata.put(LANGUAGE.key, "fre"); + metadata.put(OTHER_LANGUAGES.key, "ita,eng"); + metadata.put( + SPATIAL_DATASET_IDENTIFIER_TYPE.key, + "one,http://www.geoserver.org/one;two,http://www.geoserver.org/two,http://metadata.geoserver.org/id?two"); + getGeoServer().save(serviceInfo); + final Document dom = getAsDOM(WCS_2_0_0_GETCAPREQUEST + "&LANGUAGE=unsupported"); + + final Element suppLangs = + (Element) + dom.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguages").item(0); + + NodeList nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "DefaultLanguage"); + assertEquals("Number of DefaultLanguage elements", 1, nodeList.getLength()); + nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); + assertEquals("Number of Supported Languages", 2, nodeList.getLength()); + + final String responseLanguage = + dom.getElementsByTagNameNS(COMMON_NAMESPACE, "ResponseLanguage") + .item(0) + .getFirstChild() + .getFirstChild() + .getNodeValue(); + assertEquals("Unsupported LANGUAGE returns the Default one", "fre", responseLanguage); + } } diff --git a/src/extension/inspire/src/test/java/org/geoserver/inspire/wfs/WFSExtendedCapabilitiesTest.java b/src/extension/inspire/src/test/java/org/geoserver/inspire/wfs/WFSExtendedCapabilitiesTest.java index 3cbd4fb89f8..e8bc4739061 100644 --- a/src/extension/inspire/src/test/java/org/geoserver/inspire/wfs/WFSExtendedCapabilitiesTest.java +++ b/src/extension/inspire/src/test/java/org/geoserver/inspire/wfs/WFSExtendedCapabilitiesTest.java @@ -423,4 +423,49 @@ public void testSupportedLanguages() throws Exception { nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); assertEquals("Number of Supported Languages", 2, nodeList.getLength()); } + + @Test + public void testUnSupportedLanguages() throws Exception { + final ServiceInfo serviceInfo = getGeoServer().getService(WFSInfo.class); + final MetadataMap metadata = serviceInfo.getMetadata(); + clearInspireMetadata(metadata); + metadata.put(CREATE_EXTENDED_CAPABILITIES.key, true); + metadata.put(SERVICE_METADATA_URL.key, "http://foo.com?bar=baz"); + metadata.put(SERVICE_METADATA_TYPE.key, "application/vnd.iso.19139+xml"); + metadata.put(LANGUAGE.key, "fre"); + metadata.put(OTHER_LANGUAGES.key, "ita,eng"); + metadata.put( + SPATIAL_DATASET_IDENTIFIER_TYPE.key, + "one,http://www.geoserver.org/one;two,http://www.geoserver.org/two,http://metadata.geoserver.org/id?two"); + getGeoServer().save(serviceInfo); + + final Document dom = getAsDOM(WFS_1_1_0_GETCAPREQUEST + "&LANGUAGE=unsupported"); + + NodeList nodeList = dom.getElementsByTagNameNS(DLS_NAMESPACE, "ExtendedCapabilities"); + assertEquals("Number of INSPIRE ExtendedCapabilities elements", 1, nodeList.getLength()); + + String schemaLocation = dom.getDocumentElement().getAttribute("xsi:schemaLocation"); + assertSchemaLocationContains(schemaLocation, DLS_NAMESPACE, DLS_SCHEMA); + + final Element extendedCaps = (Element) nodeList.item(0); + + final Element suppLangs = + (Element) + extendedCaps + .getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguages") + .item(0); + + nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "DefaultLanguage"); + assertEquals("Number of DefaultLanguage elements", 1, nodeList.getLength()); + nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); + assertEquals("Number of Supported Languages", 2, nodeList.getLength()); + + final String responseLanguage = + dom.getElementsByTagNameNS(COMMON_NAMESPACE, "ResponseLanguage") + .item(0) + .getFirstChild() + .getFirstChild() + .getNodeValue(); + assertEquals("Unsupported LANGUAGE returns the Default one", "fre", responseLanguage); + } } diff --git a/src/extension/inspire/src/test/java/org/geoserver/inspire/wms/WMSExtendedCapabilitiesTest.java b/src/extension/inspire/src/test/java/org/geoserver/inspire/wms/WMSExtendedCapabilitiesTest.java index bc0e436a8c7..864508e533f 100644 --- a/src/extension/inspire/src/test/java/org/geoserver/inspire/wms/WMSExtendedCapabilitiesTest.java +++ b/src/extension/inspire/src/test/java/org/geoserver/inspire/wms/WMSExtendedCapabilitiesTest.java @@ -5,6 +5,7 @@ */ package org.geoserver.inspire.wms; +import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo; import static org.geoserver.inspire.InspireMetadata.CREATE_EXTENDED_CAPABILITIES; import static org.geoserver.inspire.InspireMetadata.LANGUAGE; import static org.geoserver.inspire.InspireMetadata.OTHER_LANGUAGES; @@ -272,6 +273,43 @@ public void testSupportedLanguageIsNull() throws Exception { assertNull(supportedLanguage); } + @Test + public void testUnSupportedLanguages() throws Exception { + final ServiceInfo serviceInfo = getGeoServer().getService(WMSInfo.class); + final MetadataMap metadata = serviceInfo.getMetadata(); + clearInspireMetadata(metadata); + GrowableInternationalString title = new GrowableInternationalString(); + title.add(Locale.ITALIAN, "italian title"); + title.add(Locale.FRENCH, "french title"); + serviceInfo.setDefaultLocale(Locale.FRENCH); + serviceInfo.setInternationalTitle(title); + metadata.put(CREATE_EXTENDED_CAPABILITIES.key, true); + metadata.put(SERVICE_METADATA_URL.key, "http://foo.com?bar=baz"); + metadata.put(SERVICE_METADATA_TYPE.key, "application/vnd.iso.19139+xml"); + metadata.put(LANGUAGE.key, "fre"); + metadata.put(OTHER_LANGUAGES.key, "ita,eng"); + getGeoServer().save(serviceInfo); + final Document dom = getAsDOM(WMS_1_3_0_GETCAPREQUEST + "&LANGUAGE=unsupported"); + + final String responseLanguage = + dom.getElementsByTagNameNS(COMMON_NAMESPACE, "ResponseLanguage") + .item(0) + .getFirstChild() + .getNextSibling() + .getFirstChild() + .getNodeValue(); + assertEquals("Unsupported LANGUAGE returns the Default one", "fre", responseLanguage); + + // title checks for configured i18n title with unsupported language and with default + + // Define the XPath expression + String xPathExpression = + "//*[local-name()='WMS_Capabilities']/*[local-name()='Service']/*[local-name()='Title']"; + + // Assert the value of the Title element + assertXpathEvaluatesTo("french title", xPathExpression, dom); + } + private boolean isLangNode(Node el) { return el != null && el.getLocalName() != null && el.getLocalName().equals("Language"); } diff --git a/src/extension/inspire/src/test/java/org/geoserver/inspire/wmts/WMTSExtendedCapabilitiesTest.java b/src/extension/inspire/src/test/java/org/geoserver/inspire/wmts/WMTSExtendedCapabilitiesTest.java index 05733130344..e31852bd734 100644 --- a/src/extension/inspire/src/test/java/org/geoserver/inspire/wmts/WMTSExtendedCapabilitiesTest.java +++ b/src/extension/inspire/src/test/java/org/geoserver/inspire/wmts/WMTSExtendedCapabilitiesTest.java @@ -94,4 +94,40 @@ public void testSupportedLanguages() throws Exception { nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); assertEquals("Number of Supported Languages", 2, nodeList.getLength()); } + + @Test + public void testUnSupportedLanguages() throws Exception { + final ServiceInfo serviceInfo = getGeoServer().getService(WMTSInfo.class); + final MetadataMap metadata = serviceInfo.getMetadata(); + clearInspireMetadata(metadata); + metadata.put(CREATE_EXTENDED_CAPABILITIES.key, true); + metadata.put(SERVICE_METADATA_URL.key, "http://foo.com?bar=baz"); + metadata.put(SERVICE_METADATA_TYPE.key, "application/vnd.iso.19139+xml"); + metadata.put(LANGUAGE.key, "fre"); + metadata.put(OTHER_LANGUAGES.key, "ita,eng"); + getGeoServer().save(serviceInfo); + final Document dom = getAsDOM(WMTS_1_0_0_GETCAPREQUEST + "&LANGUAGE=unsupported"); + NodeList nodeList = dom.getElementsByTagNameNS(VS_VS_OWS_NAMESPACE, "ExtendedCapabilities"); + final Element extendedCaps = (Element) nodeList.item(0); + + final Element suppLangs = + (Element) + extendedCaps + .getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguages") + .item(0); + + nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "DefaultLanguage"); + assertEquals("Number of DefaultLanguage elements", 1, nodeList.getLength()); + nodeList = suppLangs.getElementsByTagNameNS(COMMON_NAMESPACE, "SupportedLanguage"); + assertEquals("Number of Supported Languages", 2, nodeList.getLength()); + + final String responseLanguage = + dom.getElementsByTagNameNS(COMMON_NAMESPACE, "ResponseLanguage") + .item(0) + .getFirstChild() + .getNextSibling() + .getFirstChild() + .getNodeValue(); + assertEquals("Unsupported LANGUAGE returns the Default one", "fre", responseLanguage); + } } diff --git a/src/main/src/main/java/org/geoserver/data/InternationalContentHelper.java b/src/main/src/main/java/org/geoserver/data/InternationalContentHelper.java index b8cf3115705..87b6be67c16 100644 --- a/src/main/src/main/java/org/geoserver/data/InternationalContentHelper.java +++ b/src/main/src/main/java/org/geoserver/data/InternationalContentHelper.java @@ -42,7 +42,7 @@ public class InternationalContentHelper { private Set requestedLocales = new LinkedHashSet<>(); - // field that map the AcceptLanguages value * + // field that maps the AcceptLanguages value * protected boolean anyMatch = false; // supported locales are those used at least in one field of @@ -98,7 +98,7 @@ private void setRequestedLocales(String[] preferredLanguages) { if (preferredLanguages != null && preferredLanguages.length > 0) { for (String language : preferredLanguages) { Locale locale = null; - if (language.equals("*")) { + if (language.equals("*") || language.isEmpty()) { this.anyMatch = true; locale = Locale.getDefault(); } else if (language.contains("-")) locale = Locale.forLanguageTag(language); @@ -218,9 +218,9 @@ public List filterKeywords(List original) { * Get a String value according to the requestedLocales from the InternationalString passed as * an argument. * - * @param internationalString the internationalString from which retrieve the localized value. - * @param nullable if false when a localized value is not found for the requested locale a - * message (DID NOT FIND i18n CONTENT FOR THIS ELEMENT) will be returned. Otherwise null + * @param internationalString the internationalString from which retrieve the localized value? + * @param nullable if false, when a localized value is not found for the requested locale a + * message (DID NOT FIND i18n CONTENT FOR THIS ELEMENT) will be returned. Otherwise, null * will be returned. * @return the localized value of the internationalString. */ @@ -230,7 +230,7 @@ public String getString(InternationalString internationalString, boolean nullabl GrowableInternationalString growable = (GrowableInternationalString) internationalString; result = getFirstMatchingInternationalValue(growable, requestedLocales); - // if client specified * try with the supported locales + // if a client specified * try with the supported locales if (result == null && anyMatch) { result = growable.toString(GeoServerDefaultLocale.get()); } @@ -379,7 +379,7 @@ public void verify() { .map(l -> l.toLanguageTag()) .collect(Collectors.joining(",")); for (Locale locale : requestedLocales) { - if (supportedLocales.contains(locale)) return; + if (locale.toString().isEmpty() || supportedLocales.contains(locale)) return; } throw new UnsupportedOperationException( "Content has been requested in one of the following languages: " diff --git a/src/main/src/main/java/org/geoserver/security/impl/DigestAuthUtils.java b/src/main/src/main/java/org/geoserver/security/impl/DigestAuthUtils.java index b7d4f31360d..f17b71648ea 100644 --- a/src/main/src/main/java/org/geoserver/security/impl/DigestAuthUtils.java +++ b/src/main/src/main/java/org/geoserver/security/impl/DigestAuthUtils.java @@ -19,7 +19,7 @@ /** * This is an exact copy of org.springframework.security.web.authentication.www.DigestAuthUtils; * - *

The Spring class has package visibility, no idea why. The functionally is used for test cases + *

The Spring class has package visibility, no idea why. The functionality is used for test cases * and may be used by a client agent using the geoserver library * * @author mcr diff --git a/src/ows/src/main/java/org/geoserver/ows/util/RequestUtils.java b/src/ows/src/main/java/org/geoserver/ows/util/RequestUtils.java index 3e3a5f47aa0..8b24f4968ec 100644 --- a/src/ows/src/main/java/org/geoserver/ows/util/RequestUtils.java +++ b/src/ows/src/main/java/org/geoserver/ows/util/RequestUtils.java @@ -254,7 +254,10 @@ public static String[] getLanguageValue(Request request, String languageParamNam public static String[] getLanguageValue(Map rawKvp, String languageParamName) { String[] result = null; if (rawKvp != null && rawKvp.containsKey(languageParamName)) { - String acceptLanguages = rawKvp.get(languageParamName).toString(); + String acceptLanguages = + rawKvp.get(languageParamName) != null + ? rawKvp.get(languageParamName).toString() + : ""; if (acceptLanguages != null) { String[] langAr = acceptLanguages.split(" "); if (langAr.length == 1) {