Skip to content

Conversation

@danxuliu
Copy link
Member

@danxuliu danxuliu commented Dec 8, 2025

Fixes #56789, which is a regression introduced in #52793

When a user has an active session only the apps that are enabled for the user are initially loaded*. In order to cache the routes the routes for all apps are loaded, but routes defined in routes.php are taken into account only if the app was already loaded. Therefore, when the routes were cached in a request by a user with an active session only the routes for apps enabled for that user were cached, and those routes were used by any other user, independently of which apps they had access to. To solve that now all the enabled apps are explicitly loaded before caching the routes.

Note that this did not affect routes defined using annotations on the controller files; in that case the loaded routes do not depend on the previously loaded apps, as it explicitly checks all the enabled apps.

*As soon as the session is initialized, which happens when loading base.php, the legacy OC_APP::getEnabledApps will return only the apps enabled for the user. That method is used by AppManager::loadApps, so once the session is initialized any load of (several) apps will be restricted to those enabled for the user (explicitly loading a single app still works as expected). Therefore, when $appManager->loadApps() is called from the OCS handler or from the index.php handler (through handleRequest in base.php) only the apps for the user are loaded.

Steps to reproduce

  • Use a development server and ensure that no other requests than the ones below are handled
  • Enable APCu cache (add 'memcache.local' => '\\OC\\Memcache\\APCu', to config.php) if not enabled already
  • Enable the weather_status app only for a specific group (for simplicity admin is used here)
occ app:enable --groups admin weather_status`
  • Adjust the variables below as needed for your setup and run the following Bash code:
export ADMIN_NAME=admin
export ADMIN_PASSWORD=admin
export USER_NAME=user0
export USER_PASSWORD=user0
export SERVER_URL=http://127.0.0.1:8000

function extractRequestToken() {
	echo $(echo $1 | grep --perl-regexp --only-matching 'data-requesttoken="\K([^"]*)')
}

function extractAuthenticationToken() {
	echo $(echo $1 | grep --perl-regexp --only-matching '"token":"\K([^"]*)')
}

# Open login page to get the request token
loginPage=$(curl --silent --cookie-jar "/tmp/cookie-jar-$USER_NAME" "$SERVER_URL/index.php/login")

requestToken=$(extractRequestToken "$loginPage")

# Perform actual login
loginPost=$(curl --silent --location --cookie "/tmp/cookie-jar-$USER_NAME" --cookie-jar "/tmp/cookie-jar-$USER_NAME" --header "Origin: $SERVER_URL" --data-urlencode "user=$USER_NAME" --data-urlencode "password=$USER_PASSWORD" --data-urlencode "requesttoken=$requestToken" "$SERVER_URL/index.php/login")

requestToken=$(extractRequestToken "$loginPost")
  • Clear the APCu cache (call apcu_clear_cache() somehow, for example using https://github.com/krakjoe/apcu/blob/master/apc.php or the helper apps/testing/clean_apcu_cache.php added in this pull request; restarting the web server would reset the APCu cache, but it might also kill the user session and make the test invalid)

  • In the same Bash terminal as before, do a request with the logged in user, for example:

curl --silent --location --cookie "/tmp/cookie-jar-$USER_NAME" --cookie-jar "/tmp/cookie-jar-$USER_NAME" --header "requesttoken: $requestToken" "$SERVER_URL/ocs/v1.php/cloud/user?format=json"
  • Now request an endpoint in the weather_status app by a user member of the group that it is enabled for (again for simplicity admin is used here):
curl --user "$ADMIN_NAME:$ADMIN_PASSWORD" --header "OCS-ApiRequest: true" "$SERVER_URL/ocs/v2.php/apps/weather_status/api/v1/location"

Result with this pull request

The query succeeded

Result without this pull request

Invalid query returned; if the APCu cache is cleared again and the request repeated then it will now succeed (as the routes will be regenerated by the admin, which has access to the app)

@danxuliu danxuliu added this to the Nextcloud 33 milestone Dec 8, 2025
@danxuliu danxuliu added bug 3. to review Waiting for reviews regression feature: caching Related to our caching system: scssCacher, jsCombiner... labels Dec 8, 2025
@danxuliu
Copy link
Member Author

danxuliu commented Dec 8, 2025

/backport to stable32

@danxuliu danxuliu force-pushed the fix-caching-routes-by-users-with-an-active-session branch 2 times, most recently from 1ce0c32 to 74ea8f5 Compare December 8, 2025 17:14
When a user has an active session only the apps that are enabled for the
user are initially loaded. In order to cache the routes the routes for
all apps are loaded, but routes defined in routes.php are taken into
account only if the app was already loaded. Therefore, when the routes
were cached in a request by a user with an active session only the
routes for apps enabled for that user were cached, and those routes were
used by any other user, independently of which apps they had access to.
To solve that now all the enabled apps are explicitly loaded before
caching the routes.

Note that this did not affect routes defined using annotations on the
controller files; in that case the loaded routes do not depend on the
previously loaded apps, as it explicitly checks all the enabled apps.

Signed-off-by: Daniel Calviño Sánchez <[email protected]>
@danxuliu danxuliu force-pushed the fix-caching-routes-by-users-with-an-active-session branch from 74ea8f5 to 860bdfd Compare December 8, 2025 17:58
@danxuliu danxuliu marked this pull request as ready for review December 8, 2025 20:23
@danxuliu danxuliu requested a review from a team as a code owner December 8, 2025 20:23
@danxuliu danxuliu requested review from Altahrim, CarlSchwan, come-nc, icewind1991, provokateurin, salmart-dev and yemkareems and removed request for a team December 8, 2025 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews backport-request bug feature: caching Related to our caching system: scssCacher, jsCombiner... regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: memcache.local

2 participants