theming: handle not being in the serverroot

Currently, the theming app assumes it's in the serverroot. However, with
Nextcloud's flexibility regarding configurable app paths, this is not a
safe assumption to make. If it happens to be an incorrect assumption,
the theming app fails to work.

Instead of relying on the serverroot, just use the path from the
AppManager and utilize relative paths for assets from there.

Fix #8462

Signed-off-by: Kyle Fazzari <kyrofa@ubuntu.com>
This commit is contained in:
Kyle Fazzari 2018-02-20 22:44:37 -08:00
parent 88ece3f5d7
commit 4ecf31541b
No known key found for this signature in database
GPG Key ID: A7D23FB0E778DEDF
2 changed files with 34 additions and 5 deletions

View File

@ -53,6 +53,7 @@ use OCP\IRequest;
use OCA\Theming\Util;
use OCP\ITempManager;
use OCP\IURLGenerator;
use OCP\App\IAppManager;
/**
* Class ThemingController
@ -80,6 +81,8 @@ class ThemingController extends Controller {
private $scssCacher;
/** @var IURLGenerator */
private $urlGenerator;
/** @var IAppManager */
private $appManager;
/**
* ThemingController constructor.
@ -95,6 +98,7 @@ class ThemingController extends Controller {
* @param IAppData $appData
* @param SCSSCacher $scssCacher
* @param IURLGenerator $urlGenerator
* @param IAppManager $appManager
*/
public function __construct(
$appName,
@ -107,7 +111,8 @@ class ThemingController extends Controller {
ITempManager $tempManager,
IAppData $appData,
SCSSCacher $scssCacher,
IURLGenerator $urlGenerator
IURLGenerator $urlGenerator,
IAppManager $appManager
) {
parent::__construct($appName, $request);
@ -120,6 +125,7 @@ class ThemingController extends Controller {
$this->appData = $appData;
$this->scssCacher = $scssCacher;
$this->urlGenerator = $urlGenerator;
$this->appManager = $appManager;
}
/**
@ -413,12 +419,13 @@ class ThemingController extends Controller {
* @return FileDisplayResponse|NotFoundResponse
*/
public function getStylesheet() {
$appPath = substr(\OC::$server->getAppManager()->getAppPath('theming'), strlen(\OC::$SERVERROOT) + 1);
$appPath = $this->appManager->getAppPath('theming');
/* SCSSCacher is required here
* We cannot rely on automatic caching done by \OC_Util::addStyle,
* since we need to add the cacheBuster value to the url
*/
$cssCached = $this->scssCacher->process(\OC::$SERVERROOT, $appPath . '/css/theming.scss', 'theming');
$cssCached = $this->scssCacher->process($appPath, 'css/theming.scss', 'theming');
if(!$cssCached) {
return new NotFoundResponse();
}

View File

@ -106,7 +106,8 @@ class ThemingControllerTest extends TestCase {
$this->tempManager,
$this->appData,
$this->scssCacher,
$this->urlGenerator
$this->urlGenerator,
$this->appManager
);
return parent::setUp();
@ -798,7 +799,7 @@ class ThemingControllerTest extends TestCase {
public function testGetStylesheet() {
$this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn(\OC::$SERVERROOT . '/theming');
$file = $this->createMock(ISimpleFile::class);
$file->expects($this->any())->method('getName')->willReturn('theming.css');
$file->expects($this->any())->method('getContent')->willReturn('compiled');
@ -818,6 +819,7 @@ class ThemingControllerTest extends TestCase {
}
public function testGetStylesheetFails() {
$this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn(\OC::$SERVERROOT . '/theming');
$file = $this->createMock(ISimpleFile::class);
$file->expects($this->any())->method('getName')->willReturn('theming.css');
$file->expects($this->any())->method('getContent')->willReturn('compiled');
@ -829,6 +831,26 @@ class ThemingControllerTest extends TestCase {
$this->assertEquals($response, $actual);
}
public function testGetStylesheetOutsideServerroot() {
$this->appManager->expects($this->once())->method('getAppPath')->with('theming')->willReturn('/outside/serverroot/theming');
$file = $this->createMock(ISimpleFile::class);
$file->expects($this->any())->method('getName')->willReturn('theming.css');
$file->expects($this->any())->method('getContent')->willReturn('compiled');
$this->scssCacher->expects($this->once())->method('process')->with('/outside/serverroot/theming', 'css/theming.scss', 'theming')->willReturn(true);
$this->scssCacher->expects($this->once())->method('getCachedCSS')->willReturn($file);
$response = new Http\FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']);
$response->cacheFor(86400);
$expires = new \DateTime();
$expires->setTimestamp($this->timeFactory->getTime());
$expires->add(new \DateInterval('PT24H'));
$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
$response->addHeader('Pragma', 'cache');
$actual = $this->themingController->getStylesheet();
$this->assertEquals($response, $actual);
}
public function testGetJavascript() {
$this->themingDefaults
->expects($this->at(0))