mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #53501 from nextcloud/fix-theming-for-disabled-accounts
fix: Fix theming for disabled accounts
This commit is contained in:
commit
d4e9a8ac33
11 changed files with 229 additions and 4 deletions
1
.github/workflows/integration-sqlite.yml
vendored
1
.github/workflows/integration-sqlite.yml
vendored
|
|
@ -70,6 +70,7 @@ jobs:
|
|||
- 'setup_features'
|
||||
- 'sharees_features'
|
||||
- 'sharing_features'
|
||||
- 'theming_features'
|
||||
- 'videoverification_features'
|
||||
|
||||
php-versions: ['8.1']
|
||||
|
|
|
|||
|
|
@ -266,3 +266,13 @@ default:
|
|||
- admin
|
||||
- admin
|
||||
regular_user_password: 123456
|
||||
theming:
|
||||
paths:
|
||||
- "%paths.base%/../theming_features"
|
||||
contexts:
|
||||
- FeatureContext:
|
||||
baseUrl: http://localhost:8080
|
||||
admin:
|
||||
- admin
|
||||
- admin
|
||||
regular_user_password: 123456
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ trait BasicStructure {
|
|||
use Avatar;
|
||||
use Download;
|
||||
use Mail;
|
||||
use Theming;
|
||||
|
||||
/** @var string */
|
||||
private $currentUser = '';
|
||||
|
|
|
|||
49
build/integration/features/bootstrap/Theming.php
Normal file
49
build/integration/features/bootstrap/Theming.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
trait Theming {
|
||||
|
||||
private bool $undoAllThemingChangesAfterScenario = false;
|
||||
|
||||
/**
|
||||
* @AfterScenario
|
||||
*/
|
||||
public function undoAllThemingChanges() {
|
||||
if (!$this->undoAllThemingChangesAfterScenario) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->loggingInUsingWebAs('admin');
|
||||
$this->sendingAToWithRequesttoken('POST', '/index.php/apps/theming/ajax/undoAllChanges');
|
||||
|
||||
$this->undoAllThemingChangesAfterScenario = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @When logged in admin uploads theming image for :key from file :source
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $source
|
||||
*/
|
||||
public function loggedInAdminUploadsThemingImageForFromFile(string $key, string $source) {
|
||||
$this->undoAllThemingChangesAfterScenario = true;
|
||||
|
||||
$file = \GuzzleHttp\Psr7\Utils::streamFor(fopen($source, 'r'));
|
||||
|
||||
$this->sendingAToWithRequesttoken('POST', '/index.php/apps/theming/ajax/uploadImage?key=' . $key,
|
||||
[
|
||||
'multipart' => [
|
||||
[
|
||||
'name' => 'image',
|
||||
'contents' => $file
|
||||
]
|
||||
]
|
||||
]);
|
||||
$this->theHTTPStatusCodeShouldBe('200');
|
||||
}
|
||||
}
|
||||
131
build/integration/theming_features/theming.feature
Normal file
131
build/integration/theming_features/theming.feature
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
Feature: theming
|
||||
|
||||
Background:
|
||||
Given user "user0" exists
|
||||
|
||||
Scenario: themed stylesheets are available for users
|
||||
Given As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/default.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/opendyslexic.css"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed stylesheets are available for guests
|
||||
Given As an "anonymous"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/default.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark.css"
|
||||
Then the HTTP status code should be "200"
|
||||
# Themes that can not be explicitly set by a guest could have been
|
||||
# globally set too through "enforce_theme".
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/opendyslexic.css"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed stylesheets are available for disabled users
|
||||
Given As an "admin"
|
||||
And assure user "user0" is disabled
|
||||
And As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/default.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/light-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/dark-highcontrast.css"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/theme/opendyslexic.css"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed images are available for users
|
||||
Given Logging in using web as "admin"
|
||||
And logged in admin uploads theming image for "background" from file "data/clouds.jpg"
|
||||
And logged in admin uploads theming image for "logo" from file "data/coloured-pattern-non-square.png"
|
||||
And logged in admin uploads theming image for "logoheader" from file "data/coloured-pattern-non-square.png"
|
||||
And As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/background"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logo"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logoheader"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed images are available for guests
|
||||
Given Logging in using web as "admin"
|
||||
And logged in admin uploads theming image for "background" from file "data/clouds.jpg"
|
||||
And logged in admin uploads theming image for "logo" from file "data/coloured-pattern-non-square.png"
|
||||
And logged in admin uploads theming image for "logoheader" from file "data/coloured-pattern-non-square.png"
|
||||
And As an "anonymous"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/background"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logo"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logoheader"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed images are available for disabled users
|
||||
Given Logging in using web as "admin"
|
||||
And logged in admin uploads theming image for "background" from file "data/clouds.jpg"
|
||||
And logged in admin uploads theming image for "logo" from file "data/coloured-pattern-non-square.png"
|
||||
And logged in admin uploads theming image for "logoheader" from file "data/coloured-pattern-non-square.png"
|
||||
And As an "admin"
|
||||
And assure user "user0" is disabled
|
||||
And As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/background"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logo"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/image/logoheader"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed icons are available for users
|
||||
Given As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed icons are available for guests
|
||||
Given As an "anonymous"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
|
||||
Scenario: themed icons are available for disabled users
|
||||
Given As an "admin"
|
||||
And assure user "user0" is disabled
|
||||
And As an "user0"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/favicon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
When sending "GET" with exact url to "/index.php/apps/theming/icon/dashboard"
|
||||
Then the HTTP status code should be "200"
|
||||
23
lib/base.php
23
lib/base.php
|
|
@ -12,6 +12,7 @@ use OC\Share20\GroupDeletedListener;
|
|||
use OC\Share20\Hooks;
|
||||
use OC\Share20\UserDeletedListener;
|
||||
use OC\Share20\UserRemovedListener;
|
||||
use OC\User\DisabledUserException;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Events\BeforeFileSystemSetupEvent;
|
||||
use OCP\Group\Events\GroupDeletedEvent;
|
||||
|
|
@ -1026,7 +1027,27 @@ class OC {
|
|||
// OAuth needs to support basic auth too, so the login is not valid
|
||||
// inside Nextcloud and the Login exception would ruin it.
|
||||
if ($request->getRawPathInfo() !== '/apps/oauth2/api/v1/token') {
|
||||
self::handleLogin($request);
|
||||
try {
|
||||
self::handleLogin($request);
|
||||
} catch (DisabledUserException $e) {
|
||||
// Disabled users would not be seen as logged in and
|
||||
// trying to log them in would fail, so the login
|
||||
// exception is ignored for the themed stylesheets and
|
||||
// images.
|
||||
if ($request->getRawPathInfo() !== '/apps/theming/theme/default.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/theme/light.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/theme/dark.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/theme/light-highcontrast.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/theme/dark-highcontrast.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/theme/opendyslexic.css'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/image/background'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/image/logo'
|
||||
&& $request->getRawPathInfo() !== '/apps/theming/image/logoheader'
|
||||
&& !str_starts_with($request->getRawPathInfo(), '/apps/theming/favicon')
|
||||
&& !str_starts_with($request->getRawPathInfo(), '/apps/theming/icon')) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2124,6 +2124,7 @@ return array(
|
|||
'OC\\User\\Backend' => $baseDir . '/lib/private/User/Backend.php',
|
||||
'OC\\User\\BackgroundJobs\\CleanupDeletedUsers' => $baseDir . '/lib/private/User/BackgroundJobs/CleanupDeletedUsers.php',
|
||||
'OC\\User\\Database' => $baseDir . '/lib/private/User/Database.php',
|
||||
'OC\\User\\DisabledUserException' => $baseDir . '/lib/private/User/DisabledUserException.php',
|
||||
'OC\\User\\DisplayNameCache' => $baseDir . '/lib/private/User/DisplayNameCache.php',
|
||||
'OC\\User\\LazyUser' => $baseDir . '/lib/private/User/LazyUser.php',
|
||||
'OC\\User\\Listeners\\BeforeUserDeletedListener' => $baseDir . '/lib/private/User/Listeners/BeforeUserDeletedListener.php',
|
||||
|
|
|
|||
|
|
@ -2165,6 +2165,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\User\\Backend' => __DIR__ . '/../../..' . '/lib/private/User/Backend.php',
|
||||
'OC\\User\\BackgroundJobs\\CleanupDeletedUsers' => __DIR__ . '/../../..' . '/lib/private/User/BackgroundJobs/CleanupDeletedUsers.php',
|
||||
'OC\\User\\Database' => __DIR__ . '/../../..' . '/lib/private/User/Database.php',
|
||||
'OC\\User\\DisabledUserException' => __DIR__ . '/../../..' . '/lib/private/User/DisabledUserException.php',
|
||||
'OC\\User\\DisplayNameCache' => __DIR__ . '/../../..' . '/lib/private/User/DisplayNameCache.php',
|
||||
'OC\\User\\LazyUser' => __DIR__ . '/../../..' . '/lib/private/User/LazyUser.php',
|
||||
'OC\\User\\Listeners\\BeforeUserDeletedListener' => __DIR__ . '/../../..' . '/lib/private/User/Listeners/BeforeUserDeletedListener.php',
|
||||
|
|
|
|||
10
lib/private/User/DisabledUserException.php
Normal file
10
lib/private/User/DisabledUserException.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OC\User;
|
||||
|
||||
class DisabledUserException extends LoginException {
|
||||
}
|
||||
|
|
@ -320,7 +320,7 @@ class Session implements IUserSession, Emitter {
|
|||
// disabled users can not log in
|
||||
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
|
||||
$message = \OCP\Util::getL10N('lib')->t('Account disabled');
|
||||
throw new LoginException($message);
|
||||
throw new DisabledUserException($message);
|
||||
}
|
||||
|
||||
if ($regenerateSessionId) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
use OC\Authentication\Token\IProvider;
|
||||
use OC\User\LoginException;
|
||||
use OC\User\DisabledUserException;
|
||||
use OCP\Authentication\Exceptions\InvalidTokenException;
|
||||
use OCP\Authentication\Exceptions\WipeTokenException;
|
||||
use OCP\Authentication\Token\IToken;
|
||||
|
|
@ -151,7 +151,7 @@ class OC_User {
|
|||
|
||||
if ($userSession->getUser() && !$userSession->getUser()->isEnabled()) {
|
||||
$message = \OC::$server->getL10N('lib')->t('Account disabled');
|
||||
throw new LoginException($message);
|
||||
throw new DisabledUserException($message);
|
||||
}
|
||||
$userSession->setLoginName($uid);
|
||||
$request = OC::$server->getRequest();
|
||||
|
|
|
|||
Loading…
Reference in a new issue