Compare commits

...

570 Commits

Author SHA1 Message Date
Daniel Molkentin e5eb221a91 ownCloud Server 8.1.10 RC1 2016-08-18 13:10:45 +02:00
Vincent Petry 24224020b1 Merge pull request #25393 from owncloud/stable8.1-fdb0d4ad528425b934d9b039c9f09c132b86d0f4
[stable8.1] check if renamed user is still valid by reapplying the ld…
2016-08-18 11:31:47 +02:00
Juan Pablo Villafáñez 81d0273cb4 Fix another missing check 2016-08-18 11:30:13 +02:00
Juan Pablo Villafáñez 101902abbf Add missing filter during cleanup 2016-08-18 11:30:13 +02:00
felixboehm afe9f024f2 [stable8.1] check if renamed user is still valid by reapplying the ldap filter (#25338) 2016-08-18 11:30:13 +02:00
Thomas Müller 57fd461849 [stable8.1] Test jenkins pipeline (#25401) (#25504)
* [stable8.1] Test jenkins pipeline (#25401)

* Use phantomjs-prebuilt as warning is telling us

* Php7.0 is not supported and there are no primary storage tests on stable8.2

* [Stable8.2] fix unit test on new jenkins setup and adjust Jenkinsfile (#25772) (#25775) (#25783)

* Next step jenkinsfile (#25622)

* Adding timestamper and evaluation of test results even in case of failure

* Adding build timeout

* use fixed value 120 minutes as timeout for each test executing for now

* Terminate the build as soon as test execution fails

* Adjust external testing as well

* Finalize use of executeAndReport

* Array sort order is of no relevance
2016-08-14 12:48:29 +02:00
Daniel Molkentin 646a3bb981 ownCloud Server 8.1.9 2016-07-18 19:20:19 +02:00
Vincent Petry 4ba61ff30c Backport of guzzle fix from 5.3.1 2016-07-18 19:17:02 +02:00
Thomas Müller b569d0c250 Fix oracle unit test on 8.1 (#25471) 2016-07-13 20:23:00 +02:00
Daniel Molkentin 0c2bba5b17 ownCloud Server 8.1.9 RC2 2016-07-13 17:30:25 +02:00
Vincent Petry fb92bb1d2f Merge pull request #25329 from owncloud/stable8.1-fix-versionrevertperms
[stable8.1] Prevent revert when no permission to revert
2016-07-13 14:31:53 +02:00
Vincent Petry 2338308073 Hide revert button when no permission to revert 2016-07-13 10:40:38 +02:00
Vincent Petry ac759d6918 Additional perm check in Webdav (#25452) 2016-07-12 12:38:56 +02:00
Thomas Müller bf9524e330 [stable8.1] Set content type when downloading log file to force download in some browsers (#25382) (#25400) 2016-07-08 09:16:11 +02:00
Thomas Müller 7b92dd2cca [stable8.1] Preview tests require imagick 2 (#24588)
* SVG preview unit test requires Imagick

* Fix preview tests
2016-07-04 10:11:22 +02:00
Daniel Molkentin 280f7c9c73 ownCloud 8.1.9 RC1 2016-06-29 16:38:58 +02:00
Vincent Petry bba6470b88 Merge pull request #25230 from owncloud/stable8.1-enc-revertversionsize
[stable8.1] Rollback version must also adjust cached size
2016-06-23 10:42:45 +02:00
Vincent Petry d3537ae33f Rollback version must also adjust cached size 2016-06-22 15:40:36 +02:00
Vincent Petry ec387a604d Merge pull request #25140 from owncloud/stable81-backport-25126
[stable8.1] load authentication apps first
2016-06-16 13:15:13 +02:00
Vincent Petry 982917345e Merge pull request #25116 from owncloud/cross-storage-move-updater-81
[8.1] fix updating folder sizes with cross storage move
2016-06-16 12:31:43 +02:00
Christoph Wurst b2405a0989 load authentication apps first 2016-06-16 11:32:13 +02:00
Robin Appelman 94557129ee fix updating folder sizes with cross storage move 2016-06-15 14:11:41 +02:00
Robin Appelman b62747238f Revert "fix updating folder sizes with cross storage move"
This reverts commit 42d7a32774.
2016-06-15 12:03:31 +02:00
Robin Appelman 42d7a32774 fix updating folder sizes with cross storage move 2016-06-15 12:01:57 +02:00
Joas Schilling 9bc43d5e7e Add a warning when the transaction isolation level is not READ_COMMITED (#24917) 2016-06-01 06:59:31 +02:00
Fabian c18475009a dont update search onResize (#24849) 2016-05-30 11:32:57 +02:00
Vincent Petry f9b171e2fc Merge pull request #24412 from owncloud/stable8.1_24405
[Stable8.1] Use a CappedCache in the user database backend
2016-05-25 09:14:11 +02:00
Robin Appelman cc4f6d6ae6 Allow indirect set in CappedMemoryCache 2016-05-24 14:50:42 +02:00
Vincent Petry 418490735c Merge pull request #23403 from owncloud/backport-23282-stable8.1
[stable8.1] fix writing to cache when fallback server should be used immediately
2016-05-24 11:49:21 +02:00
Vincent Petry 97c9f57f2b Merge pull request #24693 from owncloud/stable8.1-fixchunkttl
[stable8.1] Allow chunk GC mtime tolerance for unfinished part chunks
2016-05-18 18:20:12 +02:00
Vincent Petry d46355a415 Allow chunk GC mtime tolerance for unfinished part chunks
Whenever part chunks are written, every fwrite in the write loop will
reset the mtime to the current mtime. Only at the end will the touch()
operation set the mtime to now + ttl, in the future.

However the GC code is expecting that every chunk with mtime < now are
old and must be deleted. This causes the GC to sometimes delete part
chunks in which the write loop is slow.

To fix this, a tolerance value is added in the GC code to allow for
more time before a part chunk gets deleted.
2016-05-18 13:58:20 +02:00
Vincent Petry 76b4b367f6 Merge pull request #24506 from owncloud/stable8.1-updater-server-configurable
[stable8.1.] Make update server URL configurable
2016-05-17 10:09:35 +02:00
Lukas Reschke 9a80ea4eed Make update server URL configurable
Currently testing the updates is a big problem and not really super easy possible. Since we now have a new updater server we should also make this configurable so that people can properly test updates.
2016-05-13 16:15:07 +02:00
C Montero-Luque 63769d54c3 8.1.8 2016-05-12 15:59:34 -04:00
Thomas Müller f8ffeea74a Bitmap preview unit test requires Imagick (#24577) 2016-05-12 09:15:20 +02:00
Thomas Müller 78715a4562 Merge pull request #24572 from owncloud/stable8.1_24568
[Stable 8.1] Fix etag propegation test race condition
2016-05-11 16:29:25 +02:00
Roeland Jago Douma 2be7290002 Fix test race condition
E-tag propagation replies on the mtime of the file. Order of events:

1. add file 'foo.txt' with content 'bar'
2. Set mtime to now() - 1
3. Check if etag changed.

Now this goes right often when 1 and 2 happen in the same second.
However imagine

1. add file 'foo.txt' with content 'bar' (at t=0.999)
2. Set mtime to now() - 1 (at t=1.001)

Now the mtime will be set to the same time. Thus not chaning the etag.
2016-05-11 14:57:06 +02:00
Thomas Müller c7c7d50488 Merge pull request #24556 from owncloud/kill-en@pirate-stable8.1
[stable8.1] Yo-ho-oh - Murder all band 'o pirates
2016-05-11 14:29:34 +02:00
Thomas Müller fc90829e5c Yo-ho-oh - Murder all band 'o pirates 2016-05-11 11:31:37 +02:00
C Montero-Luque 1686d809fa 8.1.8 RC2 2016-05-10 15:50:18 -04:00
C Montero-Luque cd47930d39 8.1.1 RC1 2016-05-09 18:44:05 -04:00
Roeland Jago Douma d1f8e17294 Use a CappedCache in the user database backend
When running with a user database backend on large installations the
cache can grow to significant sizes. This can be especially problematic
when running big cron/repair jobs.
2016-05-03 13:10:03 +02:00
C Montero-Luque 6080a3869e 8.1.7 2016-05-03 04:39:55 -04:00
C Montero-Luque 7a1b8f3961 8.1.7 RC2 2016-05-02 04:17:25 -04:00
C Montero-Luque 1075d0724c 8.1.7 RC1 2016-04-26 21:25:55 -04:00
Arthur Schiwon 6ecaba74a5 fix writing to cache when fallback server should be used immediately 2016-04-26 22:38:31 +02:00
Vincent Petry 99d6a4a7cc Merge pull request #24284 from owncloud/backport-24262-stable8.1
[stable8.1] check whether index is set before using it
2016-04-26 20:50:06 +02:00
Arthur Schiwon e0f687397b check whether index is set before using it 2016-04-26 14:52:34 +02:00
Thomas Müller e3cbcdf044 Merge pull request #24170 from owncloud/stable8.1-certificate
[stable8.1] Ignore certificate file if it starts with file://
2016-04-22 09:35:57 +02:00
Lukas Reschke 80db6c60a3 [stable8.1] Ignore certificate file if it starts with file:// 2016-04-21 18:55:33 +02:00
Thomas Müller 8c8ab45a1a Merge pull request #24146 from owncloud/stable8.1-quota-recognizeremoteunlimitedquota
[stable8.1] Workaround to be able to recognize unlimited quota in fed shares
2016-04-21 12:52:08 +02:00
Vincent Petry 785c49533c Workaround to be able to recognize unlimited quota in fed shares
Fixes issues where a user cannot upload to a fed share on OC >= 9.0
where the sharer has unlimited quota (-3)
2016-04-21 11:09:07 +02:00
Björn Schießle 6cfe339765 Merge pull request #24101 from owncloud/fix_23632_8.1
[stable8.1] init users mount point before recovery
2016-04-20 17:05:35 +02:00
Björn Schießle 813392f0e7 we need to initialize the mount points of the given user before we recover
access to his files
2016-04-19 17:20:21 +02:00
Morris Jobke c01ad6d895 Merge pull request #24042 from owncloud/stable8.1-autoload
[stable8.1] Exclude autoload_static.php
2016-04-18 08:48:40 +02:00
Lukas Reschke 023ca1b747 Exclude autoload_static.php 2016-04-17 11:14:35 +02:00
Vincent Petry 36a2d1a1f8 Merge pull request #23236 from owncloud/stable8.1-fix_21678
[stable8.1] Gracefull handle link shares rename hook
2016-03-18 11:33:32 +01:00
Thomas Müller 5df937f2b5 Merge pull request #23353 from owncloud/stable8.1_backport_23346
[Stable 8.1] Set proper public webdav permissions when public upload disabled
2016-03-17 20:51:06 +01:00
Roeland Jago Douma 52eb26dc9e Set proper public webdav permissions when public upload disabled
Fixes #23325

It can happen that a user shares a folder with public upload. And some
time later the admin disables public upload on the server.

To make sure this is handled correctly we need to check the config value
and reduce the permissions.

Fix is kept small to be easy backportable.
2016-03-17 13:56:51 +01:00
Morris Jobke 954a0a2dd5 Merge pull request #23311 from owncloud/check-syntax-travis-stable8.1
[stable8.1] Execute parallel-lint
2016-03-17 10:12:33 +01:00
Lukas Reschke f465320046 [stable8.1] Execute parallel-lint
Backport of https://github.com/owncloud/core/pull/22994 and https://github.com/owncloud/core/pull/23303
2016-03-17 09:09:32 +01:00
Morris Jobke c6eee6155f Merge pull request #23301 from owncloud/fix-video-viewer
[stable8.1] Backport OC.joinPaths to fix the Video Viewer
2016-03-16 15:32:33 +01:00
Vincent Petry c038e9888c More tests for joinPaths 2016-03-16 13:18:02 +01:00
Vincent Petry 58788698bc Add OC.joinPaths for convenient path joining 2016-03-16 13:17:59 +01:00
Morris Jobke 1d6099e75b Merge pull request #23267 from owncloud/fix_22907_8.1
allow group shares, even if not all public keys are available
2016-03-16 11:18:59 +01:00
Bjoern Schiessle 72d798bbfc allow group shares, even if not all public keys are available 2016-03-15 15:17:06 +01:00
Roeland Jago Douma bf851e6b27 Gracefull handle link shares rename hook
Fixes #21678

The hook is called on all renames. However when we use a link share
the getUserFolder fails. We now just opt out.
2016-03-14 17:32:37 +01:00
Thomas Müller 0cdfb2372d Merge pull request #22946 from owncloud/backport-22800-stable8.1
[8.1] don't hide server not available exception, fixes #20536
2016-03-14 16:15:10 +01:00
Vincent Petry 9978ee328c Merge pull request #23149 from owncloud/stable8.1-fix-broken-interface
[stable8.1] Fix broken scanner call in ajax/scan.php
2016-03-14 15:51:08 +01:00
Morris Jobke 62b95c33ba Fix broken scanner call in ajax/scan.php 2016-03-11 12:43:06 +01:00
Morris Jobke d363a597df Merge pull request #22843 from owncloud/stable81_22830
[Stable 8.1] Rename and move permissions are set when a file is updatable
2016-03-09 08:44:28 +01:00
C Montero-Luque e5620fe4ed 8.1.6 2016-03-08 09:03:58 -05:00
Arthur Schiwon 88232ba293 don't hide server not available exception, fixes #20536 2016-03-08 13:01:48 +01:00
C Montero-Luque a74a7d069e 8.1.6 RC2 2016-03-04 18:16:06 -05:00
C. Montero Luque 384af4731c Merge pull request #22863 from owncloud/stable8.1-trashbin-checkpath
[stable8.1] Properly check path validity before deleting to trash
2016-03-04 13:36:07 -05:00
Vincent Petry 833729808c Properly check path validity before deleting to trash
This prevents deleting the whole "files" folder of the user whenever
$ownerPath is empty. This can happen in concurrency situations.
2016-03-04 15:39:41 +01:00
Roeland Jago Douma c10c0c8504 Rename and move permissions are set when a file is updatable
* Fix unit tests
2016-03-04 09:40:14 +01:00
C Montero-Luque 279f1d0010 8.1.6 RC1 2016-03-01 20:41:49 -05:00
Thomas Müller ee1330f121 Merge pull request #22409 from owncloud/stable8.1-gdrive-reindexarraytoduetoduplicates
[stable8.1] Reindex array in GDrive after removing duplicates
2016-03-01 14:47:35 +01:00
Morris Jobke e8e694d31e Merge pull request #22617 from owncloud/backport-22358-stable8.1
[backport][stable8.1] Fix race condition when switching filter mode
2016-03-01 13:43:22 +01:00
Roeland Douma 256c2cd705 Merge pull request #22630 from owncloud/stable8.1-fedshare-testremote-after-404
[stable8.1] Properly trigger testRemote after getting a 404 from remote fed share
2016-02-29 11:26:42 +01:00
Vincent Petry 0df34d96e0 Merge pull request #22634 from owncloud/stable8.1-backport-22565
[stable8.1] Avoids scanning the root storage
2016-02-25 16:49:23 +01:00
Morris Jobke aebafadd99 Merge pull request #22632 from owncloud/stable8.1-backport-18762
[stable8.1] Use "json_encode" and "json_decode" instead of unserialize
2016-02-25 15:30:45 +01:00
Björn Schießle 1aa653177c Merge pull request #22627 from owncloud/fix_broken_unencrypted_size_8.1
[stable8.1] Heal unencrypted file sizes at download time
2016-02-25 14:59:24 +01:00
Bjoern Schiessle a369a7d478 recalculate unencrypted size if we assume that the size stored in the db is not correct 2016-02-25 11:17:09 +01:00
Morris Jobke 963c3aa93e Avoids scanning the root storage
This check will skip the background scan for the root storage
because there is nothing in the root storage that isn't already
in another (mostly user-) storage.

Fixes #22501
2016-02-24 17:35:50 +01:00
Morris Jobke a2338752c8 [user_ldap] properly decode cached objects
* fixes #21896
2016-02-24 16:35:35 +01:00
Vincent Petry 2bc01e7b42 Properly trigger testRemote after getting a 404 from remote fed share
Whenever a remote fed share's shareinfo call returns a 404, don't
directly assume the storage is not available by throwing
StorageNotAvailableException. We need to properly throw
NotFoundException to trigger the later logic that calls testRemote()
that verifies that the 404 is not from a broken server but really from
an obsolete share.
2016-02-24 16:35:22 +01:00
Lukas Reschke 241f784ad0 Use "json_encode" and "json_decode" instead of unserialize 2016-02-24 16:32:56 +01:00
Arthur Schiwon d63d4ab145 Fix race condition when switching filter mode. Fixes #22278 2016-02-24 11:21:53 +01:00
Morris Jobke e0a38cd473 Merge pull request #22572 from owncloud/stable8.1-backport-21544
[stable8.1] set etag and permission fields for trashbin entries
2016-02-24 11:09:59 +01:00
Roeland Douma 524063bf36 Merge pull request #22558 from owncloud/backport-22496-share-group-problem-8.1
[8.1] Fix on shared groups assignment.
2016-02-22 15:48:20 +01:00
Robin Appelman 18e927e5f2 set etag and permission fields for trashbin entries 2016-02-22 15:37:06 +01:00
Leonardo Diez 0f2010d8c3 Fix on shared groups assignment. 2016-02-22 10:45:30 +01:00
Morris Jobke a4668fdaf6 Merge pull request #22373 from owncloud/stable8.1-backport-22369
[stable8.1] Fix BMP support
2016-02-16 09:26:54 +01:00
Roeland Douma 0a39b1df68 Merge pull request #22363 from owncloud/backport-20152-stable8.1
[stable8.1] Remove invalid type-cast
2016-02-15 19:39:34 +01:00
Vincent Petry c5aff0933c Reindex array in GDrive after removing duplicates
Whenever duplicates are removed from the array, the indices are not in
sequence. This seems to cause trouble with opendir/the dir wrapper and
make it skip valid entries.

This fix reindexes the array to make it work.
2016-02-15 17:47:19 +01:00
Morris Jobke 5b1c0991da Fix BMP support
* fixes #16461
2016-02-14 09:37:31 +01:00
Lukas Reschke 9f3dad8353 Remove invalid type-cast
This is an `is_array` operation and not a `in_array` one. Thus this typecast is not required.

Fixes https://github.com/owncloud/core/issues/20095
2016-02-13 14:28:58 +01:00
Morris Jobke 38ebc06aa9 Merge pull request #22173 from owncloud/stable8.1-backport-22143
[Stable 8.1] When a user is removed we should remove the right shares
2016-02-06 09:27:13 +01:00
Roeland Jago Douma 8aa9b3189d When a user is removed we should remove the right shares
* This means all the shares directly shared with them
* Or all group shares having a special share with them

This patch fixes the operator precedece (AND before OR).
So before this patch:

(share_with = <deleted user> AND share_type = 0) OR share_type=2

So it deleted all user specific shares

Now:
share_with = <deleted user> AND (share_type = 0 OR (share_type=2)
2016-02-05 20:08:26 +01:00
Morris Jobke ac51b9da70 Merge pull request #21864 from owncloud/sync-certificates-with-upstream-81
[stable8.1] Sync certificates with upstream
2016-01-25 08:24:02 +01:00
Lukas Reschke 8b9e2d2426 Sync certificates with upstream 2016-01-22 22:12:21 +01:00
Thomas Müller 19e7e57fb0 Merge pull request #21748 from owncloud/stable8.1-backport-20927
[stable8.1] Handle return code of streamCopy in WebDAV put
2016-01-18 14:16:09 +01:00
Morris Jobke 952d640999 Handle return code of streamCopy in WebDAV put
* throw a different exception if streamCopy failed
2016-01-15 14:29:41 +01:00
Thomas Müller 40b76dfd56 Merge pull request #21694 from owncloud/stable8.1-users-scrolltop
[stable8.1] Keep scroll position in users page when sorting
2016-01-15 13:19:16 +01:00
Vincent Petry c55397491a Keep scroll position in users page when sorting
When sorting, some browsers like Chrome will lose the scroll position,
possibly because the sorting code is touching the DOM elements.

This fix saves the scroll position before sorting and sets it back
afterwards.
2016-01-13 15:36:32 +01:00
Vincent Petry 46253ef664 Merge pull request #21665 from owncloud/smb-statcache-cap-81
[8.1] cap the number of entries we cache in smb's statcache
2016-01-13 10:45:16 +01:00
Robin Appelman 2e5e756913 cap the number of entries we cache in smb's statcache 2016-01-12 18:12:40 +01:00
Morris Jobke 5182879c3f Merge pull request #21632 from owncloud/backport-17924-stable8.1
[backport] [stable8.1] always use an LDAP URL when connecting to LDAP
2016-01-12 10:31:45 +01:00
Arthur Schiwon 7539979e68 always use an LDAP URL when connecting to LDAP 2016-01-11 21:45:46 +01:00
Morris Jobke 6c35e7036a Merge pull request #21564 from owncloud/ext-smb-dep-stable8.1
[stable8.1] Check libsmbclient-php as well as smbclient binary
2016-01-11 11:33:47 +01:00
Robin McCorkell 016a58260c Check libsmbclient-php as well as smbclient binary 2016-01-09 09:19:13 +00:00
Vincent Petry c9c6efd157 Merge pull request #21314 from owncloud/scanner-skip-not-available-81
[8.1] Skip unavailable storages in scanner
2016-01-08 12:22:19 +01:00
Robin Appelman d523ed997a also log exception 2016-01-07 09:06:47 +01:00
Robin Appelman 49a2bbf4ab Skip unavailable storages in scanner 2016-01-07 09:06:45 +01:00
Morris Jobke f5952cbd76 Merge pull request #21463 from owncloud/stable8.1-fix-callable-ajax-scan
listen() requires a callable and not an array
2016-01-05 16:02:22 +01:00
Morris Jobke 3ccaaad687 listen() requires a callable and not an array
* fixes #21350
* fixes regression introduced with #20764
2016-01-05 14:33:25 +01:00
Morris Jobke 038351e0f7 Merge pull request #21296 from owncloud/stable8.1-prevent0bytedownloads
[stable8.1] prevent 0 byte downloads when storage returns false
2016-01-05 13:44:14 +01:00
Vincent Petry 073a00adb1 Merge pull request #21263 from owncloud/backport-21260-stable8.1
[backport] [stable8.1] initialize l10n instance earlier, fixes an undefined var warning foll…
2015-12-24 15:55:37 +01:00
Thomas Müller fbc0276ab5 Merge pull request #21340 from owncloud/fix-unit-tests
[stable8.1] Fix unit tests
2015-12-23 07:10:28 +01:00
Lukas Reschke 5fc1123f1c Fix unit tests 2015-12-22 21:24:47 +01:00
Morris Jobke 985aa59c22 Merge pull request #21235 from owncloud/stable8.1-backport-21232
[stable8.1] Use name of ICollection for exception message
2015-12-22 19:15:27 +01:00
Morris Jobke b3f8f9c9fe Merge pull request #21275 from owncloud/stable81_20884
[Stable 8.1] [Sharing] Respect disabled incoming federated shares
2015-12-22 19:13:15 +01:00
Morris Jobke 2d28fbcda6 Merge pull request #21294 from owncloud/backport-21255-stable8.1
user management: show password error temporary (backport for stable8.1)
2015-12-22 19:11:53 +01:00
C Montero-Luque 47a2c3738c 8.1.5 2015-12-21 07:23:26 -05:00
C Montero-Luque d4a53261c7 8.1.5 RC2 2015-12-18 17:32:43 -05:00
Robin Appelman 2c5234dcfe add unit test 2015-12-18 18:36:22 +01:00
Jörn Friedrich Dreyer 7090509505 prevent 0 byte downloads when storage returns false 2015-12-18 18:34:13 +01:00
michag86 fb5501fec3 Update users.js 2015-12-18 17:04:02 +01:00
Roeland Jago Douma 5721038f47 [Sharing] Respect disabled incoming federated shares
Only fetch the incoming federated shares if incoming shares are actually
enabled.

Fixes #20713
2015-12-18 09:17:54 +01:00
Arthur Schiwon bf675afafc initialize l10n instance earlier, fixes an undefined var warning followed by a php error 2015-12-17 15:56:19 +01:00
Morris Jobke 6f6bf2667b add unit test for #21230 2015-12-16 16:23:35 +01:00
Morris Jobke 2b8a6a19bc Use name of ICollection for exception message
* fixes #21230
2015-12-16 16:23:30 +01:00
C Montero-Luque 678ad217e2 8.1.5 RC1 2015-12-15 16:07:51 -05:00
Vincent Petry 9e174431f8 Merge pull request #21207 from owncloud/backport-21133-stable8.1
[backport] [stable8.1] Fix shared files of deleted users, detect DN change when checking for existence on LDAP
2015-12-15 18:43:47 +01:00
Vincent Petry d69cab983a Merge pull request #21210 from owncloud/stable8.1-handle-enforce-home-folder-rule-setting
[stable8.1] Properly handle enforce home folder naming rule setting
2015-12-15 18:43:05 +01:00
Björn Schießle c3595bd50b Merge pull request #21199 from owncloud/fix_20296_8.1
[stable8.1] don't allow to create a federated share if source and target are the same
2015-12-15 14:56:23 +01:00
Vincent Petry f2fb9fb6c2 Fixed JS unit tests for fed owner display name 2015-12-15 11:45:26 +01:00
Björn Schießle 73dda65a2e show display name but internally use the user name 2015-12-15 11:45:26 +01:00
Björn Schießle a1d59a92ab don't allow to create a federated share if source and target server are the same 2015-12-15 11:45:26 +01:00
Morris Jobke f43e1687f8 Properly handle enforce home folder naming rule setting 2015-12-15 10:10:53 +01:00
Arthur Schiwon 42c6990c8c fix find DN by UUID for AD 2015-12-14 23:19:24 +01:00
Arthur Schiwon b756dceccc unit test on getHome in combination with OfflineUser 2015-12-14 23:19:19 +01:00
Arthur Schiwon 945c4d19c5 adjust unit test 2015-12-14 23:19:14 +01:00
Arthur Schiwon 65cb4b4eee look for DN changes before marking a user as deleted 2015-12-14 23:19:08 +01:00
Arthur Schiwon 2e9f6dea90 throw NoUserException in getHome when the requested user does not exist anymore 2015-12-14 23:19:03 +01:00
Morris Jobke b6caf41387 Merge pull request #21151 from owncloud/backport-20978-stable8.1
reset mailadress/displayname on blur (backport for stable8.1)
2015-12-14 17:31:57 +01:00
Lukas Reschke 5881d7b8ed Merge pull request #21193 from owncloud/preview-non-existing-81
[8.1] Handle non existing files in version previews
2015-12-14 16:35:16 +01:00
Robin Appelman 51c6cd5c6a Handle non existing files in version previews 2015-12-14 16:04:10 +01:00
Thomas Müller ed9089f951 Merge pull request #21156 from owncloud/trashbin-loggedout-81
[8.1] Fix trashbin wrapper when no user is loggedin
2015-12-14 12:27:18 +01:00
Lukas Reschke ada7573174 Use XMLWriter to generate response
Gets rid of manual XML generation.
2015-12-14 09:39:34 +01:00
Robin Appelman e6afdd5659 skip test if we cant use the filesystem when not logged in 2015-12-11 15:41:25 +01:00
Robin Appelman 9c8083dab9 Fix thrashbin wrapper when no user is loggedin 2015-12-11 15:41:23 +01:00
michag86 9a0af8e59d reset mailadress/displayname on blur 2015-12-11 14:58:06 +01:00
Vincent Petry f11314b761 Merge pull request #21091 from owncloud/backport-20995-stable8.1
[backport] [stable8.1] ensure multiselect always receives an array when setting its value, f…
2015-12-10 18:00:05 +01:00
Vincent Petry cf009768f9 Merge pull request #21116 from owncloud/stable8.1-backport-21109
[stable8.1] Deduplicate version expire jobs
2015-12-10 16:37:23 +01:00
Morris Jobke 259e05b670 Deduplicate version expire jobs
* versionSize is calculated anyway in the expire job - > dropped
* offset/neededSpace was needed for expiry before the file is moved to the versions -> now this is included already in the currently used space because the expiry job is defered to a point in time after the version creation
* fixes #21108
2015-12-10 13:49:01 +01:00
Vincent Petry 29ae188c71 Merge pull request #21102 from owncloud/stable8.1_20989
[Stable8.1] Update parent when moving share into recieved share
2015-12-10 13:44:05 +01:00
Roeland Jago Douma 643778b028 Update parent when moving share into recieved share
Fixes #20769

When I receive a share and move a share of myself into that share (which
is allowed currently) I effectively hand over ownership of the files I
move. So we need to update the share I move to have as a parent the
share I move it into. Else our mounting system gets confused.
2015-12-10 11:32:03 +01:00
Morris Jobke fccfa3cf0b Merge pull request #21081 from owncloud/stable8.1-share-computesharepermissions-notstore
[stable8.1] Fix (re)share permission checks in a few code paths
2015-12-10 09:35:56 +01:00
Arthur Schiwon 6bedaf0f69 ensure multiselect always receives an array when setting its value, fixes #18734 2015-12-09 20:12:02 +01:00
Vincent Petry c132f91f9d Merge pull request #21085 from owncloud/occ-shall-not-fail-hard-in-maintenance-mode-stable8.1
Don't load commands of apps when in maintenance mode
2015-12-09 19:57:33 +01:00
Thomas Müller af67c456ac Don't load commands of apps when in maintenance mode - fixes #20939 2015-12-09 16:40:53 +01:00
Vincent Petry 2f2e932e02 Add explicit check for groups excluded from sharing
Since isSharable() doesn't do the check for groups excluded from
sharing, adding an explicit check in the sharing code.
2015-12-09 15:59:31 +01:00
Vincent Petry 5ecd8cc24d Fix more unit tests to pass a mock storage instead of null to FileInfo 2015-12-09 15:59:27 +01:00
Vincent Petry af70564335 Add reshare permission checks
Added in isSharable() in incoming remote share.
Added in isSharable() in regular incoming share.
Added in FileInfo to make sure the proper attributes are returned to the
clients.
2015-12-09 15:58:42 +01:00
Vincent Petry 2466972efd Compute share permissions in the view
The share permissions are now computed in the View/FileInfo instead of
storing them directly/permanently on the storage
2015-12-09 15:58:39 +01:00
Morris Jobke 873e932f59 Merge pull request #21042 from owncloud/backport-21037-stable8.1
[backport][stable8.1] passing an empty base in this diagnosis call will not result  in LDAP…
2015-12-08 17:34:43 +01:00
Arthur Schiwon d6a7b607ce passing an empty base in this diagnosis call will not result in LDAP errors
Neither in "Invalid DN syntax" nor in "Object not found"
2015-12-08 15:07:40 +01:00
Morris Jobke 2a86de9b34 Merge pull request #20999 from owncloud/backport-20981-multiple-emails-for-sharelink-8.1
[8.1] Allow sending a share email to multiple users
2015-12-07 16:25:20 +01:00
Thomas Müller 94cf29c5cf Merge pull request #20986 from owncloud/use-proper-logexception-stable8.1
ILogger has no logException()
2015-12-07 16:19:04 +01:00
Joas Schilling cfc1109073 Add a unit test for single user case as well 2015-12-07 15:50:20 +01:00
Joas Schilling b5420170e0 Allow sending a share email to multiple users 2015-12-07 15:50:16 +01:00
Thomas Müller ce2e172513 ILogger has no logException() - fixes #20797 2015-12-07 12:11:00 +01:00
Vincent Petry 563f0c8a81 Merge pull request #20795 from owncloud/stable8.1-backport-20790
[stable8.1] Deduplicate queued trashbin expire jobs
2015-12-04 17:45:24 +01:00
Morris Jobke bab3fcb134 Merge pull request #20956 from owncloud/stable8.1-backport-20877
[stable8.1] Check the expiration date for null
2015-12-04 15:55:57 +01:00
Morris Jobke e2b7f66b26 Check the expiration date for null
* null is always less than any value -> expirationDate gets null
  which is "no date set"
* ref https://github.com/owncloud/core/issues/20590#issuecomment-158393075
2015-12-04 15:03:52 +01:00
Vincent Petry 7d8aaa81c0 Merge pull request #20489 from owncloud/backport-20487-8.1
[8.1] Activity oracle sql error for favorites
2015-12-03 16:40:20 +01:00
Thomas Müller e89ab22d3a Merge pull request #20831 from owncloud/catch-missing-route-81
[8.1] Dont die when we're missing a route
2015-11-30 22:46:11 +01:00
Robin Appelman 0ac6470a2f Dont die when we're missing a route 2015-11-30 14:10:41 +01:00
Morris Jobke df6344211e Deduplicate queued trashbin expire jobs
* fixes #20425
* this removes the argument trashbin size from the expire job - it is now
  calculated in the expire job
* the queue now detects properly that the job is already queue and doesn't
  add it again
2015-11-27 15:13:08 +01:00
Vincent Petry 4c2ae6e9ee Merge pull request #20764 from owncloud/scan-eventsource-no-paths-81
[8.1] Dont output paths in scan.php
2015-11-26 16:40:03 +01:00
Robin Appelman a4a7ee1761 Dont output paths in scan.php 2015-11-26 16:35:04 +01:00
Morris Jobke 132c454d21 Merge pull request #20698 from owncloud/stable8.1-backport-19530
[stable8.1] Make sure the share we found is for the same item
2015-11-25 10:25:11 +01:00
Joas Schilling 943782bdfe Add a unit test for "share a file inside a folder that is already shared" 2015-11-24 09:58:47 +01:00
Joas Schilling a85cf1caf7 Make sure all variables are defined 2015-11-24 09:58:41 +01:00
Joas Schilling 88bba3ad15 Make sure the share we found is for the same item 2015-11-24 09:58:34 +01:00
Morris Jobke 75b4abb0d2 Merge pull request #20678 from owncloud/backport-joblist-fix-8.1
[8.1] Make the JobList test more robust by sorting the result of getAll bef…
2015-11-23 11:39:33 +01:00
Joas Schilling 6ce3419914 Make the JobList test more robust by sorting the result of getAll before comparison 2015-11-23 10:45:52 +01:00
Morris Jobke e1fc0d2345 Merge pull request #20637 from owncloud/cache-escape-like-81
[8.1] Escape like parameter in cache operations
2015-11-20 16:46:46 +01:00
Robin Appelman 9d04876824 escape like parameter in cache move 2015-11-20 14:40:08 +01:00
Robin Appelman 46942ff9ec Add test for special character during move 2015-11-20 14:40:05 +01:00
Robin Appelman fa16c219c5 define escape character for like statements on oracle 2015-11-20 14:40:01 +01:00
Robin Appelman 98f8732e83 define escape character for like statements on sqlite 2015-11-20 14:39:57 +01:00
Joas Schilling cef8c875f9 Add a unit test that executes the query 2015-11-18 10:42:33 +01:00
Joas Schilling e0a9755113 Oracle can not return statements but only values
So evaluate the condition directly and return 1 or 0
2015-11-13 11:35:30 +01:00
Morris Jobke 2e0665acb0 Merge pull request #20307 from owncloud/stable8.1-backport-use-actual-mimetype-detection-instad-of-oath-1
[stable8.1] Use actual mimetype detection instead of extension
2015-11-10 16:00:46 +01:00
Lukas Reschke 8537468c2c Use actual mimetype detection instead of extension
We cannot rely on the extension as the file may also be a valid TAR or ZIP file without such content. Especially when getting resources from the ownCloud appstore.
2015-11-10 15:06:45 +01:00
Morris Jobke 5871a0e93b Merge pull request #20395 from owncloud/stable8.1-extstorage-gdrive-forceapproval
[stable8.1] Force approval in GDrive oauth to get refresh_token
2015-11-09 14:01:06 +01:00
Vincent Petry f6872ef1a5 Force approval in GDrive oauth to get refresh_token
Forcing the approval of app permissions makes sure that the GDrive API
will always return a refresh_token.

In the case of apps that were already authorized for the current user/domain,
the API doesn't return the refresh_token which causes expiration issues.
2015-11-09 13:05:26 +01:00
Morris Jobke e67107615d Merge pull request #20367 from owncloud/stable8.1-backport-20346
[stable8.1] Show the language code in personal settings for unknown languages
2015-11-09 08:10:27 +01:00
Morris Jobke 0e0a6ba0b6 Merge pull request #20362 from owncloud/backport-20271-stable8.1
[Backport] [stable8.1] attempt to connect to backup server again
2015-11-06 15:26:19 +01:00
Morris Jobke bdeff3530c Show the language code in personal settings for unknown languages
Steps to reproduce:
* having an unknown language set in oc_preferences
* browse the personal settings
* only get listed the first letter of this language in the language chooser
2015-11-06 14:01:39 +01:00
Arthur Schiwon c603143ed7 integration tests 2015-11-06 12:59:15 +01:00
Arthur Schiwon c3155505a5 LDAP: attempt to connect to backup server again, if main server is not available. Fixes #18701 2015-11-06 12:59:08 +01:00
Vincent Petry ec999816d2 Merge pull request #20246 from owncloud/backport-20192-stable8.1
[backport] [stable8.1] if a user that is flag as deleted shows up again, remove that flag. F…
2015-11-05 17:26:23 +01:00
Vincent Petry 0c8bce90c0 Merge pull request #20286 from owncloud/stable8.1-share-preventmovemountpointintosharedfolder
[stable8.1] Prevent moving mount point into already shared folder (outgoing)
2015-11-05 10:29:46 +01:00
Morris Jobke 17ed25c542 Merge pull request #20298 from owncloud/backport-20155-8.1
[backport] [stable8.1] add port to host only, if an URL is used instead of a plain hostname
2015-11-04 16:17:43 +01:00
Arthur Schiwon ccb2a386a4 add port to host only, if an URL is used instead of a plain hostname 2015-11-04 13:01:29 +01:00
Vincent Petry 897f134889 Prevent moving mount point into already shared folder (outgoing)
It is already not allowed to share a folder containing mount points /
incoming shares.

This fixes an issue that made it possible to bypass the check by moving
the incoming share mount point into an existing outgoing share folder.
2015-11-04 10:44:10 +01:00
Morris Jobke cb0762d0d4 Merge pull request #20163 from owncloud/backport-19489
[stable8.1] fix possible infinite loop when reading groups in the wizard
2015-11-03 13:22:53 +01:00
Arthur Schiwon 21600c7b1a if a user that is flag as deleted shows up again, remove that flag. Fixes #20090
Conflicts:
	apps/user_ldap/lib/access.php
2015-11-02 22:27:34 +01:00
Morris Jobke 61a1fc9159 Merge pull request #19773 from owncloud/stable8.1-proppatch-lastmodified
[stable8.1] Fix mtime PROPPATCH to be "lastmodified" instead of "getlastmodified"
2015-11-02 09:01:55 +01:00
Morris Jobke f71f985427 Merge pull request #20137 from owncloud/LukasReschke-patch-2
[stable8.1] Update certificate bundle
2015-11-02 09:01:21 +01:00
C Montero-Luque aca9fce93f 8.1.4 2015-10-30 12:45:25 -04:00
Arthur Schiwon e0583a10f3 fix possible infinite loop when reading groups in the wizard 2015-10-29 21:46:46 +01:00
Lukas Reschke 1e2fca60e0 [stable8.1] Update certificate bundle
Backport of https://github.com/owncloud/core/pull/20126
2015-10-29 10:36:35 +01:00
C Montero-Luque f7f34dbeb4 8.1.4 RC2 2015-10-28 10:22:39 -04:00
Thomas Müller 8e0cddbe01 Merge pull request #19512 from owncloud/backport-19419-stable8.1
[backport] [stable8.1] memberOf resembles a DN as well and is actively used
2015-10-28 11:09:01 +01:00
Thomas Müller 3bad2ac1e5 fixing typo 2015-10-28 09:24:19 +01:00
Arthur Schiwon 9f3ea9116e memberOf resembles a DN as well and is actively used
Conflicts:
	apps/user_ldap/tests/access.php
2015-10-28 09:21:54 +01:00
Morris Jobke 3387d05ca9 Merge pull request #19972 from owncloud/stable8.1-backport-19635
[stable8.1] allow an attribute to return more than one value
2015-10-27 14:08:26 +01:00
Thomas Müller 74871b1676 Merge pull request #20064 from owncloud/stable8.1-add-warning-for-php7
[stable8.1] Stop processing if PHP 7 is used
2015-10-26 22:04:14 +01:00
Lukas Reschke 352d695c95 Stop processing if PHP 7 is used
PHP 7 is only compatible with ownCloud 8.2.0
2015-10-26 17:39:35 +01:00
Lukas Reschke cc9d5e44b1 Adjust unit tests 2015-10-26 16:46:34 +01:00
Lukas Reschke 643cba065a Fix style 2015-10-26 16:46:22 +01:00
Frédéric Fortier c5b28e0795 Revert "adjust to nested group fix
This reverts commit 845485cfe, which fixes #19816 regression.
2015-10-26 16:46:09 +01:00
Thomas Müller 5062007000 Merge pull request #19998 from owncloud/backport-fix-deleted-ldap-user-sharing-stable8.1
[8.1] handle NoUserException in sharing code
2015-10-23 15:26:54 +02:00
Thomas Müller 9daf3e7410 Merge pull request #20007 from owncloud/stable8.1-backport-19957
[8.1] Expose syslog tag in the configuration
2015-10-23 15:26:10 +02:00
Thomas Müller 8f6774fc4c Merge pull request #20002 from owncloud/backport-19970-8.1
[8.1] Fix "Call to a member function getUID() on boolean" in Crypt
2015-10-23 15:25:54 +02:00
Steffen Lindner 371f4bf472 Add syslog_tag docu to sample config 2015-10-23 14:17:04 +02:00
Volker Fröhlich 49879b868b Expose syslog tag in the configuration 2015-10-23 14:16:49 +02:00
Joas Schilling 1cf61baa41 Fix "Call to a member function getUID() on boolean" in Crypt 2015-10-23 13:45:09 +02:00
Morris Jobke e3642f2f3d handle NoUserException in sharing code
* setup LDAP users
* share from an LDAP user
* delete that LDAP user
* log in as share recipient
* before: unhandled NoUserException
* after: NoUserEception is logged and share is not shown anymore
2015-10-23 12:21:52 +02:00
Arthur Schiwon bb973c2d76 adjust fetchList with a single requested attribute accordingly 2015-10-22 12:08:25 +02:00
Arthur Schiwon cde21db620 adjust tests 2015-10-22 12:08:17 +02:00
Arthur Schiwon f9be35c931 fix primary group retrieval 2015-10-22 12:08:09 +02:00
Arthur Schiwon ba13cecb76 treat dn as any other attribute when building the search() return array 2015-10-22 12:07:52 +02:00
Arthur Schiwon 5412899665 adjust handling changed return array structure from search() and fetchList() 2015-10-22 12:03:07 +02:00
Arthur Schiwon 6ccc5a6cd3 allow an attribute to return more than one value 2015-10-22 12:02:48 +02:00
Arthur Schiwon 7ccd52db25 lowercase configured displayname attribute so isset works - all attribute names coming from ldap are lowercased for easy comparison 2015-10-22 12:01:26 +02:00
Arthur Schiwon a05ead505d fix update quota with known value 2015-10-22 12:01:25 +02:00
Arthur Schiwon 0a9904963d stable8.1 related adjustments to #18469 backport 2015-10-22 12:01:25 +02:00
Arthur Schiwon c1953f9676 Backport #18469 (read all relevant user attributes on login and user search, in one query)
read all relevant user attributes on login and user search, in one query. saves us some.

Conflicts:
	apps/user_ldap/user_ldap.php

adjust to nested group fix

do not throw exception when no attribute is specified
2015-10-22 12:01:25 +02:00
C Montero-Luque 5e8f0a893d 8.1.4 RC1 2015-10-21 17:09:42 -04:00
Thomas Müller c16a847163 Merge pull request #19832 from owncloud/stable8.1-public-recognizeauthsession
[stable8.1] Allow public auth to recognize sesssion
2015-10-20 14:25:59 +02:00
Thomas Müller c2ded337e6 Merge pull request #19830 from owncloud/fix-expiration-format-stable8.1
Use proper format when setting the expiration date
2015-10-16 15:43:38 +02:00
Vincent Petry df4348674b Allow public auth to recognize sesssion
When a public link password has been input, its auth is stored in the
session.
This fix makes it possible to recognize the session when using public
webdav from the files UI.
2015-10-16 13:50:39 +02:00
Thomas Müller f3392f9e59 Use proper format when setting the expiration date 2015-10-16 13:47:36 +02:00
Thomas Müller 923e6ca1bf Merge pull request #19809 from owncloud/show-serverside-share-link-expiration-stable8.1
Update expiration date on link sharing
2015-10-16 13:08:14 +02:00
Roeland Douma 64fb704c4e Merge pull request #19638 from owncloud/stable8.1_backport_sharingcheckmiddleware_fixes
Stable8.1 backport sharingcheckmiddleware fixes
2015-10-16 08:51:37 +02:00
Thomas Müller 4ba4fb5ffb Merge pull request #19784 from owncloud/stable8.1_backport_19727
[Stable8.1] Return path instead of itemsource
2015-10-15 19:58:42 +02:00
Thomas Müller e1d2ab83cc Set expiration date on password change 2015-10-15 17:16:18 +02:00
Thomas Müller 6fd2f18b85 Only show expiration date in the web ui if it has been set 2015-10-15 16:58:51 +02:00
Thomas Müller a2810f6207 Update expiration date on link sharing 2015-10-15 15:23:50 +02:00
Lukas Reschke 4d92aa551d Merge pull request #19786 from owncloud/backport-stable8.1-setup-transport
[stable8.1] Setup sendmail transport
2015-10-15 14:00:24 +02:00
Lukas Reschke 5ed1744a6f Setup sendmail transport
Replaces https://github.com/owncloud/core/pull/19047 and fixes https://github.com/owncloud/enterprise/issues/854  and https://github.com/owncloud/core/issues/19110
2015-10-14 16:29:55 +02:00
Roeland Jago Douma 371061ac6d Return path instead of itemsource
Fixes #19678

Errors should contain paths and not internal ids
2015-10-14 15:56:03 +02:00
Vincent Petry a68d9159bd Fix mtime PROPPATCH to be "lastmodified" instead of "getlastmodified"
Fix regression that makes PROPPATCH of mtime work like it did in OC <=
8.0.
The PROPPATCH must be done on the "lastmodified" property.
The "getlastmodified" now return 403 again.
2015-10-14 14:23:37 +02:00
Morris Jobke 85c8af596d Merge pull request #19740 from owncloud/stable8.1-do-not-leak-exception-data
[stable8.1] Do not print exception message
2015-10-13 18:19:18 +02:00
Morris Jobke 2f2d94f801 Merge pull request #19287 from RealRancor/restruct_config_sample
Restructure config.sample.php of stable8.1
2015-10-13 16:23:42 +02:00
Lukas Reschke 9ece45ca28 Do not print exception message
In case of an error the error message often contains sensitive data such as the full path which potentially leads to a full path disclosure.

Thus the error message should not directly get displayed to the user and instead be logged.
2015-10-13 14:31:47 +02:00
Morris Jobke e9a17fbee5 Merge pull request #19715 from owncloud/stable8.1-repair-donotrepairfoldermimetypes
[stable8.1] Do not update mime types for folders with extension
2015-10-13 09:54:00 +02:00
Vincent Petry 37747016f2 Do not update mime types for folders with extension
Some folders might have an extension like "test.conf".
This fix prevents to overwrite the folder's mime type with another mime
type while running the mimetype repair step.
2015-10-12 17:28:32 +02:00
Thomas Müller 07f903a1e3 Merge pull request #19466 from owncloud/tarstreamer-stable8.1
[stable8.1] backport Tarstreamer
2015-10-12 11:58:03 +02:00
Morris Jobke 4c13a648bb Merge pull request #18855 from owncloud/memcached-fix-stable8.1
[stable8.1] Fallback to complete Memcached flush if getAllKeys fails
2015-10-09 13:19:35 +02:00
Morris Jobke c3ec3b0fe0 Merge pull request #19658 from owncloud/stable8.1-backport-19546
Stable8.1 backport 19546
2015-10-09 13:16:33 +02:00
Thomas Müller 045c491be8 Updating 3rdparty dependency 2015-10-09 13:03:09 +02:00
Robin Appelman 56fcef3d56 fix internal path when searching in storage root
(cherry picked from commit c2d76d2)
2015-10-09 08:52:42 +02:00
Robin Appelman db909277f1 Add unit test for searching in storage root
(cherry picked from commit e28a2ff)
2015-10-09 08:52:42 +02:00
Olivier Paroz 30c149deeb The minimum size for internalRootLength is 1
(cherry picked from commit 3173ed2)
2015-10-09 08:52:42 +02:00
Thomas Müller 87f27d0ba1 Merge pull request #19652 from owncloud/backport-disable-appstore-for-ee
[stable8.1] Disable app store for EE by default
2015-10-09 08:48:43 +02:00
Thomas Müller 48ec118af6 Merge pull request #19604 from owncloud/stable8.1-backport-19574
[stable8.1] Clear the shares after the test like storages and files
2015-10-09 08:48:27 +02:00
Lukas Reschke b21912aa41 Disable app store for EE by default
This disables the app store for EE versions by default to address some problems caused by the wrong assumption that "Official" means supported by ownCloud Inc.

Administrators can still enable the app store by setting `appstoreenabled` to true in the config file.
2015-10-08 15:12:41 +02:00
Joas Schilling f83f80ac71 Only use zip64 when we have 64 bit php 2015-10-08 10:32:24 +02:00
Roeland Jago Douma c7d9936d67 sharingcheckmiddleware now handles externalshares as well
Added new annotations for the externalsharescontroller class
* @NoOutgoingFederatedSharingRequired
* @NoIncomingFederatedSharingRequired

By default both are required for all functions in the
externalSharesController.

A proper exception is thrown and then a 405 is returned instead of the
default error page. Since it is only an API endpoint this makes more
sense.

Unit tests added and updated
2015-10-08 08:20:08 +02:00
Roeland Jago Douma ffb8819125 Split files_sharing middelware
Since for external shares there is no need for link shares to be enabled
we should check which controller is actually being called.

This makes sure that in all cases we verify that the files_sharing app
is enabled. But only for the share controller (public shares) we check
if the API is enabled and if links are enabled.

TODO: add checks for federated sharing as well
2015-10-08 08:11:15 +02:00
Lukas Reschke b5f8f94341 Only intercept exceptions of type "NotFoundException" instead of any Exception
The sharing backend may throw another exception for example when the activity app encounters a problem. Previously this just triggered a 404 error page and the exception got not logged at all. With this change such exceptions get not intercepted and regularly handled as exceptions so that we have meaningful log data. Also the user will be shown a window informing him that an error happened.

Helps to debug cases such as https://github.com/owncloud/core/issues/19465
2015-10-08 08:11:06 +02:00
Roeland Jago Douma a77f679779 Respect disabled sharing API settings
If the sharing API setting is disabled that sharing check middle ware
should block the request. Thus making link shares unavailable.
Fixes #18970

* Unit test added
* Unit tests updated
2015-10-08 08:09:55 +02:00
Morris Jobke c2ca7fc91d Clear the shares after the test like storages and files
* adjusted to stable8.1 backport of #19574
2015-10-06 14:12:15 +02:00
Thomas Müller 29a4d1b512 Merge pull request #19598 from owncloud/stable8.1_backport_19553
[stable8.1] Backport of #19553: show MM-DD-YYYY as expiration date consistently
2015-10-06 14:07:04 +02:00
Roeland Jago Douma c589244b40 Backport of #19553
Show expiration date always as MM-DD-YYYY
2015-10-06 07:50:36 +02:00
Thomas Müller 4a1246fa29 Merge pull request #19485 from owncloud/stable8.1-backport-19460
[8.1] backport 19460 | Fix postScanFile event and make it available to utils scanner
2015-10-01 12:01:49 +02:00
Olivier Paroz dc128295c6 Make postScanFile and postScanFolder available to OC\Files\Utils\Scanner
(cherry picked from commit cc64c09)
2015-09-30 18:19:44 +02:00
Olivier Paroz 788831f139 Always send a postScanFile event when done scanning a file
postScanFile is important when scanning external storage as it indicates when the file is ready to be used
(cherry picked from commit 9ea05c8)
2015-09-30 18:19:11 +02:00
Thomas Müller 9a81eca7ba Merge pull request #19450 from owncloud/stable8.1-backport-19440-19426
Stable8.1 backport 19440 19426
2015-09-30 16:11:06 +02:00
Thomas Müller b9e0e6a573 Merge pull request #19475 from owncloud/thumbnail-temp-clean-81
[8.1] Clean temp files used for thumbnail generation
2015-09-30 16:10:27 +02:00
Robin Appelman 32c6fdf098 Clean temp files used for thumbnail generation 2015-09-30 15:15:08 +02:00
Thomas Müller 643b6c11c3 Adding TarStreamer and updating ZipStreamer 2015-09-30 10:32:57 +02:00
Victor Dubiniuk 9e5f538897 Uniform behavour for tar and zip 2015-09-30 10:25:33 +02:00
Victor Dubiniuk ab68469e61 More corrections 2015-09-30 10:25:33 +02:00
Victor Dubiniuk b70e7f4d0a Add namespace. Fix broken zip 2015-09-30 10:25:33 +02:00
Victor Dubiniuk 623ce418ce Add PHpdoc 2015-09-30 10:25:33 +02:00
Victor Dubiniuk 6c2f95ff9f Introduce streamer 2015-09-30 10:25:29 +02:00
Morris Jobke 2764aa1b99 Merge pull request #18572 from owncloud/stable8.1-backport-18553
[stable8.1] Save detected l10n of browser on login
2015-09-29 18:23:24 +02:00
Lukas Reschke 1a167dd5ac Add blob: scheme to default CSP policy
Fixes https://github.com/owncloud/core/issues/19438
(cherry picked from commit e735a99)
2015-09-29 17:11:39 +02:00
Olivier Paroz f934a6fae6 Fix CSP for images for legacy apps
Fixes #19425
(cherry picked from commit c4bac16)
2015-09-29 17:00:54 +02:00
Morris Jobke 50a8ba6062 Merge pull request #19446 from owncloud/stable8.1-backport-19441
[stable8.1][upgrade] switch to debug logging on upgrade
2015-09-29 16:48:09 +02:00
Morris Jobke 427f7d5a5c Merge pull request #19439 from owncloud/stable8.1-share-disablepluginwhennocoreshare
[stable8.1] Do not register JS share plugin if core sharing API is disabled
2015-09-29 16:30:59 +02:00
Morris Jobke 655eb4ce40 [upgrade] switch to debug logging on upgrade
* resets afterwards
* adds output about the previous log level
2015-09-29 16:14:45 +02:00
Vincent Petry 9bd37d2acd Do not register JS share plugin if core sharing API is disabled 2015-09-29 14:24:19 +02:00
Morris Jobke 1d2803ec9a Save detected l10n of browser on login
* fixes owncloud/activity#373
2015-09-28 14:00:33 +02:00
Thomas Müller d6994b2da6 Merge pull request #19216 from owncloud/stable8.1-discardexpirationdatefornonlinkshares
[stable8.1] Discard expiration date from result for non-link shares
2015-09-24 21:07:15 +02:00
Thomas Müller c4667d5213 Merge pull request #18957 from owncloud/stable8.1-backport-17791
[stable8.1] Add custom CSP for Win 10 compatibility
2015-09-24 21:06:49 +02:00
RealRancor 310762a118 Restructure config.sample.php of stable8.1 2015-09-23 09:57:34 +02:00
Vincent Petry 7b5218ed30 Merge pull request #19149 from owncloud/issue-19147-backport-update-break
Issue 19147 backport update break
2015-09-22 12:34:55 +02:00
Björn Schießle 00447f32f6 Merge pull request #18747 from owncloud/fix_password_reset_8.1
[stable8.1] use login name for password reset
2015-09-22 09:52:17 +02:00
Thomas Müller 876266f0ce Merge pull request #19051 from owncloud/backport-shibboleth-fix-stable8.1-2
Repeated calls to loginWithApache() should not not try to set user in…
2015-09-21 16:09:47 +02:00
blizzz dc1755ab52 Merge pull request #18123 from GreenArchon/backport-17759-stable8.1
[stable8.1]Properly nest groups when using memberOf to detect group membership, fixes #17759
2015-09-21 15:51:06 +02:00
Vincent Petry c48a61a975 Discard expiration date from result for non-link shares 2015-09-21 11:42:46 +02:00
Björn Schießle 42c454e8d0 Merge pull request #19011 from owncloud/fix_18926_8.1
[stable8.1]  check for the right user if we can change his password
2015-09-21 10:05:49 +02:00
Vincent Petry aaa1249075 Improved update version detection logic 2015-09-18 09:07:18 +02:00
Vincent Petry 380971c76d Simplify comparison algo 2015-09-18 09:07:18 +02:00
Vincent Petry 1efcbca9dc Throw exception on downgrade attempt 2015-09-18 09:07:18 +02:00
Vincent Petry 1f7b231b9a Restrict upgrades to explicit allowed version
version.php now contains the previous ownCloud version from which
upgrades are allowed. Any other upgrades will show a message that the
upgrade/downgrade is not supported.

Conflicts:
	version.php
2015-09-18 09:07:16 +02:00
Thomas Müller 0b279f9a13 Merge pull request #19075 from owncloud/check-maintenance-before-everything-else
Check for maintenance mode first so we send the 503 instead of login …
2015-09-16 10:24:22 +02:00
Joas Schilling aa12a9983a Check for maintenance mode first so we send the 503 instead of login verification 2015-09-16 09:27:38 +02:00
Thomas Müller bf149b1529 Repeated calls to loginWithApache() should not not try to set user information in the session again 2015-09-15 16:40:12 +02:00
Joas Schilling c736f5dcc4 Merge pull request #18816 from owncloud/move-background-job-registration-to-install-update-8.1
Move background job registration to install update 8.1
2015-09-15 10:36:11 +02:00
Morris Jobke 63e07b0525 Merge pull request #18703 from owncloud/request-fix-stable8.1
[stable8.1] Decode request content only on getContent
2015-09-15 09:17:13 +02:00
Individual IT Services 690a4597e3 Merge pull request #19013 from owncloud/stable8.1-backport-19006
[stable8.1] allow ".." in folder names
2015-09-14 16:22:11 +05:45
Individual IT Services 709f289beb allow ".." in folder names
backport of #19006
fix for #18987
2015-09-14 16:04:56 +05:45
Bjoern Schiessle fd259db588 check for the right user if we can change his password 2015-09-14 11:50:46 +02:00
Joas Schilling 5500cb9b4e Move registration of LDAP background jobs to the install and update 2015-09-14 11:14:54 +02:00
Joas Schilling 15a054f127 Move registration of background job to install/update 2015-09-14 11:08:40 +02:00
C Montero-Luque 015323c1cb 8.1.3 2015-09-10 10:28:00 -04:00
Lukas Reschke 4d1b898bc5 Add custom CSP for Win 10 compatibility
The default content-security-policy of ownCloud forbids inline
JavaScript for security reasons. IE starting on Windows 10 will
however also obey the CSP which will break the event source fallback.
As a workaround thus we set a custom policy which allows the execution
of inline JavaScript.

This fixes https://github.com/owncloud/core/issues/14286
2015-09-10 15:01:38 +02:00
Morris Jobke 8d800e9635 Merge pull request #18928 from owncloud/stable8.1-backport-18832
[stable8.1] Avoid re-propagation of shares during one propagation run
2015-09-09 23:21:08 +02:00
Morris Jobke bef8dd4171 Merge pull request #18904 from owncloud/missing-context-on-update-file-target_8.1
[stable8.1] Use context function call instead of static
2015-09-09 15:15:56 +02:00
Morris Jobke 2f851201db Merge pull request #18903 from owncloud/fix_sharing_add_to_group_8.1
[stable8.1] fix addToGroup hook
2015-09-09 15:15:48 +02:00
Morris Jobke cbcbbd9423 Avoid re-propagation of shares during one propagation run
* fix was proposed by @nickvergessen
2015-09-09 15:10:54 +02:00
Morris Jobke 5d433da1ae Merge pull request #18814 from owncloud/shared-mount-delay-setup-8.1
[8.1] Delay setting up the filesystem for a share owner untill the share is used
2015-09-09 15:07:52 +02:00
Joas Schilling 349c650535 Use context function call instead of static 2015-09-08 17:13:39 +02:00
Bjoern Schiessle 3ceee5408a intproduce pre_addToGroup hook. we need to calculate the possible unique
targets before the user was added to the group otherwise we will always detect
a name collision
2015-09-08 17:08:52 +02:00
Bjoern Schiessle 3b30dd4394 use the correct user if we update the share table 2015-09-08 17:08:39 +02:00
Lukas Reschke f3b8b90191 Merge pull request #18844 from owncloud/app-upgrade-routenotfound-stable8.1
[stable8.1] Always add to $loadedApps
2015-09-08 13:40:54 +02:00
Robin McCorkell 76399dc6b0 Fallback to complete Memcached flush if getAllKeys fails
Newer Memcached's do not support the underlying protocol commands that
getAllKeys() is implemented with. We should fallback to clearing
everything in that case, as causing (temporary) performance problems for
other applications on the server is better than having stale cached data.
2015-09-06 18:16:15 +01:00
Robin McCorkell a2d456c195 Always add to $loadedApps 2015-09-05 11:43:00 +01:00
Robin Appelman 9c289b71c6 setup owner when getting users for share 2015-09-03 15:12:46 +02:00
Robin Appelman 4676f39855 Delay setting up the filesystem for a share owner untill the share is used 2015-09-03 15:12:38 +02:00
C Montero-Luque 7b510f2510 8.1.2 2015-09-02 10:54:56 +02:00
Bjoern Schiessle b823bbbc28 use login name for password reset 2015-09-01 18:01:59 +02:00
Robin McCorkell 0dfa839582 Decode request content only on getContent 2015-08-31 14:05:51 +01:00
C Montero-Luque 01fc0b53f6 8.1.2 RC1 2015-08-30 10:36:12 +02:00
Morris Jobke 04bed337ee Merge pull request #18612 from owncloud/stable8.1-newer-certs-2
[stable8.1] Use certificates that expire in 10 years
2015-08-28 18:44:10 +02:00
Lukas Reschke 0e4bdfbef3 Use certificates that expire in 10 years
🙊 🙊 🙊
2015-08-27 22:25:40 +02:00
Morris Jobke 3233b9c4ee Merge pull request #18583 from owncloud/backport-of-18582
[stable8.1] Remove last occurence of `forcessl`
2015-08-26 22:08:49 +02:00
Lukas Reschke 1850476916 Remove last occurence of forcessl
This shoudl have been adjusted as well, now it's consistent with `setMagicInCookie`. While it does not have a security impact directly some automated scanners reported this all the time.
2015-08-26 15:09:00 +02:00
Morris Jobke bcc79b0e40 Merge pull request #18579 from owncloud/backport-18279-stable8.1
[backport] also don't count group members when more than 1 ldap configs are active
2015-08-26 14:29:29 +02:00
Arthur Schiwon 1d8b5ac909 also don't count group members when more than 1 ldap configs are active 2015-08-26 11:58:36 +02:00
Joas Schilling 540ad35f3b Merge pull request #18544 from owncloud/stable8.1-backport-18439
[stable8.1] [app management] fix dependency check on install
2015-08-26 11:00:39 +02:00
Morris Jobke d2c81fd3c5 Merge pull request #18555 from owncloud/fix-gs-share-stable8.1
[stable8.1] Simply hide sharing buttons for IE8 - fixes #18011
2015-08-25 21:59:32 +02:00
Lukas Reschke c3468c7b29 Merge pull request #18559 from owncloud/ext-objectstore-stable8.1
[stable8.1] Prevent objectstore being set from client side
2015-08-25 20:56:38 +02:00
Robin McCorkell a1706f61aa Prevent objectstore being set from client side 2015-08-25 16:21:09 +01:00
Thomas Müller 7d436579cb don't load gs-share 2015-08-25 16:50:17 +02:00
Thomas Müller b2adf17433 Simply hide sharing buttons for IE8 - fixes #18011 2015-08-25 16:09:28 +02:00
Morris Jobke 76306dd5a1 [app management] fix dependency check on install 2015-08-25 14:19:54 +02:00
Morris Jobke 727cb3b2a3 Merge pull request #18446 from owncloud/ext-setuservars-string-stable8.1
[stable8.1] setUserVars() should only attempt substitution with strings
2015-08-25 09:00:22 +02:00
Morris Jobke 227e338542 Merge pull request #18487 from owncloud/add-cors-header-to-allow-client-based-check
[stable8.1] Add CORS header to status.php to allow client-based check…
2015-08-24 09:30:02 +02:00
Lukas Reschke 6dffa0fc95 [stable8.1] Add CORS header to status.php to allow client-based check in the future 2015-08-22 14:48:28 +02:00
Robin McCorkell bf1096602b Retain compatibility with updated storage configurations
String booleans are still accepted
2015-08-20 12:28:59 +01:00
Robin McCorkell d6bc77599e setUserVars() should only attempt substitution with strings 2015-08-20 02:21:45 +01:00
Morris Jobke 21c9dd284b Merge pull request #18431 from owncloud/add-warning-ca-bundle-stable8.1
[stable8.1] Add warning for not existing CA bundle when updating
2015-08-19 19:53:44 +02:00
Morris Jobke 174c4e3113 Merge pull request #18353 from owncloud/backport-block-autocomplete
[stable8.1] Add option to disable autocomplete in share dialog
2015-08-19 16:16:11 +02:00
Lukas Reschke 373d1b67b2 Add warning for not existing CA bundle when updating
For newer releases we shall use an integrity check. But that's a good alternative for now.
2015-08-19 15:13:24 +02:00
Thomas Müller 31eb4f06f7 Merge pull request #18397 from owncloud/smb-1.0.4-81
[8.1] Update Icewind/SMB to 1.0.4
2015-08-19 09:16:06 +02:00
Robin Appelman b9e5809869 update icewind/smb to 1.0.4 2015-08-18 17:36:55 +02:00
Robin Appelman 8c145541f6 update icewind/smb to 1.0.3 2015-08-18 17:36:51 +02:00
Robin McCorkell 880ba38e2c Merge pull request #18367 from owncloud/config-php-tyops-8-1
typo fixes
2015-08-17 23:42:06 +01:00
Carla Schroder 47ec44da3b typo fixes 2015-08-17 10:49:28 -07:00
Morris Jobke 60cd118371 Add option to disable autocomplete in share dialog 2015-08-17 15:45:06 +02:00
Morris Jobke 2c81ac1cf7 Merge pull request #18182 from owncloud/backport-18159-stable8.1
Backport 18159 stable8.1
2015-08-16 14:39:25 +02:00
Thomas Müller 3ea3fc7b62 Merge pull request #18274 from owncloud/issue-18261-sharing-capabilities-use-wrong-default-8.1
[8.1] Issue 18261 sharing capabilities use wrong default 8.1
2015-08-14 12:24:51 +02:00
Morris Jobke dc012be598 Merge pull request #18277 from owncloud/stable8.1-17852
[stable8.1] add test for factories
2015-08-14 00:36:56 +02:00
Jan-Christoph Borchardt 94f2b2ba8c Merge pull request #18284 from owncloud/stable8.1-backport-17785
[stable8.1] fix mobile scrolling, lower sidebar sensitivity, fix #11193
2015-08-13 23:38:46 +02:00
Jan-Christoph Borchardt 116ec56e8c Merge pull request #18288 from owncloud/stable8.1-backport-18231
[stable8.1] Show strage full warning for shared storages temporary
2015-08-13 23:38:20 +02:00
Morris Jobke 444d5d27de Show strage full warning for shared storages temporary
* removed the setDefault call because then it will always be
  reshown
  * was added with ba475d4862
* fixes #18208
2015-08-13 17:12:41 +02:00
Jan-Christoph Borchardt dcda1e1e61 fix mobile scrolling, lower sidebar sensitivity, fix #11193 2015-08-13 15:43:49 +02:00
Morris Jobke 6bcf2b9e77 Merge pull request #18257 from owncloud/stable8.1-backport-17680
[stable8.1] handle rmdir on files for ftp storages
2015-08-13 15:31:51 +02:00
Thomas Müller dbc03b68ae Merge pull request #18237 from owncloud/backport-scanfilesignature
[stable8.1] Backport scanfilesignature
2015-08-13 14:54:25 +02:00
Jan-Christoph Borchardt 94eb5f645a Merge pull request #18266 from owncloud/stable8.1-filelist-emptycontentduringmask
[stable8.1] Make sure to hide empty content message when mask is shown
2015-08-13 14:48:37 +02:00
Bernhard Posselt c31e2464c8 add test for factories
use ref for factory test

Ensure we construct SimpleContainer

Use single instance of DIContainer in routing tests
2015-08-13 13:27:32 +01:00
Joas Schilling 9e42d3ed43 Fix config map provider for tests 2015-08-13 13:09:08 +02:00
Joas Schilling d3266f5459 Fix default values of sharing capabilities
The problem is the UI used a different default than the capabilities.
So when you never touched the config, the setting in admins said "disabled"
while the capabilities said "enabled".
2015-08-13 13:01:32 +02:00
Vincent Petry dcd9154f04 Make sure to hide empty content message when mask is shown 2015-08-13 11:55:15 +02:00
Joas Schilling c8e1359c9d Add a basic unit test which notifies us about incompatible extending 2015-08-13 11:41:13 +02:00
Robin Appelman 6c8689072c handle rmdir on files for ftp storages 2015-08-13 10:54:41 +02:00
Joas Schilling e272ec0c3e Fix duplicated line in doc block 2015-08-12 15:51:29 +02:00
Vincent Petry 327f96f29b Fix scanFile signature to avoid boring warning 2015-08-12 15:40:45 +02:00
Vincent Petry 1add97feae Merge pull request #17753 from oparoz/fix-previews-for-public-uploads
[stable8.1] Fix preview of old file on public upload conflicts
2015-08-12 10:58:40 +02:00
Thomas Müller e9a1a8cf75 Merge pull request #18172 from owncloud/fix-language-of-files-activities-in-emails-8.1
[8.1] Correctly make use of the languageCode argument in the files activity extension
2015-08-12 10:23:49 +02:00
Thomas Müller 69970f83f9 Merge pull request #18139 from owncloud/stable8.1-share-permwrongvar
[stable8.1] Fix removal of share permissions when share disabled for user
2015-08-12 10:23:35 +02:00
Thomas Müller 82bffa0df2 Merge pull request #18108 from owncloud/dav-upload-updater-81
[8.1] go trough the updater when uploading over webdav
2015-08-12 10:21:09 +02:00
Thomas Müller 7c58985ca1 Merge pull request #18104 from owncloud/share-group-conflict-81
[8.1] Re-use the share entry we have for the shared storage instead of searching for it every time
2015-08-12 10:20:44 +02:00
Thomas Müller 18ec257ab2 Merge pull request #18064 from owncloud/import_root_certificates_8.1
[stable8.1] disable "ssl root certificate" settings if user can't mount external storages
2015-08-12 10:20:27 +02:00
Thomas Müller 04b409fb09 Merge pull request #17991 from owncloud/backport-correct-regex
[stable8.1] Correct regex
2015-08-12 10:20:01 +02:00
Thomas Müller 571b7f0c2c Merge pull request #17972 from owncloud/stable81-17969
[stable8.1] [admin settings] only retrieve log file size if file exists
2015-08-12 10:19:52 +02:00
Thomas Müller e94d8bbf24 Merge pull request #17957 from owncloud/stable8.1-backport-17489
[stable8.1] Fix parsing of sharetime as string
2015-08-12 10:19:31 +02:00
Thomas Müller ac04692eac Merge pull request #17951 from owncloud/backport-17464-stable8.1
[stable8.1] Backport of #17464, fix uncaught exception on not permitted file type…
2015-08-12 10:19:16 +02:00
Thomas Müller f7cb36a706 Merge pull request #17947 from owncloud/fix_move_files_8.1
[stable8.1] make sure that hooks are emitted properly on file move operation
2015-08-12 10:19:01 +02:00
michag86 c9132190ab Update installer.php 2015-08-10 18:38:22 +02:00
michag86 677bb62edf Check if archive contains a directory named like appid 2015-08-10 18:38:11 +02:00
Joas Schilling 087acc550c Correctly make use of the languageCode argument in the files activity extension 2015-08-10 14:59:51 +02:00
Frank Karlitschek ca66a705ec 8.1.1 2015-08-07 20:17:23 -04:00
Vincent Petry 89ccdcf134 Fix removal of share permissions when share disabled for user 2015-08-07 19:05:55 +02:00
Frédéric Fortier 1436baaff7 fix more review comments for #18042 / #17759 2015-08-07 09:14:55 -04:00
Frédéric Fortier 30b3b075ba Take review comments into consideration for pr #18042 / issue #17759 2015-08-07 09:14:40 -04:00
Frédéric Fortier 6e1e70439b Properly nest groups when using memberOf to detect group membership, fixes #17759 2015-08-07 09:14:28 -04:00
Robin Appelman e0a330315d go trough the updater when uploading over webdav 2015-08-06 16:58:09 +02:00
Robin Appelman b91f002baf just pass the share instead of searching for it 2015-08-06 14:30:36 +02:00
Robin Appelman cb791c7fe2 add unit tests for share target conflict with group shares 2015-08-06 14:30:25 +02:00
Thomas Müller 1a1e19f929 Merge pull request #18054 from owncloud/shared-propagate-check-recipient-stable81
[8.1] fix infinite loops with propagating etags on reshares
2015-08-05 12:01:36 +02:00
Bjoern Schiessle 6534202573 also block certificate management in the back-end if external storages are disabled for the user 2015-08-05 10:40:49 +02:00
Bjoern Schiessle a430e75425 only add the possibility to import ssl root certificates to the personal
setting if the user can mount external storages
2015-08-05 10:40:40 +02:00
Robin Appelman 78a46dcac1 fix infinite loops with propagating etags on reshares 2015-08-04 14:05:41 +02:00
C Montero-Luque 8c9b8f4fe9 8.1.1 RC1 2015-08-03 07:16:38 -04:00
Thomas Müller a0ab86bb91 Merge pull request #18013 from owncloud/enc_always_update_file_cache_8.1
[stable8.1] let the encryption storage wrapper always update the file cache
2015-08-03 12:54:01 +02:00
Björn Schießle ab16bea5c7 Merge pull request #17990 from owncloud/enc_only_update_file_cache_once_8.1
[stable8.1] only update database on the first run
2015-08-03 11:34:24 +02:00
Bjoern Schiessle 2e8f47dfb6 always update file cache, the cache can handle partial data correctly if the file doesn't already exists in the file cache 2015-07-31 17:34:01 +02:00
Bjoern Schiessle a79a15e6c5 only update database on the first run (first run = we have a version number from the old encryption app) 2015-07-31 10:50:56 +02:00
Roeland Douma cf4f43363c Merge pull request #18003 from owncloud/backport-17805-stable8.1
[stable8.1][avatar] add error handlers for avatar setup
2015-07-31 10:46:18 +02:00
Morris Jobke ef2eeae852 [avatar] add error handlers for avatar setup
add colon to translated string

use placeholder in t()

Adding a size limitation for avatar upload

Unit test for file size

Fix typo & display server side error message
2015-07-31 07:35:01 +02:00
Lukas Reschke f7360795f8 Add more unit tests 2015-07-30 16:10:28 +02:00
Lukas Reschke c61b23561b Correct regular expressions
Previously the regex was only matching on single characters. Meaning that file names such as "👍.txt" where possible while "👍" alone never was. This check apparently never worked as expected.
2015-07-30 16:10:21 +02:00
Morris Jobke 4409aed581 [admin settings] only retrieve log file size if file exists
* fixes #17467
2015-07-29 22:00:21 +01:00
Morris Jobke a9524e250a Merge pull request #17949 from owncloud/stable8.1-settings-users-apprenderedforsearchbox
[stable8.1] Trigger "apprendered" event in users page
2015-07-29 15:03:58 +02:00
Morris Jobke 42ca905d62 tests for _parseTime with hex and empty strings 2015-07-29 14:55:30 +02:00
Morris Jobke 4d6dcec751 Fix parsing of sharetime as string
In some cases the ajax/share.php will return the share time as string.
If this is the case it would get parsed completely wrong and cause the
share dropdown to not work anymore. This change will properly cast the
string to an interger and also fallback if this is not possible.
2015-07-29 14:55:21 +02:00
Arthur Schiwon 9bfbed5e0d Backport of #17464, fix uncaught exception on not permitted file types when setting avatar
refactor integration tests to make it easier to add new ones

add integration tests for avatar update

fix uncaught exception on not permitted file types when setting avatar, fixes #17232

fix test after rebasing
2015-07-29 12:45:02 +02:00
Vincent Petry c411dcd30a Trigger "apprendered" event in users page
This will properly update the controls bar width and display the search
box initially.
2015-07-29 11:35:23 +02:00
Bjoern Schiessle 2c83115a3d make sure that we emit the hooks if a file gets moved from a subfolder to the root folder with the nodes API 2015-07-29 11:07:47 +02:00
Thomas Müller 73da1ca71d Merge pull request #17935 from owncloud/detect-old-openssl-versions-stable81
[stable8.1] Detect old NSS and OpenSSL versions
2015-07-29 09:22:23 +02:00
Thomas Müller 7f5f7711ad Merge pull request #17929 from owncloud/stable8.1-smb-storageiddoubleslash
[stable8.1] Double slash for SMB storage id for compatibility
2015-07-28 23:50:31 +02:00
Vincent Petry 891a4d2ccd Merge pull request #17928 from owncloud/fix_17925_8.1
[stable8.1] set logger in constructor
2015-07-28 18:30:14 +02:00
Lukas Reschke e0b5bea50f Add unit tests 2015-07-28 16:35:55 +02:00
Lukas Reschke 3133949418 Detect old NSS and OpenSSL versions
This will detect old NSS and OpenSSL versions and show appropriate errors in the admin interface.

Fixes https://github.com/owncloud/core/issues/17901
2015-07-28 16:02:06 +02:00
Vincent Petry dcd5666601 Double slash for SMB storage id for compatibility 2015-07-28 14:30:56 +02:00
Bjoern Schiessle fc467da7d3 set logger in constructor 2015-07-28 14:21:38 +02:00
Vincent Petry a949f6c576 Merge pull request #17911 from owncloud/fix-enc-wrapper-without-encryption-stable8.1
[stable8.1] Fix enc wrapper without encryption stable8.1
2015-07-27 19:29:52 +02:00
Thomas Müller e8cbfd16a2 Merge pull request #17903 from owncloud/fix_17898_8.1
[backport 8.1] get header size before we open the file to avoid locking exception
2015-07-27 17:12:12 +02:00
Bjoern Schiessle e25a116aa6 adujust version to the stable8.1 branch 2015-07-27 16:48:58 +02:00
Bjoern Schiessle 036ba93ded add condition to update query 2015-07-27 16:09:57 +02:00
Joas Schilling b8561bda9c Add an update script to reset the value
In case encryption was not enabled, we accidently set encrypted = 1 for
files inside mount points, since 8.1.0. This breaks opening the files in
8.1.1 because we fixed the code that checks if a file is encrypted.
In order to fix the file, we need to reset the flag of the file. However,
the flag might be set because the file is in fact encrypted because it was
uploaded at a time where encryption was enabled.

So we can only do this when:
- Current version of ownCloud before the update is 8.1.0 or 8.2.0.(0-2)
- Encryption is disabled
- files_encryption is not known in the app config

If the first two are not the case, we are save. However, if files_encryption
values exist in the config, we might have a false negative here.
Now if there is no file with unencrypted size greater 0, that means there are
no files that are still encrypted with "files_encryption" encryption. So we
can also safely reset the flag here.

If this is not the case, we go with "better save then sorry" and don't change
the flag but write a message to the ownCloud log file.
2015-07-27 16:09:45 +02:00
Joas Schilling c4ddf08b79 Add a unit test for the disabled encryption case 2015-07-27 16:08:19 +02:00
Joas Schilling ef65e519ae Only set is encrypted when encryption is enabled 2015-07-27 16:08:11 +02:00
Bjoern Schiessle 4b41021fc3 get header size before we open the file to avoid locking exception 2015-07-27 14:31:06 +02:00
Thomas Müller 0ef06afc75 Merge pull request #17896 from owncloud/backport-scan-check-path
[stable8.1] check if the user is trying to scan a valid path
2015-07-27 13:40:11 +02:00
Thomas Müller 6dedef7967 Merge pull request #17883 from owncloud/backport-17882
[stable8.1] Allow classes in <h2> tags
2015-07-27 11:56:32 +02:00
Thomas Müller 1c7d737124 Merge pull request #17842 from rullzer/backport_17818
[Stable8.1] assign error message to correct object (backport #17818)
2015-07-27 11:28:15 +02:00
Lukas Reschke 4ee61f3c7a Add unit tests 2015-07-27 11:22:28 +02:00
Robin Appelman c910ac1f47 check if the user is trying to scan a valid path 2015-07-27 11:19:27 +02:00
Morris Jobke 95e44bfc4e Merge pull request #17843 from owncloud/dont-set-share-password-twice-stable8.1
Adding error handling in case setting the password fails
2015-07-27 08:56:47 +02:00
Lukas Reschke ee18718099 Allow classes in <h2> tags
Previously something like `<h2 class="inlineblock"><?php p($l->t('Some title')) ?></h2>` was shown as `<h2 class="inlineblock">Some title` within the sidebar instead as `Some Title` due to the fact that the regex was catching these classes but was not properly running the string replace function.
2015-07-26 23:02:22 +02:00
Thomas Müller 6782c6d22e Merge pull request #17853 from owncloud/sharing-password-policy-stable8.1
Sharing password policy stable8.1
2015-07-24 21:25:41 +02:00
Thomas Müller cef2680c0d Fix PHPDoc on setPassword 2015-07-24 16:49:34 +02:00
Thomas Müller e29158c892 Use a hook to integrate sharing password verification 2015-07-24 16:49:19 +02:00
Thomas Müller a53b7e3240 Adding error handling in case setting the password fails 2015-07-23 16:35:10 +02:00
michag86 74e0b6f1e5 assign error message to correct object
fix for  #17817
2015-07-23 16:17:39 +02:00
Jan-Christoph Borchardt b8e8e3fdaf Merge pull request #17832 from owncloud/improve_apps_template_8.1
[8.1 backport] make sure that there is a space between user- and admin-documentation
2015-07-23 12:29:09 +02:00
Bjoern Schiessle 965fd990fc make sure that there is a space between user- and admin-documentation 2015-07-23 11:00:10 +02:00
C Montero-Luque 3fdd5d9012 8.1.1 beta1 again 2015-07-22 17:05:14 -04:00
C Montero-Luque b4bef0214e 8.1.1 beta1 2015-07-22 16:49:28 -04:00
Thomas Müller ee85d1fd37 Merge pull request #17802 from owncloud/update-sabre-dav-2.1.6
Update SabreDAV to 2.1.6
2015-07-22 21:19:35 +02:00
Björn Schießle 77a37e076f Merge pull request #17816 from owncloud/enc_improved_app_description_8.1
[8.1 backport] improved description for the default encryption module
2015-07-22 21:01:20 +02:00
Bjoern Schiessle a07675e513 improved app description and adjust it to the way the new encryption module works 2015-07-22 16:18:10 +02:00
Joas Schilling 2b63903942 Update SabreDAV to 2.1.6 2015-07-22 12:00:29 +02:00
Joas Schilling 2bc2e974b2 Merge pull request #17752 from owncloud/enc_migration_fix_mountpoint_detection_8.1
[8.1 backport] fix system wide mount point detection on migration
2015-07-21 11:06:09 +02:00
Morris Jobke 2ecba9e5a5 Merge pull request #17762 from owncloud/backport-17723-stable8.1
Backport of #17723 to stable8.1
2015-07-21 00:30:37 +02:00
Morris Jobke dd5b347672 Merge pull request #17704 from owncloud/backport-stable8.1-17255-17526
Backport stable8.1 #17255 #17526
2015-07-21 00:01:36 +02:00
Arthur Schiwon 8be59bf7e0 Backport of #17723 to stable8.1
fix runtime caching in ldap's user manager, fixes #17631

fix indentation. no code changes, whitespace only.
2015-07-20 22:50:10 +02:00
Thomas Müller e92d427dde Merge pull request #17707 from owncloud/backport-fix-closest-stable8.1
fix browser compatibility issue for element.closest
2015-07-20 21:36:22 +02:00
Olivier Paroz 897e99ac58 Fix preview of old file on public upload conflicts 2015-07-20 16:51:28 +02:00
Bjoern Schiessle dc6cc57e11 fix mount point detection 2015-07-20 16:26:07 +02:00
Morris Jobke f1df6cd4ff Merge pull request #17736 from owncloud/backport-allow-update-of-disabled-apps
[stable8.1] Allow upgrade of not enabled apps
2015-07-20 14:24:22 +02:00
Morris Jobke ff8e63c991 Merge pull request #17711 from owncloud/fix_repeated_migration_oc8.1
[8.1 backport] Don't mix up directories if the migration runs multiple times
2015-07-20 13:58:20 +02:00
Thomas Müller d4cc4019fd Allow upgrade of not enabled apps 2015-07-19 12:16:15 +02:00
Björn Schießle 6383bd3744 Merge pull request #17702 from owncloud/enc_detect_legacy_files2_8.1
[8.1 backport] make sure that we always detect legacy files correctlly
2015-07-17 21:39:45 +02:00
Morris Jobke 738e116c00 Merge pull request #17710 from owncloud/stable8.1-s2s-catchremotelockexceptions
[Stable 8.1] s2s catchremotelockexceptions
2015-07-17 18:35:10 +02:00
Bjoern Schiessle 777964ff2b unit tests 2015-07-17 15:30:55 +02:00
Bjoern Schiessle 00a044f885 don't move keys if the key where already moved in a previous migration run 2015-07-17 15:30:43 +02:00
Vincent Petry 335372064e Throw lock exceptions if remote share returned 423 status code 2015-07-17 15:26:40 +02:00
Hendrik Leppelsack 17d7a2893e fix browser compatibility issue for element.closest 2015-07-17 15:08:45 +02:00
Morris Jobke 1b8eb668de Merge pull request #17697 from owncloud/fix-undefined-REMOTE_ADDR-stable8.1
Fixing 'Undefined index: REMOTE_ADDR' - fixes #17460
2015-07-17 14:20:57 +02:00
Arthur Schiwon a3172008c6 LDAP: when checking group for matching filter, also take base DN into consideration. Fixes #17516 2015-07-17 13:42:33 +02:00
Arthur Schiwon b2db982768 Backport of 17255 to stable8.1
ensure groups match filter when using memberOf to read users group, refs #17119

integration test

adjust unit test

tests solidity
2015-07-17 13:41:58 +02:00
Bjoern Schiessle 001dd400a1 set targetIsEncrypted to true if file cache indicates that we try to read a encrypted file 2015-07-17 13:28:58 +02:00
Bjoern Schiessle 5bfbfca266 make sure that we always detect legacy files correctly 2015-07-17 13:28:58 +02:00
Thomas Müller fc6420c290 Fixing 'Undefined index: REMOTE_ADDR' - fixes #17460 2015-07-17 12:35:00 +02:00
Thomas Müller 015d4e3ba3 Merge pull request #17690 from owncloud/stable8.1-repair-ocs-ids
[stable8.1] Add repair step for outdated OCS IDs
2015-07-17 12:02:45 +02:00
Thomas Müller deeacacfae Merge pull request #17678 from owncloud/backport-encryption_migration_improvements-stable8.1
Backport encryption migration improvements stable8.1
2015-07-17 11:58:06 +02:00
Thomas Müller d199fb4e8d Merge pull request #17679 from owncloud/backport-fix_trashbin-stable8.1
only move real files to the trash bin
2015-07-17 11:57:41 +02:00
Lukas Reschke 289fd99333 Prefer OCS Id from database
To be consistent with other logic the app id from the database needs to be prefered. Especially when it comes to be able to replace an outdated OCS id.
2015-07-17 08:33:51 +02:00
Lukas Reschke 579bee03bd Add repair step for outdated OCS IDs
There is the case where OCs IDs might become outdated such as it has been with the calendar and contacts app which refer to the old dummy entry. This means that users with the old OCS id can't update updates as well will receive invalid state flags. (e.g. "experimental" instead of "approved")

To allow instances to properly update the applications in the future we need to migrate the OCS IDs for now manually.
2015-07-16 18:52:27 +02:00
Morris Jobke 816910baf1 Merge pull request #17676 from owncloud/backport-files-scan-user-path-stable8.1
Lock scanner to the given user
2015-07-16 16:00:43 +02:00
Bjoern Schiessle fb452486d7 only move real files to the trash bin 2015-07-16 15:11:12 +02:00
Bjoern Schiessle ae1332e9c9 only create new key pair if both keys are missing 2015-07-16 14:07:26 +02:00
Bjoern Schiessle 9d9ab82a17 only cleanUp the remaining keys if the migration really finished succesfully 2015-07-16 14:07:17 +02:00
Morris Jobke edb15bd493 Merge pull request #17653 from owncloud/backport-17330-share-group-path-exception
[stable8.1] Fix the path for users which have an exception for a group share
2015-07-16 13:19:19 +02:00
Robin Appelman 4c6b26d056 Lock scanner to the given user 2015-07-16 12:14:23 +02:00
Vincent Petry 8e1fca7402 Merge pull request #17658 from owncloud/share-lock-owner-parent-stable81
[8.1] lock parent folders for the owner when locking a shared file as recipient
2015-07-16 11:59:48 +02:00
Vincent Petry db5a574faf Merge pull request #17556 from owncloud/enc_fix_migration_stable8.1
[stable8.1 backport] more secure way to update the database
2015-07-16 11:57:00 +02:00
Morris Jobke 8e0294d0fd Merge pull request #17294 from owncloud/stable8.1-s2s-catchmoreexceptiontypes
[stable8.1] Catch more error codes thrown by federated shares
2015-07-16 11:50:00 +02:00
Morris Jobke 256c57c01e Merge pull request #17337 from owncloud/stable8.1-backport-17077
[stable8.1] fix getting mount points when passing a path to the files:scan command
2015-07-15 14:51:57 +02:00
Robin Appelman db21b0964c only lock the parent folders 2015-07-15 13:43:34 +02:00
Robin Appelman cc45b49de7 lock parent folders for the owner when locking a shared file as recipient 2015-07-15 13:42:59 +02:00
Morris Jobke 90104fc5d8 Merge pull request #17643 from owncloud/stable8.1-s2s-hasupdated-catch405
[stable8.1] Throw StorageNotAvailable if propfind on root failed
2015-07-15 11:11:28 +02:00
Joas Schilling 8f2ce01553 Make sure the owner always has the right path 2015-07-15 10:12:50 +02:00
Vincent Petry 3ade5f5111 Add test case when owner renames shared folder 2015-07-15 10:12:41 +02:00
Vincent Petry 60939ebd2c Add unit test for getUsersSharingFile
This is to test if the user list and paths are correct, even when a
recipient renamed the received shared folder
2015-07-15 10:12:29 +02:00
Joas Schilling c73f938ff4 Fix the path for users which have an exception for a group share 2015-07-15 10:12:16 +02:00
Björn Schießle 06d7480fa2 Merge pull request #17642 from owncloud/stable8.1-backport-17565
[stable8.1] allow remote shares for users with email as usernames
2015-07-14 18:20:45 +02:00
Vincent Petry 48b2a4e034 Throw StorageNotAvailable if propfind on root failed
If PROPFIND fails with 404 or 405 on the remote share root, it means the
storage is not available. Throw StorageNotAvailable is such case.
2015-07-14 17:41:58 +02:00
Felix Böhm 824df7e22d allow remote shares for users with email as usernames 2015-07-14 15:33:12 +02:00
Vincent Petry ab308d246a Merge pull request #17632 from owncloud/stable8.1-backport-17606
[stable8.1] Handle returned null value in app level code
2015-07-14 11:44:06 +02:00
Morris Jobke dc9454ea3c Handle returned null value in app level code
* getApplication on OCSClient can also return null
  this is now handled properly
* fixes #17587
2015-07-14 08:58:28 +02:00
Vincent Petry f920923dd6 Throw storage not available on guzzle error
If the remote server is in maintenance mode, we must throw storage not
available exception instead of not found which might auto-remove the
share.
2015-07-13 18:55:24 +02:00
Thomas Müller 698e2ebc90 Merge pull request #17607 from owncloud/stable8.1-backport-17426
[stable8.1] [config sample] Update info about appstore
2015-07-13 17:40:54 +02:00
Morris Jobke 1548d69762 [config sample] Update info about appstore 2015-07-13 14:52:38 +02:00
Bjoern Schiessle 8466d9d235 more secure way to update the database 2015-07-10 11:49:51 +02:00
Morris Jobke 48b1e9e2a6 Merge pull request #17288 from owncloud/stable8.1-chunk-cleanupgracefulonlock
Stable8.1 chunk cleanupgracefulonlock
2015-07-09 22:31:40 +02:00
Morris Jobke f21eb35431 Merge pull request #17518 from owncloud/stable8.1-backport-config-sample
[stable8.1] backport config sample
2015-07-09 14:30:05 +02:00
Morris Jobke 509725fad9 [config sample] improve RST markup and wording 2015-07-09 10:09:11 +02:00
Morris Jobke 447c60c4e4 refine sample config text 2015-07-09 10:06:06 +02:00
Morris Jobke eb055b0d78 [config sample] merge Miscellaneous & All other options 2015-07-09 10:06:01 +02:00
Morris Jobke d48d59661a Merge pull request #17289 from owncloud/stable8.1-files-cleanuppartfileonlyonce
Stable8.1 files cleanuppartfileonlyonce
2015-07-08 10:34:55 +02:00
Morris Jobke 312d82fe71 Merge pull request #17332 from owncloud/fix-temporary-mountpoint-name-in-activities
Fix the mount point name before creating the activities
2015-07-08 10:33:15 +02:00
Morris Jobke 96b97d1567 Merge pull request #17338 from owncloud/stable8.1-backport-17252
[stable8.1] Only do the description kung-fu on strings - fixes #17028
2015-07-08 10:32:53 +02:00
Morris Jobke 97e49e422f Merge pull request #17366 from owncloud/fix_16740_8.1
[oc8.1] owner is stored as 'uid_owner', not as 'owner' in the oc_share table
2015-07-08 10:32:30 +02:00
Morris Jobke 5d3d44eeb9 Merge pull request #17370 from owncloud/stable8.1-share-onlyshowstaticownerifavailable
[stable8.1] Do not show static share owner if not available
2015-07-08 10:31:33 +02:00
Morris Jobke 51978aa296 Merge pull request #17417 from owncloud/stable8.1-backport-17159
[stable8.1] remove duplicate ID in HTML template for public shares
2015-07-08 10:31:11 +02:00
Morris Jobke 3823713c7c Merge pull request #17429 from owncloud/stable8.1-backport-17088
[stable8.1] [upgrade] add verbosity check and show repair info & steps
2015-07-08 10:29:16 +02:00
Thomas Müller 3854dead08 Merge pull request #17431 from owncloud/stable8.1-update-readme
[stable8.1] Update readme versions
2015-07-07 10:33:36 +02:00
Vincent Petry ce0f391ecd Update README version and bower 2015-07-07 10:22:36 +02:00
Morris Jobke 388409290a [Repair] add repair info for changed collation 2015-07-07 10:16:54 +02:00
Morris Jobke fb85fc619d [upgrade] add verbosity check and show repair info & steps 2015-07-07 10:16:49 +02:00
Morris Jobke d5e90e7239 remove duplicate ID in HTML template for public shares 2015-07-06 13:34:11 +02:00
Vincent Petry c04beb0bad Do not show static share owner if not available
In some corner cases, an outgoing share exists but sharing is not
allowed for the current user. This would cause the file list to break
because the static text could not be rendered as the owner was
undefined.
2015-07-03 11:54:50 +02:00
Bjoern Schiessle 9def2fcf71 call post_addToGroup als for class OC_User because sharing and LDAP are using this class. Minimal approach to fix #16740 2015-07-03 10:36:09 +02:00
Bjoern Schiessle 1427a79643 owner is stored as 'uid_owner', not as 'owner' in the oc_share table 2015-07-03 10:36:01 +02:00
C Montero-Luque 06ec916b11 8.1.0 2015-07-02 18:20:11 -04:00
Lukas Reschke 7d94d963e9 Merge pull request #17356 from owncloud/stable8.1-apps-keepgloballist
[stable8.1] Fix global app list state
2015-07-02 21:37:41 +02:00
Vincent Petry c051c180ab Fix global app list state 2015-07-02 17:31:22 +02:00
Lukas Reschke 9cba7c1793 Merge pull request #17317 from owncloud/stable81-clean-ocsid
[stable8.1] Delete OCS ID from DB if none is specified
2015-07-02 14:15:27 +02:00
Lukas Reschke 16514762bf Merge pull request #17311 from owncloud/stable81-remove-ocs-ids
[stable8.1] Remove OCS IDs
2015-07-02 14:15:19 +02:00
Thomas Müller 2727d9797d Only do the description kung-fu on strings - fixes #17028 2015-07-02 13:16:47 +02:00
Robin Appelman a95b5c3b3e handle invalid results from mount providers 2015-07-02 13:03:09 +02:00
Robin Appelman 1902101923 handle error during setup 2015-07-02 13:03:06 +02:00
Robin Appelman 8a3f54c225 add unit test 2015-07-02 13:03:03 +02:00
Robin Appelman 478fe752e7 fix getting mount points when passing a path to the files:scan command 2015-07-02 13:02:59 +02:00
Joas Schilling ea731c5c66 Use the item name when refering to the unaccepted remote share 2015-07-02 12:35:30 +02:00
Björn Schießle caa3210a59 Merge pull request #17308 from owncloud/stable8.1-backport-17293
Stable8.1 backport 17293
2015-07-02 12:17:56 +02:00
Lukas Reschke 8fe5d4b268 Bump versions 2015-07-02 09:20:25 +02:00
Lukas Reschke 85fc84e3d3 Delete OCS ID from DB if none is specified
If no OCS ID is specified in appinfo.xml and an app update is triggered and a OCS ID is stored in the DB we should clean the value.

Ref https://github.com/owncloud/activity/issues/320#issuecomment-117937748
2015-07-02 09:20:21 +02:00
Lukas Reschke 6008bf975d [stable81] Remove OCS IDs
While making the AppStore ready for 8.1 I also deleted some dummy entries which means that these IDs do not resolve anymore. We should remove them to prevent errors such as https://github.com/owncloud/core/issues/17307

Ref https://github.com/owncloud/activity/issues/320#issuecomment-117691867
2015-07-02 08:47:31 +02:00
Jan-Christoph Borchardt 4abec8b5b9 Revert "fix z-index of share-autocomplete"
This reverts commit 4edf388a38.
2015-07-02 08:24:04 +02:00
Jan-Christoph Borchardt d6cbf8be71 Revert "explicitly set z-index on app-content, fix overlap from navigation"
This reverts commit 71e5bc1803.
2015-07-02 08:23:58 +02:00
Vincent Petry 2d92b5a64e Catch more error codes thrown by federated shares
Most of the time it doesn't make sense to forward Guzzle's
RequestException, so we convert it to StorageNotAvailable instead.

This prevents unpredictable error codes to block access to unrelated
folders needlessly.
2015-07-01 16:23:57 +02:00
Thomas Müller d6b24c7bbc Merge pull request #17266 from owncloud/stable8.1-backport-17224
Stable8.1 backport 17224
2015-07-01 16:12:55 +02:00
Vincent Petry 4aa2eff94c Only delete part file on error if it is really a part file 2015-07-01 15:25:17 +02:00
Vincent Petry 4fff832fa6 Clean up part file only once, not twice on error 2015-07-01 15:25:09 +02:00
Vincent Petry 39e391fd1a Catch cache garbage collection exception on postLogin
Just log the exception instead of preventing access to OC.
2015-07-01 15:19:46 +02:00
Vincent Petry e48afaf334 Test for chunk cache garbage collection 2015-07-01 15:19:43 +02:00
Vincent Petry 18e4fe7add Do not try clearing locked files in cache folder 2015-07-01 15:19:38 +02:00
Morris Jobke c7bc669e00 Merge pull request #17267 from owncloud/stable8.1-backport-17264
Use UTF-8 mode for preg_split and preg_replace
2015-07-01 09:13:48 +02:00
Lukas Reschke 09038697cd Use UTF-8 mode for preg_split and preg_replace
Otherwise a single application with a description containing a non compliant character can break the whole ownCloud appstore. This is for example https://apps.owncloud.com/content/show.php?content=149553

Fixes https://github.com/owncloud/core/issues/17101#issuecomment-117365224
2015-07-01 07:52:40 +02:00
Thomas Müller eb2e8d99cc Avoid namespace clash 2015-07-01 07:48:35 +02:00
Thomas Müller 82493e9789 Fixing content type detection and handle all local printErrorPage calls 2015-07-01 07:48:31 +02:00
Thomas Müller 526a45be18 Adding request specific exception handling - now with WebDAV responses - refs #17192 2015-07-01 07:48:27 +02:00
Thomas Müller 283f8e7e69 Adding exception handling for ServerNotAvailableException - refs #17192 2015-07-01 07:48:23 +02:00
330 changed files with 9059 additions and 2971 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# Version: 8.1.0
# Version: 8.1.10
<IfModule mod_headers.c>
<IfModule mod_fcgid.c>
<IfModule mod_setenvif.c>
+23
View File
@@ -0,0 +1,23 @@
sudo: false
language: php
php:
- 5.4
branches:
only:
- master
- /^stable\d+(\.\d+)?$/
script:
- sh -c "if [ '$TC' = 'syntax' ]; then composer install && vendor/bin/parallel-lint --exclude vendor/jakub-onderka/ --exclude 3rdparty/patchwork/utf8/class/Patchwork/Utf8/Bootup/ --exclude vendor/composer/autoload_static.php --exclude 3rdparty/composer/autoload_static.php .; fi"
matrix:
include:
- php: 5.4
env: DB=sqlite;TC=syntax
- php: 5.5
env: DB=sqlite;TC=syntax
- php: 5.6
env: DB=sqlite;TC=syntax
fast_finish: true
Vendored
+87
View File
@@ -0,0 +1,87 @@
#!groovy
/*
* This Jenkinsfile is intended to run on https://ci.owncloud.org and may fail anywhere else.
* It makes assumptions about plugins being installed, labels mapping to nodes that can build what is needed, etc.
*/
timestampedNode('SLAVE') {
stage 'Checkout'
checkout scm
sh '''git submodule update --init'''
stage 'JavaScript Testing'
executeAndReport('tests/autotest-results-js.xml') {
sh '''./autotest-js.sh'''
}
stage 'PHPUnit'
executeAndReport('tests/autotest-results-sqlite.xml') {
sh '''
export NOCOVERAGE=1
unset USEDOCKER
phpenv local 5.6
./autotest.sh sqlite
'''
}
executeAndReport('tests/autotest-results-mysql.xml') {
sh '''
export NOCOVERAGE=1
unset USEDOCKER
phpenv local 5.4
./autotest.sh mysql
'''
}
executeAndReport('tests/autotest-results-pgsql.xml') {
sh '''
export NOCOVERAGE=1
unset USEDOCKER
phpenv local 5.6
./autotest.sh pgsql
'''
}
executeAndReport('tests/autotest-results-oci.xml') {
sh '''
export NOCOVERAGE=1
unset USEDOCKER
phpenv local 5.5
./autotest.sh oci
'''
}
stage 'Files External Testing'
executeAndReport('tests/autotest-external-results-sqlite-webdav-ownCloud.xml') {
sh '''phpenv local 5.6
export NOCOVERAGE=1
unset USEDOCKER
./autotest-external.sh sqlite webdav-ownCloud
'''
}
}
void executeAndReport(String testResultLocation, def body) {
def failed = false
// We're wrapping this in a timeout - if it takes longer, kill it.
try {
timeout(time: 120, unit: 'MINUTES') {
body.call()
}
} catch (Exception e) {
failed = true
echo "Test execution failed: ${e}"
} finally {
step([$class: 'JUnitResultArchiver', testResults: testResultLocation])
}
if (failed) {
error "Test execution failed. Terminating the build"
}
}
// Runs the given body within a Timestamper wrapper on the given label.
def timestampedNode(String label, Closure body) {
node(label) {
wrap([$class: 'TimestamperBuildWrapper']) {
body.call()
}
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ Depencencies:
[![Dependency Status](https://www.versioneye.com/user/projects/54d1f76f3ca0840b190000c0/badge.svg?style=flat)](https://www.versioneye.com/user/projects/54d1f76f3ca0840b190000c0)
### Installation instructions
https://doc.owncloud.org/server/8.0/developer_manual/app/index.html
https://doc.owncloud.org/server/8.1/developer_manual/app/index.html
### Contribution Guidelines
https://owncloud.org/contribute/
@@ -35,4 +35,4 @@ https://www.transifex.com/projects/p/owncloud/
[![Transifex](https://www.transifex.com/projects/p/owncloud/resource/core/chart/image_png)](https://www.transifex.com/projects/p/owncloud/)
For more detailed information about translations:
http://doc.owncloud.org/server/8.0/developer_manual/core/translation.html
http://doc.owncloud.org/server/8.1/developer_manual/core/translation.html
+3 -1
View File
@@ -81,6 +81,7 @@ class Application extends \OCP\AppFramework\App {
$hookManager->registerHook([
new UserHooks($container->query('KeyManager'),
$server->getUserManager(),
$server->getLogger(),
$container->query('UserSetup'),
$server->getUserSession(),
@@ -195,7 +196,8 @@ class Application extends \OCP\AppFramework\App {
$server->getUserSession(),
$c->query('KeyManager'),
$c->query('Crypt'),
$c->query('Session')
$c->query('Session'),
$server->getSession()
);
});
+8 -13
View File
@@ -2,19 +2,14 @@
<info>
<id>encryption</id>
<description>
This application encrypts all files accessed by ownCloud at rest,
wherever they are stored. As an example, with this application
enabled, external cloud based Amazon S3 storage will be encrypted,
protecting this data on storage outside of the control of the Admin.
When this application is enabled for the first time, all files are
encrypted as users log in and are prompted for their password. The
recommended recovery key option enables recovery of files in case
the key is lost.
Note that this app encrypts all files that are touched by ownCloud,
so external storage providers and applications such as SharePoint
will see new files encrypted when they are accessed. Encryption is
based on AES 128 or 256 bit keys. More information is available in
the Encryption documentation
In order to use this encryption module you need to enable server-side
encryption in the admin settings. Once enabled this module will encrypt
all your files transparently. The encryption is based on AES 256 keys.
The module won't touch existing files, only new files will be encrypted
after server-side encryption was enabled. It is also not possible to
disable the encryption again and switch back to a unencrypted system.
Please read the documentation to know all implications before you decide
to enable server-side encryption.
</description>
<name>Default encryption module</name>
<license>AGPL</license>
+2 -1
View File
@@ -26,4 +26,5 @@ $userManager = OC::$server->getUserManager();
$view = new \OC\Files\View();
$config = \OC::$server->getConfig();
$connection = \OC::$server->getDatabaseConnection();
$application->add(new MigrateKeys($userManager, $view, $connection, $config));
$logger = \OC::$server->getLogger();
$application->add(new MigrateKeys($userManager, $view, $connection, $config, $logger));
+10 -2
View File
@@ -27,6 +27,7 @@ use OC\Files\View;
use OC\User\Manager;
use OCA\Encryption\Migration;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IUserBackend;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
@@ -44,22 +45,27 @@ class MigrateKeys extends Command {
private $connection;
/** @var IConfig */
private $config;
/** @var ILogger */
private $logger;
/**
* @param Manager $userManager
* @param View $view
* @param Connection $connection
* @param IConfig $config
* @param ILogger $logger
*/
public function __construct(Manager $userManager,
View $view,
Connection $connection,
IConfig $config) {
IConfig $config,
ILogger $logger) {
$this->userManager = $userManager;
$this->view = $view;
$this->connection = $connection;
$this->config = $config;
$this->logger = $logger;
parent::__construct();
}
@@ -77,7 +83,7 @@ class MigrateKeys extends Command {
protected function execute(InputInterface $input, OutputInterface $output) {
// perform system reorganization
$migration = new Migration($this->config, $this->view, $this->connection);
$migration = new Migration($this->config, $this->view, $this->connection, $this->logger);
$users = $input->getArgument('user_id');
if (!empty($users)) {
@@ -115,5 +121,7 @@ class MigrateKeys extends Command {
}
}
$migration->finalCleanUp();
}
}
@@ -31,6 +31,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\IL10N;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUserManager;
use OCP\IUserSession;
@@ -54,6 +55,9 @@ class SettingsController extends Controller {
/** @var Session */
private $session;
/** @var ISession */
private $ocSession;
/**
* @param string $AppName
* @param IRequest $request
@@ -63,6 +67,7 @@ class SettingsController extends Controller {
* @param KeyManager $keyManager
* @param Crypt $crypt
* @param Session $session
* @param ISession $ocSession
*/
public function __construct($AppName,
IRequest $request,
@@ -71,7 +76,8 @@ class SettingsController extends Controller {
IUserSession $userSession,
KeyManager $keyManager,
Crypt $crypt,
Session $session) {
Session $session,
ISession $ocSession) {
parent::__construct($AppName, $request);
$this->l = $l10n;
$this->userSession = $userSession;
@@ -79,6 +85,7 @@ class SettingsController extends Controller {
$this->keyManager = $keyManager;
$this->crypt = $crypt;
$this->session = $session;
$this->ocSession = $ocSession;
}
@@ -97,6 +104,13 @@ class SettingsController extends Controller {
//check if password is correct
$passwordCorrect = $this->userManager->checkPassword($uid, $newPassword);
if ($passwordCorrect === false) {
// if check with uid fails we need to check the password with the login name
// e.g. in the ldap case. For local user we need to check the password with
// the uid because in this case the login name is case insensitive
$loginName = $this->ocSession->get('loginname');
$passwordCorrect = $this->userManager->checkPassword($loginName, $newPassword);
}
if ($passwordCorrect !== false) {
$encryptedKey = $this->keyManager->getPrivateKey($uid);
+20 -1
View File
@@ -24,6 +24,8 @@
namespace OCA\Encryption\Hooks;
use OC\Files\Filesystem;
use OCP\IUserManager;
use OCP\Util as OCUtil;
use OCA\Encryption\Hooks\Contracts\IHook;
use OCA\Encryption\KeyManager;
@@ -41,6 +43,10 @@ class UserHooks implements IHook {
* @var KeyManager
*/
private $keyManager;
/**
* @var IUserManager
*/
private $userManager;
/**
* @var ILogger
*/
@@ -74,6 +80,7 @@ class UserHooks implements IHook {
* UserHooks constructor.
*
* @param KeyManager $keyManager
* @param IUserManager $userManager
* @param ILogger $logger
* @param Setup $userSetup
* @param IUserSession $user
@@ -83,6 +90,7 @@ class UserHooks implements IHook {
* @param Recovery $recovery
*/
public function __construct(KeyManager $keyManager,
IUserManager $userManager,
ILogger $logger,
Setup $userSetup,
IUserSession $user,
@@ -92,6 +100,7 @@ class UserHooks implements IHook {
Recovery $recovery) {
$this->keyManager = $keyManager;
$this->userManager = $userManager;
$this->logger = $logger;
$this->userSetup = $userSetup;
$this->user = $user;
@@ -196,7 +205,7 @@ class UserHooks implements IHook {
public function preSetPassphrase($params) {
if (App::isEnabled('encryption')) {
$user = $this->user->getUser();
$user = $this->userManager->get($params['uid']);
if ($user && !$user->canChangePassword()) {
$this->setPassphrase($params);
@@ -236,6 +245,7 @@ class UserHooks implements IHook {
// used to decrypt it has changed
} else { // admin changed the password for a different user, create new keys and re-encrypt file keys
$user = $params['uid'];
$this->initMountPoints($user);
$recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
// we generate new keys if...
@@ -275,6 +285,15 @@ class UserHooks implements IHook {
}
}
/**
* init mount points for given user
*
* @param string $user
* @throws \OC\User\NoUserException
*/
protected function initMountPoints($user) {
Filesystem::initMountPoints($user);
}
/**
+4 -4
View File
@@ -49,7 +49,7 @@ class Crypt {
*/
private $logger;
/**
* @var IUser
* @var string
*/
private $user;
/**
@@ -64,7 +64,7 @@ class Crypt {
*/
public function __construct(ILogger $logger, IUserSession $userSession, IConfig $config) {
$this->logger = $logger;
$this->user = $userSession && $userSession->isLoggedIn() ? $userSession->getUser() : false;
$this->user = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : '"no user given"';
$this->config = $config;
}
@@ -79,7 +79,7 @@ class Crypt {
$res = $this->getOpenSSLPKey();
if (!$res) {
$log->error("Encryption Library couldn't generate users key-pair for {$this->user->getUID()}",
$log->error("Encryption Library couldn't generate users key-pair for {$this->user}",
['app' => 'encryption']);
if (openssl_error_string()) {
@@ -98,7 +98,7 @@ class Crypt {
'privateKey' => $privateKey
];
}
$log->error('Encryption library couldn\'t export users private key, please check your servers OpenSSL configuration.' . $this->user->getUID(),
$log->error('Encryption library couldn\'t export users private key, please check your servers OpenSSL configuration.' . $this->user,
['app' => 'encryption']);
if (openssl_error_string()) {
$log->error('Encryption Library:' . openssl_error_string(),
+5 -1
View File
@@ -311,7 +311,11 @@ class Encryption implements IEncryptionModule {
$publicKeys = array();
foreach ($accessList['users'] as $user) {
$publicKeys[$user] = $this->keyManager->getPublicKey($user);
try {
$publicKeys[$user] = $this->keyManager->getPublicKey($user);
} catch (PublicKeyMissingException $e) {
$this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage());
}
}
$publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid);
+23 -6
View File
@@ -406,19 +406,36 @@ class KeyManager {
}
/**
* @param $userId
* check if user has a private and a public key
*
* @param string $userId
* @return bool
* @throws PrivateKeyMissingException
* @throws PublicKeyMissingException
*/
public function userHasKeys($userId) {
$privateKey = $publicKey = true;
try {
$this->getPrivateKey($userId);
$this->getPublicKey($userId);
} catch (PrivateKeyMissingException $e) {
return false;
} catch (PublicKeyMissingException $e) {
return false;
$privateKey = false;
$exception = $e;
}
try {
$this->getPublicKey($userId);
} catch (PublicKeyMissingException $e) {
$publicKey = false;
$exception = $e;
}
if ($privateKey && $publicKey) {
return true;
} elseif (!$privateKey && !$publicKey) {
return false;
} else {
throw $exception;
}
return true;
}
/**
+105 -35
View File
@@ -26,6 +26,7 @@ namespace OCA\Encryption;
use OC\DB\Connection;
use OC\Files\View;
use OCP\IConfig;
use OCP\ILogger;
class Migration {
@@ -36,21 +37,28 @@ class Migration {
private $connection;
/** @var IConfig */
private $config;
/** @var ILogger */
private $logger;
/** @var string*/
protected $installedVersion;
/**
* @param IConfig $config
* @param View $view
* @param Connection $connection
* @param ILogger $logger
*/
public function __construct(IConfig $config, View $view, Connection $connection) {
public function __construct(IConfig $config, View $view, Connection $connection, ILogger $logger) {
$this->view = $view;
$this->view->getUpdater()->disable();
$this->connection = $connection;
$this->moduleId = \OCA\Encryption\Crypto\Encryption::ID;
$this->config = $config;
$this->logger = $logger;
$this->installedVersion = $this->config->getAppValue('files_encryption', 'installed_version', '-1');
}
public function __destruct() {
public function finalCleanUp() {
$this->view->deleteAll('files_encryption/public_keys');
$this->updateFileCache();
$this->config->deleteAppValue('files_encryption', 'installed_version');
@@ -60,12 +68,16 @@ class Migration {
* update file cache, copy unencrypted_size to the 'size' column
*/
private function updateFileCache() {
$query = $this->connection->createQueryBuilder();
$query->update('`*PREFIX*filecache`')
->set('`size`', '`unencrypted_size`')
->where($query->expr()->eq('`encrypted`', ':encrypted'))
->setParameter('encrypted', 1);
$query->execute();
// make sure that we don't update the file cache multiple times
// only update during the first run
if ($this->installedVersion !== '-1') {
$query = $this->connection->createQueryBuilder();
$query->update('`*PREFIX*filecache`')
->set('`size`', '`unencrypted_size`')
->where($query->expr()->eq('`encrypted`', ':encrypted'))
->setParameter('encrypted', 1);
$query->execute();
}
}
/**
@@ -138,27 +150,43 @@ class Migration {
*/
public function updateDB() {
// make sure that we don't update the file cache multiple times
// only update during the first run
if ($this->installedVersion === '-1') {
return;
}
// delete left-over from old encryption which is no longer needed
$this->config->deleteAppValue('files_encryption', 'ocsid');
$this->config->deleteAppValue('files_encryption', 'types');
$this->config->deleteAppValue('files_encryption', 'enabled');
$oldAppValues = $this->connection->createQueryBuilder();
$oldAppValues->select('*')
->from('`*PREFIX*appconfig`')
->where($oldAppValues->expr()->eq('`appid`', ':appid'))
->setParameter('appid', 'files_encryption');
$appSettings = $oldAppValues->execute();
$query = $this->connection->createQueryBuilder();
$query->update('`*PREFIX*appconfig`')
->set('`appid`', ':newappid')
->where($query->expr()->eq('`appid`', ':oldappid'))
->setParameter('oldappid', 'files_encryption')
->setParameter('newappid', 'encryption');
$query->execute();
while ($row = $appSettings->fetch()) {
// 'installed_version' gets deleted at the end of the migration process
if ($row['configkey'] !== 'installed_version' ) {
$this->config->setAppValue('encryption', $row['configkey'], $row['configvalue']);
$this->config->deleteAppValue('files_encryption', $row['configkey']);
}
}
$query = $this->connection->createQueryBuilder();
$query->update('`*PREFIX*preferences`')
->set('`appid`', ':newappid')
->where($query->expr()->eq('`appid`', ':oldappid'))
->setParameter('oldappid', 'files_encryption')
->setParameter('newappid', 'encryption');
$query->execute();
$oldPreferences = $this->connection->createQueryBuilder();
$oldPreferences->select('*')
->from('`*PREFIX*preferences`')
->where($oldPreferences->expr()->eq('`appid`', ':appid'))
->setParameter('appid', 'files_encryption');
$preferenceSettings = $oldPreferences->execute();
while ($row = $preferenceSettings->fetch()) {
$this->config->setUserValue($row['userid'], 'encryption', $row['configkey'], $row['configvalue']);
$this->config->deleteUserValue($row['userid'], 'files_encryption', $row['configkey']);
}
}
/**
@@ -224,9 +252,10 @@ class Migration {
private function renameUsersPrivateKey($user) {
$oldPrivateKey = $user . '/files_encryption/' . $user . '.privateKey';
$newPrivateKey = $user . '/files_encryption/' . $this->moduleId . '/' . $user . '.privateKey';
$this->createPathForKeys(dirname($newPrivateKey));
$this->view->rename($oldPrivateKey, $newPrivateKey);
if ($this->view->file_exists($oldPrivateKey)) {
$this->createPathForKeys(dirname($newPrivateKey));
$this->view->rename($oldPrivateKey, $newPrivateKey);
}
}
/**
@@ -237,9 +266,10 @@ class Migration {
private function renameUsersPublicKey($user) {
$oldPublicKey = '/files_encryption/public_keys/' . $user . '.publicKey';
$newPublicKey = $user . '/files_encryption/' . $this->moduleId . '/' . $user . '.publicKey';
$this->createPathForKeys(dirname($newPublicKey));
$this->view->rename($oldPublicKey, $newPublicKey);
if ($this->view->file_exists($oldPublicKey)) {
$this->createPathForKeys(dirname($newPublicKey));
$this->view->rename($oldPublicKey, $newPublicKey);
}
}
/**
@@ -251,6 +281,11 @@ class Migration {
*/
private function renameFileKeys($user, $path, $trash = false) {
if ($this->view->is_dir($user . '/' . $path) === false) {
$this->logger->info('Skip dir /' . $user . '/' . $path . ': does not exist');
return;
}
$dh = $this->view->opendir($user . '/' . $path);
if (is_resource($dh)) {
@@ -260,8 +295,15 @@ class Migration {
$this->renameFileKeys($user, $path . '/' . $file, $trash);
} else {
$target = $this->getTargetDir($user, $path, $file, $trash);
$this->createPathForKeys(dirname($target));
$this->view->rename($user . '/' . $path . '/' . $file, $target);
if ($target !== false) {
$this->createPathForKeys(dirname($target));
$this->view->rename($user . '/' . $path . '/' . $file, $target);
} else {
$this->logger->warning(
'did not move key "' . $file
. '" could not find the corresponding file in /data/' . $user . '/files.'
. 'Most likely the key was already moved in a previous migration run and is already on the right place.');
}
}
}
}
@@ -269,23 +311,51 @@ class Migration {
}
}
/**
* get system mount points
* wrap static method so that it can be mocked for testing
*
* @internal
* @return array
*/
protected function getSystemMountPoints() {
return \OC_Mount_Config::getSystemMountPoints();
}
/**
* generate target directory
*
* @param string $user
* @param string $filePath
* @param string $keyPath
* @param string $filename
* @param bool $trash
* @return string
*/
private function getTargetDir($user, $filePath, $filename, $trash) {
private function getTargetDir($user, $keyPath, $filename, $trash) {
if ($trash) {
$targetDir = $user . '/files_encryption/keys/files_trashbin/' . substr($filePath, strlen('/files_trashbin/keys/')) . '/' . $this->moduleId . '/' . $filename;
$filePath = substr($keyPath, strlen('/files_trashbin/keys/'));
$targetDir = $user . '/files_encryption/keys/files_trashbin/' . $filePath . '/' . $this->moduleId . '/' . $filename;
} else {
$targetDir = $user . '/files_encryption/keys/files/' . substr($filePath, strlen('/files_encryption/keys/')) . '/' . $this->moduleId . '/' . $filename;
$filePath = substr($keyPath, strlen('/files_encryption/keys/'));
$targetDir = $user . '/files_encryption/keys/files/' . $filePath . '/' . $this->moduleId . '/' . $filename;
}
return $targetDir;
if ($user === '') {
// for system wide mounts we need to check if the mount point really exists
$normalized = \OC\Files\Filesystem::normalizePath($filePath);
$systemMountPoints = $this->getSystemMountPoints();
foreach ($systemMountPoints as $mountPoint) {
$normalizedMountPoint = \OC\Files\Filesystem::normalizePath($mountPoint['mountpoint']) . '/';
if (strpos($normalized, $normalizedMountPoint) === 0)
return $targetDir;
}
} else if ($trash === false && $this->view->file_exists('/' . $user. '/files/' . $filePath)) {
return $targetDir;
} else if ($trash === true && $this->view->file_exists('/' . $user. '/files_trashbin/' . $filePath)) {
return $targetDir;
}
return false;
}
/**
@@ -54,6 +54,9 @@ class SettingsControllerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $sessionMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $ocSessionMock;
protected function setUp() {
parent::setUp();
@@ -91,9 +94,11 @@ class SettingsControllerTest extends TestCase {
])
->getMock();
$this->ocSessionMock = $this->getMockBuilder('\OCP\ISession')->disableOriginalConstructor()->getMock();
$this->userSessionMock->expects($this->any())
->method('getUID')
->willReturn('testUser');
->willReturn('testUserUid');
$this->userSessionMock->expects($this->any())
->method($this->anything())
@@ -110,7 +115,8 @@ class SettingsControllerTest extends TestCase {
$this->userSessionMock,
$this->keyManagerMock,
$this->cryptMock,
$this->sessionMock
$this->sessionMock,
$this->ocSessionMock
);
}
@@ -122,8 +128,10 @@ class SettingsControllerTest extends TestCase {
$oldPassword = 'old';
$newPassword = 'new';
$this->userSessionMock->expects($this->once())->method('getUID')->willReturn('uid');
$this->userManagerMock
->expects($this->once())
->expects($this->exactly(2))
->method('checkPassword')
->willReturn(false);
@@ -171,16 +179,22 @@ class SettingsControllerTest extends TestCase {
$oldPassword = 'old';
$newPassword = 'new';
$this->userSessionMock
->expects($this->once())
->method('getUID')
->willReturn('testUser');
$this->ocSessionMock->expects($this->once())
->method('get')->with('loginname')->willReturn('testUser');
$this->userManagerMock
->expects($this->once())
->expects($this->at(0))
->method('checkPassword')
->with('testUserUid', 'new')
->willReturn(false);
$this->userManagerMock
->expects($this->at(1))
->method('checkPassword')
->with('testUser', 'new')
->willReturn(true);
$this->cryptMock
->expects($this->once())
->method('decryptPrivateKey')
@@ -200,7 +214,7 @@ class SettingsControllerTest extends TestCase {
$this->keyManagerMock
->expects($this->once())
->method('setPrivateKey')
->with($this->equalTo('testUser'), $this->equalTo('header.encryptedKey'));
->with($this->equalTo('testUserUid'), $this->equalTo('header.encryptedKey'));
$this->sessionMock
->expects($this->once())
+97 -13
View File
@@ -30,6 +30,12 @@ use OCA\Encryption\Crypto\Crypt;
use OCA\Encryption\Hooks\UserHooks;
use Test\TestCase;
/**
* Class UserHooksTest
*
* @group DB
* @package OCA\Encryption\Tests\Hooks
*/
class UserHooksTest extends TestCase {
/**
* @var \PHPUnit_Framework_MockObject_MockObject
@@ -47,6 +53,11 @@ class UserHooksTest extends TestCase {
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $keyManagerMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $userManagerMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
@@ -101,11 +112,58 @@ class UserHooksTest extends TestCase {
$this->assertNull($this->instance->postDeleteUser($this->params));
}
public function testPreSetPassphrase() {
$this->userSessionMock->expects($this->once())
->method('canChangePassword');
/**
* @dataProvider dataTestPreSetPassphrase
*/
public function testPreSetPassphrase($canChange) {
$this->assertNull($this->instance->preSetPassphrase($this->params));
/** @var UserHooks | \PHPUnit_Framework_MockObject_MockObject $instance */
$instance = $this->getMockBuilder('OCA\Encryption\Hooks\UserHooks')
->setConstructorArgs(
[
$this->keyManagerMock,
$this->userManagerMock,
$this->loggerMock,
$this->userSetupMock,
$this->userSessionMock,
$this->utilMock,
$this->sessionMock,
$this->cryptMock,
$this->recoveryMock
]
)
->setMethods(['setPassphrase'])
->getMock();
$userMock = $this->getMock('OCP\IUser');
$this->userManagerMock->expects($this->once())
->method('get')
->with($this->params['uid'])
->willReturn($userMock);
$userMock->expects($this->once())
->method('canChangePassword')
->willReturn($canChange);
if ($canChange) {
// in this case the password will be changed in the post hook
$instance->expects($this->never())->method('setPassphrase');
} else {
// if user can't change the password we update the encryption
// key password already in the pre hook
$instance->expects($this->once())
->method('setPassphrase')
->with($this->params);
}
$instance->preSetPassphrase($this->params);
}
public function dataTestPreSetPassphrase() {
return [
[true],
[false]
];
}
public function testSetPassphrase() {
@@ -139,6 +197,23 @@ class UserHooksTest extends TestCase {
->willReturnOnConsecutiveCalls(true, false);
$this->instance = $this->getMockBuilder('OCA\Encryption\Hooks\UserHooks')
->setConstructorArgs(
[
$this->keyManagerMock,
$this->userManagerMock,
$this->loggerMock,
$this->userSetupMock,
$this->userSessionMock,
$this->utilMock,
$this->sessionMock,
$this->cryptMock,
$this->recoveryMock
]
)->setMethods(['initMountPoints'])->getMock();
$this->instance->expects($this->exactly(3))->method('initMountPoints');
// Test first if statement
$this->assertNull($this->instance->setPassphrase($this->params));
@@ -185,15 +260,20 @@ class UserHooksTest extends TestCase {
->with('testUser')
->willReturn(false);
$userHooks = new UserHooks($this->keyManagerMock,
$this->loggerMock,
$this->userSetupMock,
$userSessionMock,
$this->utilMock,
$this->sessionMock,
$this->cryptMock,
$this->recoveryMock
);
$userHooks = $this->getMockBuilder('OCA\Encryption\Hooks\UserHooks')
->setConstructorArgs(
[
$this->keyManagerMock,
$this->userManagerMock,
$this->loggerMock,
$this->userSetupMock,
$userSessionMock,
$this->utilMock,
$this->sessionMock,
$this->cryptMock,
$this->recoveryMock
]
)->setMethods(['initMountPoints'])->getMock();
$this->assertNull($userHooks->setPassphrase($this->params));
}
@@ -216,6 +296,9 @@ class UserHooksTest extends TestCase {
$this->keyManagerMock = $this->getMockBuilder('OCA\Encryption\KeyManager')
->disableOriginalConstructor()
->getMock();
$this->userManagerMock = $this->getMockBuilder('OCP\IUserManager')
->disableOriginalConstructor()
->getMock();
$this->userSetupMock = $this->getMockBuilder('OCA\Encryption\Users\Setup')
->disableOriginalConstructor()
->getMock();
@@ -258,6 +341,7 @@ class UserHooksTest extends TestCase {
$this->recoveryMock = $recoveryMock;
$this->utilMock = $utilMock;
$this->instance = new UserHooks($this->keyManagerMock,
$this->userManagerMock,
$this->loggerMock,
$this->userSetupMock,
$this->userSessionMock,
+47 -3
View File
@@ -182,18 +182,62 @@ class KeyManagerTest extends TestCase {
);
}
public function testUserHasKeys() {
/**
* @dataProvider dataTestUserHasKeys
*/
public function testUserHasKeys($key, $expected) {
$this->keyStorageMock->expects($this->exactly(2))
->method('getUserKey')
->with($this->equalTo($this->userId), $this->anything())
->willReturn('key');
->willReturn($key);
$this->assertTrue(
$this->assertSame($expected,
$this->instance->userHasKeys($this->userId)
);
}
public function dataTestUserHasKeys() {
return [
['key', true],
['', false]
];
}
/**
* @expectedException \OCA\Encryption\Exceptions\PrivateKeyMissingException
*/
public function testUserHasKeysMissingPrivateKey() {
$this->keyStorageMock->expects($this->exactly(2))
->method('getUserKey')
->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) {
if ($keyID=== 'privateKey') {
return '';
}
return 'key';
});
$this->instance->userHasKeys($this->userId);
}
/**
* @expectedException \OCA\Encryption\Exceptions\PublicKeyMissingException
*/
public function testUserHasKeysMissingPublicKey() {
$this->keyStorageMock->expects($this->exactly(2))
->method('getUserKey')
->willReturnCallback(function ($uid, $keyID, $encryptionModuleId){
if ($keyID === 'publicKey') {
return '';
}
return 'key';
});
$this->instance->userHasKeys($this->userId);
}
public function testInit() {
$this->keyStorageMock->expects($this->any())
->method('getUserKey')
+179 -4
View File
@@ -24,6 +24,7 @@
namespace OCA\Encryption\Tests;
use OCA\Encryption\Migration;
use OCP\ILogger;
class MigrationTest extends \Test\TestCase {
@@ -37,6 +38,9 @@ class MigrationTest extends \Test\TestCase {
private $recovery_key_id = 'recovery_key_id';
private $moduleId;
/** @var PHPUnit_Framework_MockObject_MockObject | ILogger */
private $logger;
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
\OC_User::createUser(self::TEST_ENCRYPTION_MIGRATION_USER1, 'foo');
@@ -53,6 +57,7 @@ class MigrationTest extends \Test\TestCase {
public function setUp() {
$this->logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock();
$this->view = new \OC\Files\View();
$this->moduleId = \OCA\Encryption\Crypto\Encryption::ID;
}
@@ -100,6 +105,17 @@ class MigrationTest extends \Test\TestCase {
$this->view->file_put_contents($uid . '/files_encryption/keys/folder2/file.2.1/fileKey' , 'data');
}
protected function createDummyFiles($uid) {
$this->view->mkdir($uid . '/files/folder1/folder2/folder3/file3');
$this->view->mkdir($uid . '/files/folder1/folder2/file2');
$this->view->mkdir($uid . '/files/folder1/file.1');
$this->view->mkdir($uid . '/files/folder2/file.2.1');
$this->view->file_put_contents($uid . '/files/folder1/folder2/folder3/file3/fileKey' , 'data');
$this->view->file_put_contents($uid . '/files/folder1/folder2/file2/fileKey' , 'data');
$this->view->file_put_contents($uid . '/files/folder1/file.1/fileKey' , 'data');
$this->view->file_put_contents($uid . '/files/folder2/file.2.1/fileKey' , 'data');
}
protected function createDummyFilesInTrash($uid) {
$this->view->mkdir($uid . '/files_trashbin/keys/file1.d5457864');
$this->view->mkdir($uid . '/files_trashbin/keys/folder1.d7437648723/file2');
@@ -109,6 +125,11 @@ class MigrationTest extends \Test\TestCase {
$this->view->file_put_contents($uid . '/files_trashbin/keys/file1.d5457864/fileKey' , 'data');
$this->view->file_put_contents($uid . '/files_trashbin/keys/folder1.d7437648723/file2/fileKey' , 'data');
// create the files itself
$this->view->mkdir($uid . '/files_trashbin/folder1.d7437648723');
$this->view->file_put_contents($uid . '/files_trashbin/file1.d5457864' , 'data');
$this->view->file_put_contents($uid . '/files_trashbin/folder1.d7437648723/file2' , 'data');
}
protected function createDummySystemWideKeys() {
@@ -118,7 +139,6 @@ class MigrationTest extends \Test\TestCase {
$this->view->file_put_contents('files_encryption/systemwide_2.privateKey', 'data');
$this->view->file_put_contents('files_encryption/public_keys/systemwide_1.publicKey', 'data');
$this->view->file_put_contents('files_encryption/public_keys/systemwide_2.publicKey', 'data');
}
public function testMigrateToNewFolderStructure() {
@@ -134,6 +154,10 @@ class MigrationTest extends \Test\TestCase {
$this->createDummyFileKeys(self::TEST_ENCRYPTION_MIGRATION_USER2);
$this->createDummyFileKeys(self::TEST_ENCRYPTION_MIGRATION_USER3);
$this->createDummyFiles(self::TEST_ENCRYPTION_MIGRATION_USER1);
$this->createDummyFiles(self::TEST_ENCRYPTION_MIGRATION_USER2);
$this->createDummyFiles(self::TEST_ENCRYPTION_MIGRATION_USER3);
$this->createDummyFilesInTrash(self::TEST_ENCRYPTION_MIGRATION_USER2);
// no user for system wide mount points
@@ -142,7 +166,21 @@ class MigrationTest extends \Test\TestCase {
$this->createDummySystemWideKeys();
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection());
$m = $this->getMockBuilder('OCA\Encryption\Migration')
->setConstructorArgs(
[
\OC::$server->getConfig(),
new \OC\Files\View(),
\OC::$server->getDatabaseConnection(),
$this->logger
]
)->setMethods(['getSystemMountPoints'])->getMock();
$m->expects($this->any())->method('getSystemMountPoints')
->willReturn([['mountpoint' => 'folder1'], ['mountpoint' => 'folder2']]);
$m->reorganizeFolderStructure();
// even if it runs twice folder should always move only once
$m->reorganizeFolderStructure();
$this->assertTrue(
@@ -242,6 +280,12 @@ class MigrationTest extends \Test\TestCase {
$config->setAppValue('files_encryption', 'recoveryAdminEnabled', '1');
$config->setUserValue(self::TEST_ENCRYPTION_MIGRATION_USER1, 'files_encryption', 'recoverKeyEnabled', '1');
//$this->invokePrivate($config, 'cache', [[]]);
$cache = $this->invokePrivate(\OC::$server->getAppConfig(), 'cache');
unset($cache['encryption']);
unset($cache['files_encryption']);
$this->invokePrivate(\OC::$server->getAppConfig(), 'cache', [$cache]);
// delete default values set by the encryption app during initialization
/** @var \OC\DB\Connection $connection */
@@ -261,7 +305,8 @@ class MigrationTest extends \Test\TestCase {
public function testUpdateDB() {
$this->prepareDB();
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection());
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection(), $this->logger);
$this->invokePrivate($m, 'installedVersion', ['0.7']);
$m->updateDB();
$this->verifyDB('`*PREFIX*appconfig`', 'files_encryption', 0);
@@ -271,6 +316,59 @@ class MigrationTest extends \Test\TestCase {
}
/**
* test update db if the db already contain some existing new values
*/
public function testUpdateDBExistingNewConfig() {
$this->prepareDB();
$config = \OC::$server->getConfig();
$config->setAppValue('encryption', 'publicShareKeyId', 'wrong_share_id');
$config->setUserValue(self::TEST_ENCRYPTION_MIGRATION_USER1, 'encryption', 'recoverKeyEnabled', '9');
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection(), $this->logger);
$this->invokePrivate($m, 'installedVersion', ['0.7']);
$m->updateDB();
$this->verifyDB('`*PREFIX*appconfig`', 'files_encryption', 0);
$this->verifyDB('`*PREFIX*preferences`', 'files_encryption', 0);
$this->verifyDB('`*PREFIX*appconfig`', 'encryption', 3);
$this->verifyDB('`*PREFIX*preferences`', 'encryption', 1);
// check if the existing values where overwritten correctly
/** @var \OC\DB\Connection $connection */
$connection = \OC::$server->getDatabaseConnection();
$query = $connection->createQueryBuilder();
$query->select('`configvalue`')
->from('`*PREFIX*appconfig`')
->where($query->expr()->andX(
$query->expr()->eq('`appid`', ':appid'),
$query->expr()->eq('`configkey`', ':configkey')
))
->setParameter('appid', 'encryption')
->setParameter('configkey', 'publicShareKeyId');
$result = $query->execute();
$value = $result->fetch();
$this->assertTrue(isset($value['configvalue']));
$this->assertSame('share_id', $value['configvalue']);
$query = $connection->createQueryBuilder();
$query->select('`configvalue`')
->from('`*PREFIX*preferences`')
->where($query->expr()->andX(
$query->expr()->eq('`appid`', ':appid'),
$query->expr()->eq('`configkey`', ':configkey'),
$query->expr()->eq('`userid`', ':userid')
))
->setParameter('appid', 'encryption')
->setParameter('configkey', 'recoverKeyEnabled')
->setParameter('userid', self::TEST_ENCRYPTION_MIGRATION_USER1);
$result = $query->execute();
$value = $result->fetch();
$this->assertTrue(isset($value['configvalue']));
$this->assertSame('1', $value['configvalue']);
}
public function verifyDB($table, $appid, $expected) {
/** @var \OC\DB\Connection $connection */
$connection = \OC::$server->getDatabaseConnection();
@@ -291,7 +389,8 @@ class MigrationTest extends \Test\TestCase {
*/
public function testUpdateFileCache() {
$this->prepareFileCache();
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection());
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection(), $this->logger);
$this->invokePrivate($m, 'installedVersion', ['0.7']);
self::invokePrivate($m, 'updateFileCache');
// check results
@@ -353,4 +452,80 @@ class MigrationTest extends \Test\TestCase {
$this->assertSame(19, count($result));
}
/**
* @dataProvider dataTestGetTargetDir
*/
public function testGetTargetDir($user, $keyPath, $filename, $trash, $systemMounts, $expected) {
$updater = $this->getMockBuilder('\OC\Files\Cache\Updater')
->disableOriginalConstructor()->getMock();
$view = $this->getMockBuilder('\OC\Files\View')
->disableOriginalConstructor()->getMock();
$view->expects($this->any())->method('file_exists')->willReturn(true);
$view->expects($this->any())->method('getUpdater')->willReturn($updater);
$m = $this->getMockBuilder('OCA\Encryption\Migration')
->setConstructorArgs(
[
\OC::$server->getConfig(),
$view,
\OC::$server->getDatabaseConnection(),
$this->logger
]
)->setMethods(['getSystemMountPoints'])->getMock();
$m->expects($this->any())->method('getSystemMountPoints')
->willReturn($systemMounts);
$this->assertSame($expected,
$this->invokePrivate($m, 'getTargetDir', [$user, $keyPath, $filename, $trash])
);
}
public function dataTestGetTargetDir() {
return [
[
'user1',
'/files_encryption/keys/foo/bar.txt',
'user1.shareKey',
false,
[],
'user1/files_encryption/keys/files/foo/bar.txt/OC_DEFAULT_MODULE/user1.shareKey'
],
[
'user1',
'/files_trashbin/keys/foo/bar.txt',
'user1.shareKey',
true,
[],
'user1/files_encryption/keys/files_trashbin/foo/bar.txt/OC_DEFAULT_MODULE/user1.shareKey'
],
[
'',
'/files_encryption/keys/foo/bar.txt',
'user1.shareKey',
false,
[['mountpoint' => 'foo']],
'/files_encryption/keys/files/foo/bar.txt/OC_DEFAULT_MODULE/user1.shareKey'
],
[
'',
'/files_encryption/keys/foo/bar.txt',
'user1.shareKey',
false,
[['mountpoint' => 'foobar']],
false
],
[
'',
'/files_encryption/keys/foobar/bar.txt',
'user1.shareKey',
false,
[['mountpoint' => 'foo']],
false
]
];
}
}
@@ -224,7 +224,6 @@ class EncryptionTest extends TestCase {
$this->assertSame($expected,
$this->instance->update('path', 'user1', ['users' => ['user1']])
);
}
public function dataTestUpdate() {
@@ -234,6 +233,43 @@ class EncryptionTest extends TestCase {
);
}
/**
* Test case if the public key is missing. ownCloud should still encrypt
* the file for the remaining users
*/
public function testUpdateMissingPublicKey() {
$this->keyManagerMock->expects($this->once())
->method('getFileKey')->willReturn('fileKey');
$this->keyManagerMock->expects($this->any())
->method('getPublicKey')->willReturnCallback(
function($user) {
throw new PublicKeyMissingException($user);
}
);
$this->keyManagerMock->expects($this->any())
->method('addSystemKeys')
->willReturnCallback(function($accessList, $publicKeys) {
return $publicKeys;
});
$this->cryptMock->expects($this->once())->method('multiKeyEncrypt')
->willReturnCallback(
function($fileKey, $publicKeys) {
$this->assertEmpty($publicKeys);
$this->assertSame('fileKey', $fileKey);
}
);
$this->keyManagerMock->expects($this->never())->method('getVersion');
$this->keyManagerMock->expects($this->never())->method('setVersion');
$this->assertTrue(
$this->instance->update('path', 'user1', ['users' => ['user1']])
);
}
/**
* by default the encryption module should encrypt regular files, files in
* files_versions and files in files_trashbin
+12 -14
View File
@@ -46,13 +46,18 @@ $listener = new ScanListener($eventSource);
foreach ($users as $user) {
$eventSource->send('user', $user);
$scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection());
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', array($listener, 'file'));
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', array($listener, 'folder'));
if ($force) {
$scanner->scan($dir);
} else {
$scanner->backgroundScan($dir);
$scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger());
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function () use ($listener) {
$listener->file();
});
try {
if ($force) {
$scanner->scan($dir);
} else {
$scanner->backgroundScan($dir);
}
} catch (\Exception $e) {
$eventSource->send('error', get_class($e) . ': ' . $e->getMessage());
}
}
@@ -76,13 +81,6 @@ class ScanListener {
$this->eventSource = $eventSource;
}
/**
* @param string $path
*/
public function folder($path) {
$this->eventSource->send('folder', $path);
}
public function file() {
$this->fileCount++;
if ($this->fileCount > $this->lastCount + 20) { //send a count update every 20 files
+1 -1
View File
@@ -148,7 +148,7 @@ if ($maxUploadFileSize >= 0 and $totalSize > $maxUploadFileSize) {
}
$result = array();
if (strpos($dir, '..') === false) {
if (\OC\Files\Filesystem::isValidPath($dir) === true) {
$fileCount = count($files['name']);
for ($i = 0; $i < $fileCount; $i++) {
+1 -1
View File
@@ -45,12 +45,12 @@ $server->setBaseUri($baseuri);
// Load plugins
$defaults = new OC_Defaults();
$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
$server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin(\OC::$server->getConfig()));
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());
$server->addPlugin(new \OC\Connector\Sabre\FilesPlugin($objectTree));
$server->addPlugin(new \OC\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
$server->addPlugin(new \OC\Connector\Sabre\ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
// wait with registering these until auth is handled and the filesystem is setup
+96
View File
@@ -0,0 +1,96 @@
<?php
/**
* @author Björn Schießle <schiessle@owncloud.com>
* @author Joas Schilling <nickvergessen@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
$installedVersion = \OC::$server->getConfig()->getAppValue('files', 'installed_version');
$ocVersion = explode('.', \OC::$server->getSystemConfig()->getValue('version'));
/**
* In case encryption was not enabled, we accidently set encrypted = 1 for
* files inside mount points, since 8.1.0. This breaks opening the files in
* 8.1.1 because we fixed the code that checks if a file is encrypted.
* In order to fix the file, we need to reset the flag of the file. However,
* the flag might be set because the file is in fact encrypted because it was
* uploaded at a time where encryption was enabled.
*
* So we can only do this when:
* - Current version of ownCloud before the update is 8.1.0 or 8.2.0.(0-2)
* - Encryption is disabled
* - files_encryption is not known in the app config
*
* If the first two are not the case, we are save. However, if files_encryption
* values exist in the config, we might have a false negative here.
* Now if there is no file with unencrypted size greater 0, that means there are
* no files that are still encrypted with "files_encryption" encryption. So we
* can also safely reset the flag here.
*
* If this is not the case, we go with "better save then sorry" and don't change
* the flag but write a message to the ownCloud log file.
*/
/**
* @param \OCP\IDBConnection $conn
*/
function owncloud_reset_encrypted_flag(\OCP\IDBConnection $conn) {
$conn->executeUpdate('UPDATE `*PREFIX*filecache` SET `encrypted` = 0 WHERE `encrypted` = 1');
}
// Current version of ownCloud before the update is 8.1.0 or 8.2.0.(0-2)
if ($installedVersion === '1.1.9' && (
// 8.1.0.x
(((int) $ocVersion[0]) === 8 && ((int) $ocVersion[1]) === 1 && ((int) $ocVersion[2]) === 0)
||
// < 8.1.1.1
(((int) $ocVersion[0]) === 8 && ((int) $ocVersion[1]) === 1 && ((int) $ocVersion[2]) === 1 && ((int) $ocVersion[3]) < 1)
)) {
// Encryption is not enabled
if (!\OC::$server->getEncryptionManager()->isEnabled()) {
$conn = \OC::$server->getDatabaseConnection();
// Old encryption is not known in app config
$oldEncryption = \OC::$server->getConfig()->getAppKeys('files_encryption');
if (empty($oldEncryption)) {
owncloud_reset_encrypted_flag($conn);
} else {
$query = $conn->prepare('SELECT * FROM `*PREFIX*filecache` WHERE `encrypted` = 1 AND `unencrypted_size` > 0', 1);
$query->execute();
$empty = $query->fetch();
if (empty($empty)) {
owncloud_reset_encrypted_flag($conn);
} else {
/**
* Sorry in case you are a false positive, but we are not 100% that
* you don't have any encrypted files anymore, so we can not reset
* the value safely
*/
\OC::$server->getLogger()->warning(
'If you have a problem with files not being accessible and '
. 'you are not using encryption, please have a look at the following'
. 'issue: {issue}',
[
'issue' => 'https://github.com/owncloud/core/issues/17846',
]
);
}
}
}
}
+1 -1
View File
@@ -1 +1 @@
1.1.9
1.1.10
+10 -5
View File
@@ -26,6 +26,7 @@
namespace OCA\Files\Command;
use OC\ForbiddenException;
use OCP\Files\StorageNotAvailableException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@@ -74,7 +75,7 @@ class Scan extends Command {
}
protected function scanFiles($user, $path, $quiet, OutputInterface $output) {
$scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection());
$scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger());
if (!$quiet) {
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) {
$output->writeln("Scanning file <info>$path</info>");
@@ -82,6 +83,9 @@ class Scan extends Command {
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
$output->writeln("Scanning folder <info>$path</info>");
});
$scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) {
$output->writeln("Error while scanning, storage not available (" . $e->getMessage() . ")");
});
}
try {
$scanner->scan($path);
@@ -92,10 +96,10 @@ class Scan extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output) {
$path = $input->getOption('path');
if ($path) {
$path = '/'.trim($path, '/');
list (, $user, ) = explode('/', $path, 3);
$inputPath = $input->getOption('path');
if ($inputPath) {
$inputPath = '/' . trim($inputPath, '/');
list (, $user,) = explode('/', $inputPath, 3);
$users = array($user);
} else if ($input->getOption('all')) {
$users = $this->userManager->search('');
@@ -114,6 +118,7 @@ class Scan extends Command {
if (is_object($user)) {
$user = $user->getUID();
}
$path = $inputPath ? $inputPath : '/' . $user;
if ($this->userManager->userExists($user)) {
$this->scanFiles($user, $path, $quiet, $output);
} else {
+1 -2
View File
@@ -276,8 +276,6 @@
containerWidth -= $('#app-navigation-toggle').width();
this.breadcrumb.setMaxWidth(containerWidth - actionsWidth - 10);
this.updateSearch();
},
/**
@@ -1659,6 +1657,7 @@
}
this.$table.addClass('hidden');
this.$el.find('#emptycontent').addClass('hidden');
$mask = $('<div class="mask transparent"></div>');
+2 -3
View File
@@ -116,7 +116,7 @@
ownerDisplayName = $('#ownerDisplayName').val();
if (usedSpacePercent > 98) {
if (owner !== oc_current_user) {
OC.Notification.show(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!',
OC.Notification.showTemporary(t('files', 'Storage of {owner} is full, files can not be updated or synced anymore!',
{ owner: ownerDisplayName }));
return;
}
@@ -125,7 +125,7 @@
}
if (usedSpacePercent > 90) {
if (owner !== oc_current_user) {
OC.Notification.show(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)',
OC.Notification.showTemporary(t('files', 'Storage of {owner} is almost full ({usedSpacePercent}%)',
{ usedSpacePercent: usedSpacePercent, owner: ownerDisplayName }));
return;
}
@@ -239,7 +239,6 @@
// display storage warnings
setTimeout(Files.displayStorageWarnings, 100);
OC.Notification.setDefault(Files.displayStorageWarnings);
// only possible at the moment if user is logged in or the files app is loaded
if (OC.currentUser && OCA.Files.App) {
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"files",
{
"Download" : "Download"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Download" : "Download"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+16 -12
View File
@@ -136,25 +136,26 @@ class Activity implements IExtension {
return false;
}
$l = $this->getL10N($languageCode);
switch ($text) {
case 'created_self':
return (string) $this->l->t('You created %1$s', $params);
return (string) $l->t('You created %1$s', $params);
case 'created_by':
return (string) $this->l->t('%2$s created %1$s', $params);
return (string) $l->t('%2$s created %1$s', $params);
case 'created_public':
return (string) $this->l->t('%1$s was created in a public folder', $params);
return (string) $l->t('%1$s was created in a public folder', $params);
case 'changed_self':
return (string) $this->l->t('You changed %1$s', $params);
return (string) $l->t('You changed %1$s', $params);
case 'changed_by':
return (string) $this->l->t('%2$s changed %1$s', $params);
return (string) $l->t('%2$s changed %1$s', $params);
case 'deleted_self':
return (string) $this->l->t('You deleted %1$s', $params);
return (string) $l->t('You deleted %1$s', $params);
case 'deleted_by':
return (string) $this->l->t('%2$s deleted %1$s', $params);
return (string) $l->t('%2$s deleted %1$s', $params);
case 'restored_self':
return (string) $this->l->t('You restored %1$s', $params);
return (string) $l->t('You restored %1$s', $params);
case 'restored_by':
return (string) $this->l->t('%2$s restored %1$s', $params);
return (string) $l->t('%2$s restored %1$s', $params);
default:
return false;
@@ -332,6 +333,7 @@ class Activity implements IExtension {
*/
$parameters = $fileQueryList = [];
$parameters[] = 'files';
$parameters[] = 'files';
$fileQueryList[] = '(`type` <> ? AND `type` <> ?)';
$parameters[] = self::TYPE_SHARE_CREATED;
@@ -346,10 +348,12 @@ class Activity implements IExtension {
$parameters[] = $favorite . '/%';
}
$parameters[] = 'files';
return [
' CASE WHEN `app` = ? THEN (' . implode(' OR ', $fileQueryList) . ') ELSE `app` <> ? END ',
' CASE '
. 'WHEN `app` <> ? THEN 1 '
. 'WHEN `app` = ? AND (' . implode(' OR ', $fileQueryList) . ') THEN 1 '
. 'ELSE 0 '
. 'END = 1 ',
$parameters,
];
}
+61 -5
View File
@@ -42,6 +42,9 @@ class ActivityTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $activityHelper;
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $l10nFactory;
/** @var \OCA\Files\Activity */
protected $activityExtension;
@@ -67,8 +70,28 @@ class ActivityTest extends TestCase {
$this->config
);
$this->l10nFactory = $this->getMockBuilder('OC\L10N\Factory')
->disableOriginalConstructor()
->getMock();
$deL10n = $this->getMockBuilder('OC_L10N')
->disableOriginalConstructor()
->getMock();
$deL10n->expects($this->any())
->method('t')
->willReturnCallback(function ($argument) {
return 'translate(' . $argument . ')';
});
$this->l10nFactory->expects($this->any())
->method('get')
->willReturnMap([
['files', null, new \OC_L10N('files', 'en')],
['files', 'en', new \OC_L10N('files', 'en')],
['files', 'de', $deL10n],
]);
$this->activityExtension = $activityExtension = new Activity(
new \OC\L10N\Factory(),
$this->l10nFactory,
$this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
$this->activityManager,
$this->activityHelper,
@@ -111,6 +134,26 @@ class ActivityTest extends TestCase {
$this->activityExtension->translate('files_sharing', '', [], false, false, 'en'),
'Asserting that no translations are set for files_sharing'
);
// Test english
$this->assertNotFalse(
$this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en'),
'Asserting that translations are set for files.deleted_self'
);
$this->assertStringStartsWith(
'You deleted ',
$this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'en')
);
// Test translation
$this->assertNotFalse(
$this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de'),
'Asserting that translations are set for files.deleted_self'
);
$this->assertStringStartsWith(
'translate(You deleted ',
$this->activityExtension->translate('files', 'deleted_self', ['file'], false, false, 'de')
);
}
public function testGetSpecialParameterList() {
@@ -247,16 +290,16 @@ class ActivityTest extends TestCase {
'items' => [],
'folders' => [],
],
' CASE WHEN `app` = ? THEN ((`type` <> ? AND `type` <> ?)) ELSE `app` <> ? END ',
['files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'files']
' CASE WHEN `app` <> ? THEN 1 WHEN `app` = ? AND ((`type` <> ? AND `type` <> ?)) THEN 1 ELSE 0 END = 1 ',
['files', 'files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED]
],
[
[
'items' => ['file.txt', 'folder'],
'folders' => ['folder'],
],
' CASE WHEN `app` = ? THEN ((`type` <> ? AND `type` <> ?) OR `file` = ? OR `file` = ? OR `file` LIKE ?) ELSE `app` <> ? END ',
['files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'file.txt', 'folder', 'folder/%', 'files']
' CASE WHEN `app` <> ? THEN 1 WHEN `app` = ? AND ((`type` <> ? AND `type` <> ?) OR `file` = ? OR `file` = ? OR `file` LIKE ?) THEN 1 ELSE 0 END = 1 ',
['files', 'files', Activity::TYPE_SHARE_CREATED, Activity::TYPE_SHARE_CHANGED, 'file.txt', 'folder', 'folder/%']
],
];
}
@@ -290,6 +333,19 @@ class ActivityTest extends TestCase {
$result = $this->activityExtension->getQueryForFilter('all');
$this->assertEquals([$query, $parameters], $result);
$this->executeQueryForFilter($result);
}
public function executeQueryForFilter(array $result) {
list($resultQuery, $resultParameters) = $result;
$resultQuery = str_replace('`file`', '`user`', $resultQuery);
$resultQuery = str_replace('`type`', '`key`', $resultQuery);
$connection = \OC::$server->getDatabaseConnection();
$result = $connection->executeQuery('SELECT * FROM `*PREFIX*privatedata` WHERE ' . $resultQuery, $resultParameters);
$rows = $result->fetchAll();
$result->closeCursor();
}
protected function mockUserSession($user) {
@@ -93,6 +93,7 @@ class ApiControllerTest extends TestCase {
[
'mtime' => 55,
'mimetype' => 'application/pdf',
'permissions' => 31,
'size' => 1234,
'etag' => 'MyEtag',
],
@@ -114,7 +115,7 @@ class ApiControllerTest extends TestCase {
'mtime' => 55000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo),
'name' => 'root.txt',
'permissions' => null,
'permissions' => 31,
'mimetype' => 'application/pdf',
'size' => 1234,
'type' => 'file',
@@ -142,6 +143,7 @@ class ApiControllerTest extends TestCase {
[
'mtime' => 55,
'mimetype' => 'application/pdf',
'permissions' => 31,
'size' => 1234,
'etag' => 'MyEtag',
],
@@ -158,6 +160,7 @@ class ApiControllerTest extends TestCase {
[
'mtime' => 999,
'mimetype' => 'application/binary',
'permissions' => 31,
'size' => 9876,
'etag' => 'SubEtag',
],
@@ -179,7 +182,7 @@ class ApiControllerTest extends TestCase {
'mtime' => 55000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo1),
'name' => 'root.txt',
'permissions' => null,
'permissions' => 31,
'mimetype' => 'application/pdf',
'size' => 1234,
'type' => 'file',
@@ -198,7 +201,7 @@ class ApiControllerTest extends TestCase {
'mtime' => 999000,
'icon' => \OCA\Files\Helper::determineIcon($fileInfo2),
'name' => 'root.txt',
'permissions' => null,
'permissions' => 31,
'mimetype' => 'application/binary',
'size' => 9876,
'type' => 'file',
+3
View File
@@ -1 +1,4 @@
example.php
icewind/smb/tests
icewind/smb/install_libsmbclient.sh
icewind/smb/.travis.yml
+1 -1
View File
@@ -6,7 +6,7 @@
"vendor-dir": "."
},
"require": {
"icewind/smb": "1.0.1",
"icewind/smb": "1.0.4",
"icewind/streams": "0.2"
}
}
+7 -7
View File
@@ -1,23 +1,23 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "7b46d64e33feb600c5f0ec830b211e6f",
"hash": "5c612406bc1235075305b09a5d6996a9",
"packages": [
{
"name": "icewind/smb",
"version": "v1.0.1",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
"reference": "8041bc1960bf2da94e60b88b34e5c78300eac476"
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/8041bc1960bf2da94e60b88b34e5c78300eac476",
"reference": "8041bc1960bf2da94e60b88b34e5c78300eac476",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/9277bd20262a01b38a33cc7356e98055f2262d32",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32",
"shasum": ""
},
"require": {
@@ -45,7 +45,7 @@
}
],
"description": "php wrapper for smbclient and libsmbclient-php",
"time": "2015-04-20 11:16:24"
"time": "2015-08-17 14:20:38"
},
{
"name": "icewind/streams",
+6 -6
View File
@@ -43,17 +43,17 @@
},
{
"name": "icewind/smb",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"version": "v1.0.4",
"version_normalized": "1.0.4.0",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
"reference": "8041bc1960bf2da94e60b88b34e5c78300eac476"
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/8041bc1960bf2da94e60b88b34e5c78300eac476",
"reference": "8041bc1960bf2da94e60b88b34e5c78300eac476",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/9277bd20262a01b38a33cc7356e98055f2262d32",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32",
"shasum": ""
},
"require": {
@@ -63,7 +63,7 @@
"require-dev": {
"satooshi/php-coveralls": "dev-master"
},
"time": "2015-04-20 11:16:24",
"time": "2015-08-17 14:20:38",
"type": "library",
"installation-source": "source",
"autoload": {
-50
View File
@@ -1,50 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
env:
global:
- CURRENT_DIR=`pwd`
before_install:
- pass=$(perl -e 'print crypt("test", "password")')
- sudo useradd -m -p $pass test
- sudo apt-get update -qq
- sudo apt-get install samba smbclient libsmbclient-dev libsmbclient
- wget -O /tmp/libsmbclient-php.zip https://github.com/eduardok/libsmbclient-php/archive/master.zip
- unzip /tmp/libsmbclient-php.zip -d /tmp
- cd /tmp/libsmbclient-php-master
- phpize && ./configure && make && sudo make install
- echo 'extension="libsmbclient.so"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- cd $CURRENT_DIR
- chmod go+w $HOME
- printf "%s\n%s\n" test test|sudo smbpasswd -s test
- sudo mkdir /home/test/test
- sudo chown test /home/test/test
- |
echo "[test]
comment = test
path = /home/test
guest ok = yes
writeable = yes
map archive = yes
map system = yes
map hidden = yes
create mask = 0777
inherit permissions = yes" | sudo tee -a /etc/samba/smb.conf
- sudo service smbd restart
- testparm -s
install:
- composer install --dev --no-interaction
script:
- mkdir -p build/logs
- cd tests
- phpunit --coverage-clover ../build/logs/clover.xml --configuration phpunit.xml
after_script:
- cd $CURRENT_DIR
- php vendor/bin/coveralls -v
@@ -0,0 +1,26 @@
<?php
/**
* Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB;
use Icewind\SMB\Exception\InvalidPathException;
abstract class AbstractShare implements IShare {
private $forbiddenCharacters;
public function __construct() {
$this->forbiddenCharacters = array('?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r");
}
protected function verifyPath($path) {
foreach ($this->forbiddenCharacters as $char) {
if (strpos($path, $char) !== false) {
throw new InvalidPathException('Invalid path, "' . $char . '" is not allowed');
}
}
}
}
+19 -6
View File
@@ -8,8 +8,10 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\ConnectException;
use Icewind\SMB\Exception\ConnectionException;
use Icewind\SMB\Exception\InvalidHostException;
use Icewind\SMB\Exception\NoLoginServerException;
class Connection extends RawConnection {
const DELIMITER = 'smb:';
@@ -26,18 +28,25 @@ class Connection extends RawConnection {
/**
* get all unprocessed output from smbclient until the next prompt
*
* @throws ConnectionException
* @return string
* @throws AuthenticationException
* @throws ConnectException
* @throws ConnectionException
* @throws InvalidHostException
* @throws NoLoginServerException
*/
public function read() {
if (!$this->isValid()) {
throw new ConnectionException();
throw new ConnectionException('Connection not valid');
}
$line = $this->readLine(); //first line is prompt
$this->checkConnectionError($line);
$output = array();
$line = $this->readLine();
if ($line === false) {
throw new ConnectException('Unknown error');
}
$length = mb_strlen(self::DELIMITER);
while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter
$output[] .= $line;
@@ -52,20 +61,24 @@ class Connection extends RawConnection {
* @param $line
* @throws AuthenticationException
* @throws InvalidHostException
* @throws NoLoginServerException
*/
private function checkConnectionError($line) {
$line = rtrim($line, ')');
if (substr($line, -23) === ErrorCodes::LogonFailure) {
throw new AuthenticationException();
throw new AuthenticationException('Invalid login');
}
if (substr($line, -26) === ErrorCodes::BadHostName) {
throw new InvalidHostException();
throw new InvalidHostException('Invalid hostname');
}
if (substr($line, -22) === ErrorCodes::Unsuccessful) {
throw new InvalidHostException();
throw new InvalidHostException('Connection unsuccessful');
}
if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
throw new InvalidHostException();
throw new InvalidHostException('Connection refused');
}
if (substr($line, -26) === ErrorCodes::NoLogonServers) {
throw new NoLoginServerException('No login server');
}
}
@@ -15,6 +15,7 @@ class ErrorCodes {
const BadHostName = 'NT_STATUS_BAD_NETWORK_NAME';
const Unsuccessful = 'NT_STATUS_UNSUCCESSFUL';
const ConnectionRefused = 'NT_STATUS_CONNECTION_REFUSED';
const NoLogonServers = 'NT_STATUS_NO_LOGON_SERVERS';
const PathNotFound = 'NT_STATUS_OBJECT_PATH_NOT_FOUND';
const NoSuchFile = 'NT_STATUS_NO_SUCH_FILE';
@@ -0,0 +1,10 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Exception;
class InvalidPathException extends InvalidRequestException {}
@@ -5,5 +5,6 @@
* http://opensource.org/licenses/MIT
*/
date_default_timezone_set('UTC');
require_once __DIR__.'/../vendor/autoload.php';
namespace Icewind\SMB\Exception;
class NoLoginServerException extends ConnectException {}
@@ -24,12 +24,7 @@ class NativeServer extends Server {
}
protected function connect() {
$user = $this->getUser();
$workgroup = null;
if (strpos($user, '/')) {
list($workgroup, $user) = explode($user, '/');
}
$this->state->init($workgroup, $user, $this->getPassword());
$this->state->init($this->getWorkgroup(), $this->getUser(), $this->getPassword());
}
/**
@@ -7,7 +7,7 @@
namespace Icewind\SMB;
class NativeShare implements IShare {
class NativeShare extends AbstractShare {
/**
* @var Server $server
*/
@@ -28,6 +28,7 @@ class NativeShare implements IShare {
* @param string $name
*/
public function __construct($server, $name) {
parent::__construct();
$this->server = $server;
$this->name = $name;
$this->state = new NativeState();
@@ -43,15 +44,7 @@ class NativeShare implements IShare {
return;
}
$user = $this->server->getUser();
if (strpos($user, '/')) {
list($workgroup, $user) = explode('/', $user);
} elseif (strpos($user, '\\')) {
list($workgroup, $user) = explode('\\', $user);
} else {
$workgroup = null;
}
$this->state->init($workgroup, $user, $this->server->getPassword());
$this->state->init($this->server->getWorkgroup(), $this->server->getUser(), $this->server->getPassword());
}
/**
@@ -64,6 +57,7 @@ class NativeShare implements IShare {
}
private function buildUrl($path) {
$this->verifyPath($path);
$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
if ($path) {
$path = trim($path, '/');
@@ -149,6 +143,7 @@ class NativeShare implements IShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function del($path) {
$this->connect();
return $this->state->unlink($this->buildUrl($path));
}
+32 -1
View File
@@ -29,6 +29,11 @@ class Server {
*/
protected $password;
/**
* @var string $workgroup
*/
protected $workgroup;
/**
* Check if the smbclient php extension is available
*
@@ -45,10 +50,28 @@ class Server {
*/
public function __construct($host, $user, $password) {
$this->host = $host;
list($workgroup, $user) = $this->splitUser($user);
$this->user = $user;
$this->workgroup = $workgroup;
$this->password = $password;
}
/**
* Split workgroup from username
*
* @param $user
* @return string[] [$workgroup, $user]
*/
public function splitUser($user) {
if (strpos($user, '/')) {
return explode('/', $user, 2);
} elseif (strpos($user, '\\')) {
return explode('\\', $user);
} else {
return array(null, $user);
}
}
/**
* @return string
*/
@@ -77,6 +100,13 @@ class Server {
return $this->host;
}
/**
* @return string
*/
public function getWorkgroup() {
return $this->workgroup;
}
/**
* @return \Icewind\SMB\IShare[]
*
@@ -84,7 +114,8 @@ class Server {
* @throws \Icewind\SMB\Exception\InvalidHostException
*/
public function listShares() {
$command = Server::CLIENT . ' --authentication-file=/proc/self/fd/3' .
$workgroupArgument = ($this->workgroup) ? ' -W ' . escapeshellarg($this->workgroup) : '';
$command = Server::CLIENT . $workgroupArgument . ' --authentication-file=/proc/self/fd/3' .
' -gL ' . escapeshellarg($this->getHost());
$connection = new RawConnection($command);
$connection->writeAuthentication($this->getUser(), $this->getPassword());
+22 -22
View File
@@ -7,17 +7,13 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\AccessDeniedException;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\ConnectionException;
use Icewind\SMB\Exception\Exception;
use Icewind\SMB\Exception\FileInUseException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotEmptyException;
use Icewind\SMB\Exception\NotFoundException;
use Icewind\Streams\CallbackWrapper;
class Share implements IShare {
class Share extends AbstractShare {
/**
* @var Server $server
*/
@@ -43,6 +39,7 @@ class Share implements IShare {
* @param string $name
*/
public function __construct($server, $name) {
parent::__construct();
$this->server = $server;
$this->name = $name;
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost()));
@@ -57,10 +54,11 @@ class Share implements IShare {
if ($this->connection and $this->connection->isValid()) {
return;
}
$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s',
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
Server::CLIENT,
$this->server->getHost(),
$this->name
$workgroupArgument,
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
);
$this->connection = new Connection($command);
$this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
@@ -256,18 +254,18 @@ class Share implements IShare {
*/
public function read($source) {
$source = $this->escapePath($source);
// close the single quote, open a double quote where we put the single quote...
$source = str_replace('\'', '\'"\'"\'', $source);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s -c \'get %s /proc/self/fd/5\'',
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
Server::CLIENT,
$this->server->getHost(),
$this->name,
$source
$workgroupArgument,
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
);
$connection = new Connection($command);
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
$connection->write('get ' . $source . ' /proc/self/fd/5');
$connection->write('exit');
$fh = $connection->getFileOutputStream();
stream_context_set_option($fh, 'file', 'connection', $connection);
return $fh;
@@ -284,23 +282,24 @@ class Share implements IShare {
*/
public function write($target) {
$target = $this->escapePath($target);
// close the single quote, open a double quote where we put the single quote...
$target = str_replace('\'', '\'"\'"\'', $target);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
$command = sprintf('%s --authentication-file=/proc/self/fd/3 //%s/%s -c \'put /proc/self/fd/4 %s\'',
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
Server::CLIENT,
$this->server->getHost(),
$this->name,
$target
$workgroupArgument,
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
);
$connection = new RawConnection($command);
$connection = new Connection($command);
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
$fh = $connection->getFileInputStream();
$connection->write('put /proc/self/fd/4 ' . $target);
$connection->write('exit');
// use a close callback to ensure the upload is finished before continuing
// this also serves as a way to keep the connection in scope
return CallbackWrapper::wrap($fh, null, null, function () use ($connection) {
return CallbackWrapper::wrap($fh, null, null, function () use ($connection, $target) {
$connection->close(false); // dont terminate, give the upload some time
});
}
@@ -378,6 +377,7 @@ class Share implements IShare {
* @return string
*/
protected function escapePath($path) {
$this->verifyPath($path);
if ($path === '/') {
$path = '';
}
@@ -1,539 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
use Icewind\SMB\FileInfo;
abstract class AbstractShare extends \PHPUnit_Framework_TestCase {
/**
* @var \Icewind\SMB\Server $server
*/
protected $server;
/**
* @var \Icewind\SMB\IShare $share
*/
protected $share;
/**
* @var string $root
*/
protected $root;
protected $config;
public function tearDown() {
try {
if ($this->share) {
$this->cleanDir($this->root);
}
unset($this->share);
} catch (\Exception $e) {
unset($this->share);
throw $e;
}
}
public function nameProvider() {
// / ? < > \ : * | " are illegal characters in path on windows
return array(
array('simple'),
array('with spaces_and-underscores'),
array("single'quote'"),
array('日本語'),
array('url %2F +encode'),
array('a somewhat longer filename than the other with more charaters as the all the other filenames'),
array('$as#d€££Ö€ßœĚęĘĞĜΣΥΦΩΫ')
);
}
public function fileDataProvider() {
return array(
array('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'),
array('Mixed language, 日本語 が わからか and Various _/* characters \\|” €')
);
}
public function nameAndDataProvider() {
$names = $this->nameProvider();
$data = $this->fileDataProvider();
$result = array();
foreach ($names as $name) {
foreach ($data as $text) {
$result[] = array($name[0], $text[0]);
}
}
return $result;
}
public function cleanDir($dir) {
$content = $this->share->dir($dir);
foreach ($content as $metadata) {
if ($metadata->isDirectory()) {
$this->cleanDir($metadata->getPath());
} else {
$this->share->del($metadata->getPath());
}
}
$this->share->rmdir($dir);
}
private function getTextFile($text = '') {
if (!$text) {
$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';
}
$file = tempnam('/tmp', 'smb_test_');
file_put_contents($file, $text);
return $file;
}
public function testListShares() {
$shares = $this->server->listShares();
foreach ($shares as $share) {
if ($share->getName() === $this->config->share) {
return;
}
}
$this->fail('Share "' . $this->config->share . '" not found');
}
public function testRootStartsEmpty() {
$this->assertEquals(array(), $this->share->dir($this->root));
}
/**
* @dataProvider nameProvider
*/
public function testMkdir($name) {
$this->share->mkdir($this->root . '/' . $name);
$dirs = $this->share->dir($this->root);
$this->assertCount(1, $dirs);
$this->assertEquals($name, $dirs[0]->getName());
$this->assertTrue($dirs[0]->isDirectory());
}
/**
* @dataProvider nameProvider
*/
public function testRenameDirectory($name) {
$this->share->mkdir($this->root . '/' . $name);
$this->share->rename($this->root . '/' . $name, $this->root . '/' . $name . '_rename');
$dirs = $this->share->dir($this->root);
$this->assertEquals(1, count($dirs));
$this->assertEquals($name . '_rename', $dirs[0]->getName());
}
/**
* @dataProvider nameProvider
*/
public function testRmdir($name) {
$this->share->mkdir($this->root . '/' . $name);
$this->share->rmdir($this->root . '/' . $name);
$this->assertCount(0, $this->share->dir($this->root));
}
/**
* @dataProvider nameAndDataProvider
*/
public function testPut($name, $text) {
$tmpFile = $this->getTextFile($text);
$size = filesize($tmpFile);
$this->share->put($tmpFile, $this->root . '/' . $name);
unlink($tmpFile);
$files = $this->share->dir($this->root);
$this->assertCount(1, $files);
$this->assertEquals($name, $files[0]->getName());
$this->assertEquals($size, $files[0]->getSize());
$this->assertFalse($files[0]->isDirectory());
}
/**
* @dataProvider nameProvider
*/
public function testRenameFile($name) {
$tmpFile = $this->getTextFile();
$this->share->put($tmpFile, $this->root . '/' . $name);
unlink($tmpFile);
$this->share->rename($this->root . '/' . $name, $this->root . '/' . $name . '_renamed');
$files = $this->share->dir($this->root);
$this->assertEquals(1, count($files));
$this->assertEquals($name . '_renamed', $files[0]->getName());
}
/**
* @dataProvider nameAndDataProvider
*/
public function testGet($name, $text) {
$tmpFile = $this->getTextFile($text);
$this->share->put($tmpFile, $this->root . '/' . $name);
unlink($tmpFile);
$targetFile = tempnam('/tmp', 'smb_test_');
$this->share->get($this->root . '/' . $name, $targetFile);
$this->assertEquals($text, file_get_contents($targetFile));
unlink($targetFile);
}
/**
* @dataProvider nameProvider
*/
public function testDel($name) {
$tmpFile = $this->getTextFile();
$this->share->put($tmpFile, $this->root . '/' . $name);
unlink($tmpFile);
$this->share->del($this->root . '/' . $name);
$this->assertCount(0, $this->share->dir($this->root));
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testCreateFolderInNonExistingFolder() {
$this->share->mkdir($this->root . '/foo/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testRemoveFolderInNonExistingFolder() {
$this->share->rmdir($this->root . '/foo/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testRemoveNonExistingFolder() {
$this->share->rmdir($this->root . '/foo');
}
/**
* @expectedException \Icewind\SMB\Exception\AlreadyExistsException
*/
public function testCreateExistingFolder() {
$this->share->mkdir($this->root . '/bar');
$this->share->mkdir($this->root . '/bar');
$this->share->rmdir($this->root . '/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\InvalidTypeException
*/
public function testCreateFileExistingFolder() {
$this->share->mkdir($this->root . '/bar');
$this->share->put($this->getTextFile(), $this->root . '/bar');
$this->share->rmdir($this->root . '/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testCreateFileInNonExistingFolder() {
$this->share->put($this->getTextFile(), $this->root . '/foo/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testTestRemoveNonExistingFile() {
$this->share->del($this->root . '/foo');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testDownloadNonExistingFile() {
$this->share->get($this->root . '/foo', '/dev/null');
}
/**
* @expectedException \Icewind\SMB\Exception\InvalidTypeException
*/
public function testDownloadFolder() {
$this->share->mkdir($this->root . '/foobar');
$this->share->get($this->root . '/foobar', '/dev/null');
$this->share->rmdir($this->root . '/foobar');
}
/**
* @expectedException \Icewind\SMB\Exception\InvalidTypeException
*/
public function testDelFolder() {
$this->share->mkdir($this->root . '/foobar');
$this->share->del($this->root . '/foobar');
$this->share->rmdir($this->root . '/foobar');
}
/**
* @expectedException \Icewind\SMB\Exception\InvalidTypeException
*/
public function testRmdirFile() {
$this->share->put($this->getTextFile(), $this->root . '/foobar');
$this->share->rmdir($this->root . '/foobar');
$this->share->del($this->root . '/foobar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotEmptyException
*/
public function testRmdirNotEmpty() {
$this->share->mkdir($this->root . '/foobar');
$this->share->put($this->getTextFile(), $this->root . '/foobar/asd');
$this->share->rmdir($this->root . '/foobar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testDirNonExisting() {
$this->share->dir('/foobar/asd');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testRmDirNonExisting() {
$this->share->rmdir('/foobar/asd');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testRenameNonExisting() {
$this->share->rename('/foobar/asd', '/foobar/bar');
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testRenameTargetNonExisting() {
$txt = $this->getTextFile();
$this->share->put($txt, $this->root . '/foo.txt');
unlink($txt);
$this->share->rename($this->root . '/foo.txt', $this->root . '/bar/foo.txt');
}
public function testModifiedDate() {
$now = time();
$this->share->put($this->getTextFile(), $this->root . '/foo.txt');
$dir = $this->share->dir($this->root);
$mtime = $dir[0]->getMTime();
$this->assertTrue(abs($now - $mtime) <= 2, 'Modified time differs by ' . abs($now - $mtime) . ' seconds');
$this->share->del($this->root . '/foo.txt');
}
/**
* @dataProvider nameAndDataProvider
*/
public function testReadStream($name, $text) {
$sourceFile = $this->getTextFile($text);
$this->share->put($sourceFile, $this->root . '/' . $name);
$fh = $this->share->read($this->root . '/' . $name);
$content = stream_get_contents($fh);
fclose($fh);
$this->share->del($this->root . '/' . $name);
$this->assertEquals(file_get_contents($sourceFile), $content);
}
/**
* @dataProvider nameAndDataProvider
*/
public function testWriteStream($name, $text) {
$fh = $this->share->write($this->root . '/' . $name);
fwrite($fh, $text);
fclose($fh);
$tmpFile1 = tempnam('/tmp', 'smb_test_');
$this->share->get($this->root . '/' . $name, $tmpFile1);
$this->assertEquals($text, file_get_contents($tmpFile1));
$this->share->del($this->root . '/' . $name);
unlink($tmpFile1);
}
public function testDir() {
$txtFile = $this->getTextFile();
$this->share->mkdir($this->root . '/dir');
$this->share->put($txtFile, $this->root . '/file.txt');
unlink($txtFile);
$dir = $this->share->dir($this->root);
if ($dir[0]->getName() === 'dir') {
$dirEntry = $dir[0];
} else {
$dirEntry = $dir[1];
}
$this->assertTrue($dirEntry->isDirectory());
$this->assertFalse($dirEntry->isReadOnly());
$this->assertFalse($dirEntry->isReadOnly());
if ($dir[0]->getName() === 'file.txt') {
$fileEntry = $dir[0];
} else {
$fileEntry = $dir[1];
}
$this->assertFalse($fileEntry->isDirectory());
$this->assertFalse($fileEntry->isReadOnly());
$this->assertFalse($fileEntry->isReadOnly());
}
/**
* @dataProvider nameProvider
*/
public function testStat($name) {
$txtFile = $this->getTextFile();
$size = filesize($txtFile);
$this->share->put($txtFile, $this->root . '/' . $name);
unlink($txtFile);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertEquals($size, $info->getSize());
}
/**
* @expectedException \Icewind\SMB\Exception\NotFoundException
*/
public function testStatNonExisting() {
$this->share->stat($this->root . '/fo.txt');
}
/**
* note setting archive and system bit is not supported
*
* @dataProvider nameProvider
*/
public function testSetMode($name) {
$txtFile = $this->getTextFile();
$this->share->put($txtFile, $this->root . '/' . $name);
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_NORMAL);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertFalse($info->isReadOnly());
$this->assertFalse($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertFalse($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_READONLY);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertTrue($info->isReadOnly());
$this->assertFalse($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertFalse($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_ARCHIVE);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertFalse($info->isReadOnly());
$this->assertTrue($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertFalse($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertTrue($info->isReadOnly());
$this->assertTrue($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertFalse($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_HIDDEN);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertFalse($info->isReadOnly());
$this->assertFalse($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertTrue($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_SYSTEM);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertFalse($info->isReadOnly());
$this->assertFalse($info->isArchived());
$this->assertTrue($info->isSystem());
$this->assertFalse($info->isHidden());
$this->share->setMode($this->root . '/' . $name, FileInfo::MODE_NORMAL);
$info = $this->share->stat($this->root . '/' . $name);
$this->assertFalse($info->isReadOnly());
$this->assertFalse($info->isArchived());
$this->assertFalse($info->isSystem());
$this->assertFalse($info->isHidden());
}
public function pathProvider() {
// / ? < > \ : * | " are illegal characters in path on windows
return array(
array('dir/sub/foo.txt'),
array('bar.txt'),
array("single'quote'/sub/foo.txt"),
array('日本語/url %2F +encode/asd.txt'),
array(
'a somewhat longer folder than the other with more charaters as the all the other filenames/' .
'followed by a somewhat long file name after that.txt'
)
);
}
/**
* @dataProvider pathProvider
*/
public function testSubDirs($path) {
$dirs = explode('/', $path);
$name = array_pop($dirs);
$fullPath = '';
foreach ($dirs as $dir) {
$fullPath .= '/' . $dir;
$this->share->mkdir($this->root . $fullPath);
}
$txtFile = $this->getTextFile();
$size = filesize($txtFile);
$this->share->put($txtFile, $this->root . $fullPath . '/' . $name);
unlink($txtFile);
$info = $this->share->stat($this->root . $fullPath . '/' . $name);
$this->assertEquals($size, $info->getSize());
$this->assertFalse($info->isHidden());
}
public function testDelAfterStat() {
$name = 'foo.txt';
$txtFile = $this->getTextFile();
$this->share->put($txtFile, $this->root . '/' . $name);
unlink($txtFile);
$this->share->stat($this->root . '/' . $name);
$this->share->del($this->root . '/foo.txt');
}
/**
* @param $name
* @dataProvider nameProvider
*/
public function testDirPaths($name) {
$txtFile = $this->getTextFile();
$this->share->mkdir($this->root . '/' . $name);
$this->share->put($txtFile, $this->root . '/' . $name . '/' . $name);
unlink($txtFile);
$content = $this->share->dir($this->root . '/' . $name);
$this->assertCount(1, $content);
$this->assertEquals($name, $content[0]->getName());
}
public function testStatRoot() {
$info = $this->share->stat('/');
$this->assertInstanceOf('\Icewind\SMB\IFileInfo', $info);
}
}
@@ -1,27 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
use Icewind\SMB\NativeServer;
class NativeShare extends AbstractShare {
public function setUp() {
if (!function_exists('smbclient_state_new')) {
$this->markTestSkipped('libsmbclient php extension not installed');
}
$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
$this->server = new NativeServer($this->config->host, $this->config->user, $this->config->password);
$this->share = $this->server->getShare($this->config->share);
if ($this->config->root) {
$this->root = '/' . $this->config->root . '/' . uniqid();
} else {
$this->root = '/' . uniqid();
}
$this->share->mkdir($this->root);
}
}
@@ -1,143 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
use Icewind\SMB\NativeServer;
class NativeStream extends \PHPUnit_Framework_TestCase {
/**
* @var \Icewind\SMB\Server $server
*/
protected $server;
/**
* @var \Icewind\SMB\NativeShare $share
*/
protected $share;
/**
* @var string $root
*/
protected $root;
protected $config;
public function setUp() {
if (!function_exists('smbclient_state_new')) {
$this->markTestSkipped('libsmbclient php extension not installed');
}
$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
$this->server = new NativeServer($this->config->host, $this->config->user, $this->config->password);
$this->share = $this->server->getShare($this->config->share);
if ($this->config->root) {
$this->root = '/' . $this->config->root . '/' . uniqid();
} else {
$this->root = '/' . uniqid();
}
$this->share->mkdir($this->root);
}
private function getTextFile() {
$text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';
$file = tempnam('/tmp', 'smb_test_');
file_put_contents($file, $text);
return $file;
}
public function testSeekTell() {
$sourceFile = $this->getTextFile();
$this->share->put($sourceFile, $this->root . '/foobar');
$fh = $this->share->read($this->root . '/foobar');
$content = fread($fh, 3);
$this->assertEquals('Lor', $content);
fseek($fh, -2, SEEK_CUR);
$content = fread($fh, 3);
$this->assertEquals('ore', $content);
fseek($fh, 3, SEEK_SET);
$content = fread($fh, 3);
$this->assertEquals('em ', $content);
fseek($fh, -3, SEEK_END);
$content = fread($fh, 3);
$this->assertEquals('qua', $content);
fseek($fh, -3, SEEK_END);
$this->assertEquals(120, ftell($fh));
}
public function testStat() {
$sourceFile = $this->getTextFile();
$this->share->put($sourceFile, $this->root . '/foobar');
$fh = $this->share->read($this->root . '/foobar');
$stat = fstat($fh);
$this->assertEquals(filesize($sourceFile), $stat['size']);
unlink($sourceFile);
}
public function testTruncate() {
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
}
$fh = $this->share->write($this->root . '/foobar');
fwrite($fh, 'foobar');
ftruncate($fh, 3);
fclose($fh);
$fh = $this->share->read($this->root . '/foobar');
$this->assertEquals('foo', stream_get_contents($fh));
}
public function testEOF() {
if (version_compare(phpversion(), '5.4.0', '<')) {
$this->markTestSkipped('php <5.4 doesn\'t support truncate for stream wrappers');
}
$fh = $this->share->write($this->root . '/foobar');
fwrite($fh, 'foobar');
fclose($fh);
$fh = $this->share->read($this->root . '/foobar');
fread($fh, 3);
$this->assertFalse(feof($fh));
fread($fh, 5);
$this->assertTrue(feof($fh));
}
public function testLockUnsupported() {
$fh = $this->share->write($this->root . '/foobar');
$this->assertFalse(flock($fh, LOCK_SH));
}
public function testSetOptionUnsupported() {
$fh = $this->share->write($this->root . '/foobar');
$this->assertFalse(stream_set_blocking($fh, false));
}
public function tearDown() {
if ($this->share) {
$this->cleanDir($this->root);
}
unset($this->share);
}
public function cleanDir($dir) {
$content = $this->share->dir($dir);
foreach ($content as $metadata) {
if ($metadata->isDirectory()) {
$this->cleanDir($metadata->getPath());
} else {
$this->share->del($metadata->getPath());
}
}
$this->share->rmdir($dir);
}
}
@@ -1,103 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
use Icewind\SMB\FileInfo;
class Parser extends \PHPUnit_Framework_TestCase {
public function modeProvider() {
return array(
array('D', FileInfo::MODE_DIRECTORY),
array('A', FileInfo::MODE_ARCHIVE),
array('S', FileInfo::MODE_SYSTEM),
array('H', FileInfo::MODE_HIDDEN),
array('R', FileInfo::MODE_READONLY),
array('N', FileInfo::MODE_NORMAL),
array('RA', FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE),
array('RAH', FileInfo::MODE_READONLY | FileInfo::MODE_ARCHIVE | FileInfo::MODE_HIDDEN)
);
}
/**
* @param string $timeZone
* @return \Icewind\SMB\TimeZoneProvider
*/
private function getTimeZoneProvider($timeZone) {
$mock = $this->getMockBuilder('\Icewind\SMB\TimeZoneProvider')
->disableOriginalConstructor()
->getMock();
$mock->expects($this->any())
->method('get')
->will($this->returnValue($timeZone));
return $mock;
}
/**
* @dataProvider modeProvider
*/
public function testParseMode($string, $mode) {
$parser = new \Icewind\SMB\Parser($this->getTimeZoneProvider('UTC'));
$this->assertEquals($mode, $parser->parseMode($string), 'Failed parsing ' . $string);
}
public function statProvider() {
return array(
array(
array(
'altname: test.txt',
'create_time: Sat Oct 12 07:05:58 PM 2013 CEST',
'access_time: Tue Oct 15 02:58:48 PM 2013 CEST',
'write_time: Sat Oct 12 07:05:58 PM 2013 CEST',
'change_time: Sat Oct 12 07:05:58 PM 2013 CEST',
'attributes: (80)',
'stream: [::$DATA], 29634 bytes'
),
array(
'mtime' => strtotime('12 Oct 2013 19:05:58 CEST'),
'mode' => FileInfo::MODE_NORMAL,
'size' => 29634
)
)
);
}
/**
* @dataProvider statProvider
*/
public function testStat($output, $stat) {
$parser = new \Icewind\SMB\Parser($this->getTimeZoneProvider('UTC'));
$this->assertEquals($stat, $parser->parseStat($output));
}
public function dirProvider() {
return array(
array(
array(
' . D 0 Tue Aug 26 19:11:56 2014',
' .. DR 0 Sun Oct 28 15:24:02 2012',
' c.pdf N 29634 Sat Oct 12 19:05:58 2013',
'',
' 62536 blocks of size 8388608. 57113 blocks available'
),
array(
new FileInfo('/c.pdf', 'c.pdf', 29634, strtotime('12 Oct 2013 19:05:58 CEST'),
FileInfo::MODE_NORMAL)
)
)
);
}
/**
* @dataProvider dirProvider
*/
public function testDir($output, $dir) {
$parser = new \Icewind\SMB\Parser($this->getTimeZoneProvider('CEST'));
$this->assertEquals($dir, $parser->parseDir($output, ''));
}
}
@@ -1,57 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
class Server extends \PHPUnit_Framework_TestCase {
/**
* @var \Icewind\SMB\Server $server
*/
private $server;
private $config;
public function setUp() {
$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
$this->server = new \Icewind\SMB\Server($this->config->host, $this->config->user, $this->config->password);
}
public function testListShares() {
$shares = $this->server->listShares();
foreach ($shares as $share) {
if ($share->getName() === $this->config->share) {
return;
}
}
$this->fail('Share "' . $this->config->share . '" not found');
}
/**
* @expectedException \Icewind\SMB\Exception\AuthenticationException
*/
public function testWrongUserName() {
$this->markTestSkipped('This fails for no reason on travis');
$server = new \Icewind\SMB\Server($this->config->host, uniqid(), uniqid());
$server->listShares();
}
/**
* @expectedException \Icewind\SMB\Exception\AuthenticationException
*/
public function testWrongPassword() {
$server = new \Icewind\SMB\Server($this->config->host, $this->config->user, uniqid());
$server->listShares();
}
/**
* @expectedException \Icewind\SMB\Exception\InvalidHostException
*/
public function testWrongHost() {
$server = new \Icewind\SMB\Server(uniqid(), $this->config->user, $this->config->password);
$server->listShares();
}
}
@@ -1,24 +0,0 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Test;
use Icewind\SMB\Server as NormalServer;
class Share extends AbstractShare {
public function setUp() {
$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
$this->server = new NormalServer($this->config->host, $this->config->user, $this->config->password);
$this->share = $this->server->getShare($this->config->share);
if ($this->config->root) {
$this->root = '/' . $this->config->root . '/' . uniqid();
} else {
$this->root = '/' . uniqid();
}
$this->share->mkdir($this->root);
}
}
@@ -1,7 +0,0 @@
{
"host": "localhost",
"user": "test",
"password": "test",
"share": "test",
"root": "test"
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="bootstrap.php">
<testsuite name='SMB'>
<directory suffix='.php'>./</directory>
</testsuite>
</phpunit>
+1
View File
@@ -39,6 +39,7 @@ if (isset($_POST['client_id']) && isset($_POST['client_secret']) && isset($_POST
$client->setClientSecret((string)$_POST['client_secret']);
$client->setRedirectUri((string)$_POST['redirect']);
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$client->setApprovalPrompt('force');
$client->setAccessType('offline');
if (isset($_POST['step'])) {
$step = $_POST['step'];
@@ -90,6 +90,15 @@ abstract class StoragesController extends Controller {
}
// TODO: validate that other attrs are set
if ($storage->getBackendOption('objectstore')) {
// objectstore must not be sent from client side
return new DataResponse(
array(
'message' => (string)$this->l10n->t('Objectstore forbidden')
),
Http::STATUS_UNPROCESSABLE_ENTITY
);
}
$backends = \OC_Mount_Config::getBackends();
if (!isset($backends[$storage->getBackendClass()])) {
-6
View File
@@ -1,6 +0,0 @@
OC.L10N.register(
"files_external",
{
"Password" : "Secret Code"
},
"nplurals=2; plural=(n != 1);");
-4
View File
@@ -1,4 +0,0 @@
{ "translations": {
"Password" : "Secret Code"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+2 -2
View File
@@ -121,7 +121,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
$params['region'] = empty($params['region']) ? 'eu-west-1' : $params['region'];
$params['hostname'] = empty($params['hostname']) ? 's3.amazonaws.com' : $params['hostname'];
if (!isset($params['port']) || $params['port'] === '') {
$params['port'] = ($params['use_ssl'] === 'false') ? 80 : 443;
$params['port'] = ($params['use_ssl'] === false || $params['use_ssl'] === 'false') ? 80 : 443;
}
$this->params = $params;
}
@@ -586,7 +586,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
return $this->connection;
}
$scheme = ($this->params['use_ssl'] === 'false') ? 'http' : 'https';
$scheme = ($this->params['use_ssl'] === false || $this->params['use_ssl'] === 'false') ? 'http' : 'https';
$base_url = $scheme . '://' . $this->params['hostname'] . ':' . $this->params['port'] . '/';
$this->connection = S3Client::factory(array(
+3 -1
View File
@@ -297,7 +297,9 @@ class OC_Mount_Config {
}
}
} else {
$input = str_replace('$user', $user, $input);
if (is_string($input)) {
$input = str_replace('$user', $user, $input);
}
}
return $input;
}
+2
View File
@@ -291,6 +291,8 @@ class Google extends \OC\Files\Storage\Common {
}
$pageToken = $children->getNextPageToken();
}
// reindex values to compensate for removed duplicates
$files = array_values($files);
\OC\Files\Stream\Dir::register('google'.$path, $files);
return opendir('fakedir://google'.$path);
} else {
+16 -4
View File
@@ -35,6 +35,7 @@ use Icewind\SMB\NativeServer;
use Icewind\SMB\Server;
use Icewind\Streams\CallbackWrapper;
use Icewind\Streams\IteratorDirectory;
use OC\Cache\CappedMemoryCache;
use OC\Files\Filesystem;
class SMB extends Common {
@@ -48,10 +49,15 @@ class SMB extends Common {
*/
protected $share;
/**
* @var string
*/
protected $root;
/**
* @var \Icewind\SMB\FileInfo[]
*/
protected $statCache = array();
protected $statCache;
public function __construct($params) {
if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) {
@@ -72,13 +78,17 @@ class SMB extends Common {
} else {
throw new \Exception('Invalid configuration');
}
$this->statCache = new CappedMemoryCache();
}
/**
* @return string
*/
public function getId() {
return 'smb::' . $this->server->getUser() . '@' . $this->server->getHost() . '/' . $this->share->getName() . '/' . $this->root;
// FIXME: double slash to keep compatible with the old storage ids,
// failure to do so will lead to creation of a new storage id and
// loss of shares from the storage
return 'smb::' . $this->server->getUser() . '@' . $this->server->getHost() . '//' . $this->share->getName() . '/' . $this->root;
}
/**
@@ -295,7 +305,9 @@ class SMB extends Common {
* check if smbclient is installed
*/
public static function checkDependencies() {
$smbClientExists = (bool)\OC_Helper::findBinaryPath('smbclient');
return $smbClientExists ? true : array('smbclient');
return (
(bool)\OC_Helper::findBinaryPath('smbclient')
|| Server::NativeAvailable()
) ? true : ['smbclient'];
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ class SMB_OC extends SMB {
public function __construct($params) {
if (isset($params['host'])) {
$host = $params['host'];
$this->username_as_share = ($params['username_as_share'] === 'true');
$this->username_as_share = ($params['username_as_share'] === true);
// dummy credentials, unused, to satisfy constructor
$user = 'foo';
+19
View File
@@ -173,6 +173,25 @@ class StorageConfig implements \JsonSerializable {
$this->backendOptions = $backendOptions;
}
/**
* @param string $option
* @return mixed
*/
public function getBackendOption($key) {
if (isset($this->backendOptions[$key])) {
return $this->backendOptions[$key];
}
return null;
}
/**
* @param string $option
* @param mixed $value
*/
public function setBackendOption($key, $value) {
$this->backendOptions[$key] = $value;
}
/**
* Returns the mount priority
*
+4 -1
View File
@@ -40,8 +40,11 @@ abstract class StreamWrapper extends Common {
}
public function rmdir($path) {
if ($this->file_exists($path) && $this->isDeletable($path)) {
if ($this->is_dir($path) && $this->isDeletable($path)) {
$dh = $this->opendir($path);
if (!is_resource($dh)) {
return false;
}
while (($file = readdir($dh)) !== false) {
if ($this->is_dir($path . '/' . $file)) {
$this->rmdir($path . '/' . $file);
@@ -352,10 +352,14 @@ abstract class StoragesService {
if (!isset($allStorages[$id])) {
throw new NotFoundException('Storage with id "' . $id . '" not found');
}
$oldStorage = $allStorages[$id];
$allStorages[$id] = $updatedStorage;
// ensure objectstore is persistent
if ($objectstore = $oldStorage->getBackendOption('objectstore')) {
$updatedStorage->setBackendOption('objectstore', $objectstore);
}
$allStorages[$id] = $updatedStorage;
$this->writeConfig($allStorages);
$this->triggerChangeHooks($oldStorage, $updatedStorage);
+1 -1
View File
@@ -60,7 +60,7 @@
<?php elseif (strpos($placeholder, '!') === 0): ?>
<label><input type="checkbox"
data-parameter="<?php p($parameter); ?>"
<?php if ($value == 'true'): ?> checked="checked"<?php endif; ?>
<?php if ($value === true || $value === 'true'): ?> checked="checked"<?php endif; ?>
/><?php p(substr($placeholder, 1)); ?></label>
<?php elseif (strpos($placeholder, '#') === 0): ?>
<input type="hidden"
@@ -61,4 +61,16 @@ class SMB extends Storage {
$this->assertTrue($result);
$this->assertTrue($this->instance->is_dir('foo bar'));
}
public function testStorageId() {
$this->instance = new \OC\Files\Storage\SMB([
'host' => 'testhost',
'user' => 'testuser',
'password' => 'somepass',
'share' => 'someshare',
'root' => 'someroot',
]);
$this->assertEquals('smb::testuser@testhost//someshare//someroot/', $this->instance->getId());
$this->instance = null;
}
}
+11 -1
View File
@@ -38,6 +38,7 @@ if (OCA\Files_Sharing\Helper::isIncomingServer2serverShareEnabled() === false) {
$token = $_POST['token'];
$remote = $_POST['remote'];
$owner = $_POST['owner'];
$ownerDisplayName = $_POST['ownerDisplayName'];
$name = $_POST['name'];
$password = $_POST['password'];
@@ -47,6 +48,14 @@ if(!\OCP\Util::isValidFileName($name)) {
exit();
}
$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
$currentServer = \OC::$server->getURLGenerator()->getAbsoluteURL('/');
if (\OC\Share\Helper::isSameUserOnSameServer($owner, $remote, $currentUser, $currentServer )) {
\OCP\JSON::error(array('data' => array('message' => $l->t('Not allowed to create a federated share with the same user server'))));
exit();
}
$externalManager = new \OCA\Files_Sharing\External\Manager(
\OC::$server->getDatabaseConnection(),
\OC\Files\Filesystem::getMountManager(),
@@ -56,11 +65,12 @@ $externalManager = new \OCA\Files_Sharing\External\Manager(
);
// check for ssl cert
if (substr($remote, 0, 5) === 'https' and !OC_Util::getUrlContent($remote)) {
\OCP\JSON::error(array('data' => array('message' => $l->t('Invalid or untrusted SSL certificate'))));
exit;
} else {
$mount = $externalManager->addShare($remote, $token, $password, $name, $owner, true);
$mount = $externalManager->addShare($remote, $token, $password, $name, $ownerDisplayName, true);
/**
* @var \OCA\Files_Sharing\External\Storage $storage
+7 -1
View File
@@ -170,8 +170,14 @@ class Server2Server {
$query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external` WHERE `remote_id` = ? AND `share_token` = ?');
$query->execute(array($id, $token));
if ($share['accepted']) {
$path = trim($mountpoint, '/');
} else {
$path = trim($share['name'], '/');
}
\OC::$server->getActivityManager()->publishActivity(
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_UNSHARED, array($owner, $mountpoint), '', array(),
'files_sharing', \OCA\Files_Sharing\Activity::SUBJECT_REMOTE_SHARE_UNSHARED, array($owner, $path), '', array(),
'', '', $user, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::PRIORITY_MEDIUM);
}
+3 -7
View File
@@ -39,9 +39,6 @@ $l = \OC::$server->getL10N('files_sharing');
\OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
\OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
// Exceptions
\OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
$application = new Application();
$application->registerMountProviders();
$application->setupPropagation();
@@ -55,11 +52,10 @@ $application->setupPropagation();
\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
\OCP\Util::addScript('files_sharing', 'share');
\OCP\Util::addScript('files_sharing', 'external');
// FIXME: registering a job here will cause additional useless SQL queries
// when the route is not cron.php, needs a better way
\OC::$server->getJobList()->add('OCA\Files_sharing\Lib\DeleteOrphanedSharesJob');
if (\OC::$server->getConfig()->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes') {
\OCP\Util::addScript('files_sharing', 'external');
}
\OC::$server->getActivityManager()->registerExtension(function() {
return new \OCA\Files_Sharing\Activity(
+2 -5
View File
@@ -59,7 +59,6 @@ class Application extends App {
return new ExternalSharesController(
$c->query('AppName'),
$c->query('Request'),
$c->query('IsIncomingShareEnabled'),
$c->query('ExternalManager')
);
});
@@ -76,9 +75,6 @@ class Application extends App {
$container->registerService('UserManager', function (SimpleContainer $c) use ($server) {
return $server->getUserManager();
});
$container->registerService('IsIncomingShareEnabled', function (SimpleContainer $c) {
return Helper::isIncomingServer2serverShareEnabled();
});
$container->registerService('ExternalManager', function (SimpleContainer $c) use ($server) {
$user = $server->getUserSession()->getUser();
$uid = $user ? $user->getUID() : null;
@@ -98,7 +94,8 @@ class Application extends App {
return new SharingCheckMiddleware(
$c->query('AppName'),
$server->getConfig(),
$server->getAppManager()
$server->getAppManager(),
$c['ControllerMethodReflector']
);
});
-1
View File
@@ -19,5 +19,4 @@ Turning the feature off removes shared files and folders on the server for all s
<files>public.php</files>
<webdav>publicwebdav.php</webdav>
</public>
<ocsid>166050</ocsid>
</info>
+22
View File
@@ -0,0 +1,22 @@
<?php
/**
* @author Joas Schilling <nickvergessen@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
\OC::$server->getJobList()->add('OCA\Files_sharing\Lib\DeleteOrphanedSharesJob');
+1
View File
@@ -28,3 +28,4 @@ if (version_compare($installedVersion, '0.6.0', '<')) {
$m->addAcceptRow();
}
\OC::$server->getJobList()->add('OCA\Files_sharing\Lib\DeleteOrphanedSharesJob');
+1 -1
View File
@@ -1 +1 @@
0.6.1
0.6.3
+1 -1
View File
@@ -72,7 +72,7 @@ thead {
}
/* keep long file names in one line to not overflow download button on mobile */
.directDownload #download {
.directDownload #downloadFile {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
+2 -1
View File
@@ -19,7 +19,7 @@
*/
OCA.Sharing.showAddExternalDialog = function (share, passwordProtected, callback) {
var remote = share.remote;
var owner = share.owner;
var owner = share.ownerDisplayName || share.owner;
var name = share.name;
var remoteClean = (remote.substr(0, 8) === 'https://') ? remote.substr(8) : remote.substr(7);
@@ -92,6 +92,7 @@
remote: share.remote,
token: share.token,
owner: share.owner,
ownerDisplayName: share.ownerDisplayName || share.owner,
name: share.name,
password: password}, function(result) {
if (result.status === 'error') {
+17 -14
View File
@@ -158,9 +158,18 @@ OCA.Sharing.PublicApp = {
};
this.fileList.generatePreviewUrl = function (urlSpec) {
urlSpec = urlSpec || {};
if (!urlSpec.x) {
urlSpec.x = 36;
}
if (!urlSpec.y) {
urlSpec.y = 36;
}
urlSpec.x *= window.devicePixelRatio;
urlSpec.y *= window.devicePixelRatio;
urlSpec.x = Math.floor(urlSpec.x);
urlSpec.y = Math.floor(urlSpec.y);
urlSpec.t = $('#dirToken').val();
urlSpec.y = Math.floor(36 * window.devicePixelRatio);
urlSpec.x = Math.floor(36 * window.devicePixelRatio);
return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec);
};
@@ -213,9 +222,10 @@ OCA.Sharing.PublicApp = {
var remote = $(this).find('input[type="text"]').val();
var token = $('#sharingToken').val();
var owner = $('#save').data('owner');
var ownerDisplayName = $('#save').data('owner-display-name');
var name = $('#save').data('name');
var isProtected = $('#save').data('protected') ? 1 : 0;
OCA.Sharing.PublicApp._saveToOwnCloud(remote, token, owner, name, isProtected);
OCA.Sharing.PublicApp._saveToOwnCloud(remote, token, owner, ownerDisplayName, name, isProtected);
});
$('#save #save-button').click(function () {
@@ -254,11 +264,11 @@ OCA.Sharing.PublicApp = {
this.fileList.changeDirectory(params.path || params.dir, false, true);
},
_saveToOwnCloud: function (remote, token, owner, name, isProtected) {
_saveToOwnCloud: function (remote, token, owner, ownerDisplayName, name, isProtected) {
var location = window.location.protocol + '//' + window.location.host + OC.webroot;
var url = remote + '/index.php/apps/files#' + 'remote=' + encodeURIComponent(location) // our location is the remote for the other server
+ "&token=" + encodeURIComponent(token) + "&owner=" + encodeURIComponent(owner) + "&name=" + encodeURIComponent(name) + "&protected=" + isProtected;
+ "&token=" + encodeURIComponent(token) + "&owner=" + encodeURIComponent(owner) +"&ownerDisplayName=" + encodeURIComponent(ownerDisplayName) + "&name=" + encodeURIComponent(name) + "&protected=" + isProtected;
if (remote.indexOf('://') > 0) {
@@ -292,15 +302,8 @@ $(document).ready(function () {
if (window.Files) {
// HACK: for oc-dialogs previews that depends on Files:
Files.lazyLoadPreview = function (path, mime, ready, width, height, etag) {
return App.fileList.lazyLoadPreview({
path: path,
mime: mime,
callback: ready,
width: width,
height: height,
etag: etag
});
Files.generatePreviewUrl = function (urlSpec) {
return App.fileList.generatePreviewUrl(urlSpec);
};
}
});
+5 -1
View File
@@ -25,6 +25,10 @@
* @param {OCA.Files.FileList} fileList file list to be extended
*/
attach: function(fileList) {
// core sharing is disabled/not loaded
if (!OC.Share) {
return;
}
if (fileList.id === 'trashbin' || fileList.id === 'files.public') {
return;
}
@@ -151,7 +155,7 @@
var permissions = $tr.data('permissions');
var hasLink = !!(shareStatus && shareStatus.link);
OC.Share.markFileAsShared($tr, true, hasLink);
if ((permissions & OC.PERMISSION_SHARE) === 0) {
if ((permissions & OC.PERMISSION_SHARE) === 0 && $tr.attr('data-share-owner')) {
// if no share action exists because the admin disabled sharing for this user
// we create a share notification action to inform the user about files
// shared with him otherwise we just update the existing share action.
-7
View File
@@ -1,7 +0,0 @@
OC.L10N.register(
"files_sharing",
{
"Password" : "Secret Code",
"Download" : "Download"
},
"nplurals=2; plural=(n != 1);");
-5
View File
@@ -1,5 +0,0 @@
{ "translations": {
"Password" : "Secret Code",
"Download" : "Download"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+1 -1
View File
@@ -190,12 +190,12 @@ class Activity implements IExtension {
if ($app === self::FILES_SHARING_APP) {
switch ($text) {
case self::SUBJECT_REMOTE_SHARE_RECEIVED:
case self::SUBJECT_REMOTE_SHARE_UNSHARED:
return array(
0 => '',// We can not use 'username' since the user is in a different ownCloud
);
case self::SUBJECT_REMOTE_SHARE_ACCEPTED:
case self::SUBJECT_REMOTE_SHARE_DECLINED:
case self::SUBJECT_REMOTE_SHARE_UNSHARED:
return array(
0 => '',// We can not use 'username' since the user is in a different ownCloud
1 => 'file',
+9 -3
View File
@@ -31,6 +31,7 @@
namespace OC\Files\Cache;
use OC\User\NoUserException;
use OCP\Share_Backend_Collection;
/**
@@ -60,9 +61,14 @@ class Shared_Cache extends Cache {
if ($target === false || $target === $this->storage->getMountPoint()) {
$target = '';
}
$source = \OC_Share_Backend_File::getSource($target, $this->storage->getMountPoint(), $this->storage->getItemType());
$source = \OC_Share_Backend_File::getSource($target, $this->storage->getShare());
if (isset($source['path']) && isset($source['fileOwner'])) {
\OC\Files\Filesystem::initMountPoints($source['fileOwner']);
try {
\OC\Files\Filesystem::initMountPoints($source['fileOwner']);
} catch(NoUserException $e) {
\OCP\Util::logException('files_sharing', $e);
return false;
}
$mounts = \OC\Files\Filesystem::getMountByNumericId($source['storage']);
if (is_array($mounts) and !empty($mounts)) {
$fullPath = $mounts[0]->getMountPoint() . $source['path'];
@@ -242,7 +248,7 @@ class Shared_Cache extends Cache {
*/
protected function getMoveInfo($path) {
$cache = $this->getSourceCache($path);
$file = \OC_Share_Backend_File::getSource($path, $this->storage->getMountPoint(), $this->storage->getItemType());
$file = \OC_Share_Backend_File::getSource($path, $this->storage->getShare());
return [$cache->getNumericStorageId(), $file['path']];
}
+5 -5
View File
@@ -59,20 +59,20 @@ class Capabilities {
$public['enabled'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
if ($public['enabled']) {
$public['password'] = [];
$public['password']['enforced'] = ($this->config->getAppValue('core', 'shareapi_enforce_links_password', 'yes') === 'yes');
$public['password']['enforced'] = ($this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes');
$public['expire_date'] = [];
$public['expire_date']['enabled'] = $this->config->getAppValue('core', 'shareapi_default_expire_date', 'yes') === 'yes';
$public['expire_date']['enabled'] = $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
if ($public['expire_date']['enabled']) {
$public['expire_date']['days'] = $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
$public['expire_date']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'yes') === 'yes';
$public['expire_date']['enforced'] = $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
}
$public['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'yes') === 'yes';
$public['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no') === 'yes';
}
$res["public"] = $public;
$res['user']['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'yes') === 'yes';
$res['user']['send_mail'] = $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'no') === 'yes';
$res['resharing'] = $this->config->getAppValue('core', 'shareapi_allow_resharing', 'yes') === 'yes';
@@ -60,6 +60,11 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
return false;
}
if ((int)$linkItem['share_type'] === \OCP\Share::SHARE_TYPE_LINK &&
$this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') !== 'yes') {
$this->share['permissions'] &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE);
}
// check if the share is password protected
if (isset($linkItem['share_with'])) {
if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) {
@@ -82,10 +87,13 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
}
return true;
} else if (\OC::$server->getSession()->exists('public_link_authenticated')
&& \OC::$server->getSession()->get('public_link_authenticated') === $linkItem['id']) {
return true;
} else {
return false;
}
} elseif ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_REMOTE) {
} else if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_REMOTE) {
return true;
} else {
return false;
@@ -36,8 +36,6 @@ use OCP\AppFramework\Http\JSONResponse;
*/
class ExternalSharesController extends Controller {
/** @var bool */
private $incomingShareEnabled;
/** @var \OCA\Files_Sharing\External\Manager */
private $externalManager;
@@ -49,52 +47,42 @@ class ExternalSharesController extends Controller {
*/
public function __construct($appName,
IRequest $request,
$incomingShareEnabled,
\OCA\Files_Sharing\External\Manager $externalManager) {
parent::__construct($appName, $request);
$this->incomingShareEnabled = $incomingShareEnabled;
$this->externalManager = $externalManager;
}
/**
* @NoAdminRequired
* @NoOutgoingFederatedSharingRequired
*
* @return JSONResponse
*/
public function index() {
$shares = [];
if ($this->incomingShareEnabled) {
$shares = $this->externalManager->getOpenShares();
}
return new JSONResponse($shares);
return new JSONResponse($this->externalManager->getOpenShares());
}
/**
* @NoAdminRequired
* @NoOutgoingFederatedSharingRequired
*
* @param int $id
* @return JSONResponse
*/
public function create($id) {
if ($this->incomingShareEnabled) {
$this->externalManager->acceptShare($id);
}
$this->externalManager->acceptShare($id);
return new JSONResponse();
}
/**
* @NoAdminRequired
* @NoOutgoingFederatedSharingRequired
*
* @param $id
* @return JSONResponse
*/
public function destroy($id) {
if ($this->incomingShareEnabled) {
$this->externalManager->declineShare($id);
}
$this->externalManager->declineShare($id);
return new JSONResponse();
}
}
@@ -46,6 +46,7 @@ use OCA\Files_Sharing\Helper;
use OCP\User;
use OCP\Util;
use OCA\Files_Sharing\Activity;
use \OCP\Files\NotFoundException;
/**
* Class ShareController
@@ -148,6 +149,7 @@ class ShareController extends Controller {
* @param string $token
* @param string $path
* @return TemplateResponse|RedirectResponse
* @throws NotFoundException
*/
public function showShare($token, $path = '') {
\OC_User::setIncognitoMode(true);
@@ -171,13 +173,14 @@ class ShareController extends Controller {
$getPath = Filesystem::normalizePath($path);
$originalSharePath .= $path;
} else {
throw new OCP\Files\NotFoundException();
throw new NotFoundException();
}
$file = basename($originalSharePath);
$shareTmpl = [];
$shareTmpl['displayName'] = User::getDisplayName($shareOwner);
$shareTmpl['owner'] = $shareOwner;
$shareTmpl['filename'] = $file;
$shareTmpl['directory_path'] = $linkItem['file_target'];
$shareTmpl['mimetype'] = Filesystem::getMimeType($originalSharePath);
@@ -303,7 +306,7 @@ class ShareController extends Controller {
/**
* @param string $token
* @return string Resolved file path of the token
* @throws \Exception In case share could not get properly resolved
* @throws NotFoundException In case share could not get properly resolved
*/
private function getPath($token) {
$linkItem = Share::getShareByToken($token, false);
@@ -312,7 +315,7 @@ class ShareController extends Controller {
$rootLinkItem = Share::resolveReShare($linkItem);
if (isset($rootLinkItem['uid_owner'])) {
if(!$this->userManager->userExists($rootLinkItem['uid_owner'])) {
throw new \Exception('Owner of the share does not exist anymore');
throw new NotFoundException('Owner of the share does not exist anymore');
}
OC_Util::tearDownFS();
OC_Util::setupFS($rootLinkItem['uid_owner']);
@@ -324,6 +327,6 @@ class ShareController extends Controller {
}
}
throw new \Exception('No file found belonging to file.');
throw new NotFoundException('No file found belonging to file.');
}
}
@@ -0,0 +1,26 @@
<?php
/**
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Files_Sharing\Exceptions;
/**
* S2S sharing not allowed
*/
class S2SException extends \Exception {
}
+2 -1
View File
@@ -48,9 +48,10 @@ class Scanner extends \OC\Files\Cache\Scanner {
* @param int $reuseExisting
* @param int $parentId
* @param array | null $cacheData existing data in the cache for the file to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @return array an array of metadata of the scanned file
*/
public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null) {
public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
try {
return parent::scanFile($file, $reuseExisting);
} catch (ForbiddenException $e) {
+17 -13
View File
@@ -191,7 +191,7 @@ class Storage extends DAV implements ISharedStorage {
throw new StorageInvalidException();
} else {
// ownCloud instance is gone, likely to be a temporary server configuration error
throw $e;
throw new StorageNotAvailableException();
}
} catch (ForbiddenException $e) {
// auth error, remove share for now (provide a dialog in the future)
@@ -201,10 +201,7 @@ class Storage extends DAV implements ISharedStorage {
} catch (\GuzzleHttp\Exception\ConnectException $e) {
throw new StorageNotAvailableException();
} catch (\GuzzleHttp\Exception\RequestException $e) {
if ($e->getCode() === 503) {
throw new StorageNotAvailableException();
}
throw $e;
throw new StorageNotAvailableException();
} catch (\Exception $e) {
throw $e;
}
@@ -250,18 +247,25 @@ class Storage extends DAV implements ISharedStorage {
try {
$response = $client->post($url, ['body' => ['password' => $password]]);
} catch (\GuzzleHttp\Exception\RequestException $e) {
switch ($e->getCode()) {
case 401:
case 403:
if ($e->getCode() === 401 || $e->getCode() === 403) {
throw new ForbiddenException();
case 404:
throw new NotFoundException();
case 500:
throw new \Exception();
}
throw $e;
if ($e->getCode() === 404) {
throw new NotFoundException();
}
// throw this to be on the safe side: the share will still be visible
// in the UI in case the failure is intermittent, and the user will
// be able to decide whether to remove it if it's really gone
throw new StorageNotAvailableException();
}
return json_decode($response->getBody(), true);
}
public function isSharable($path) {
if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
return false;
}
return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
}
}
@@ -27,7 +27,11 @@ use OCP\App\IAppManager;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Middleware;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Files\NotFoundException;
use OCP\IConfig;
use OCP\AppFramework\Utility\IControllerMethodReflector;
use OCA\Files_Sharing\Exceptions\S2SException;
use OCP\AppFramework\Http\JSONResponse;
/**
* Checks whether the "sharing check" is enabled
@@ -42,6 +46,8 @@ class SharingCheckMiddleware extends Middleware {
protected $config;
/** @var IAppManager */
protected $appManager;
/** @var IControllerMethodReflector */
protected $reflector;
/***
* @param string $appName
@@ -50,30 +56,74 @@ class SharingCheckMiddleware extends Middleware {
*/
public function __construct($appName,
IConfig $config,
IAppManager $appManager) {
IAppManager $appManager,
IControllerMethodReflector $reflector
) {
$this->appName = $appName;
$this->config = $config;
$this->appManager = $appManager;
$this->reflector = $reflector;
}
/**
* Check if sharing is enabled before the controllers is executed
*
* @param \OCP\AppFramework\Controller $controller
* @param string $methodName
* @throws NotFoundException
*/
public function beforeController($controller, $methodName) {
if(!$this->isSharingEnabled()) {
throw new \Exception('Sharing is disabled.');
throw new NotFoundException('Sharing is disabled.');
}
if ($controller instanceof \OCA\Files_Sharing\Controllers\ExternalSharesController &&
!$this->externalSharesChecks()) {
throw new S2SException('Federated sharing not allowed');
} else if ($controller instanceof \OCA\Files_Sharing\Controllers\ShareController &&
!$this->isLinkSharingEnabled()) {
throw new NotFoundException('Link sharing is disabled');
}
}
/**
* Return 404 page in case of an exception
* Return 404 page in case of a not found exception
*
* @param \OCP\AppFramework\Controller $controller
* @param string $methodName
* @param \Exception $exception
* @return TemplateResponse
* @return NotFoundResponse
* @throws \Exception
*/
public function afterException($controller, $methodName, \Exception $exception){
return new NotFoundResponse();
public function afterException($controller, $methodName, \Exception $exception) {
if(is_a($exception, '\OCP\Files\NotFoundException')) {
return new NotFoundResponse();
}
if (is_a($exception, '\OCA\Files_Sharing\Exceptions\S2SException')) {
return new JSONResponse($exception->getMessage(), 405);
}
throw $exception;
}
/**
* Checks for externalshares controller
* @return bool
*/
private function externalSharesChecks() {
if (!$this->reflector->hasAnnotation('NoIncomingFederatedSharingRequired') &&
$this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') !== 'yes') {
return false;
}
if (!$this->reflector->hasAnnotation('NoOutgoingFederatedSharingRequired') &&
$this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') !== 'yes') {
return false;
}
return true;
}
/**
@@ -87,6 +137,19 @@ class SharingCheckMiddleware extends Middleware {
return false;
}
return true;
}
/**
* Check if link sharing is allowed
* @return bool
*/
private function isLinkSharingEnabled() {
// Check if the shareAPI is enabled
if ($this->config->getAppValue('core', 'shareapi_enabled', 'yes') !== 'yes') {
return false;
}
// Check whether public sharing is enabled
if($this->config->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
return false;
-6
View File
@@ -66,12 +66,6 @@ class MountProvider implements IMountProvider {
return $share['permissions'] > 0;
});
$shares = array_map(function ($share) use ($user, $storageFactory) {
try {
Filesystem::initMountPoints($share['uid_owner']);
} catch(NoUserException $e) {
\OC::$server->getLogger()->warning('The user \'' . $share['uid_owner'] . '\' of share with ID \'' . $share['id'] . '\' can\'t be retrieved.', array('app' => 'files_sharing'));
return null;
}
// for updating etags for the share owner when we make changes to this share.
$ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']);
@@ -126,20 +126,28 @@ class RecipientPropagator {
});
}
protected $propagatingIds = [];
public function propagateById($id) {
if (isset($this->propagatingIds[$id])) {
return;
}
$this->propagatingIds[$id] = true;
$shares = Share::getAllSharesForFileId($id);
foreach ($shares as $share) {
// propagate down the share tree
$this->markDirty($share, microtime(true));
// propagate up the share tree
$user = $share['uid_owner'];
if($user !== $this->userId) {
if ($share['share_with'] === $this->userId) {
$user = $share['uid_owner'];
$view = new View('/' . $user . '/files');
$path = $view->getPath($share['file_source']);
$watcher = new ChangeWatcher($view, $this->manager->getSharePropagator($user));
$watcher->writeHook(['path' => $path]);
}
}
unset($this->propagatingIds[$id]);
}
}
+7 -19
View File
@@ -206,27 +206,15 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent {
/**
* @param string $target
* @param string $mountPoint
* @param string $itemType
* @param array $share
* @return array|false source item
*/
public static function getSource($target, $mountPoint, $itemType) {
if ($itemType === 'folder') {
$source = \OCP\Share::getItemSharedWith('folder', $mountPoint, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
if ($source && $target !== '') {
// note: in case of ext storage mount points the path might be empty
// which would cause a leading slash to appear
$source['path'] = ltrim($source['path'] . '/' . $target, '/');
}
} else {
$source = \OCP\Share::getItemSharedWith('file', $mountPoint, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
public static function getSource($target, $share) {
if ($share['item_type'] === 'folder' && $target !== '') {
// note: in case of ext storage mount points the path might be empty
// which would cause a leading slash to appear
$share['path'] = ltrim($share['path'] . '/' . $target, '/');
}
if ($source) {
return self::resolveReshares($source);
}
\OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::DEBUG);
return false;
return self::resolveReshares($share);
}
}
+27 -14
View File
@@ -41,35 +41,47 @@ class SharedMount extends MountPoint implements MoveableMount {
*/
protected $ownerPropagator;
/**
* @var \OC\Files\View
*/
private $recipientView;
/**
* @var string
*/
private $user;
public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
// first update the mount point before creating the parent
$this->ownerPropagator = $arguments['propagator'];
$newMountPoint = $this->verifyMountPoint($arguments['share'], $arguments['user']);
$absMountPoint = '/' . $arguments['user'] . '/files' . $newMountPoint;
$this->user = $arguments['user'];
$this->recipientView = new View('/' . $this->user . '/files');
$newMountPoint = $this->verifyMountPoint($arguments['share']);
$absMountPoint = '/' . $this->user . '/files' . $newMountPoint;
$arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files');
parent::__construct($storage, $absMountPoint, $arguments, $loader);
}
/**
* check if the parent folder exists otherwise move the mount point up
*/
private function verifyMountPoint(&$share, $user) {
private function verifyMountPoint(&$share) {
$mountPoint = basename($share['file_target']);
$parent = dirname($share['file_target']);
$view = new View('/' . $user . '/files');
if (!$view->is_dir($parent)) {
if (!$this->recipientView->is_dir($parent)) {
$parent = Helper::getShareFolder();
}
$newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(
\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
array(),
new \OC\Files\View('/' . $user . '/files')
);
\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint),
[],
$this->recipientView
);
if($newMountPoint !== $share['file_target']) {
self::updateFileTarget($newMountPoint, $share);
if ($newMountPoint !== $share['file_target']) {
$this->updateFileTarget($newMountPoint, $share);
$share['file_target'] = $newMountPoint;
$share['unique_name'] = true;
}
@@ -79,11 +91,12 @@ class SharedMount extends MountPoint implements MoveableMount {
/**
* update fileTarget in the database if the mount point changed
*
* @param string $newPath
* @param array $share reference to the share which should be modified
* @return bool
*/
private static function updateFileTarget($newPath, &$share) {
private function updateFileTarget($newPath, &$share) {
// if the user renames a mount point from a group share we need to create a new db entry
// for the unique name
if ($share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP && empty($share['unique_name'])) {
@@ -91,7 +104,7 @@ class SharedMount extends MountPoint implements MoveableMount {
.' `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
.' `file_target`, `token`, `parent`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
$arguments = array($share['item_type'], $share['item_source'], $share['item_target'],
2, \OCP\User::getUser(), $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'],
2, $this->user, $share['uid_owner'], $share['permissions'], $share['stime'], $share['file_source'],
$newPath, $share['token'], $share['id']);
} else {
// rename mount point
@@ -99,7 +112,7 @@ class SharedMount extends MountPoint implements MoveableMount {
'Update `*PREFIX*share`
SET `file_target` = ?
WHERE `id` = ?'
);
);
$arguments = array($newPath, $share['id']);
}
+25 -4
View File
@@ -45,8 +45,18 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
private $files = array();
private static $isInitialized = array();
/**
* @var \OC\Files\View
*/
private $ownerView;
public function __construct($arguments) {
$this->share = $arguments['share'];
$this->ownerView = $arguments['ownerView'];
}
private function init() {
Filesystem::initMountPoints($this->share['uid_owner']);
}
/**
@@ -74,17 +84,18 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
* @return array Returns array with the keys path, permissions, and owner or false if not found
*/
public function getFile($target) {
$this->init();
if (!isset($this->files[$target])) {
// Check for partial files
if (pathinfo($target, PATHINFO_EXTENSION) === 'part') {
$source = \OC_Share_Backend_File::getSource(substr($target, 0, -5), $this->getMountPoint(), $this->getItemType());
$source = \OC_Share_Backend_File::getSource(substr($target, 0, -5), $this->getShare());
if ($source) {
$source['path'] .= '.part';
// All partial files have delete permission
$source['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
}
} else {
$source = \OC_Share_Backend_File::getSource($target, $this->getMountPoint(), $this->getItemType());
$source = \OC_Share_Backend_File::getSource($target, $this->getShare());
}
$this->files[$target] = $source;
}
@@ -236,7 +247,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
}
public function isSharable($path) {
if (\OCP\Util::isSharingDisabledForUser()) {
if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) {
return false;
}
return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE);
@@ -313,7 +324,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
}
public function rename($path1, $path2) {
$this->init();
// we need the paths relative to data/user/files
$relPath1 = $this->getMountPoint() . '/' . $path1;
$relPath2 = $this->getMountPoint() . '/' . $path2;
@@ -623,6 +634,11 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/** @var \OCP\Files\Storage $targetStorage */
list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
$targetStorage->acquireLock($targetInternalPath, $type, $provider);
// lock the parent folders of the owner when locking the share as recipient
if ($path === '') {
$sourcePath = $this->ownerView->getPath($this->share['file_source']);
$this->ownerView->lockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
}
}
/**
@@ -634,6 +650,11 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/** @var \OCP\Files\Storage $targetStorage */
list($targetStorage, $targetInternalPath) = $this->resolvePath($path);
$targetStorage->releaseLock($targetInternalPath, $type, $provider);
// unlock the parent folders of the owner when unlocking the share as recipient
if ($path === '') {
$sourcePath = $this->ownerView->getPath($this->share['file_source']);
$this->ownerView->unlockFile(dirname($sourcePath), ILockingProvider::LOCK_SHARED, true);
}
}
/**
+44
View File
@@ -56,6 +56,50 @@ class Shared_Updater {
*/
static public function renameHook($params) {
self::renameChildren($params['oldpath'], $params['newpath']);
self::moveShareToShare($params['newpath']);
}
/**
* Fix for https://github.com/owncloud/core/issues/20769
*
* The owner is allowed to move their files (if they are shared) into a receiving folder
* In this case we need to update the parent of the moved share. Since they are
* effectively handing over ownership of the file the rest of the code needs to know
* they need to build up the reshare tree.
*
* @param string $path
*/
static private function moveShareToShare($path) {
$userFolder = \OC::$server->getUserFolder();
// If the user folder can't be constructed (e.g. link share) just return.
if ($userFolder === null) {
return;
}
$src = $userFolder->get($path);
$type = $src instanceof \OCP\Files\File ? 'file' : 'folder';
$shares = \OCP\Share::getItemShared($type, $src->getId());
// If the path we move is not a share we don't care
if (empty($shares)) {
return;
}
// Check if the destination is inside a share
$mountManager = \OC\Files\Filesystem::getMountManager();
$dstMount = $mountManager->find($src->getPath());
if (!($dstMount instanceof \OCA\Files_Sharing\SharedMount)) {
return;
}
$parenShare = $dstMount->getShare();
foreach ($shares as $share) {
$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` = ?');
$query->execute([$parenShare['id'], $share['id']]);
}
}
/**

Some files were not shown because too many files have changed in this diff Show More