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

[Master] sync upstream
This commit is contained in:
Morris Jobke 2016-06-28 09:02:03 +02:00 committed by GitHub
commit b6397ef73a
42 changed files with 387 additions and 252 deletions

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>",

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>",

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>",

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>",

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);
}
/**

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) {

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([]);

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'

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) {

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;
})

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);

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",

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",

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 |

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 {

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;

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;
}

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;
}

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;}

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;
},
/**

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({

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."
},

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);"

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>

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>

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>

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));
}

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);
}

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');
}
}

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;
}

View File

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

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;

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);

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);

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);

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",

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",

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>

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
*/

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

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
*/

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';