1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-09-20 13:34:04 +00:00
Commit graph

1501 commits

Author SHA1 Message Date
lukinovec
1ef7710da4 remove directory rtrim
The rtrim is redundant, it doesn't communicate anything useful.
2026-09-18 10:58:01 +02:00
lukinovec
35d96b5b6f Use rmdir instead of deleteDirectory
rmdir refuses to delete non-empty directories, so it's the better alternative to deleteDirectory here.
2026-09-15 11:09:40 +02:00
lukinovec
388f253964 Assert symlink jobs dispatch events
Also cover RemoveStorageSymlinksAction not doing anything if there's no existing symlink
2026-09-14 16:39:33 +02:00
lukinovec
1a3ab476b0 In the asset controller, throw if tenancy isn't initialized
Instead of falling back to returning storage_path('app/public') in assetRoot(), throw an exception *at the start of the method* -- tenant assets shouldn't be served in central context.
2026-09-14 12:57:37 +02:00
lukinovec
42df25ac39 Update removeNestedDirectories docblock 2026-09-11 07:05:31 +02:00
lukinovec
9ec732cfce rtrim directory and public root in remove symlinks action
realpath() already returns paths without the trailing separator -- rtrim is used just so that the code is more self=documenting.
2026-09-11 07:05:10 +02:00
lukinovec
9e890e9a67 Improve symlink comments
Make it clear that both diskRoot and publicPath get the same prefix appended.

In the possibleTenantSymlinks() docblock, correct the array example (the values are not just 'disk root' anymore -- if the disk has a prefix, it will be appended to the configured root).
2026-09-10 12:32:14 +02:00
lukinovec
1e1e2efb8c Refactor remove symlinks action, add static::$removeNestedDirectories
In removeLink(), return early if the symlink doesn't exist.

The nested directory deletion is now controlled by the $removeNestedDirectories static property. It's disabled by default.

public_path() and dirname($publicPath) are now normalized using realpath() before the nested dir deletion.

The delete loop now checks if the directory-to-be-deleted is *inside* the public root instead of checking if it's not equal to to the public root.
2026-09-10 12:09:07 +02:00
lukinovec
b2b8d50edb Add symlink support for prefixed disks
Disk prefixes are no longer ignored by tenants:link. possibleTenantSymlinks() now appends them to both the public path and the disk root.

CreateStorageSymlinksAction now creates parent directories for the symlinks in the public/ directory (e.g. for a disk with 'abc/def' prefix, the 'abc/def' subdirectory will be created inside public/<url_override>).

RemoveStorageSymlinksAction removes the directories that  CreateStorageSymlinksAction creates for the symlinks.
2026-09-09 12:18:04 +02:00
9673464128
minor test cleanup 2026-09-08 20:17:40 -07:00
d783879f98
add assertion to ensure the two paths are the same 2026-09-08 19:45:12 -07:00
lukinovec
9bfc9c4dca Delete the 'tenant assets are served from the central storage path in central context' test
On one hand, this test covered the TenantAssetController's fallback. On the other hand, using tenant asset routes in central context is not a valid use case (also, the fallback isn't exactly a new thing)
2026-09-08 18:27:38 +02:00
lukinovec
823e5c34d6 Merge the 'served from the resolved root' tests 2026-09-08 18:18:54 +02:00
lukinovec
fe85fe45bd Merge 'not a local disk'/'not tenant-aware'/'unnamed parent' throwing tests into a single test 2026-09-08 18:11:41 +02:00
lukinovec
1abeb852de Merge the new "throws an exception when accessing a file in a directory whose name starts with the name of the asset root" test with the pre-existing one
"test asset controller returns a 404 when accessing a file outside the storage root" tested very similar things to the new test (which had some redundant config anyway). Merged these tests into one -- "tenant asset controller only serves files inside the asset root"
2026-09-08 17:54:20 +02:00
lukinovec
4af473ede5 Move falsy url_override assertions to more appropriate places 2026-09-08 16:59:23 +02:00
lukinovec
e3ba445630 Refactor scoped disk exception throwing tests, remove redundant test
"adding a scoped disk to tenancy.filesystem.disks throws an exception if its base disk is not listed" doesn't use a dataset and deal with inline baes disks anymore.

Added a separate test for scoped disks with inline base ("adding a scoped disk with an inline base disk to tenancy.filesystem.disks throws an exception").

Removed the "adding a scoped disk to tenancy.filesystem.disks has no effect on the disk when its base disk is listed too" test, it was mostly redundant.
2026-09-08 16:59:23 +02:00
lukinovec
e6d785a8d1 Refactor DeleteTenantStorage tests
Use the *original* 'tenant storage gets deleted during tenant deletion when the DeletingTenant pipeline contains DeleteTenantStorage' test and remove what's not necessary anymore. Also make it clear that enabling FS bootstrapper is not required for the deletion to work -- the tenant directory just has to exist.

Delete the nonsensical 'DeleteTenantStorage does not delete the central storage directory when the filesystem bootstrapper is disabled' test. That one was there to test that the central dir never gets deleted, but it was wrong. Added 'DeleteTenantStorage never deletes the central storage directory' which actually makes the job's realpath() comparison check pass and the job just returns.
2026-09-08 16:59:23 +02:00
lukinovec
45100453c5 Refactor scoped disks test
Remove redundant config(['filesystem.disks.public.prefix' => 'scoped_disk_prefix']); line, try making the test less dense.
2026-09-08 16:59:23 +02:00
lukinovec
496e0c36bd Improve TenantAssetController comments 2026-09-08 16:59:23 +02:00
lukinovec
45f6bc6b96 Fix getBoundTenantStoragePath -> getTenantStoragePath rename leftover 2026-09-07 18:32:15 -07:00
lukinovec
197ca18566 Simplify baseDiskName()
Refrain from dealing with the impossible "self-referencing" scoped disk case. Instead of that, test the inline parent behavior.

Also update the exception message in forgetDisks() so that it's a bit less vague.
2026-09-07 18:32:15 -07:00
lukinovec
dde9be6f58 Throw an exception if a scoped disk is listed in tenant-aware disks without its base disk
In FSBootstrapper::forgetDisks():
- `tenancy.filesystem.disks => ['scoped']` throws
- `tenancy.filesystem.disks => ['scoped', 'parent']` does NOT throw
- `tenancy.filesystem.disks => ['scoped_with_scoped_parent', 'scoped_parent']` (invalid config where a scoped disk's base disk doesn't actually exist because the scoped disks just reference themselves) throws
2026-09-07 18:32:15 -07:00
lukinovec
e7c0193931 Add comment above $attemptedPath
At first glance, it could look weird that $attemptedPath uses "/" but the check in abortIf below uses DIRECTORY_SEPARATOR. Add comment that explains this.
2026-09-07 18:32:15 -07:00
efc0877f10 minor polish 2026-09-07 18:32:15 -07:00
lukinovec
394a9fa562 Explicitly skip scoped disks in diskRoot()
If diskRoot() somehow ended up receiving a scoped disk (e.g. in case the scoped disk was listed in tenancy.filesystem.disks), its root would get configured, and it'd be completely redundant. It wouldn't break anything since scoped disk's configured root is ignored -- its parent's root is always used. Even though not adding this skipping code would essentially do no harm, it prevents the method from doing redundant work and defines the behavior a bit more clearly.

diskUrl() is similar in that regard, but that method already has a strict "disk driver has to be 'local'" -- scoped disks never made it through so nothing to change there.
2026-09-07 18:32:15 -07:00
lukinovec
9cda4cb3e4 Forget scoped disk's parent no matter how nested it is
This includes moving the TenantAssetController baseDiskName() method to FSBootstrapper and making it public static, since the same logic is used in two places now. Also cover the edge case where a scoped disk A has a scoped disk B as its parent, and B has A as its parent -- in that case, the method would be stuck in an infinite loop (also added separate test for this, commenting out the $visited-related code in baseDiskName will make the test fail).

Also updated the assetRoot's unnamed disk exception message.
2026-09-07 18:32:15 -07:00
lukinovec
e20085588b Assert that TenantAssetController throws for scoped disks with a non-local parent 2026-09-07 18:32:15 -07:00
lukinovec
2cd514c781 Test that listing scoped disks in tenancy.filesystem.disks is harmless (regression test)
FilesystemTenancyBootstrapper should only change config of the base/parent disks -- scoped disks should be ignored.
2026-09-07 18:32:15 -07:00
lukinovec
3936ab9eff Test that non-local scoped disks get scoped per tenant 2026-09-07 18:32:15 -07:00
lukinovec
ae91281d3a Assert that nested scoped disks are scoped properly (regression test)
The test fails with the nested disk dataset because we resolve a disk first, then initialize tenancy, and because the nested scoped disks aren't forgotten, so the disk config changes that the FS bootstrapper applies aren't reflected on the already-resolved disk instance.
2026-09-07 18:32:15 -07:00
lukinovec
e0e696f83e Throw an exception in TenantAssetController if the disk is not tenant-aware
Instead of just saying that the publicDisk *should* be listed in tenancy.filesystem.disks, enforce that -- if the disk isn't tenant-aware, throw an exception.

Also update comments accordingly. E.g. since scoped disks don't have to have a single "parent disk" (the parent can also be a scoped disk and have another parent, and so on), use "base disk".
2026-09-07 18:32:15 -07:00
lukinovec
041b023a95 Assert that TenantAssetController cannot serve assets from a disk that isn't tenant-aware (regression test) 2026-09-07 18:32:15 -07:00
lukinovec
99994dca85 Delete redundant comment 2026-09-07 18:32:15 -07:00
lukinovec
8e671fe5be Use "placed within" instead of "appended to" in log bootstrapper comment
In response to https://github.com/archtechx/tenancy/pull/1479#discussion_r3876808350
2026-09-07 18:32:15 -07:00
41f7e2e034 improve comments 2026-09-07 18:32:15 -07:00
lukinovec
bb12443fa6 Update src/Jobs/DeleteTenantStorage.php
Co-authored-by: Samuel Stancl <samuel@archte.ch>
2026-09-07 18:32:15 -07:00
lukinovec
2ef1ea94ed Make LogChannelBootstrapper not depend on suffixed storage_path()
Since the tenant storage path can now be grabbed using FilesystemTenancyBootstrapper::getBoundTenantStoragePath(), the log bootstrapper doesn't need to depend on the FSBootstrapper being enabled and storage_path() being suffixed.

Instead of adding a regression test, just delete FilesystemTenancyBootstrapper from the config settings in the log bootstrapper tests (and in tests that did use storage_path() in tenant context assertions, use explicitly "hardcoded" paths instead).
2026-09-07 18:32:15 -07:00
lukinovec
ae88836c0b Clarify TenantAssetController's docblock 2026-09-07 18:32:15 -07:00
github-actions[bot]
ae98ac3bd4 Fix code style (php-cs-fixer) 2026-09-07 18:32:15 -07:00
lukinovec
802022a926 Exercise the valid asset path before testing traversal
Request photo.jpg and assert success before asserting rejection of ../media-originals/photo.jpg

(addresses https://github.com/archtechx/tenancy/pull/1479#pullrequestreview-4984403598)
2026-09-07 18:32:15 -07:00
lukinovec
e70057e3ba Read the tenant asset root from the resolved disk instead of the disk config
Also, instead of throwing the "no root path configured" exception, just throw an exception if the disk is not local (i.e. is not instanceof LocalFilesystemAdapter). A local disk HAS to have a string root, otherwise, Laravel throws an exception while instantiating that disk.
2026-09-07 18:32:15 -07:00
lukinovec
efa8c03680 Assert that the tenant asset root is read from the resolved disk (regression tests)
Test that tenant assets can be served from scoped disks, and that tenant asset roots respect the disk's configured prefix.

Currently, the tests fail because TenantAssetController grabs the root from the config instead of resolving it via Storage::disk(...)->path('').
2026-09-07 18:32:15 -07:00
lukinovec
848736448c Clarify TenantAssetController docblock 2026-09-07 18:32:15 -07:00
lukinovec
9403d8c8fd Add afterEach cleanup to TenantAssetTest 2026-09-07 18:32:15 -07:00
lukinovec
5e54e3e7d9 Reword DeleteTenantStorage docblock
The docblock said that the FSBootstrapper was required for this job to work at all, but that's not fully true since the job just uses the FSBootstrapper's public static methods to get the storage paths.
2026-09-07 18:32:15 -07:00
lukinovec
4826667ac1 Add test that covers how tenant_asset() works when called in central context
Added to cover the `return storage_path('app/public')` line in TenantAssetController::assetRoot
2026-09-07 18:32:15 -07:00
lukinovec
1a693d8e36 Improve comments
Correct misleading ones, add ones that were missing (e.g. the TenantAssetController's docblock, the FSBootstrapper dependency should be mentioned there)
2026-09-07 18:32:15 -07:00
lukinovec
15144def3c Update tenancy.filesystem config docblocks
Briefly document the root_override placeholders, make the links point to v4 docs instead of the v3 ones. Also in the url_override comments, mention that local disks must have a valid root in order for the override to work correctly.
2026-09-07 18:32:15 -07:00
lukinovec
7ecb34f3fe Skip disks with *empty* url_override in diskUrl()
Previously, we only skipped disks with `null` override. But an override with an empty string is also incorrect, and simply checking if $this->app['config']["tenancy.filesystem.url_override.{$disk}"]) is falsy instead of strictly null takes care of that.
2026-09-07 18:32:15 -07:00