Browse Source

Merge pull request #236 from nextcloud/master-sync-upstream

[Master] sync upstream
tags/v10.0RC1
Morris Jobke 7 years ago
parent
commit
b6397ef73a
42 changed files with 387 additions and 252 deletions
  1. 3
    0
      apps/comments/l10n/fi_FI.js
  2. 3
    0
      apps/comments/l10n/fi_FI.json
  3. 3
    0
      apps/comments/l10n/pl.js
  4. 3
    0
      apps/comments/l10n/pl.json
  5. 2
    2
      apps/federatedfilesharing/lib/FederatedShareProvider.php
  6. 18
    4
      apps/files/js/filelist.js
  7. 11
    0
      apps/files/tests/js/filelistSpec.js
  8. 4
    0
      apps/files_external/lib/AppInfo/Application.php
  9. 17
    5
      apps/files_sharing/lib/API/Share20OCS.php
  10. 67
    10
      apps/files_sharing/tests/API/Share20OCSTest.php
  11. 14
    2
      apps/files_sharing/tests/ApiTest.php
  12. 1
    0
      apps/systemtags/l10n/pl.js
  13. 1
    0
      apps/systemtags/l10n/pl.json
  14. 3
    3
      build/integration/features/sharing-v1.feature
  15. 3
    0
      core/Command/Encryption/DecryptAll.php
  16. 0
    8
      core/css/apps.css
  17. 0
    116
      core/css/fixes.css
  18. 0
    7
      core/css/multiselect.css
  19. 1
    9
      core/css/styles.css
  20. 5
    25
      core/js/js.js
  21. 1
    1
      core/js/sharedialoglinkshareview.js
  22. 7
    0
      core/l10n/pl.js
  23. 7
    0
      core/l10n/pl.json
  24. 1
    3
      core/templates/layout.base.php
  25. 1
    3
      core/templates/layout.guest.php
  26. 1
    3
      core/templates/layout.user.php
  27. 12
    3
      lib/private/IntegrityCheck/Checker.php
  28. 23
    0
      lib/private/Repair/RepairInvalidShares.php
  29. 1
    6
      lib/private/Share20/Manager.php
  30. 11
    2
      lib/private/User/Session.php
  31. 1
    0
      settings/Controller/AuthSettingsController.php
  32. 8
    8
      settings/css/settings.css
  33. 3
    3
      settings/js/authtoken.js
  34. 3
    3
      settings/js/authtoken_collection.js
  35. 16
    5
      settings/js/authtoken_view.js
  36. 2
    0
      settings/l10n/pl.js
  37. 2
    0
      settings/l10n/pl.json
  38. 10
    2
      settings/templates/personal.php
  39. 87
    0
      tests/lib/Repair/RepairInvalidSharesTest.php
  40. 0
    18
      tests/lib/Share20/ManagerTest.php
  41. 30
    0
      tests/lib/User/SessionTest.php
  42. 1
    1
      version.php

+ 3
- 0
apps/comments/l10n/fi_FI.js View File

@@ -12,6 +12,9 @@ OC.L10N.register(
"More comments..." : "Lisää kommentteja...",
"Save" : "Tallenna",
"Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}",
"Error occurred while retrieving comment with id {id}" : "Virhe noutaessa kommenttia tunnisteella {id}",
"Error occurred while updating comment with id {id}" : "Virhe päivittäessä kommenttia tunnisteella {id}",
"Error occurred while posting comment" : "Virhe kommenttia lähettäessä",
"{count} unread comments" : "{count} lukematonta kommenttia",
"Comment" : "Kommentti",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>",

+ 3
- 0
apps/comments/l10n/fi_FI.json View File

@@ -10,6 +10,9 @@
"More comments..." : "Lisää kommentteja...",
"Save" : "Tallenna",
"Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}",
"Error occurred while retrieving comment with id {id}" : "Virhe noutaessa kommenttia tunnisteella {id}",
"Error occurred while updating comment with id {id}" : "Virhe päivittäessä kommenttia tunnisteella {id}",
"Error occurred while posting comment" : "Virhe kommenttia lähettäessä",
"{count} unread comments" : "{count} lukematonta kommenttia",
"Comment" : "Kommentti",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>",

+ 3
- 0
apps/comments/l10n/pl.js View File

@@ -12,6 +12,9 @@ OC.L10N.register(
"More comments..." : "Więcej komentarzy...",
"Save" : "Zapisz",
"Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}",
"Error occurred while retrieving comment with id {id}" : "W trakcie otrzymywania komentarza o identyfikatorze {id} wystąpił błąd.",
"Error occurred while updating comment with id {id}" : "W trakcie aktualizacji komentarza o identyfikatorze {id} wystąpił błąd.",
"Error occurred while posting comment" : "Podczas wysyłania komentarza wystąpił błąd",
"{count} unread comments" : "{count} nieprzeczytanych komentarzy",
"Comment" : "Komentarz",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Komentarze</strong> dla plików <em>(zawsze wypisane w strumieniu)</em>",

+ 3
- 0
apps/comments/l10n/pl.json View File

@@ -10,6 +10,9 @@
"More comments..." : "Więcej komentarzy...",
"Save" : "Zapisz",
"Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}",
"Error occurred while retrieving comment with id {id}" : "W trakcie otrzymywania komentarza o identyfikatorze {id} wystąpił błąd.",
"Error occurred while updating comment with id {id}" : "W trakcie aktualizacji komentarza o identyfikatorze {id} wystąpił błąd.",
"Error occurred while posting comment" : "Podczas wysyłania komentarza wystąpił błąd",
"{count} unread comments" : "{count} nieprzeczytanych komentarzy",
"Comment" : "Komentarz",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Komentarze</strong> dla plików <em>(zawsze wypisane w strumieniu)</em>",

+ 2
- 2
apps/federatedfilesharing/lib/FederatedShareProvider.php View File

@@ -473,6 +473,8 @@ class FederatedShareProvider implements IShareProvider {

$isOwner = false;

$this->removeShareFromTable($share);

// if the local user is the owner we can send the unShare request directly...
if ($this->userManager->userExists($share->getShareOwner())) {
$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
@@ -494,8 +496,6 @@ class FederatedShareProvider implements IShareProvider {
}
$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
}

$this->removeShareFromTable($share);
}

/**

+ 18
- 4
apps/files/js/filelist.js View File

@@ -2351,22 +2351,36 @@
* @param filter
*/
setFilter:function(filter) {
var total = 0;
this._filter = filter;
this.fileSummary.setFilter(filter, this.files);
total = this.fileSummary.getTotal();
if (!this.$el.find('.mask').exists()) {
this.hideIrrelevantUIWhenNoFilesMatch();
}
var that = this;
var visibleCount = 0;
filter = filter.toLowerCase();
this.$fileList.find('tr').each(function(i,e) {
var $e = $(e);

function filterRows(tr) {
var $e = $(tr);
if ($e.data('file').toString().toLowerCase().indexOf(filter) === -1) {
$e.addClass('hidden');
} else {
visibleCount++;
$e.removeClass('hidden');
}
});
that.$container.trigger('scroll');
}

var $trs = this.$fileList.find('tr');
do {
_.each($trs, filterRows);
if (visibleCount < total) {
$trs = this._nextPage(false);
}
} while (visibleCount < total);

this.$container.trigger('scroll');
},
hideIrrelevantUIWhenNoFilesMatch:function() {
if (this._filter && this.fileSummary.summary.totalDirs + this.fileSummary.summary.totalFiles === 0) {

+ 11
- 0
apps/files/tests/js/filelistSpec.js View File

@@ -989,6 +989,17 @@ describe('OCA.Files.FileList tests', function() {
expect($summary.find('.info').text()).toEqual("1 folder and 3 files");
expect($nofilterresults.hasClass('hidden')).toEqual(true);
});
it('filters the list of non-rendered rows using filter()', function() {
var $summary = $('#filestable .summary');
var $nofilterresults = fileList.$el.find(".nofilterresults");
fileList.setFiles(generateFiles(0, 64));

fileList.setFilter('63');
expect($('#fileList tr:not(.hidden)').length).toEqual(1);
expect($summary.hasClass('hidden')).toEqual(false);
expect($summary.find('.info').text()).toEqual("0 folders and 1 file matches '63'");
expect($nofilterresults.hasClass('hidden')).toEqual(true);
});
it('hides the emptyfiles notice when using filter()', function() {
expect(fileList.files.length).toEqual(0);
expect(fileList.files).toEqual([]);

+ 4
- 0
apps/files_external/lib/AppInfo/Application.php View File

@@ -52,6 +52,10 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide
$backendService->registerBackendProvider($this);
$backendService->registerAuthMechanismProvider($this);

// force-load auth mechanisms since some will register hooks
// TODO: obsolete these and use the TokenProvider to get the user's password from the session
$this->getAuthMechanisms();

// app developers: do NOT depend on this! it will disappear with oC 9.0!
\OC::$server->getEventDispatcher()->dispatch(
'OCA\\Files_External::loadAdditionalBackends'

+ 17
- 5
apps/files_sharing/lib/API/Share20OCS.php View File

@@ -354,7 +354,8 @@ class Share20OCS {
$share->setPermissions(
\OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE
\OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE
);
} else {
$share->setPermissions(\OCP\Constants::PERMISSION_READ);
@@ -591,7 +592,7 @@ class Share20OCS {

$newPermissions = null;
if ($publicUpload === 'true') {
$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE;
$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
} else if ($publicUpload === 'false') {
$newPermissions = \OCP\Constants::PERMISSION_READ;
}
@@ -602,13 +603,21 @@ class Share20OCS {

if ($newPermissions !== null &&
$newPermissions !== \OCP\Constants::PERMISSION_READ &&
$newPermissions !== (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) &&
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
// legacy
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) &&
// correct
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links'));
}

if ($newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) {
if (
// legacy
$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
// correct
$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
) {
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
@@ -618,6 +627,9 @@ class Share20OCS {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders'));
}

// normalize to correct public upload permissions
$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
}

if ($newPermissions !== null) {

+ 67
- 10
apps/files_sharing/tests/API/Share20OCSTest.php View File

@@ -1035,7 +1035,7 @@ class Share20OCSTest extends \Test\TestCase {
$this->callback(function (\OCP\Share\IShare $share) use ($path) {
return $share->getNode() === $path &&
$share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
$share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
$share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
$share->getSharedBy() === 'currentUser' &&
$share->getPassword() === null &&
$share->getExpirationDate() === null;
@@ -1366,7 +1366,7 @@ class Share20OCSTest extends \Test\TestCase {
$date = new \DateTime('2000-01-01');
$date->setTime(0,0,0);

return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE && \OCP\Constants::PERMISSION_DELETE &&
return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
$share->getPassword() === 'password' &&
$share->getExpirationDate() == $date;
})
@@ -1379,6 +1379,44 @@ class Share20OCSTest extends \Test\TestCase {
$this->assertEquals($expected->getData(), $result->getData());
}

/**
* @dataProvider publicUploadParamsProvider
*/
public function testUpdateLinkShareEnablePublicUpload($params) {
$ocs = $this->mockFormatShare();

$folder = $this->getMock('\OCP\Files\Folder');

$share = \OC::$server->getShareManager()->newShare();
$share->setPermissions(\OCP\Constants::PERMISSION_ALL)
->setSharedBy($this->currentUser->getUID())
->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setPassword('password')
->setNode($folder);

$this->request
->method('getParam')
->will($this->returnValueMap($params));

$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
$this->shareManager->method('getSharedWith')->willReturn([]);

$this->shareManager->expects($this->once())->method('updateShare')->with(
$this->callback(function (\OCP\Share\IShare $share) {
return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
$share->getPassword() === 'password' &&
$share->getExpirationDate() === null;
})
)->will($this->returnArgument(0));

$expected = new \OC_OCS_Result(null);
$result = $ocs->updateShare(42);

$this->assertEquals($expected->getMeta(), $result->getMeta());
$this->assertEquals($expected->getData(), $result->getData());
}

public function testUpdateLinkShareInvalidDate() {
$ocs = $this->mockFormatShare();

@@ -1408,7 +1446,30 @@ class Share20OCSTest extends \Test\TestCase {
$this->assertEquals($expected->getData(), $result->getData());
}

public function testUpdateLinkSharePublicUploadNotAllowed() {
public function publicUploadParamsProvider() {
return [
[[
['publicUpload', null, 'true'],
['expireDate', '', null],
['password', '', 'password'],
]], [[
// legacy had no delete
['permissions', null, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE],
['expireDate', '', null],
['password', '', 'password'],
]], [[
// correct
['permissions', null, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE],
['expireDate', '', null],
['password', '', 'password'],
]],
];
}

/**
* @dataProvider publicUploadParamsProvider
*/
public function testUpdateLinkSharePublicUploadNotAllowed($params) {
$ocs = $this->mockFormatShare();

$folder = $this->getMock('\OCP\Files\Folder');
@@ -1421,11 +1482,7 @@ class Share20OCSTest extends \Test\TestCase {

$this->request
->method('getParam')
->will($this->returnValueMap([
['publicUpload', null, 'true'],
['expireDate', '', null],
['password', '', 'password'],
]));
->will($this->returnValueMap($params));

$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
@@ -1585,7 +1642,7 @@ class Share20OCSTest extends \Test\TestCase {

$this->shareManager->expects($this->once())->method('updateShare')->with(
$this->callback(function (\OCP\Share\IShare $share) use ($date) {
return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
$share->getPassword() === 'password' &&
$share->getExpirationDate() === $date;
})
@@ -1625,7 +1682,7 @@ class Share20OCSTest extends \Test\TestCase {

$this->shareManager->expects($this->once())->method('updateShare')->with(
$this->callback(function (\OCP\Share\IShare $share) use ($date) {
return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) &&
$share->getPassword() === 'password' &&
$share->getExpirationDate() === $date;
})

+ 14
- 2
apps/files_sharing/tests/ApiTest.php View File

@@ -257,7 +257,13 @@ class ApiTest extends TestCase {
$this->assertTrue($result->succeeded());

$data = $result->getData();
$this->assertEquals(7, $data['permissions']);
$this->assertEquals(
\OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE,
$data['permissions']
);
$this->assertEmpty($data['expiration']);
$this->assertTrue(is_string($data['token']));

@@ -1081,7 +1087,13 @@ class ApiTest extends TestCase {
$this->assertTrue($result->succeeded());

$share1 = $this->shareManager->getShareById($share1->getFullId());
$this->assertEquals(7, $share1->getPermissions());
$this->assertEquals(
\OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE,
$share1->getPermissions()
);

// cleanup
$this->shareManager->deleteShare($share1);

+ 1
- 0
apps/systemtags/l10n/pl.js View File

@@ -14,6 +14,7 @@ OC.L10N.register(
"%1$s updated system tag %3$s to %2$s" : "%1$s zaktualizowany system etykiet%3$s do %2$s",
"%1$s assigned system tag %3$s to %2$s" : "%1$s przypisywalny system etykiet%3$s do %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s nieprzypisany system etykiet %3$s z %2$s",
"%s (restricted)" : "%s (ograniczone)",
"%s (invisible)" : "%s (niewidoczny)",
"No files in here" : "Brak plików",
"No entries found in this folder" : "Brak wpisów w tym folderze",

+ 1
- 0
apps/systemtags/l10n/pl.json View File

@@ -12,6 +12,7 @@
"%1$s updated system tag %3$s to %2$s" : "%1$s zaktualizowany system etykiet%3$s do %2$s",
"%1$s assigned system tag %3$s to %2$s" : "%1$s przypisywalny system etykiet%3$s do %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s nieprzypisany system etykiet %3$s z %2$s",
"%s (restricted)" : "%s (ograniczone)",
"%s (invisible)" : "%s (niewidoczny)",
"No files in here" : "Brak plików",
"No entries found in this folder" : "Brak wpisów w tym folderze",

+ 3
- 3
build/integration/features/sharing-v1.feature View File

@@ -61,7 +61,7 @@ Feature: sharing
And the HTTP status code should be "200"
And Share fields of last share match with
| id | A_NUMBER |
| permissions | 7 |
| permissions | 15 |
| expiration | +3 days |
| url | AN_URL |
| token | A_TOKEN |
@@ -159,7 +159,7 @@ Feature: sharing
| share_type | 3 |
| file_source | A_NUMBER |
| file_target | /FOLDER |
| permissions | 7 |
| permissions | 15 |
| stime | A_NUMBER |
| token | A_TOKEN |
| storage | A_NUMBER |
@@ -189,7 +189,7 @@ Feature: sharing
| share_type | 3 |
| file_source | A_NUMBER |
| file_target | /FOLDER |
| permissions | 7 |
| permissions | 15 |
| stime | A_NUMBER |
| token | A_TOKEN |
| storage | A_NUMBER |

+ 3
- 0
core/Command/Encryption/DecryptAll.php View File

@@ -150,6 +150,9 @@ class DecryptAll extends Command {
$output->writeln(' aborted.');
$output->writeln('Server side encryption remains enabled');
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
} else if ($uid !== '') {
$output->writeln('Server side encryption remains enabled');
$this->config->setAppValue('core', 'encryption_enabled', 'yes');
}
$this->resetSingleUserAndTrashbin();
} else {

+ 0
- 8
core/css/apps.css View File

@@ -162,7 +162,6 @@
text-overflow: ellipsis;
overflow: hidden;
display: inline-block;
width: 201px; /* fallback for IE8 */
width: calc(100% - 49px);
line-height: 44px;
float: left;
@@ -309,12 +308,6 @@
.edge #app-navigation .app-navigation-entry-menu:after {
border: 1px solid #eee;
}
.ie8 .bubble {
margin-top: 18px;
}
.ie8 .bubble:after {
display: none;
}
/* miraculous border arrow stuff */
.bubble:after,
#app-navigation .app-navigation-entry-menu:after {
@@ -392,7 +385,6 @@
#app-navigation .app-navigation-entry-edit input {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
width: 204px; /* fallback for IE8 */
width: calc(100% - 36px);
padding: 5px;
margin-right: 0;

+ 0
- 116
core/css/fixes.css View File

@@ -10,125 +10,9 @@ select {
height: 32px;
}

/* reset typeface for IE8 because OpenSans renders too small */
.ie8 body {
font-family: Frutiger, Calibri, 'Myriad Pro', Myriad, Arial, sans-serif;
}

.lte8 .icon-delete { background-image: url('../img/actions/delete.png'); }
.lte8 .icon-delete:hover, .icon-delete:focus {
background-image: url('../img/actions/delete-hover.png');
}

.ie8 .icon-checkmark {
background-image: url('../img/actions/checkmark.png');
}

.ie8 .icon-close {
background-image: url('../img/actions/close.png');
}

.lte9 .icon-triangle-e {
background-image: url('../img/actions/triangle-e.png');
}
.lte9 .icon-triangle-n {
background-image: url('../img/actions/triangle-n.png');
}
.lte9 .icon-triangle-s {
background-image: url('../img/actions/triangle-s.png');
}
.lte9 .icon-settings,
.lte9 .settings-button {
background-image: url('../img/actions/settings.png');
}

.lte9 input[type="submit"], .lte9 input[type="button"],
.lte9 button, .lte9 .button,
.lte9 #quota, .lte9 select, .lte9 .pager li a {
background-color: #f1f1f1;
}

/* IE8 needs PNG image for header logo */
.ie8 #header .logo {
background-image: url(../img/logo-icon-175px.png);
}

/* IE8 needs background to be set to same color to make transparency look good. */
.lte9 #body-login form input[type="text"] {
border: 1px solid lightgrey; /* use border to add 1px line between input fields */
background-color: white; /* don't change background on hover */
}
.lte9 #body-login form input[type="password"] {
/* leave out top border for 1px line between input fields*/
border-left: 1px solid lightgrey;
border-right: 1px solid lightgrey;
border-bottom: 1px solid lightgrey;
background-color: white; /* don't change background on hover */
}
.ie8 #body-login input[type="submit"] {
padding: 10px 5px;
margin-top: 3px;
}
/* for whatever unexplained reason */
.ie8 #password {
width: 271px !important;
min-width: auto !important;
}

/* disable opacity of info text on gradient
since we cannot set a good backround color to use the filter&background hack as with the input labels */
.lte9 #body-login p.info {
filter: initial;
}

/* deactivate show password toggle for IE. Does not work for 8 and 9+ have their own implementation. */
.ie #show, .ie #show+label {
display: none;
visibility: hidden;
}

/* fix installation screen rendering issue for IE8+9 */
.lte9 #body-login {
min-height: 100%;
height: auto !important;
}

/* oc-dialog only uses box shadow which is not supported by ie8 */
.ie8 .oc-dialog {
border: 1px solid #888888;
}

/* IE8 doesn't support transparent background - let's emulate black with an opacity of .3 on a dark blue background*/
.ie8 fieldset .warning, .ie8 #body-login .error {
background-color: #1B314D;
}

/* IE8 isn't able to display transparent background. So it is specified using a gradient */
.ie8 #nojavascript {
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#4c320000', endColorstr='#4c320000');
}

/* fix background of navigation popup in IE8 */
.ie8 #navigation,
.ie8 #expanddiv {
background-color: #111;
}

/* needed else IE8 will randomly hide the borders... */
.ie8 table th#headerDate, table td.date,
.ie8 table th.column-last, table td.column-last {
position: static;
}

.ie8 #controls {
background-color: white;
}

.ie8 #content-wrapper {
overflow-y: auto;
}

.ie8 #app-navigation .app-navigation-entry-edit input {
line-height: 38px;
}


+ 0
- 7
core/css/multiselect.css View File

@@ -111,10 +111,3 @@ ul.multiselectoptions > li.creator > input {
padding: 5px;
margin: -5px;
}

.ie8 div.multiselect span:first-child {
display:block;
position:relative;
width: 90%;
margin-right:-1px;
}

+ 1
- 9
core/css/styles.css View File

@@ -189,7 +189,6 @@ a.two-factor-cancel {
.emptycontent {
color: #888;
text-align: center;
margin-top: 100px; /* ie8 */
margin-top: 30vh;
width: 100%;
}
@@ -418,14 +417,7 @@ label.infield {
-ms-user-select: none;
user-select: none;
}
html.ie8 #body-login form input[type="checkbox"]+label {
margin-left: -28px;
margin-top: -3px;
vertical-align: auto;
}
html.ie8 #body-login form input[type="checkbox"] {
margin-top: 5px;
}

#body-login form .errors { background:#fed7d7; border:1px solid #f00; list-style-indent:inside; margin:0 0 2em; padding:1em; }
#body-login .success { background:#d7fed7; border:1px solid #0f0; width: 35%; margin: 30px auto; padding:1em; text-align: center;}


+ 5
- 25
core/js/js.js View File

@@ -788,7 +788,6 @@ var OC={
$(document).trigger(new $.Event('ajaxError'), xhr);
};

// FIXME: also needs an IE8 way
if (xhr.addEventListener) {
xhr.addEventListener('load', loadCallback);
xhr.addEventListener('error', errorCallback);
@@ -1857,30 +1856,10 @@ OC.Util = {
* This scales the image to the element's actual size, the URL is
* taken from the "background-image" CSS attribute.
*
* @deprecated IE8 isn't supported since 9.0
* @param {Object} $el image element
*/
scaleFixForIE8: function($el) {
if (!this.isIE8()) {
return;
}
var self = this;
$($el).each(function() {
var url = $(this).css('background-image');
var r = url.match(/url\(['"]?([^'")]*)['"]?\)/);
if (!r) {
return;
}
url = r[1];
url = self.replaceSVGIcon(url);
// TODO: escape
url = url.replace(/'/g, '%27');
$(this).css({
'filter': 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + url + '\', sizingMethod=\'scale\')',
'background-image': ''
});
});
return $el;
},
scaleFixForIE8: function($el) {},

/**
* Returns whether this is IE
@@ -1894,10 +1873,11 @@ OC.Util = {
/**
* Returns whether this is IE8
*
* @return {bool} true if this is IE8, false otherwise
* @deprecated IE8 isn't supported since 9.0
* @return {bool} false (IE8 isn't supported anymore)
*/
isIE8: function() {
return $('html').hasClass('ie8');
return false;
},

/**

+ 1
- 1
core/js/sharedialoglinkshareview.js View File

@@ -215,7 +215,7 @@

var permissions = OC.PERMISSION_READ;
if($checkbox.is(':checked')) {
permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ;
permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE;
}

this.model.saveLinkShare({

+ 7
- 0
core/l10n/pl.js View File

@@ -166,9 +166,13 @@ OC.L10N.register(
"delete" : "usuń",
"access control" : "kontrola dostępu",
"Could not unshare" : "Nie udało się usunąć udostępnienia",
"Share details could not be loaded for this item." : "Szczegóły udziału nie mogły zostać wczytane dla tego obiektu.",
"No users or groups found for {search}" : "Nie znaleziono użytkowników lub grup dla {search}",
"No users found for {search}" : "Nie znaleziono użytkowników dla {search}",
"An error occurred. Please try again" : "Wystąpił błąd. Proszę spróbować ponownie.",
"{sharee} (group)" : "{sharee} (grupa)",
"{sharee} (at {server})" : "{sharee} (na {server})",
"{sharee} (remote)" : "{sharee} (zdalny)",
"Share" : "Udostępnij",
"Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Współdziel z użytkownikami innych chmur ownCloud używając wzorca uzytkownik@example.com/owncloud",
"Share with users…" : "Współdziel z użytkownikami...",
@@ -181,6 +185,7 @@ OC.L10N.register(
"Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje",
"restricted" : "ograniczone",
"invisible" : "niewidoczny",
"({scope})" : "({scope})",
"Delete" : "Usuń",
"Rename" : "Zmień nazwę",
"The object type is not specified." : "Nie określono typu obiektu.",
@@ -237,6 +242,7 @@ OC.L10N.register(
"Data folder" : "Katalog danych",
"Configure the database" : "Skonfiguruj bazę danych",
"Only %s is available." : "Dostępne jest wyłącznie %s.",
"Install and activate additional PHP modules to choose other database types." : "Zainstaluj lub aktywuj dodatkowe moduły PHP, aby uzyskać możliwość wyboru innych typów baz danych.",
"For more details check out the documentation." : "Aby uzyskać więcej informacji zapoznaj się z dokumentacją.",
"Database user" : "Użytkownik bazy danych",
"Database password" : "Hasło do bazy danych",
@@ -289,6 +295,7 @@ OC.L10N.register(
"To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby uniknąć timeout-ów przy większych instalacjach, możesz zamiast tego uruchomić następującą komendę w katalogu Twojej instalacji:",
"Detailed logs" : "Szczegółowe logi",
"Update needed" : "Wymagana aktualizacja",
"Please use the command line updater because you have a big instance." : "Ze względu na rozmiar Twojej instalacji użyj programu do aktualizacji z linii poleceń.",
"For help, see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation</a>." : "Aby uzyskać pomoc, zajrzyj do <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">dokumentacji</a>.",
"This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna."
},

+ 7
- 0
core/l10n/pl.json View File

@@ -164,9 +164,13 @@
"delete" : "usuń",
"access control" : "kontrola dostępu",
"Could not unshare" : "Nie udało się usunąć udostępnienia",
"Share details could not be loaded for this item." : "Szczegóły udziału nie mogły zostać wczytane dla tego obiektu.",
"No users or groups found for {search}" : "Nie znaleziono użytkowników lub grup dla {search}",
"No users found for {search}" : "Nie znaleziono użytkowników dla {search}",
"An error occurred. Please try again" : "Wystąpił błąd. Proszę spróbować ponownie.",
"{sharee} (group)" : "{sharee} (grupa)",
"{sharee} (at {server})" : "{sharee} (na {server})",
"{sharee} (remote)" : "{sharee} (zdalny)",
"Share" : "Udostępnij",
"Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Współdziel z użytkownikami innych chmur ownCloud używając wzorca uzytkownik@example.com/owncloud",
"Share with users…" : "Współdziel z użytkownikami...",
@@ -179,6 +183,7 @@
"Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje",
"restricted" : "ograniczone",
"invisible" : "niewidoczny",
"({scope})" : "({scope})",
"Delete" : "Usuń",
"Rename" : "Zmień nazwę",
"The object type is not specified." : "Nie określono typu obiektu.",
@@ -235,6 +240,7 @@
"Data folder" : "Katalog danych",
"Configure the database" : "Skonfiguruj bazę danych",
"Only %s is available." : "Dostępne jest wyłącznie %s.",
"Install and activate additional PHP modules to choose other database types." : "Zainstaluj lub aktywuj dodatkowe moduły PHP, aby uzyskać możliwość wyboru innych typów baz danych.",
"For more details check out the documentation." : "Aby uzyskać więcej informacji zapoznaj się z dokumentacją.",
"Database user" : "Użytkownik bazy danych",
"Database password" : "Hasło do bazy danych",
@@ -287,6 +293,7 @@
"To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Aby uniknąć timeout-ów przy większych instalacjach, możesz zamiast tego uruchomić następującą komendę w katalogu Twojej instalacji:",
"Detailed logs" : "Szczegółowe logi",
"Update needed" : "Wymagana aktualizacja",
"Please use the command line updater because you have a big instance." : "Ze względu na rozmiar Twojej instalacji użyj programu do aktualizacji z linii poleceń.",
"For help, see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation</a>." : "Aby uzyskać pomoc, zajrzyj do <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">dokumentacji</a>.",
"This page will refresh itself when the %s instance is available again." : "Strona odświeży się gdy instancja %s będzie ponownie dostępna."
},"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"

+ 1
- 3
core/templates/layout.base.php View File

@@ -1,7 +1,5 @@
<!DOCTYPE html>
<!--[if lte IE 8]><html class="ng-csp ie ie8 lte9 lte8" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if IE 9]><html class="ng-csp ie ie9 lte9" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><!--<![endif]-->
<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" >
<head data-requesttoken="<?php p($_['requesttoken']); ?>">
<meta charset="utf-8">
<title>

+ 1
- 3
core/templates/layout.guest.php View File

@@ -1,7 +1,5 @@
<!DOCTYPE html>
<!--[if lte IE 8]><html class="ng-csp ie ie8 lte9 lte8" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if IE 9]><html class="ng-csp ie ie9 lte9" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><!--<![endif]-->
<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" >
<head data-requesttoken="<?php p($_['requesttoken']); ?>">
<meta charset="utf-8">
<title>

+ 1
- 3
core/templates/layout.user.php View File

@@ -1,7 +1,5 @@
<!DOCTYPE html>
<!--[if lte IE 8]><html class="ng-csp ie ie8 lte9 lte8" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if IE 9]><html class="ng-csp ie ie9 lte9" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" ><!--<![endif]-->
<html class="ng-csp" data-placeholder-focus="false" lang="<?php p($_['language']); ?>" >
<head data-user="<?php p($_['user_uid']); ?>" data-user-displayname="<?php p($_['user_displayname']); ?>" data-requesttoken="<?php p($_['requesttoken']); ?>">
<meta charset="utf-8">
<title>

+ 12
- 3
lib/private/IntegrityCheck/Checker.php View File

@@ -108,7 +108,11 @@ class Checker {
* applicable for very specific scenarios and we should not advertise it
* too prominent. So please do not add it to config.sample.php.
*/
$isIntegrityCheckDisabled = $this->config->getSystemValue('integrity.check.disabled', false);
if ($this->config !== null) {
$isIntegrityCheckDisabled = $this->config->getSystemValue('integrity.check.disabled', false);
} else {
$isIntegrityCheckDisabled = false;
}
if($isIntegrityCheckDisabled === true) {
return false;
}
@@ -401,7 +405,10 @@ class Checker {
return json_decode($cachedResults, true);
}

return json_decode($this->config->getAppValue('core', self::CACHE_KEY, '{}'), true);
if ($this->config !== null) {
return json_decode($this->config->getAppValue('core', self::CACHE_KEY, '{}'), true);
}
return [];
}

/**
@@ -416,7 +423,9 @@ class Checker {
if(!empty($result)) {
$resultArray[$scope] = $result;
}
$this->config->setAppValue('core', self::CACHE_KEY, json_encode($resultArray));
if ($this->config !== null) {
$this->config->setAppValue('core', self::CACHE_KEY, json_encode($resultArray));
}
$this->cache->set(self::CACHE_KEY, json_encode($resultArray));
}


+ 23
- 0
lib/private/Repair/RepairInvalidShares.php View File

@@ -71,6 +71,25 @@ class RepairInvalidShares implements IRepairStep {
}
}

/**
* In the past link shares with public upload enabled were missing the delete permission.
*/
private function addShareLinkDeletePermission(IOutput $out) {
$oldPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE;
$newPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
$builder = $this->connection->getQueryBuilder();
$builder
->update('share')
->set('permissions', $builder->expr()->literal($newPerms))
->where($builder->expr()->eq('share_type', $builder->expr()->literal(\OC\Share\Constants::SHARE_TYPE_LINK)))
->andWhere($builder->expr()->eq('permissions', $builder->expr()->literal($oldPerms)));

$updatedEntries = $builder->execute();
if ($updatedEntries > 0) {
$out->info('Fixed link share permissions for ' . $updatedEntries . ' shares');
}
}

/**
* Remove shares where the parent share does not exist anymore
*/
@@ -113,6 +132,10 @@ class RepairInvalidShares implements IRepairStep {
// this situation was only possible before 8.2
$this->removeExpirationDateFromNonLinkShares($out);
}
if (version_compare($ocVersionFromBeforeUpdate, '9.1.0.9', '<')) {
// this situation was only possible before 9.1
$this->addShareLinkDeletePermission($out);
}

$this->removeSharesNonExistingParent($out);
}

+ 1
- 6
lib/private/Share20/Manager.php View File

@@ -452,14 +452,9 @@ class Manager implements IManager {
throw new \InvalidArgumentException('Link shares can\'t have reshare permissions');
}

// We don't allow deletion on link shares
if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
throw new \InvalidArgumentException('Link shares can\'t have delete permissions');
}

// Check if public upload is allowed
if (!$this->shareApiLinkAllowPublicUpload() &&
($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE))) {
($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
throw new \InvalidArgumentException('Public upload not allowed');
}
}

+ 11
- 2
lib/private/User/Session.php View File

@@ -280,7 +280,7 @@ class Session implements IUserSession, Emitter {
*/
public function login($uid, $password) {
$this->session->regenerateId();
if ($this->validateToken($password)) {
if ($this->validateToken($password, $uid)) {
// When logging in with token, the password must be decrypted first before passing to login hook
try {
$token = $this->tokenProvider->getToken($password);
@@ -584,15 +584,24 @@ class Session implements IUserSession, Emitter {
* Invalidates the token if checks fail
*
* @param string $token
* @param string $user login name
* @return boolean
*/
private function validateToken($token) {
private function validateToken($token, $user = null) {
try {
$dbToken = $this->tokenProvider->getToken($token);
} catch (InvalidTokenException $ex) {
return false;
}

// Check if login names match
if (!is_null($user) && $dbToken->getLoginName() !== $user) {
// TODO: this makes it imposssible to use different login names on browser and client
// e.g. login by e-mail 'user@example.com' on browser for generating the token will not
// allow to use the client token with the login name 'user'.
return false;
}

if (!$this->checkTokenCredentials($dbToken, $token)) {
return false;
}

+ 1
- 0
settings/Controller/AuthSettingsController.php View File

@@ -118,6 +118,7 @@ class AuthSettingsController extends Controller {

return [
'token' => $token,
'loginName' => $loginName,
'deviceToken' => $deviceToken
];
}

+ 8
- 8
settings/css/settings.css View File

@@ -131,11 +131,19 @@ table.nostyle td { padding: 0.2em 0; }
opacity: 0.6;
}

#new-app-login-name,
#new-app-password {
width: 186px;
font-family: monospace;
background-color: lightyellow;
}
.app-password-row {
display: table-row;
}
.app-password-label {
display: table-cell;
padding-right: 1em;
}

/* USERS */
#newgroup-init a span { margin-left: 20px; }
@@ -161,10 +169,6 @@ table.nostyle td { padding: 0.2em 0; }
width: 32px;
}

.ie8 #newgroup-form .icon-add {
height: 30px;
}

.isgroup .groupname {
width: 85%;
display: block;
@@ -281,10 +285,6 @@ input.userFilter {width: 200px;}
width: 32px;
}


.ie8 table.hascontrols{border-collapse:collapse;width: 100%;}
.ie8 table.hascontrols tbody tr{border-collapse:collapse;border: 1px solid #ddd !important;}

/* used to highlight a user row in red */
#userlist tr.row-warning {
background-color: #FDD;

+ 3
- 3
settings/js/authtoken.js View File

@@ -20,14 +20,14 @@
*
*/

(function(OC, Backbone) {
(function(OC) {
'use strict';

OC.Settings = OC.Settings || {};

var AuthToken = Backbone.Model.extend({
var AuthToken = OC.Backbone.Model.extend({
});

OC.Settings.AuthToken = AuthToken;

})(OC, Backbone);
})(OC);

+ 3
- 3
settings/js/authtoken_collection.js View File

@@ -20,12 +20,12 @@
*
*/

(function(OC, Backbone) {
(function(OC) {
'use strict';

OC.Settings = OC.Settings || {};

var AuthTokenCollection = Backbone.Collection.extend({
var AuthTokenCollection = OC.Backbone.Collection.extend({

model: OC.Settings.AuthToken,

@@ -49,4 +49,4 @@

OC.Settings.AuthTokenCollection = AuthTokenCollection;

})(OC, Backbone);
})(OC);

+ 16
- 5
settings/js/authtoken_view.js View File

@@ -1,4 +1,4 @@
/* global Backbone, Handlebars, moment */
/* global Handlebars, moment */

/**
* @author Christoph Wurst <christoph@owncloud.com>
@@ -20,7 +20,7 @@
*
*/

(function(OC, _, Backbone, $, Handlebars, moment) {
(function(OC, _, $, Handlebars, moment) {
'use strict';

OC.Settings = OC.Settings || {};
@@ -32,7 +32,7 @@
+ '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>'
+ '<tr>';

var SubView = Backbone.View.extend({
var SubView = OC.Backbone.View.extend({
collection: null,

/**
@@ -94,7 +94,7 @@
}
});

var AuthTokenView = Backbone.View.extend({
var AuthTokenView = OC.Backbone.View.extend({
collection: null,

_views: [],
@@ -107,6 +107,8 @@

_result: undefined,

_newAppLoginName: undefined,

_newAppPassword: undefined,

_hideAppPasswordBtn: undefined,
@@ -136,6 +138,8 @@
this._addAppPasswordBtn.click(_.bind(this._addAppPassword, this));

this._result = $('#app-password-result');
this._newAppLoginName = $('#new-app-login-name');
this._newAppLoginName.on('focus', _.bind(this._onNewTokenLoginNameFocus, this));
this._newAppPassword = $('#new-app-password');
this._newAppPassword.on('focus', _.bind(this._onNewTokenFocus, this));
this._hideAppPasswordBtn = $('#app-password-hide');
@@ -181,6 +185,7 @@
$.when(creatingToken).done(function(resp) {
_this.collection.add(resp.deviceToken);
_this.render();
_this._newAppLoginName.val(resp.loginName);
_this._newAppPassword.val(resp.token);
_this._toggleFormResult(false);
_this._newAppPassword.select();
@@ -194,6 +199,10 @@
});
},

_onNewTokenLoginNameFocus: function() {
this._newAppLoginName.select();
},

_onNewTokenFocus: function() {
this._newAppPassword.select();
},
@@ -220,6 +229,8 @@

var destroyingToken = token.destroy();

$row.find('.icon-delete').tooltip('hide');

var _this = this;
$.when(destroyingToken).fail(function() {
OC.Notification.showTemporary(t('core', 'Error while deleting the token'));
@@ -237,4 +248,4 @@

OC.Settings.AuthTokenView = AuthTokenView;

})(OC, _, Backbone, $, Handlebars, moment);
})(OC, _, $, Handlebars, moment);

+ 2
- 0
settings/l10n/pl.js View File

@@ -28,6 +28,7 @@ OC.L10N.register(
"Email saved" : "E-mail zapisany",
"Your full name has been changed." : "Twoja pełna nazwa została zmieniona.",
"Unable to change full name" : "Nie można zmienić pełnej nazwy",
"Redis" : "Redis",
"Security & setup warnings" : "Ostrzeżenia bezpieczeństwa i konfiguracji",
"Sharing" : "Udostępnianie",
"Server-side encryption" : "Szyfrowanie po stronie serwera",
@@ -48,6 +49,7 @@ OC.L10N.register(
"Migration in progress. Please wait until the migration is finished" : "Trwa migracja. Proszę poczekać, aż migracja dobiegnie końca.",
"Migration started …" : "Migracja rozpoczęta...",
"Sending..." : "Wysyłam...",
"Experimental" : "Eksperymentalny",
"All" : "Wszystkie",
"No apps found for your version" : "Nie znaleziono aplikacji dla twojej wersji",
"Update to %s" : "Uaktualnij do %s",

+ 2
- 0
settings/l10n/pl.json View File

@@ -26,6 +26,7 @@
"Email saved" : "E-mail zapisany",
"Your full name has been changed." : "Twoja pełna nazwa została zmieniona.",
"Unable to change full name" : "Nie można zmienić pełnej nazwy",
"Redis" : "Redis",
"Security & setup warnings" : "Ostrzeżenia bezpieczeństwa i konfiguracji",
"Sharing" : "Udostępnianie",
"Server-side encryption" : "Szyfrowanie po stronie serwera",
@@ -46,6 +47,7 @@
"Migration in progress. Please wait until the migration is finished" : "Trwa migracja. Proszę poczekać, aż migracja dobiegnie końca.",
"Migration started …" : "Migracja rozpoczęta...",
"Sending..." : "Wysyłam...",
"Experimental" : "Eksperymentalny",
"All" : "Wszystkie",
"No apps found for your version" : "Nie znaleziono aplikacji dla twojej wersji",
"Update to %s" : "Uaktualnij do %s",

+ 10
- 2
settings/templates/personal.php View File

@@ -201,8 +201,16 @@ if($_['passwordChangeSupported']) {
<button id="add-app-password" class="button"><?php p($l->t('Create new app password')); ?></button>
</div>
<div id="app-password-result" class="hidden">
<input id="new-app-password" type="text" readonly="readonly"/>
<button id="app-password-hide" class="button"><?php p($l->t('Done')); ?></button>
<span><?php p($l->t('Use the credentials below to configure your app or device.')); ?></span>
<div class="app-password-row">
<span class="app-password-label"><?php p($l->t('Username')); ?></span>
<input id="new-app-login-name" type="text" readonly="readonly"/>
</div>
<div class="app-password-row">
<span class="app-password-label"><?php p($l->t('Password')); ?></span>
<input id="new-app-password" type="text" readonly="readonly"/>
<button id="app-password-hide" class="button"><?php p($l->t('Done')); ?></button>
</div>
</div>
</div>


+ 87
- 0
tests/lib/Repair/RepairInvalidSharesTest.php View File

@@ -123,6 +123,93 @@ class RepairInvalidSharesTest extends TestCase {
$this->assertNotNull($linkShare['expiration'], 'valid link share expiration date still there');
}

/**
* Test remove expiration date for non-link shares
*/
public function testAddShareLinkDeletePermission() {
$oldPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE;
$newPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;

// share with old permissions
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK),
'uid_owner' => $qb->expr()->literal('user1'),
'item_type' => $qb->expr()->literal('folder'),
'item_source' => $qb->expr()->literal(123),
'item_target' => $qb->expr()->literal('/123'),
'file_source' => $qb->expr()->literal(123),
'file_target' => $qb->expr()->literal('/test'),
'permissions' => $qb->expr()->literal($oldPerms),
'stime' => $qb->expr()->literal(time()),
])
->execute();

$bogusShareId = $this->getLastShareId();

// share with read-only permissions
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK),
'uid_owner' => $qb->expr()->literal('user1'),
'item_type' => $qb->expr()->literal('folder'),
'item_source' => $qb->expr()->literal(123),
'item_target' => $qb->expr()->literal('/123'),
'file_source' => $qb->expr()->literal(123),
'file_target' => $qb->expr()->literal('/test'),
'permissions' => $qb->expr()->literal(\OCP\Constants::PERMISSION_READ),
'stime' => $qb->expr()->literal(time()),
])
->execute();

$keepThisShareId = $this->getLastShareId();

// user share to keep
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER),
'share_with' => $qb->expr()->literal('recipientuser1'),
'uid_owner' => $qb->expr()->literal('user1'),
'item_type' => $qb->expr()->literal('folder'),
'item_source' => $qb->expr()->literal(123),
'item_target' => $qb->expr()->literal('/123'),
'file_source' => $qb->expr()->literal(123),
'file_target' => $qb->expr()->literal('/test'),
'permissions' => $qb->expr()->literal(3),
'stime' => $qb->expr()->literal(time()),
])
->execute();

$keepThisShareId2 = $this->getLastShareId();

/** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */
$outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
->disableOriginalConstructor()
->getMock();

$this->repair->run($outputMock);

$results = $this->connection->getQueryBuilder()
->select('*')
->from('share')
->orderBy('permissions', 'ASC')
->execute()
->fetchAll();

$this->assertCount(3, $results);

$untouchedShare = $results[0];
$untouchedShare2 = $results[1];
$updatedShare = $results[2];
$this->assertEquals($keepThisShareId, $untouchedShare['id'], 'sanity check');
$this->assertEquals($keepThisShareId2, $untouchedShare2['id'], 'sanity check');
$this->assertEquals($bogusShareId, $updatedShare['id'], 'sanity check');
$this->assertEquals($newPerms, $updatedShare['permissions'], 'delete permission was added');
}

/**
* Test remove shares where the parent share does not exist anymore
*/

+ 0
- 18
tests/lib/Share20/ManagerTest.php View File

@@ -1327,24 +1327,6 @@ class ManagerTest extends \Test\TestCase {
$this->invokePrivate($this->manager, 'linkCreateChecks', [$share]);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Link shares can't have delete permissions
*/
public function testLinkCreateChecksDeletePermissions() {
$share = $this->manager->newShare();

$share->setPermissions(\OCP\Constants::PERMISSION_DELETE);

$this->config
->method('getAppValue')
->will($this->returnValueMap([
['core', 'shareapi_allow_links', 'yes', 'yes'],
]));

$this->invokePrivate($this->manager, 'linkCreateChecks', [$share]);
}

/**
* @expectedException Exception
* @expectedExceptionMessage Public upload not allowed

+ 30
- 0
tests/lib/User/SessionTest.php View File

@@ -314,6 +314,36 @@ class SessionTest extends \Test\TestCase {
$userSession->login('foo', 'bar');
}

/**
* When using a device token, the loginname must match the one that was used
* when generating the token on the browser.
*/
public function testLoginWithDifferentTokenLoginName() {
$session = $this->getMock('\OC\Session\Memory', array(), array(''));
$manager = $this->getMock('\OC\User\Manager');
$backend = $this->getMock('\Test\Util\User\Dummy');
$userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config);
$username = 'user123';
$token = new \OC\Authentication\Token\DefaultToken();
$token->setLoginName($username);

$session->expects($this->never())
->method('set');
$session->expects($this->once())
->method('regenerateId');
$this->tokenProvider->expects($this->once())
->method('getToken')
->with('bar')
->will($this->returnValue($token));

$manager->expects($this->once())
->method('checkPassword')
->with('foo', 'bar')
->will($this->returnValue(false));

$userSession->login('foo', 'bar');
}

/**
* @expectedException \OC\Authentication\Exceptions\PasswordLoginForbiddenException
*/

+ 1
- 1
version.php View File

@@ -25,7 +25,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version = array(9, 1, 0, 9);
$OC_Version = array(9, 1, 0, 10);

// The human readable string
$OC_VersionString = '9.1.0 beta 2';

Loading…
Cancel
Save