2222
2323use OC \Files \View ;
2424use OC \Share20 \Manager ;
25+ use OC \Share20 \ShareAttributes ;
2526use OCP \Files \File ;
2627use OC \Share20 \Share ;
2728use OCP \DB \QueryBuilder \IExpressionBuilder ;
3940use OCP \ILogger ;
4041use OCP \IUser ;
4142use OCP \IUserManager ;
43+ use OCP \IUserSession ;
4244use OCP \Security \IHasher ;
4345use OCP \Security \ISecureRandom ;
4446use OCP \Share \Exceptions \ShareNotFound ;
47+ use OCP \Share \IAttributes ;
4548use OCP \Share \IProviderFactory ;
4649use OCP \Share \IShare ;
4750use OCP \Share \IShareProvider ;
@@ -88,6 +91,8 @@ class ManagerTest extends \Test\TestCase {
8891 protected $ view ;
8992 /** @var IDBConnection | \PHPUnit\Framework\MockObject\MockObject */
9093 protected $ connection ;
94+ /** @var IUserSession | \PHPUnit\Framework\MockObject\MockObject */
95+ protected $ userSession ;
9196
9297 public function setUp () {
9398 parent ::setUp ();
@@ -103,6 +108,7 @@ public function setUp() {
103108 $ this ->eventDispatcher = new EventDispatcher ();
104109 $ this ->view = $ this ->createMock (View::class);
105110 $ this ->connection = $ this ->createMock (IDBConnection::class);
111+ $ this ->userSession = $ this ->createMock (IUserSession::class);
106112
107113 $ this ->l = $ this ->createMock ('\OCP\IL10N ' );
108114 $ this ->l ->method ('t ' )
@@ -125,7 +131,8 @@ public function setUp() {
125131 $ this ->rootFolder ,
126132 $ this ->eventDispatcher ,
127133 $ this ->view ,
128- $ this ->connection
134+ $ this ->connection ,
135+ $ this ->userSession
129136 );
130137
131138 $ this ->defaultProvider = $ this ->getMockBuilder ('\OC\Share20\DefaultShareProvider ' )
@@ -819,26 +826,18 @@ public function dataGeneralChecks() {
819826 $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_GROUP , $ rootFolder , $ group0 , $ user0 , $ user0 , 2 , null , null ), 'You can \'t share your root folder ' , true ];
820827 $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_LINK , $ rootFolder , null , $ user0 , $ user0 , 16 , null , null ), 'You can \'t share your root folder ' , true ];
821828
822- /**
823- * Basic share (not re-share) with enough permission inputs
824- */
825- $ ownerUser = $ this ->createMock (IUser::class);
826- $ ownerUser ->method ('getUID ' )->willReturn ('user1 ' );
827829 $ fileFullPermission = $ this ->createMock (File::class);
828830 $ fileFullPermission ->method ('getPermissions ' )->willReturn (31 );
829- $ fileFullPermission ->method ('getOwner ' )->willReturn ($ ownerUser );
830831 $ fileFullPermission ->method ('isShareable ' )->willReturn (true );
832+
831833 $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileFullPermission , $ user0 , $ user1 , $ user1 , null , null , null ), 'A share requires permissions ' , true ];
832834
833- /**
834- * Normal share (not re-share) with not enough permission input
835- */
836- $ fileLessPermission = $ this ->createMock (File::class);
837- $ fileLessPermission ->method ('getPermissions ' )->willReturn (1 );
838- $ fileLessPermission ->method ('getOwner ' )->willReturn ($ ownerUser );
839- $ fileLessPermission ->method ('isShareable ' )->willReturn (true );
840- $ fileLessPermission ->method ('getPath ' )->willReturn ('/user1/sharedfile ' );
841- $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileLessPermission , $ user0 , $ user1 , $ user1 , 17 , null , null ), 'Cannot increase permissions of /user1/sharedfile ' , true ];
835+ $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileFullPermission , $ user0 , $ user1 , $ user1 , -1 , null , null ), 'Invalid permissions ' , true ];
836+ $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileFullPermission , $ user0 , $ user1 , $ user1 , 100 , null , null ), 'Invalid permissions ' , true ];
837+
838+ $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileFullPermission , $ user0 , $ user1 , $ user1 , 0 , null , null ), 'Cannot remove all permissions ' , true ];
839+
840+ $ data [] = [$ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ fileFullPermission , $ user0 , $ user1 , $ user1 , 31 , null , null ), null , false ];
842841
843842 return $ data ;
844843 }
@@ -880,11 +879,120 @@ public function testGeneralChecks($share, $exceptionMessage, $exception) {
880879 $ this ->assertSame ($ exception , $ thrown );
881880 }
882881
882+ public function dataShareNotEnoughPermissions () {
883+ $ file = $ this ->createMock (File::class);
884+ $ file ->method ('getPermissions ' )->willReturn (17 );
885+ $ file ->method ('getName ' )->willReturn ('sharedfile ' );
886+ $ file ->method ('getPath ' )->willReturn ('/user1/sharedfile ' );
887+
888+ // Normal share (not re-share) should just use share node permission
889+ // exception when trying to share with more permission than share has
890+ $ share = $ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ file , 'user0 ' , 'user1 ' , 'user1 ' , 31 , null , null );
891+ $ data [] = [$ share , null , 'Cannot set the requested share permissions for sharedfile ' , true ];
892+
893+ // Federated reshare should just use share node permission
894+ // exception when trying to share with more permission than node has
895+ $ fileExternalStorage = $ this ->createMock ('OCA\Files_Sharing\External\Storage ' );
896+ $ fileExternalStorage ->method ('instanceOfStorage ' )
897+ ->willReturnCallback (function ($ storageClass ) {
898+ return ($ storageClass === 'OCA\Files_Sharing\External\Storage ' );
899+ });
900+ $ fileExternal = $ this ->createMock (File::class);
901+ $ fileExternal ->method ('getStorage ' )->willReturn ($ fileExternalStorage );
902+ $ share = $ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ file , 'user0 ' , 'user1 ' , 'user2 ' , 31 , null , null );
903+ $ data [] = [$ share , $ fileExternal , 'Cannot set the requested share permissions for sharedfile ' , true ];
904+
905+ // Normal reshare should just use supershare node permission
906+ // exception when trying to share with more permission than supershare has
907+ $ superShare = $ this ->createMock (IShare::class);
908+ $ superShare ->method ('getPermissions ' )->willReturn (1 );
909+ $ fileReshareStorage = $ this ->createMock ('OCA\Files_Sharing\SharedStorage ' );
910+ $ fileReshareStorage ->method ('instanceOfStorage ' )
911+ ->willReturnCallback (function ($ storageClass ) {
912+ return ($ storageClass === 'OCA\Files_Sharing\SharedStorage ' );
913+ });
914+ $ fileReshareStorage ->method ('getShare ' )->willReturn ($ superShare );
915+ $ fileReshare = $ this ->createMock (File::class);
916+ $ fileReshare ->method ('getStorage ' )->willReturn ($ fileReshareStorage );
917+ $ share = $ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ file , 'user0 ' , 'user1 ' , 'user2 ' , 17 , null , null );
918+ $ data [] = [$ share , $ fileReshare , 'Cannot set the requested share permissions for sharedfile ' , true ];
919+
920+ // Normal reshare should just use supershare node attributes
921+ // exception when trying to share with more attributes than supershare has
922+ $ superShareAttributes = new ShareAttributes ();
923+ $ shareAttributes = new ShareAttributes ();
924+ $ shareAttributes ->setAttribute ('test ' , 'test ' , true );
925+ $ superShare = $ this ->createMock (IShare::class);
926+ $ superShare ->method ('getPermissions ' )->willReturn (17 );
927+ $ superShare ->method ('getAttributes ' )->willReturn ($ superShareAttributes );
928+ $ fileReshareStorage = $ this ->createMock ('OCA\Files_Sharing\SharedStorage ' );
929+ $ fileReshareStorage ->method ('instanceOfStorage ' )
930+ ->willReturnCallback (function ($ storageClass ) {
931+ return ($ storageClass === 'OCA\Files_Sharing\SharedStorage ' );
932+ });
933+ $ fileReshareStorage ->method ('getShare ' )->willReturn ($ superShare );
934+ $ fileReshare = $ this ->createMock (File::class);
935+ $ fileReshare ->method ('getStorage ' )->willReturn ($ fileReshareStorage );
936+ $ share = $ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ file , 'user0 ' , 'user1 ' , 'user2 ' , 17 , null , null , $ shareAttributes );
937+ $ data [] = [$ share , $ fileReshare , 'Cannot set the requested share attributes for sharedfile ' , true ];
938+
939+ return $ data ;
940+ }
941+
942+ /**
943+ * @dataProvider dataShareNotEnoughPermissions
944+ *
945+ * @param $share
946+ * @param $superShareNode
947+ * @param $exceptionMessage
948+ * @param $exception
949+ */
950+ public function testShareNotEnoughPermissions ($ share , $ superShareNode , $ exceptionMessage , $ exception ) {
951+ $ sharer = $ this ->createMock (IUser::class);
952+ $ sharer ->method ('getUID ' )->willReturn ($ share ->getSharedBy ());
953+ $ this ->userSession ->method ('getUser ' )->willReturn ($ sharer );
954+
955+ $ userFolder = $ this ->createMock (Folder::class);
956+ $ userFolder ->method ('getById ' )->willReturn ([$ superShareNode ]);
957+ $ this ->rootFolder ->method ('getUserFolder ' )->willReturn ($ userFolder );
958+
959+ try {
960+ $ this ->invokePrivate ($ this ->manager , 'validatePermissions ' , [$ share ]);
961+ $ thrown = false ;
962+ } catch (\OCP \Share \Exceptions \GenericShareException $ e ) {
963+ $ this ->assertEquals ($ exceptionMessage , $ e ->getHint ());
964+ $ thrown = true ;
965+ }
966+
967+ $ this ->assertSame ($ exception , $ thrown );
968+ }
969+
970+ /**
971+ * Non-movable mount share can be shared with delete and update permission
972+ * even if permission for file do not have this permission
973+ */
974+ public function testShareNonMovableMountPermissions () {
975+ $ nonMovableMountPoint = $ this ->createMock (IMountPoint::class);
976+ $ file = $ this ->createMock (File::class);
977+ $ file ->method ('getPermissions ' )->willReturn (1 );
978+ $ file ->method ('getMountPoint ' )->willReturn ($ nonMovableMountPoint );
979+ $ share = $ this ->createShare (null , \OCP \Share::SHARE_TYPE_USER , $ file , 'user0 ' , 'user1 ' , 'user1 ' , 11 , null , null );
980+
981+ try {
982+ $ this ->invokePrivate ($ this ->manager , 'validatePermissions ' , [$ share ]);
983+ $ thrown = false ;
984+ } catch (\Exception $ e ) {
985+ $ thrown = true ;
986+ }
987+
988+ $ this ->assertSame (false , $ thrown );
989+ }
990+
883991 /**
884992 * @expectedException \OCP\Share\Exceptions\GenericShareException
885993 * @expectedExceptionMessage Expiration date is in the past
886994 */
887- public function testvalidateExpirationDateInPast () {
995+ public function testValidateExpirationDateInPast () {
888996
889997 // Expire date in the past
890998 $ past = new \DateTime ();
@@ -3497,6 +3605,102 @@ public function testGetAllSharedWith() {
34973605 $ this ->assertSame ($ shares , [$ share1 , $ share2 ]);
34983606 }
34993607
3608+ /**
3609+ * @dataProvider strictSubsetOfAttributesDataProvider
3610+ *
3611+ * @param IAttributes $allowedAttributes
3612+ * @param IAttributes $newAttributes
3613+ * @param boolean $expected
3614+ */
3615+ public function testStrictSubsetOfAttributes ($ allowedAttributes , $ newAttributes , $ expected ) {
3616+ $ this ->assertEquals (
3617+ $ expected ,
3618+ $ this ->invokePrivate (
3619+ $ this ->manager ,
3620+ 'strictSubsetOfAttributes ' ,
3621+ [$ allowedAttributes , $ newAttributes ]
3622+ )
3623+ );
3624+ }
3625+
3626+ public function strictSubsetOfAttributesDataProvider () {
3627+ // no exception - supershare and share are equal
3628+ $ superShareAttributes = new ShareAttributes ();
3629+ $ shareAttributes = new ShareAttributes ();
3630+ $ data [] = [$ superShareAttributes ,$ shareAttributes , true ];
3631+
3632+ // no exception - supershare and share are equal
3633+ $ superShareAttributes = new ShareAttributes ();
3634+ $ superShareAttributes ->setAttribute ('test ' , 'test ' , true );
3635+ $ shareAttributes = new ShareAttributes ();
3636+ $ shareAttributes ->setAttribute ('test ' , 'test ' , true );
3637+ $ data [] = [$ superShareAttributes ,$ shareAttributes , true ];
3638+
3639+ // no exception - disabling attribute that supershare has enabled
3640+ $ superShareAttributes = new ShareAttributes ();
3641+ $ superShareAttributes ->setAttribute ('test ' , 'test ' , true );
3642+ $ shareAttributes = new ShareAttributes ();
3643+ $ shareAttributes ->setAttribute ('test ' , 'test ' , false );
3644+ $ data [] = [$ superShareAttributes ,$ shareAttributes , true ];
3645+
3646+ // exception - adding an attribute while supershare has none
3647+ $ superShareAttributes = new ShareAttributes ();
3648+ $ shareAttributes = new ShareAttributes ();
3649+ $ shareAttributes ->setAttribute ('test ' , 'test ' , true );
3650+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3651+
3652+ // exception - enabling attribute that supershare has disabled
3653+ $ superShareAttributes = new ShareAttributes ();
3654+ $ superShareAttributes ->setAttribute ('test ' , 'test ' , false );
3655+ $ shareAttributes = new ShareAttributes ();
3656+ $ shareAttributes ->setAttribute ('test ' , 'test ' , true );
3657+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3658+
3659+ // exception - removing attribute of that supershare has enabled
3660+ $ superShareAttributes = new ShareAttributes ();
3661+ $ superShareAttributes ->setAttribute ('test ' , 'test ' , true );
3662+ $ shareAttributes = new ShareAttributes ();
3663+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3664+
3665+ // exception - removing attribute of that supershare has disabled
3666+ $ superShareAttributes = new ShareAttributes ();
3667+ $ superShareAttributes ->setAttribute ('test ' , 'test ' , false );
3668+ $ shareAttributes = new ShareAttributes ();
3669+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3670+
3671+ // exception - removing one of attributes of supershare
3672+ $ superShareAttributes = new ShareAttributes ();
3673+ $ superShareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3674+ $ superShareAttributes ->setAttribute ('test ' , 'test2 ' , false );
3675+ $ shareAttributes = new ShareAttributes ();
3676+ $ shareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3677+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3678+
3679+ // exception - disabling one of attributes of supershare
3680+ $ superShareAttributes = new ShareAttributes ();
3681+ $ superShareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3682+ $ superShareAttributes ->setAttribute ('test ' , 'test2 ' , false );
3683+ $ shareAttributes = new ShareAttributes ();
3684+ $ shareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3685+ $ shareAttributes ->setAttribute ('test ' , 'test2 ' , true );
3686+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3687+
3688+ // exception - swaping one of attributes of supershare
3689+ $ superShareAttributes = new ShareAttributes ();
3690+ $ superShareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3691+ $ superShareAttributes ->setAttribute ('test ' , 'test01 ' , false );
3692+ $ superShareAttributes ->setAttribute ('test ' , 'test3 ' , true );
3693+ $ superShareAttributes ->setAttribute ('test ' , 'test4 ' , null );
3694+ $ shareAttributes = new ShareAttributes ();
3695+ $ shareAttributes ->setAttribute ('test ' , 'test1 ' , false );
3696+ $ shareAttributes ->setAttribute ('test ' , 'test10 ' , false );
3697+ $ superShareAttributes ->setAttribute ('test ' , 'test3 ' , null );
3698+ $ superShareAttributes ->setAttribute ('test ' , 'test4 ' , true );
3699+ $ data [] = [$ superShareAttributes ,$ shareAttributes , false ];
3700+
3701+ return $ data ;
3702+ }
3703+
35003704 /**
35013705 * @dataProvider strictSubsetOfPermissionsDataProvider
35023706 *
0 commit comments