wso2 / product-is

Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
http://wso2.github.io/
Apache License 2.0
742 stars 720 forks source link

Internal Server Error When Using Offset >= Total Organizations and Limit = 0 in Organization Discovery GET API #21025

Open BimsaraBodaragama opened 2 weeks ago

BimsaraBodaragama commented 2 weeks ago

Describe the issue: When querying the Organization Discovery GET API with an offset greater than or equal to the total number of organizations and with a limit of 0, the server returns a 500 Internal Server Error. The error message indicates an "Unexpected Processing Error" and the server logs show a StackOverflowError caused by a recursive call in the calculateOffsetForPreviousLink method.

Error Message:

{
    "code": "SE-50000",
    "message": "Unexpected Processing Error.",
    "description": "Server encountered an error while serving the request.",
    "traceId": <Trace ID>
}

How to reproduce:

  1. Create 10 organizations (or any number of organizations for demonstration purposes).
  2. Send a GET request to the Organization Discovery API with offset=10 and limit=0.
  3. Observe that the server returns a 500 Internal Server Error.
  4. Repeat the request with offset=15 and limit=0 to observe the same behavior (you can use any offset greater than the total number of organizations for demonstration).

Example Requests:

curl -X GET "https://localhost:9443/t/carbon.super/api/server/v1/organizations/discovery?filter=&offset=<Your count of orgs>&limit=0" \
-H "Authorization: Bearer <Your Bearer Token>" \
-H "Cookie: <Your Cookies>" \
-H "accept: application/json"
curl -X GET "https://localhost:9443/t/carbon.super/api/server/v1/organizations/discovery?filter=&offset=<Your count of orgs + 5>&limit=0" \
-H "Authorization: Bearer <Your Bearer Token>" \
-H "Cookie: <Your Cookies>" \
-H "accept: application/json"

You can replace <Your Bearer Token>, <Your Cookies>, and <Your count of orgs> with the relevant values before using these curl commands.

Expected behavior: The API should return a valid response with count=0, startIndex=offset+1, and a previous link as shown in the responses for other valid limits. The API should not cause a server error or throw a StackOverflowError.

BimsaraBodaragama commented 2 weeks ago

For testing purposes, you can create 10 organizations using the following bash script.

#!/bin/bash

# Base values
BASE_URL='https://localhost:9443/api/server/v1/organizations'
AUTH_TOKEN='<Your Auth Token>'
PARENT_ID='<Your Parent ID>'

# Loop to create organizations org1 to org10
for i in {1..10}
do
  # Organization name
  ORG_NAME="org${i}"

  # JSON payload
  DATA=$(cat <<EOF
{
    "name": "${ORG_NAME}",
    "parentId": "${PARENT_ID}",
    "type": "TENANT"
}
EOF
)

  # Make the curl request
  curl --location --insecure "$BASE_URL" \
  --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:129.0) Gecko/20100101 Firefox/129.0' \
  --header 'Accept: application/json' \
  --header 'Accept-Language: en-US,en;q=0.5' \
  --header 'Accept-Encoding: gzip, deflate, br, zstd' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer $AUTH_TOKEN" \
  --header 'Origin: https://localhost:9443' \
  --header 'Connection: keep-alive' \
  --header 'Cookie: <Your Cookies>' \
  --header 'Sec-Fetch-Dest: empty' \
  --header 'Sec-Fetch-Mode: cors' \
  --header 'Sec-Fetch-Site: same-origin' \
  --data "$DATA"

  echo "Created organization $ORG_NAME"
done
BimsaraBodaragama commented 2 weeks ago

Note Once this issue is resolved, please remove the testGetPaginatedOrganizationsDiscoveryWithInvalidOffsetAndLimitZero test method and its corresponding data provider, organizationDiscoveryInvalidOffsetAtLimitAndLimitZeroDataProvider, from the file located at:

modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/rest/api/server/organization/management/v1/OrganizationManagementFailureTest.java

These tests will no longer be necessary after the fix.