Skip to content

Commit

Permalink
Merge pull request #33992 from owncloud/files_ux_eh
Browse files Browse the repository at this point in the history
 Improve Files UX error handling
  • Loading branch information
Vincent Petry authored Mar 25, 2019
2 parents 51e12cf + 91f4cb1 commit 67c3a1f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 24 deletions.
45 changes: 31 additions & 14 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ public function initialize(\Sabre\DAV\Server $server) {
$this->server->on('propPatch', [$this, 'handleUpdateProperties']);
$this->server->on('afterBind', [$this, 'sendFileIdHeader']);
$this->server->on('afterWriteContent', [$this, 'sendFileIdHeader']);
$this->server->on('afterMethod:GET', [$this,'httpGet']);
$this->server->on('afterMethod:GET', [$this, 'httpGet']);
$this->server->on('afterMethod:GET', [$this, 'handleDownloadToken']);
$this->server->on('exception', [$this, 'handleDownloadFailure']);
$this->server->on('afterResponse', function ($request, ResponseInterface $response) {
$body = $response->getBody();
if (\is_resource($body)) {
Expand Down Expand Up @@ -191,29 +192,30 @@ public function checkMove($source, $destination) {
}
}

/**
* This sets a cookie to be able to recognize the failure of the download
*
* @param \Exception $ex
*/
public function handleDownloadFailure(\Exception $ex) {
$queryParams = $this->server->httpRequest->getQueryParameters();

if (isset($queryParams['downloadStartSecret'])) {
$this->setSecretCookie('ocDownloadStarted', '-1');
}
}

/**
* This sets a cookie to be able to recognize the start of the download
* the content must not be longer than 32 characters and must only contain
* alphanumeric characters
*
* @param RequestInterface $request
* @param ResponseInterface $response
*/
public function handleDownloadToken(RequestInterface $request, ResponseInterface $response) {
$queryParams = $request->getQueryParameters();

/**
* this sets a cookie to be able to recognize the start of the download
* the content must not be longer than 32 characters and must only contain
* alphanumeric characters
*/
if (isset($queryParams['downloadStartSecret'])) {
$token = $queryParams['downloadStartSecret'];
if (!isset($token[32])
&& \preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) {
// FIXME: use $response->setHeader() instead
\setcookie('ocDownloadStarted', $token, \time() + 20, '/');
}
$this->setSecretCookie('ocDownloadStarted', $queryParams['downloadStartSecret']);
}
}

Expand Down Expand Up @@ -433,4 +435,19 @@ public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
}
}
}

/**
* This sets a cookie, which content must not be longer than 32 characters and must only contain
* alphanumeric characters if request is successfuk, or -1 if request failed.
*
* @param $secretName
* @param $secretToken
*/
private function setSecretCookie($secretName, $secretToken) {
if ($secretToken == '-1' || (!isset($secretToken[32])
&& \preg_match('!^[a-zA-Z0-9]+$!', $secretToken) === 1)) {
// FIXME: use $response->setHeader() instead
\setcookie($secretName, $secretToken, \time() + 20, '/');
}
}
}
8 changes: 5 additions & 3 deletions apps/files/js/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,14 @@
handleDownload: function(url, callback) {
var randomToken = Math.random().toString(36).substring(2),
checkForDownloadCookie = function() {
if (!OC.Util.isCookieSetToValue('ocDownloadStarted', randomToken)){
return false;
} else {
// Successfull request should return cookie with token, failed with -1
if (OC.Util.isCookieSetToValue('ocDownloadStarted', randomToken) ||
OC.Util.isCookieSetToValue('ocDownloadStarted', '-1')) {
callback();
return true;
}

return false
};

if (url.indexOf('?') >= 0) {
Expand Down
19 changes: 12 additions & 7 deletions apps/files/tests/js/filesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,24 @@ describe('OCA.Files.Files tests', function() {
token = OC.parseQueryString(redirectStub.getCall(0).args[0]).downloadStartSecret;
expect(token).toBeDefined();

expect(cookieStub.calledOnce).toEqual(true);
cookieStub.returns(false);
expect(cookieStub.callCount).toEqual(2);
cookieStub.onCall(0).returns(false);
cookieStub.onCall(1).returns(false);
clock.tick(600);

expect(cookieStub.calledTwice).toEqual(true);
expect(cookieStub.getCall(1).args[0]).toEqual('ocDownloadStarted');
expect(cookieStub.getCall(1).args[1]).toEqual(token);
expect(cookieStub.callCount).toEqual(4);
expect(cookieStub.getCall(2).args[0]).toEqual('ocDownloadStarted');
expect(cookieStub.getCall(2).args[1]).toEqual(token);
expect(cookieStub.getCall(3).args[0]).toEqual('ocDownloadStarted');
expect(cookieStub.getCall(3).args[1]).toEqual('-1');
expect(callbackStub.notCalled).toEqual(true);

// now 1 ocDownloadStarted expected, with token argument
// should be called and return true
cookieStub.returns(true);
clock.tick(2000);

expect(cookieStub.callCount).toEqual(3);
clock.tick(2000);
expect(cookieStub.callCount).toEqual(5);
expect(callbackStub.calledOnce).toEqual(true);
});
});
Expand Down

0 comments on commit 67c3a1f

Please sign in to comment.