1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 09:54:03 +00:00
Commit graph

924 commits

Author SHA1 Message Date
lukinovec
0dc187510b
[4.x] Clean up expired impersonation tokens instead of just aborting, add command for cleaning up expired tokens (#1387)
This PR makes the expired/invalid tenant impersonation tokens get
deleted instead of just aborting with 403.

The PR also adds a command (ClearExpiredImpersonationTokens) used like
`php artisan tenants:purge-impersonation-tokens`. As the name suggests,
it clears all expired impersonation tokens (= tokens older than
`UserImpersonation::$ttl`).

Resolves #1348

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-10-28 14:14:52 +01:00
lukinovec
469595534e
[4.x] Make TenancyUrlGenerator inherit the original UrlGenerator's scheme (http or https) (#1390)
Before, when using UrlGeneratorBootstrapper, and your app had a
`https://` url, in tenant context, the url would have the `http://`
scheme.

Now, the bootstrapper makes sure that the TenancyUrlGenerator inherits
the original UrlGenerator's scheme. So if your app has e.g. url
"https://some-url.test", `route('home')` in tenant context will return
"http**s**://some-url.test/home" (originally, you'd get
"http://some-url.test/home" - the original scheme - https - wouldn't be
respected in the tenant context).

This PR addresses the issue reported on Discord
(https://discord.com/channels/976506366502006874/976506736120823909/1399012794514411621).

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-10-28 13:26:50 +01:00
6523f24a60 Pending tenants: Add getPendingAttributes()
This method lets the user specify default values for custom
non-nullable columns. The primary use case is when the tenants table
has a column like 'slug' and createPending() is called with no
value for 'slug'. This would produce an exception due to the column
having no default value.

Here, getPendingAttributes() can set an initial dummy slug (like a
randomly generated string) before it's overwritten during a pull.

getPendingAttributes() accepts an $attributes array which corresponds
to the attributes passed to createPending(). The array returned from
getPendingAttributes() is ultimately merged with $attributes, so
the user doesn't need to use the $attributes value in
getPendingAttributes(), however it serves to provide more context when
the pending attributes might be dependent on $attributes and therefore
derived from the $attributes actually being used.

Also fixed the `finally` branch in createPending() as it was
potentially referencing the $tenant variable before it was initialized.
2025-10-28 12:50:13 +01:00
aba7a50619
Minor fixes
The change in SQLiteDatabaseManager wasn't properly saving the
updated internal value.

The check in CacheTenancyBootstrapper wasn't handling that local tests
have a 'testing' environment, not local. However fixing only the
condition would've still added the store to $names which would throw
an exception down the line. We make sure to only throw the exception
in prod, but also make sure to only add the store to $names if it is
supported.
2025-10-22 12:58:45 +02:00
99b79a5d08
SQLite DB manager: use setInternal() instead of hardcoded tenancy_db_* 2025-10-20 02:16:31 +02:00
5dfb4843b9
Resolve misc todos, fix phpstan error 2025-10-20 01:57:02 +02:00
github-actions[bot]
be93d6031c Fix code style (php-cs-fixer) 2025-10-19 23:47:46 +00:00
fadf1001f8
PHP 8.5 support
This commit adds support for building a docker image based on PHP 8.5
(RC). It also removes some unused code in tests that was triggering
deprecation warnings. For similar deprecation warnings coming from
testbench we have a temporary patch script until this is resolved
upstream.

This commit also adds logic to the DisallowSqliteAttach feature
leveraging the new native setAuthorizer() method, instead of loading
a compiled extension.

We also remove the unused `php` parameter from ci.yml
2025-10-20 01:44:24 +02:00
91f6c61fcd
Fix assert: run createDatabase() outside assert()
assert() calls, including assert(foo()), can be entirely compiled out
depending on the INI settings described here:
https://www.php.net/manual/en/function.assert.php

That in turn means even side effects of foo() can be entirely compiled
out.

Therefore, to ensure the call actually runs, we need to run it before
the assert(), store its return value, and only then make assertions
about the return value.
2025-10-16 01:10:07 +02:00
6049ade20e
Fix exception message
Properly retrieve session driver name, previously $name was undefined
2025-10-16 00:15:28 +02:00
74634dfe4b
Session scoping (cache bootstrapper): throw on incompatible driver 2025-10-16 00:05:58 +02:00
ddf83c4b55
Assert createDatabase() success
Pretty much all errors that can happen in createDatabase() end up
throwing an exception, however the function still does return a boolean
(it bubbles up the value from the underlying $conn->statement() call)
which should be checked in at least some way.
2025-10-16 00:01:58 +02:00
151e81b412
Merge dev branch (minor breaking changes)
From the perspective of the master branch, this commit merges in a
few small breaking changes from the dev branch:

6b0066c5ef
- Make pullPendingFromPool() $firstOrCreate arg default to false
  (pullPending() is now a direct alias for pullPendingFromPool() with
  default $firstOrCreate=true)
- See full commit message for other changes. They shouldn't be breaking
  though.

13a2209f11
- Remove $WAL static property. We instead just let Laravel use its
  journal_mode config now

This merge also adds a deprecation:

b320f8f33d
- Deprecate TenantConfig feature in favor of TenantConfigBootstrapper
2025-10-14 17:32:44 +02:00
github-actions[bot]
5fdae28edc Fix code style (php-cs-fixer) 2025-10-14 15:26:19 +00:00
e1b8658414
Fix #1404: support universal routes in CheckTenantForMaintenanceMode
This commit also corrects an Event::fake() call in a separate test, as
general Event::fake() calls without specified events can lead to
incorrect (and difficult to debug) behavior in some cases, since
Tenancy depends on the event system being functional.
2025-10-14 17:22:35 +02:00
3cf102ebd6 Update stubs, add PHP 8.5 todo
Remove comments about shouldBeQueued(true) being preferable in
production as that isn't necessarily true anymore with pending tenants
(or even the absence of any "optimizations", they're all optional).
Using queued tenant creation also requires some code changes in the
tenant onboarding logic, so it is misleading to imply that it's a
switch that should simply be turned on in production.

Add DatabaseCacheBootstrapper to config.php as it was missing there.

Remove note about MailConfigBootstrapper needing forceRefresh in the
QueueTenancyBootstrapper as we now use a non-persistent queue
bootstrapper by default.
2025-10-13 16:16:40 +02:00
e6cc6d6777 phpstan: Remove ignore that is no longer necessary 2025-10-13 16:12:01 +02:00
a0a9b85982 Refactor DatabaseConfig, minor DB manager improvements, resolve todos
Notable changes:
- CreateUserWithRLSPolicies: Clarify why we're creating a custom
  DatabaseConfing instance
- HasDatabase: Clarify why we're ignoring tenancy_db_connection
- DatabaseConfig: General refactor, clarify the role of the host conn
- SQLiteDatabaseManager: Handle trailing DIRECTORY_SEPARATOR
  in static::$path
- DisallowSqliteAttach: Don't throw any exceptions, just silently fail
  since the class isn't 100% portable
- Clean up todos that are no longer relevant
- Clean up dead code or comments in some database managers
2025-10-13 16:01:34 +02:00
3846fe88ec install: support starring using GH CLI 2025-09-26 13:49:15 +02:00
b320f8f33d Add TenantConfigBootstrapper, deprecate Feature implementation
The feature was pretty much a soft-bootstrapper -- it listened
to both Bootstrapped and Reverted. Bootstrappers have a few more
protections in terms of error handling and safe reverting, so there's
no point in (badly) re-implementing bootstrapper functionality within
TenantConfig just so it could be a Feature.

Going forward, all Features should be things that are mostly agnostic
of the tenant state, and especially they should not use bootstrapped/
reverted events. Bootstrappers are simply more appropriate and safe.
2025-09-26 13:49:15 +02:00
lukinovec
d983bf9547
Add tenant parameter BEFORE existing prefixes by default, add tenantParameterBeforePrefix() to allow customizing this (#1393) 2025-09-03 15:56:12 +02:00
github-actions[bot]
364637dc23 Fix code style (php-cs-fixer) 2025-09-01 14:14:34 +00:00
13a2209f11 SQLite improvements
- (BC BREAK) Remove $WAL static property. We instead just let
  Laravel use its journal_mode config now
- Remove journal, wal, and shm files when deleting tenant DB
- Check that the system is 64-bit when using NoAttach (we don't
  build 32 bit extensions)
- Use local static instead of a class static property for caching
  loadExtensionSupported
2025-09-01 16:13:09 +02:00
github-actions[bot]
b2f95592a6 Fix code style (php-cs-fixer) 2025-08-31 21:19:08 +00:00
4578c9ed7d Features refactor
Features are now *always* bootstrapped, even if Tenancy is not resolved
from the container.

Previous implementations include
https://github.com/tenancy-for-laravel/v4/pull/19
https://github.com/archtechx/tenancy/pull/1021

Bug originally reported here
https://github.com/archtechx/tenancy/issues/949

This implementation is much simpler, we do not distinguish between
features that should be "always bootstrapped" and features that should
only be bootstrapped after Tenancy is resolved. All features should work
without issues if they're bootstrapped when TSP::boot() is called. We
also add a Tenancy::bootstrapFeatures() method that can be used to
bootstrap any features dynamically added at runtime that weren't
bootstrapped in TSP::boot(). The function keeps track of which features
were already bootstrapped so it doesn't bootstrap them again.

The only potentialy risky thing in this implementation is that we're now
resolving Tenancy in TSP::boot() (previously Tenancy was not being
resolved) but that shouldn't be causing any issues.
2025-08-31 23:18:44 +02:00
33e4a8e4e2 Remove and recategorize todos 2025-08-31 16:57:52 +02:00
24797278cd phpstan fix 2025-08-25 17:50:09 +02:00
1f0c668578 Merge branch 'master' into august 2025-08-25 17:44:11 +02:00
e806825f71 Merge branch 'master' of github.com:archtechx/tenancy 2025-08-25 17:43:53 +02:00
Farishrf
99d854ed8e
[4.x] Fix ViteBundler not affecting Vite static calls (#1389)
* Fix ViteBundler not affecting Vite static calls

Replace custom Vite class override with Vite::createAssetPathsUsing() to ensure ViteBundler works for both container and static usage when asset_helper_override is enabled.

Fixes #1388

* Remove redundant logic from tests

* Simplify test further

* Re-add file creation logic

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-08-25 17:27:59 +02:00
lukinovec
3b42c9e20c
[4.x] Use --database in tenants:migrate as the template connection (#1386)
* Make the `--database` option passed to `tenants:migrate` use the passed connection as the tenant connection template

* Reset template connection regardless of process count

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-08-25 15:57:15 +02:00
lukinovec
d9f3525700
Add --force option to tenants:migrate-fresh (#1391) 2025-08-25 15:47:16 +02:00
6b0066c5ef Pending tenants refactor (BC break)
- [BC BREAK] Make pullPendingFromPool() $firstOrCreate arg
  default to false (pullPending() is now a direct alias for
  pullPendingFromPool() with default $firstOrCreate=true)
- Resolve race conditions in pullPendingFromPool()
- Make createPending() set pending_since regardless of exceptions
- Make pullPending() accept $attributes
- Fire PullingPendingTenant from within a DB transaction
- Clarify --count arg description for CreatePendingTenants command
- Add docblock to PullingPendingTenant with a notice
2025-08-25 00:01:02 +02:00
7089efb2ee resolve minor todos 2025-08-18 15:05:17 +02:00
ecc3374293 [4.x] Support database cache store tenancy (#1290) (resolve #852)
* Initial implementation (lukinovec)

* Make sure DatabaseCacheBootstrapper runs after DatabaseTenancyBootstrapper, misc wip changes

* Fix withTenantDatabases()

* Add failing test (GlobalCacheTest)

* Configure globalCache's DB stores to use central connection instead of default connection every time it's reinstantiated

* Make GlobalCache facade not cached. Even though it wasn't causing issues
in our existing tests, it likely was flaky, and making it not $cached
makes it now consistent with global_cache() - always getting a new
CacheManager from the globalCache container binding

* Add database connection assertions in GlobalCacheTest

* Run all cached resolver/global cache tests with DatabaseCacheBootstrapper

* Reset adjustCacheManagerUsing in revert() and TestCase

* Reset static $stores property

* Finalize GlobalCache-related changes

* tests: remove pointless cache TTLs

* Refactor DatabaseCacheBootstrapper

* Refactor tests

Co-authored-by: lukinovec <lukinovec@gmail.com>
2025-08-08 00:54:01 +02:00
3984d64cfa Use globalCache in CachedTenantResolver (fix #1340) 2025-08-05 12:33:16 +02:00
8f8af34c32
[4.x] Only revert initialized bootstrappers (#1385)
* Only revert initialized bootstrappers (Tenancy::initializedBootstrappers)

* Fix use of @property across the codebase
2025-08-05 11:12:25 +02:00
lukinovec
f308e2f84d
[4.x] Resolve testing todos (#1361)
* Test encrypted cookie identification

* Add Fortify bootstrapper custom query param passing test

* Correct Fortify route bootstrapper test (todo  refactor, convoluted)

* Clarify Fortify bootstrapper test

* Fix encrypted cookie identification test

* Move encrypted cookie assertion to "cookie identification works"

* Cover configured tenant model columns in cached resolver tests

* Refactor testing resolver with default vs custom tenant model name config

* Delete resolved todo

* Make code more concise

* Keep initial formatting (minimize diff noise)

* Make dataset/helper method parameter clearer

* Clarify fortify test

* Clarify assertions, improve comments

* Delete excessive comments, make existing comments consistent and clearer

* Make cached resolver test file clearer, update outdated comments

* Use the tenant model column term consistently

* FIx inconsistencies

* Provide more info in comment

* make comment more clear

* static property reset

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-08-03 23:21:03 +02:00
lukinovec
81fff15afe
[4.x] Update ForgetTenantParameter-related comments (#1375)
* Update ForgetTenantParameter-related comments

* Improve path id mw config docblock

* improve docblocks

---------

Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-08-03 23:15:34 +02:00
lukinovec
b2f2669885
[4.x] Cloning: addTenantParameter(bool), domain(string|null) (#1374)
* Add test for the new clone action addTenantParameter property

* Add $addTenantParameter properyt to the clone action

* Fix code style (php-cs-fixer)

* Update clone action annotation

* Make addTenantParameter(false) sound by adding domain() logic to route cloning

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-07-29 17:17:32 +02:00
62624275cc phpstan fix 2025-07-14 21:48:30 +02:00
91295f01e2 fix origin identification: parse hostname when full URL is used 2025-07-14 21:44:12 +02:00
d8af9b4b43 remove JobBatchBootstrapper 2025-07-10 01:08:49 +02:00
lukinovec
4ead17a56b
[4.x] TableRLSManager refactor, comment constraints (#1354)
* Add option to provide constraint information in column comment

* Fix code style (php-cs-fixer)

* Correct comment functionality, add comment constraint exception

* Simplify and clarify comment-related TableRLSManager code

* Make path skipping logic more explicit

* Correct terminology, add test for throwing exceptions

* Fix code style (php-cs-fixer)

* Improve comments

* Refactor TableRLSManagerr (dynamic programming, deal with recursive relationships, determine shortest paths while generating the paths)

* Fix code style (php-cs-fixer)

* Improve TableRLSManager comments

* Test uncovered edge cases

* Improve code for determining the shortest path

* Improve readability

* Fix code style (php-cs-fixer)

* Update the tree terminology

* Use consistent shortest path terminology

* Improve comment

* Improve method name

* Simplify and clarify core shortest path generation test

* Clarify and simplify tests, add comments

* Delete excessive test

* Test data separation with comment constraints

* Use tenant id instead of getTenantKey()

* Make higher-level code clearer, improve comments

* Improve comments, delete excessive methods, make methods more concise, position helper methods more appropriately

* Fix code style (php-cs-fixer)

* Add a "single source of truth" for path array format, make lower-level code more concise, improve comments

* Fix code style (php-cs-fixer)

* Correct terminology and comments in TableRLSManager

* Correct terminology in table manager test file

* Improve comments and method name

* Fix typo

* bump php memory limit when running tests

* Delete findShortestPath, merge the code into shortestPathToTenantsTabke

* Minor shortestPathToTenantsTable improvement

* Improve docblocks,as discussed

* Move RLSCommentConstraintException to src/RLS/Exceptions

* Fully cover shouldSkipPathLeadingThrough in tests

* test improvements

* tests: add comment to clarify the chosen path

* formatting

* Fix typo

* Use `===` instead of `Str::is()`

* Refactor constraint formatting in TableRLSManager

* Fix code style (php-cs-fixer)

* Update key names of the formatted constraints

* Rename shouldSkipPathLeadingThrough() to shouldSkipPathLeadingThroughConstraint()

* misc improvements

* code improvements

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-07-03 21:12:04 +02:00
lukinovec
d1f12f594d
Instead of assigning $innerMiddleware during group MW unpacking, merge it (#1371) 2025-07-01 17:23:13 +02:00
lukinovec
1e926a1dde
[4.x] Route cloning refactor (#1353)
* Refactor cloning action, update tests

* Delete redundant "should not be cloned" part from shouldBeCloned()

* Use 'clone' instead of a universal route in tenant parameter removal test

* Improve comment

* Add test for cloneRoutesWithMiddleware(), correct existing tests

* Allow cloning specific routes by name

* Fix typo in CloneActionTest

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* clean up CloneRoutesAsTenant, add a todo

* phpstan

* Add test for handling 'clone'  in MW groups

* Improve regression test

* Improve regression test

* Handle nested cloning flags in CloneRoutesAsTenant

* Ignore routes that are already considered tenant routes from cloning, update test accordingly

* Clarify cloning logic

* CloneRoutesAsTenant cleanup

* Rewrite clone action annotation, fix fluent usage bug

* Improve tests (comments, use $tenant->id instead of $tenant->getTenantKey())

* Test that the clone action can be used fluently without issues now (could serve as a regression test for the routesToClone change in previous commit)

* Minor annotation improvements

* Improve route cloning action docblock

* Add note about clearing the $routesToClone property

* improve docblock

* clean up tests

* fix typo

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-07-01 00:32:42 +02:00
7481229063 revert regression in last commit, opt for a phpstan ignore instead 2025-06-19 00:12:38 +02:00
12fcbabd76 phpstan fix 2025-06-18 23:52:35 +02:00
551895d582 Merge branch 'master' into may25 2025-06-18 23:38:21 +02:00
e1fc0e107d remove ignition dependencies 2025-06-18 23:29:24 +02:00