@@ -42,8 +42,8 @@ public function __construct($parameters) {
4242 /**
4343 * @throws ForbiddenException
4444 */
45- protected function checkFileAccess (string $ path , ?bool $ isDir = null ): void {
46- $ this ->operation ->checkFileAccess ($ path , $ this ->mount , is_bool ($ isDir ) ? $ isDir : $ this ->is_dir ($ path ));
45+ protected function checkFileAccess (string $ path , ?bool $ isDir = null , ? int $ permissions = null ): ? int {
46+ return $ this ->operation ->checkFileAccess ($ path , $ this ->mount , is_bool ($ isDir ) ? $ isDir : $ this ->is_dir ($ path ), null , $ permissions ?? Constants:: PERMISSION_ALL );
4747 }
4848
4949 /*
@@ -59,7 +59,7 @@ protected function checkFileAccess(string $path, ?bool $isDir = null): void {
5959 */
6060 #[\Override]
6161 public function mkdir ($ path ): bool {
62- $ this ->checkFileAccess ($ path , true );
62+ $ this ->checkFileAccess ($ path , true , Constants:: PERMISSION_CREATE );
6363 return $ this ->storage ->mkdir ($ path );
6464 }
6565
@@ -72,7 +72,7 @@ public function mkdir($path): bool {
7272 */
7373 #[\Override]
7474 public function rmdir ($ path ): bool {
75- $ this ->checkFileAccess ($ path , true );
75+ $ this ->checkFileAccess ($ path , true , Constants:: PERMISSION_DELETE );
7676 return $ this ->storage ->rmdir ($ path );
7777 }
7878
@@ -85,7 +85,7 @@ public function rmdir($path): bool {
8585 #[\Override]
8686 public function isCreatable ($ path ): bool {
8787 try {
88- $ this ->checkFileAccess ($ path );
88+ $ this ->checkFileAccess ($ path, null , Constants:: PERMISSION_CREATE );
8989 } catch (ForbiddenException $ e ) {
9090 return false ;
9191 }
@@ -101,7 +101,7 @@ public function isCreatable($path): bool {
101101 #[\Override]
102102 public function isReadable ($ path ): bool {
103103 try {
104- $ this ->checkFileAccess ($ path );
104+ $ this ->checkFileAccess ($ path, null , Constants:: PERMISSION_READ );
105105 } catch (ForbiddenException $ e ) {
106106 return false ;
107107 }
@@ -117,7 +117,7 @@ public function isReadable($path): bool {
117117 #[\Override]
118118 public function isUpdatable ($ path ): bool {
119119 try {
120- $ this ->checkFileAccess ($ path );
120+ $ this ->checkFileAccess ($ path, null , Constants:: PERMISSION_UPDATE );
121121 } catch (ForbiddenException $ e ) {
122122 return false ;
123123 }
@@ -133,7 +133,7 @@ public function isUpdatable($path): bool {
133133 #[\Override]
134134 public function isDeletable ($ path ): bool {
135135 try {
136- $ this ->checkFileAccess ($ path );
136+ $ this ->checkFileAccess ($ path, null , Constants:: PERMISSION_DELETE );
137137 } catch (ForbiddenException $ e ) {
138138 return false ;
139139 }
@@ -143,10 +143,16 @@ public function isDeletable($path): bool {
143143 #[\Override]
144144 public function getPermissions ($ path ): int {
145145 try {
146- $ this ->checkFileAccess ($ path );
146+ $ permissions = $ this ->checkFileAccess ($ path, null , 0 );
147147 } catch (ForbiddenException $ e ) {
148148 return $ this ->mask ;
149149 }
150+
151+ if ($ permissions !== null ) {
152+ // override with permissions granted by the operation, if any
153+ return $ permissions & $ this ->storage ->getPermissions ($ path );
154+ }
155+
150156 return $ this ->storage ->getPermissions ($ path );
151157 }
152158
@@ -159,7 +165,7 @@ public function getPermissions($path): int {
159165 */
160166 #[\Override]
161167 public function file_get_contents ($ path ): string |false {
162- $ this ->checkFileAccess ($ path , false );
168+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_READ );
163169 return $ this ->storage ->file_get_contents ($ path );
164170 }
165171
@@ -173,7 +179,7 @@ public function file_get_contents($path): string|false {
173179 */
174180 #[\Override]
175181 public function file_put_contents (string $ path , mixed $ data ): int |float |false {
176- $ this ->checkFileAccess ($ path , false );
182+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_CREATE | Constants:: PERMISSION_UPDATE );
177183 return $ this ->storage ->file_put_contents ($ path , $ data );
178184 }
179185
@@ -186,7 +192,7 @@ public function file_put_contents(string $path, mixed $data): int|float|false {
186192 */
187193 #[\Override]
188194 public function unlink ($ path ): bool {
189- $ this ->checkFileAccess ($ path , false );
195+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_DELETE );
190196 return $ this ->storage ->unlink ($ path );
191197 }
192198
@@ -201,8 +207,8 @@ public function unlink($path): bool {
201207 #[\Override]
202208 public function rename ($ source , $ target ): bool {
203209 $ isDir = $ this ->is_dir ($ source );
204- $ this ->checkFileAccess ($ source , $ isDir );
205- $ this ->checkFileAccess ($ target , $ isDir );
210+ $ this ->checkFileAccess ($ source , $ isDir, Constants:: PERMISSION_READ | Constants:: PERMISSION_DELETE );
211+ $ this ->checkFileAccess ($ target , $ isDir, Constants:: PERMISSION_CREATE );
206212 return $ this ->storage ->rename ($ source , $ target );
207213 }
208214
@@ -217,8 +223,8 @@ public function rename($source, $target): bool {
217223 #[\Override]
218224 public function copy ($ source , $ target ): bool {
219225 $ isDir = $ this ->is_dir ($ source );
220- $ this ->checkFileAccess ($ source , $ isDir );
221- $ this ->checkFileAccess ($ target , $ isDir );
226+ $ this ->checkFileAccess ($ source , $ isDir, Constants:: PERMISSION_READ );
227+ $ this ->checkFileAccess ($ target , $ isDir, Constants:: PERMISSION_CREATE );
222228 return $ this ->storage ->copy ($ source , $ target );
223229 }
224230
@@ -232,7 +238,18 @@ public function copy($source, $target): bool {
232238 */
233239 #[\Override]
234240 public function fopen ($ path , $ mode ) {
235- $ this ->checkFileAccess ($ path , false );
241+ $ hasPlus = str_contains ($ mode , '+ ' );
242+ $ isRead = str_contains ($ mode , 'r ' );
243+ $ isExclusive = str_contains ($ mode , 'x ' );
244+ $ isWac = str_contains ($ mode , 'w ' ) || str_contains ($ mode , 'a ' ) || str_contains ($ mode , 'c ' );
245+ $ checkPermissions = match (true ) {
246+ $ isWac => Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | ($ hasPlus ? Constants::PERMISSION_READ : 0 ),
247+ $ isExclusive => Constants::PERMISSION_CREATE | ($ hasPlus ? Constants::PERMISSION_READ : 0 ),
248+ $ isRead => Constants::PERMISSION_READ | ($ hasPlus ? Constants::PERMISSION_UPDATE : 0 ),
249+ default => Constants::PERMISSION_ALL ,
250+ };
251+
252+ $ this ->checkFileAccess ($ path , false , $ checkPermissions );
236253 return $ this ->storage ->fopen ($ path , $ mode );
237254 }
238255
@@ -247,7 +264,7 @@ public function fopen($path, $mode) {
247264 */
248265 #[\Override]
249266 public function touch ($ path , $ mtime = null ): bool {
250- $ this ->checkFileAccess ($ path , false );
267+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_CREATE | Constants:: PERMISSION_UPDATE );
251268 return $ this ->storage ->touch ($ path , $ mtime );
252269 }
253270
@@ -278,7 +295,7 @@ public function getCache($path = '', $storage = null): ICache {
278295 */
279296 #[\Override]
280297 public function getDirectDownload ($ path ): array |false {
281- $ this ->checkFileAccess ($ path , false );
298+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_READ );
282299 return $ this ->storage ->getDirectDownload ($ path );
283300 }
284301
@@ -302,7 +319,7 @@ public function getDirectDownloadById(string $fileId): array|false {
302319 // We would have actually a result, so lets see if the user should be able to access it
303320 $ path = $ this ->getCache ()->getPathById ((int )$ fileId );
304321 if ($ path !== null ) {
305- $ this ->checkFileAccess ($ path , false );
322+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_READ );
306323 }
307324
308325 return $ data ;
@@ -321,7 +338,7 @@ public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $t
321338 return $ this ->copy ($ sourceInternalPath , $ targetInternalPath );
322339 }
323340
324- $ this ->checkFileAccess ($ targetInternalPath , $ sourceStorage ->is_dir ($ sourceInternalPath ));
341+ $ this ->checkFileAccess ($ targetInternalPath , $ sourceStorage ->is_dir ($ sourceInternalPath ), Constants:: PERMISSION_CREATE );
325342 return $ this ->storage ->copyFromStorage ($ sourceStorage , $ sourceInternalPath , $ targetInternalPath );
326343 }
327344
@@ -338,7 +355,7 @@ public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $t
338355 return $ this ->rename ($ sourceInternalPath , $ targetInternalPath );
339356 }
340357
341- $ this ->checkFileAccess ($ targetInternalPath , $ sourceStorage ->is_dir ($ sourceInternalPath ));
358+ $ this ->checkFileAccess ($ targetInternalPath , $ sourceStorage ->is_dir ($ sourceInternalPath ), Constants:: PERMISSION_CREATE );
342359 return $ this ->storage ->moveFromStorage ($ sourceStorage , $ sourceInternalPath , $ targetInternalPath );
343360 }
344361
@@ -348,7 +365,7 @@ public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $t
348365 #[\Override]
349366 public function writeStream (string $ path , $ stream , ?int $ size = null ): int {
350367 if (!$ this ->isPartFile ($ path )) {
351- $ this ->checkFileAccess ($ path , false );
368+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_CREATE | Constants:: PERMISSION_UPDATE );
352369 }
353370
354371 $ result = parent ::writeStream ($ path , $ stream , $ size );
@@ -359,7 +376,7 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
359376 // Required for object storage since part file is not in the storage so we cannot check it before moving it to the storage
360377 // As an alternative we might be able to check on the cache update/insert/delete though the Cache wrapper
361378 try {
362- $ this ->checkFileAccess ($ path , false );
379+ $ this ->checkFileAccess ($ path , false , Constants:: PERMISSION_CREATE | Constants:: PERMISSION_UPDATE );
363380 } catch (\Exception $ e ) {
364381 $ this ->storage ->unlink ($ path );
365382 throw $ e ;
0 commit comments