Merge remote-tracking branch 'upstream/master' into master-sync-upstream

This commit is contained in:
Lukas Reschke 2016-06-27 18:23:00 +02:00
commit 6670d37658
42 changed files with 387 additions and 252 deletions

View File

@ -12,6 +12,9 @@ OC.L10N.register(
"More comments..." : "Lisää kommentteja...", "More comments..." : "Lisää kommentteja...",
"Save" : "Tallenna", "Save" : "Tallenna",
"Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", "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", "{count} unread comments" : "{count} lukematonta kommenttia",
"Comment" : "Kommentti", "Comment" : "Kommentti",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>", "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>",

View File

@ -10,6 +10,9 @@
"More comments..." : "Lisää kommentteja...", "More comments..." : "Lisää kommentteja...",
"Save" : "Tallenna", "Save" : "Tallenna",
"Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", "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", "{count} unread comments" : "{count} lukematonta kommenttia",
"Comment" : "Kommentti", "Comment" : "Kommentti",
"<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>", "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Kommentit</strong> tiedostoille <em>(aina listattu luettelossa)</em>",

View File

@ -12,6 +12,9 @@ OC.L10N.register(
"More comments..." : "Więcej komentarzy...", "More comments..." : "Więcej komentarzy...",
"Save" : "Zapisz", "Save" : "Zapisz",
"Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}", "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", "{count} unread comments" : "{count} nieprzeczytanych komentarzy",
"Comment" : "Komentarz", "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>", "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Komentarze</strong> dla plików <em>(zawsze wypisane w strumieniu)</em>",

View File

@ -10,6 +10,9 @@
"More comments..." : "Więcej komentarzy...", "More comments..." : "Więcej komentarzy...",
"Save" : "Zapisz", "Save" : "Zapisz",
"Allowed characters {count} of {max}" : "Dozwolone znaki {count} z {max}", "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", "{count} unread comments" : "{count} nieprzeczytanych komentarzy",
"Comment" : "Komentarz", "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>", "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Komentarze</strong> dla plików <em>(zawsze wypisane w strumieniu)</em>",

View File

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

View File

@ -2351,22 +2351,36 @@
* @param filter * @param filter
*/ */
setFilter:function(filter) { setFilter:function(filter) {
var total = 0;
this._filter = filter; this._filter = filter;
this.fileSummary.setFilter(filter, this.files); this.fileSummary.setFilter(filter, this.files);
total = this.fileSummary.getTotal();
if (!this.$el.find('.mask').exists()) { if (!this.$el.find('.mask').exists()) {
this.hideIrrelevantUIWhenNoFilesMatch(); this.hideIrrelevantUIWhenNoFilesMatch();
} }
var that = this; var that = this;
var visibleCount = 0;
filter = filter.toLowerCase(); 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) { if ($e.data('file').toString().toLowerCase().indexOf(filter) === -1) {
$e.addClass('hidden'); $e.addClass('hidden');
} else { } else {
visibleCount++;
$e.removeClass('hidden'); $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() { hideIrrelevantUIWhenNoFilesMatch:function() {
if (this._filter && this.fileSummary.summary.totalDirs + this.fileSummary.summary.totalFiles === 0) { if (this._filter && this.fileSummary.summary.totalDirs + this.fileSummary.summary.totalFiles === 0) {

View File

@ -989,6 +989,17 @@ describe('OCA.Files.FileList tests', function() {
expect($summary.find('.info').text()).toEqual("1 folder and 3 files"); expect($summary.find('.info').text()).toEqual("1 folder and 3 files");
expect($nofilterresults.hasClass('hidden')).toEqual(true); 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() { it('hides the emptyfiles notice when using filter()', function() {
expect(fileList.files.length).toEqual(0); expect(fileList.files.length).toEqual(0);
expect(fileList.files).toEqual([]); expect(fileList.files).toEqual([]);

View File

@ -52,6 +52,10 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide
$backendService->registerBackendProvider($this); $backendService->registerBackendProvider($this);
$backendService->registerAuthMechanismProvider($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! // app developers: do NOT depend on this! it will disappear with oC 9.0!
\OC::$server->getEventDispatcher()->dispatch( \OC::$server->getEventDispatcher()->dispatch(
'OCA\\Files_External::loadAdditionalBackends' 'OCA\\Files_External::loadAdditionalBackends'

View File

@ -354,7 +354,8 @@ class Share20OCS {
$share->setPermissions( $share->setPermissions(
\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE \OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE
); );
} else { } else {
$share->setPermissions(\OCP\Constants::PERMISSION_READ); $share->setPermissions(\OCP\Constants::PERMISSION_READ);
@ -591,7 +592,7 @@ class Share20OCS {
$newPermissions = null; $newPermissions = null;
if ($publicUpload === 'true') { 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') { } else if ($publicUpload === 'false') {
$newPermissions = \OCP\Constants::PERMISSION_READ; $newPermissions = \OCP\Constants::PERMISSION_READ;
} }
@ -602,13 +603,21 @@ class Share20OCS {
if ($newPermissions !== null && if ($newPermissions !== null &&
$newPermissions !== \OCP\Constants::PERMISSION_READ && $newPermissions !== \OCP\Constants::PERMISSION_READ &&
$newPermissions !== (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) && // legacy
$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) &&
// correct
$newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED); $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links')); 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()) { if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED); $share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator')); 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); $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')); 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) { if ($newPermissions !== null) {

View File

@ -1035,7 +1035,7 @@ class Share20OCSTest extends \Test\TestCase {
$this->callback(function (\OCP\Share\IShare $share) use ($path) { $this->callback(function (\OCP\Share\IShare $share) use ($path) {
return $share->getNode() === $path && return $share->getNode() === $path &&
$share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && $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->getSharedBy() === 'currentUser' &&
$share->getPassword() === null && $share->getPassword() === null &&
$share->getExpirationDate() === null; $share->getExpirationDate() === null;
@ -1366,7 +1366,7 @@ class Share20OCSTest extends \Test\TestCase {
$date = new \DateTime('2000-01-01'); $date = new \DateTime('2000-01-01');
$date->setTime(0,0,0); $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->getPassword() === 'password' &&
$share->getExpirationDate() == $date; $share->getExpirationDate() == $date;
}) })
@ -1379,6 +1379,44 @@ class Share20OCSTest extends \Test\TestCase {
$this->assertEquals($expected->getData(), $result->getData()); $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() { public function testUpdateLinkShareInvalidDate() {
$ocs = $this->mockFormatShare(); $ocs = $this->mockFormatShare();
@ -1408,7 +1446,30 @@ class Share20OCSTest extends \Test\TestCase {
$this->assertEquals($expected->getData(), $result->getData()); $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(); $ocs = $this->mockFormatShare();
$folder = $this->getMock('\OCP\Files\Folder'); $folder = $this->getMock('\OCP\Files\Folder');
@ -1421,11 +1482,7 @@ class Share20OCSTest extends \Test\TestCase {
$this->request $this->request
->method('getParam') ->method('getParam')
->will($this->returnValueMap([ ->will($this->returnValueMap($params));
['publicUpload', null, 'true'],
['expireDate', '', null],
['password', '', 'password'],
]));
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
@ -1585,7 +1642,7 @@ class Share20OCSTest extends \Test\TestCase {
$this->shareManager->expects($this->once())->method('updateShare')->with( $this->shareManager->expects($this->once())->method('updateShare')->with(
$this->callback(function (\OCP\Share\IShare $share) use ($date) { $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->getPassword() === 'password' &&
$share->getExpirationDate() === $date; $share->getExpirationDate() === $date;
}) })
@ -1625,7 +1682,7 @@ class Share20OCSTest extends \Test\TestCase {
$this->shareManager->expects($this->once())->method('updateShare')->with( $this->shareManager->expects($this->once())->method('updateShare')->with(
$this->callback(function (\OCP\Share\IShare $share) use ($date) { $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->getPassword() === 'password' &&
$share->getExpirationDate() === $date; $share->getExpirationDate() === $date;
}) })

View File

@ -257,7 +257,13 @@ class ApiTest extends TestCase {
$this->assertTrue($result->succeeded()); $this->assertTrue($result->succeeded());
$data = $result->getData(); $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->assertEmpty($data['expiration']);
$this->assertTrue(is_string($data['token'])); $this->assertTrue(is_string($data['token']));
@ -1081,7 +1087,13 @@ class ApiTest extends TestCase {
$this->assertTrue($result->succeeded()); $this->assertTrue($result->succeeded());
$share1 = $this->shareManager->getShareById($share1->getFullId()); $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 // cleanup
$this->shareManager->deleteShare($share1); $this->shareManager->deleteShare($share1);

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 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 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", "%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)", "%s (invisible)" : "%s (niewidoczny)",
"No files in here" : "Brak plików", "No files in here" : "Brak plików",
"No entries found in this folder" : "Brak wpisów w tym folderze", "No entries found in this folder" : "Brak wpisów w tym folderze",

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 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 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", "%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)", "%s (invisible)" : "%s (niewidoczny)",
"No files in here" : "Brak plików", "No files in here" : "Brak plików",
"No entries found in this folder" : "Brak wpisów w tym folderze", "No entries found in this folder" : "Brak wpisów w tym folderze",

View File

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

View File

@ -150,6 +150,9 @@ class DecryptAll extends Command {
$output->writeln(' aborted.'); $output->writeln(' aborted.');
$output->writeln('Server side encryption remains enabled'); $output->writeln('Server side encryption remains enabled');
$this->config->setAppValue('core', 'encryption_enabled', 'yes'); $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(); $this->resetSingleUserAndTrashbin();
} else { } else {

View File

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

View File

@ -10,125 +10,9 @@ select {
height: 32px; 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. */ /* deactivate show password toggle for IE. Does not work for 8 and 9+ have their own implementation. */
.ie #show, .ie #show+label { .ie #show, .ie #show+label {
display: none; display: none;
visibility: hidden; 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;
}

View File

@ -111,10 +111,3 @@ ul.multiselectoptions > li.creator > input {
padding: 5px; padding: 5px;
margin: -5px; margin: -5px;
} }
.ie8 div.multiselect span:first-child {
display:block;
position:relative;
width: 90%;
margin-right:-1px;
}

View File

@ -189,7 +189,6 @@ a.two-factor-cancel {
.emptycontent { .emptycontent {
color: #888; color: #888;
text-align: center; text-align: center;
margin-top: 100px; /* ie8 */
margin-top: 30vh; margin-top: 30vh;
width: 100%; width: 100%;
} }
@ -418,14 +417,7 @@ label.infield {
-ms-user-select: none; -ms-user-select: none;
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 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;} #body-login .success { background:#d7fed7; border:1px solid #0f0; width: 35%; margin: 30px auto; padding:1em; text-align: center;}

View File

@ -788,7 +788,6 @@ var OC={
$(document).trigger(new $.Event('ajaxError'), xhr); $(document).trigger(new $.Event('ajaxError'), xhr);
}; };
// FIXME: also needs an IE8 way
if (xhr.addEventListener) { if (xhr.addEventListener) {
xhr.addEventListener('load', loadCallback); xhr.addEventListener('load', loadCallback);
xhr.addEventListener('error', errorCallback); xhr.addEventListener('error', errorCallback);
@ -1857,30 +1856,10 @@ OC.Util = {
* This scales the image to the element's actual size, the URL is * This scales the image to the element's actual size, the URL is
* taken from the "background-image" CSS attribute. * taken from the "background-image" CSS attribute.
* *
* @deprecated IE8 isn't supported since 9.0
* @param {Object} $el image element * @param {Object} $el image element
*/ */
scaleFixForIE8: function($el) { 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;
},
/** /**
* Returns whether this is IE * Returns whether this is IE
@ -1894,10 +1873,11 @@ OC.Util = {
/** /**
* Returns whether this is IE8 * 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() { isIE8: function() {
return $('html').hasClass('ie8'); return false;
}, },
/** /**

View File

@ -215,7 +215,7 @@
var permissions = OC.PERMISSION_READ; var permissions = OC.PERMISSION_READ;
if($checkbox.is(':checked')) { 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({ this.model.saveLinkShare({

View File

@ -166,9 +166,13 @@ OC.L10N.register(
"delete" : "usuń", "delete" : "usuń",
"access control" : "kontrola dostępu", "access control" : "kontrola dostępu",
"Could not unshare" : "Nie udało się usunąć udostępnienia", "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 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}", "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.", "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" : "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 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...", "Share with users…" : "Współdziel z użytkownikami...",
@ -181,6 +185,7 @@ OC.L10N.register(
"Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje", "Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje",
"restricted" : "ograniczone", "restricted" : "ograniczone",
"invisible" : "niewidoczny", "invisible" : "niewidoczny",
"({scope})" : "({scope})",
"Delete" : "Usuń", "Delete" : "Usuń",
"Rename" : "Zmień nazwę", "Rename" : "Zmień nazwę",
"The object type is not specified." : "Nie określono typu obiektu.", "The object type is not specified." : "Nie określono typu obiektu.",
@ -237,6 +242,7 @@ OC.L10N.register(
"Data folder" : "Katalog danych", "Data folder" : "Katalog danych",
"Configure the database" : "Skonfiguruj bazę danych", "Configure the database" : "Skonfiguruj bazę danych",
"Only %s is available." : "Dostępne jest wyłącznie %s.", "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ą.", "For more details check out the documentation." : "Aby uzyskać więcej informacji zapoznaj się z dokumentacją.",
"Database user" : "Użytkownik bazy danych", "Database user" : "Użytkownik bazy danych",
"Database password" : "Hasło do 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:", "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", "Detailed logs" : "Szczegółowe logi",
"Update needed" : "Wymagana aktualizacja", "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>.", "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." "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."
}, },

View File

@ -164,9 +164,13 @@
"delete" : "usuń", "delete" : "usuń",
"access control" : "kontrola dostępu", "access control" : "kontrola dostępu",
"Could not unshare" : "Nie udało się usunąć udostępnienia", "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 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}", "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.", "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" : "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 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...", "Share with users…" : "Współdziel z użytkownikami...",
@ -179,6 +183,7 @@
"Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje", "Non-existing tag #{tag}" : "Znacznik #{tag} nie istnieje",
"restricted" : "ograniczone", "restricted" : "ograniczone",
"invisible" : "niewidoczny", "invisible" : "niewidoczny",
"({scope})" : "({scope})",
"Delete" : "Usuń", "Delete" : "Usuń",
"Rename" : "Zmień nazwę", "Rename" : "Zmień nazwę",
"The object type is not specified." : "Nie określono typu obiektu.", "The object type is not specified." : "Nie określono typu obiektu.",
@ -235,6 +240,7 @@
"Data folder" : "Katalog danych", "Data folder" : "Katalog danych",
"Configure the database" : "Skonfiguruj bazę danych", "Configure the database" : "Skonfiguruj bazę danych",
"Only %s is available." : "Dostępne jest wyłącznie %s.", "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ą.", "For more details check out the documentation." : "Aby uzyskać więcej informacji zapoznaj się z dokumentacją.",
"Database user" : "Użytkownik bazy danych", "Database user" : "Użytkownik bazy danych",
"Database password" : "Hasło do 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:", "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", "Detailed logs" : "Szczegółowe logi",
"Update needed" : "Wymagana aktualizacja", "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>.", "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." "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);" },"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"

View File

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

View File

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

View File

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

View File

@ -108,7 +108,11 @@ class Checker {
* applicable for very specific scenarios and we should not advertise it * applicable for very specific scenarios and we should not advertise it
* too prominent. So please do not add it to config.sample.php. * too prominent. So please do not add it to config.sample.php.
*/ */
if ($this->config !== null) {
$isIntegrityCheckDisabled = $this->config->getSystemValue('integrity.check.disabled', false); $isIntegrityCheckDisabled = $this->config->getSystemValue('integrity.check.disabled', false);
} else {
$isIntegrityCheckDisabled = false;
}
if($isIntegrityCheckDisabled === true) { if($isIntegrityCheckDisabled === true) {
return false; return false;
} }
@ -401,8 +405,11 @@ class Checker {
return json_decode($cachedResults, true); return json_decode($cachedResults, true);
} }
if ($this->config !== null) {
return json_decode($this->config->getAppValue('core', self::CACHE_KEY, '{}'), true); return json_decode($this->config->getAppValue('core', self::CACHE_KEY, '{}'), true);
} }
return [];
}
/** /**
* Stores the results in the app config as well as cache * Stores the results in the app config as well as cache
@ -416,7 +423,9 @@ class Checker {
if(!empty($result)) { if(!empty($result)) {
$resultArray[$scope] = $result; $resultArray[$scope] = $result;
} }
if ($this->config !== null) {
$this->config->setAppValue('core', self::CACHE_KEY, json_encode($resultArray)); $this->config->setAppValue('core', self::CACHE_KEY, json_encode($resultArray));
}
$this->cache->set(self::CACHE_KEY, json_encode($resultArray)); $this->cache->set(self::CACHE_KEY, json_encode($resultArray));
} }

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 * 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 situation was only possible before 8.2
$this->removeExpirationDateFromNonLinkShares($out); $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); $this->removeSharesNonExistingParent($out);
} }

View File

@ -452,14 +452,9 @@ class Manager implements IManager {
throw new \InvalidArgumentException('Link shares can\'t have reshare permissions'); 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 // Check if public upload is allowed
if (!$this->shareApiLinkAllowPublicUpload() && 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'); throw new \InvalidArgumentException('Public upload not allowed');
} }
} }

View File

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

View File

@ -118,6 +118,7 @@ class AuthSettingsController extends Controller {
return [ return [
'token' => $token, 'token' => $token,
'loginName' => $loginName,
'deviceToken' => $deviceToken 'deviceToken' => $deviceToken
]; ];
} }

View File

@ -131,11 +131,19 @@ table.nostyle td { padding: 0.2em 0; }
opacity: 0.6; opacity: 0.6;
} }
#new-app-login-name,
#new-app-password { #new-app-password {
width: 186px; width: 186px;
font-family: monospace; font-family: monospace;
background-color: lightyellow; background-color: lightyellow;
} }
.app-password-row {
display: table-row;
}
.app-password-label {
display: table-cell;
padding-right: 1em;
}
/* USERS */ /* USERS */
#newgroup-init a span { margin-left: 20px; } #newgroup-init a span { margin-left: 20px; }
@ -161,10 +169,6 @@ table.nostyle td { padding: 0.2em 0; }
width: 32px; width: 32px;
} }
.ie8 #newgroup-form .icon-add {
height: 30px;
}
.isgroup .groupname { .isgroup .groupname {
width: 85%; width: 85%;
display: block; display: block;
@ -281,10 +285,6 @@ input.userFilter {width: 200px;}
width: 32px; 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 */ /* used to highlight a user row in red */
#userlist tr.row-warning { #userlist tr.row-warning {
background-color: #FDD; background-color: #FDD;

View File

@ -20,14 +20,14 @@
* *
*/ */
(function(OC, Backbone) { (function(OC) {
'use strict'; 'use strict';
OC.Settings = OC.Settings || {}; OC.Settings = OC.Settings || {};
var AuthToken = Backbone.Model.extend({ var AuthToken = OC.Backbone.Model.extend({
}); });
OC.Settings.AuthToken = AuthToken; OC.Settings.AuthToken = AuthToken;
})(OC, Backbone); })(OC);

View File

@ -20,12 +20,12 @@
* *
*/ */
(function(OC, Backbone) { (function(OC) {
'use strict'; 'use strict';
OC.Settings = OC.Settings || {}; OC.Settings = OC.Settings || {};
var AuthTokenCollection = Backbone.Collection.extend({ var AuthTokenCollection = OC.Backbone.Collection.extend({
model: OC.Settings.AuthToken, model: OC.Settings.AuthToken,
@ -49,4 +49,4 @@
OC.Settings.AuthTokenCollection = AuthTokenCollection; OC.Settings.AuthTokenCollection = AuthTokenCollection;
})(OC, Backbone); })(OC);

View File

@ -1,4 +1,4 @@
/* global Backbone, Handlebars, moment */ /* global Handlebars, moment */
/** /**
* @author Christoph Wurst <christoph@owncloud.com> * @author Christoph Wurst <christoph@owncloud.com>
@ -20,7 +20,7 @@
* *
*/ */
(function(OC, _, Backbone, $, Handlebars, moment) { (function(OC, _, $, Handlebars, moment) {
'use strict'; 'use strict';
OC.Settings = OC.Settings || {}; OC.Settings = OC.Settings || {};
@ -32,7 +32,7 @@
+ '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>' + '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>'
+ '<tr>'; + '<tr>';
var SubView = Backbone.View.extend({ var SubView = OC.Backbone.View.extend({
collection: null, collection: null,
/** /**
@ -94,7 +94,7 @@
} }
}); });
var AuthTokenView = Backbone.View.extend({ var AuthTokenView = OC.Backbone.View.extend({
collection: null, collection: null,
_views: [], _views: [],
@ -107,6 +107,8 @@
_result: undefined, _result: undefined,
_newAppLoginName: undefined,
_newAppPassword: undefined, _newAppPassword: undefined,
_hideAppPasswordBtn: undefined, _hideAppPasswordBtn: undefined,
@ -136,6 +138,8 @@
this._addAppPasswordBtn.click(_.bind(this._addAppPassword, this)); this._addAppPasswordBtn.click(_.bind(this._addAppPassword, this));
this._result = $('#app-password-result'); 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 = $('#new-app-password');
this._newAppPassword.on('focus', _.bind(this._onNewTokenFocus, this)); this._newAppPassword.on('focus', _.bind(this._onNewTokenFocus, this));
this._hideAppPasswordBtn = $('#app-password-hide'); this._hideAppPasswordBtn = $('#app-password-hide');
@ -181,6 +185,7 @@
$.when(creatingToken).done(function(resp) { $.when(creatingToken).done(function(resp) {
_this.collection.add(resp.deviceToken); _this.collection.add(resp.deviceToken);
_this.render(); _this.render();
_this._newAppLoginName.val(resp.loginName);
_this._newAppPassword.val(resp.token); _this._newAppPassword.val(resp.token);
_this._toggleFormResult(false); _this._toggleFormResult(false);
_this._newAppPassword.select(); _this._newAppPassword.select();
@ -194,6 +199,10 @@
}); });
}, },
_onNewTokenLoginNameFocus: function() {
this._newAppLoginName.select();
},
_onNewTokenFocus: function() { _onNewTokenFocus: function() {
this._newAppPassword.select(); this._newAppPassword.select();
}, },
@ -220,6 +229,8 @@
var destroyingToken = token.destroy(); var destroyingToken = token.destroy();
$row.find('.icon-delete').tooltip('hide');
var _this = this; var _this = this;
$.when(destroyingToken).fail(function() { $.when(destroyingToken).fail(function() {
OC.Notification.showTemporary(t('core', 'Error while deleting the token')); OC.Notification.showTemporary(t('core', 'Error while deleting the token'));
@ -237,4 +248,4 @@
OC.Settings.AuthTokenView = AuthTokenView; OC.Settings.AuthTokenView = AuthTokenView;
})(OC, _, Backbone, $, Handlebars, moment); })(OC, _, $, Handlebars, moment);

View File

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

View File

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

View File

@ -201,9 +201,17 @@ if($_['passwordChangeSupported']) {
<button id="add-app-password" class="button"><?php p($l->t('Create new app password')); ?></button> <button id="add-app-password" class="button"><?php p($l->t('Create new app password')); ?></button>
</div> </div>
<div id="app-password-result" class="hidden"> <div id="app-password-result" class="hidden">
<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"/> <input id="new-app-password" type="text" readonly="readonly"/>
<button id="app-password-hide" class="button"><?php p($l->t('Done')); ?></button> <button id="app-password-hide" class="button"><?php p($l->t('Done')); ?></button>
</div> </div>
</div>
</div> </div>
<div id="clientsbox" class="section clientsbox"> <div id="clientsbox" class="section clientsbox">

View File

@ -123,6 +123,93 @@ class RepairInvalidSharesTest extends TestCase {
$this->assertNotNull($linkShare['expiration'], 'valid link share expiration date still there'); $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 * Test remove shares where the parent share does not exist anymore
*/ */

View File

@ -1327,24 +1327,6 @@ class ManagerTest extends \Test\TestCase {
$this->invokePrivate($this->manager, 'linkCreateChecks', [$share]); $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 * @expectedException Exception
* @expectedExceptionMessage Public upload not allowed * @expectedExceptionMessage Public upload not allowed

View File

@ -314,6 +314,36 @@ class SessionTest extends \Test\TestCase {
$userSession->login('foo', 'bar'); $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 * @expectedException \OC\Authentication\Exceptions\PasswordLoginForbiddenException
*/ */

View File

@ -25,7 +25,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades // 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 // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number. // when updating major/minor version number.
$OC_Version = array(9, 1, 0, 9); $OC_Version = array(9, 1, 0, 10);
// The human readable string // The human readable string
$OC_VersionString = '9.1.0 beta 2'; $OC_VersionString = '9.1.0 beta 2';