-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tenant Quota #65
Comments
Thank you for the suggestion. I have an idea. For objects, we have the interface method "beforeObject". We can make a "tenantQuota" plugin, which implements this interface and throws an Exception if the creating of the object is denied. For attachments, we should also create a similar plugin with methods like "beforeUpload" and "afterUpload". The "tenantQuota" plugin then also can deny/revert the upload if the file is too large or if there are too many files. Furthermore, the "tenantQuota" plugin can be configured with the What do you think? |
before* Hab mal eine zip generation für die frdl_plugins hinzugefügt (um nicht jeden dev-schritt nach github laden zu müssen) ... |
Das frdl_plugins Repo war eigentlich nur eine Übergangslösung, damit ich deine Plugins updaten konnte. Wenn du es behalten möchtest, ist das natürlich kein Problem. Idealerweise sollte der Quellcode mit den "richtigen" Repos vereint werden, weil ich Sorge habe, dass die Versionen auseinanderlaufen. Und richtig super wäre natürlich, wenn die Änderungen der GitHub Repos automatisch von GitHub nach registry.frdl.de geladen werden, sodass man nur an einer Stelle ändern muss (und ich im Notfall einen Patch einfügen kann). Kann ich dir beim Zusammenführen helfen? |
Hallo Daniel,
-es gibt die github plugins
- es gibt eine last version von registry.frdl.de (siehe zipper und
readme)
Letztere soll eben NICHT von github geladen werden!!!
Die github repos und das .zip bundle funktionieren unabhängig!
Es geht hier um das IO4 und frdl plugins INTERN(!), die github packages
bzw.
der main code kommen extra, wenn sie entsprechend fertig und abgenommen
sind!
Viele Grüße
Till
Am 2024-08-05 11:54, schrieb Daniel Marschall:
… Das frdl_plugins Repo war eigentlich nur eine Übergangslösung, damit
ich deine Plugins updaten konnte. Wenn du es behalten möchtest, ist
das natürlich kein Problem. Idealerweise sollte der Quellcode mit den
"richtigen" Repos vereint werden, weil ich Sorge habe, dass die
Versionen auseinanderlaufen. Und richtig super wäre natürlich, wenn
die Änderungen der GitHub Repos automatisch von GitHub nach
registry.frdl.de geladen werden, sodass man nur an einer Stelle
ändern muss (und ich im Notfall einen Patch einfügen kann). Kann ich
dir beim Zusammenführen helfen?
--
Reply to this email directly, view it on GitHub [1], or unsubscribe
[2].
You are receiving this because you authored the thread.Message ID:
***@***.***>
Links:
------
[1]
#65 (comment)
[2]
https://github.com/notifications/unsubscribe-auth/AAUI53RL3RNJFRH5JW46SJ3ZP5DVNAVCNFSM6AAAAABL7H35MCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENRYGY3DQNZXGQ
--
Webfan Homepagesystem
Till Wehowski
Wattenscheider Straße 59
DE 44793 Bochum
USt-IdNr.: DE280259761
Tel.: +49-234-7921596
Mob.: +49-174-4440298
E-Mail: ***@***.***
Website: https://webfan.de
|
Hallo Till, |
Die "master copy" wird generiert (siehe den code den ich verlinkt habe),
Bisher wird doch nur das RDAP Plugin vom core verwendet!? Das für Dich relevante repository, das für den Core sollte sein: https://github.com/frdl/oidplus-frdlweb-rdap ... Viele Grüße |
The quota the user can use may depand on "plans" the user can register/buy/order, the plans could add available quota (within a time period), this may out of scope of OIDplus. getQuotaAvailable() ??? Auch out of scope, aber Vorschlag, oder per adapter/apis https://startforum.de/content/perma?id=2150 ? |
The next version of OIDplus (to be released in a few days) will introduce the following feature:
$id is the id of the object, e.g. "oid:" $filename_relative is the filename "test.docx" To find out the size of the file to be uploaded, you can query You can create a quota plugin which implements afterAttachmentUpload() and throws an Exception if the quota has been reached. |
…plugins, see #65 git-svn-id: https://svn.viathinksoft.com/svn/oidplus/trunk@1620 02e4d621-2042-4998-a0bc-9ccd24201011
@danielmarschall Thank you! I stay tuned for the next version. I will next think how to implement provisioning of quota. P.S.: Ich mache eventuell heut Nachtschicht. |
... für die before* after* Object Hooks wurden do_action hooks getriggert: |
Version ist veröffentlicht |
Are you sure this will work? I am not sure if data size and index size will bloat up if the database tables are not defragmented regularly. At least for SQL Server and I think also for InnoDB, the files will grow, even if no data is added. Also, if the database is filled up with OIDplus Log entries, then it will also grow in size. We should not punish the customer if we went crazy with logging too much stuff :-) So, I would rather count:
This should be a good quota which is a measurement how much the customer is using. |
I am not sure to account the logs or not. |
In any case, you should do a small experiment by adding and removing data and then check if data + index sizes increase and don't lower again. As far as I know, a lot of DBMS have this behavior, so even pruning log files won't shrink the database! So either there would be a prune + defrag command... ... or you check the data (row count) instead of the database size. Monitoring the row count also has the advantage that your quota plugin is independent of DBMS (which would be a requirement if the plugin would be bundled to the core, since OIDplus must support SQL Server, SQlite and many more) |
...it would also be convenient if we would have access to seperate DB Connections for the central domain/system and the current tenant system. E.g. //for the CURRENT system (central or tenant):
OIDplus::db()-> ...
//for the EXAMPLE tenant
OIDplus::db('example.com')-> ...
//for the CENTRAL system
OIDplus::db(true)-> ...
//for the TENANT system
OIDplus::db(false)-> ... The same syntax way we could select a specific config to act on... and other OIDplus::service() Object getters //for the CURRENT system (central or tenant):
OIDplus::config()-> ...
//for the EXAMPLE tenant
OIDplus::config('example.com')-> ...
//for the CENTRAL config
OIDplus::config(true)-> ...
//for the TENANT config
OIDplus::config(false)-> ... |
namespace ViaThinkSoft\OIDplus\Plugins\PublicPages\Attachments;
interface INTF_OID_1_3_6_1_4_1_37476_2_5_2_3_11 {
public function beforeAttachmentUpload(string $id, string $filename_relative, array $file_data): void;
public function afterAttachmentUpload(string $id, string $filename_relative, array $file_data): void;
public function beforeAttachmentDelete(string $id, string $filename_relative): void;
public function afterAttachmentDelete(string $id, string $filename_relative): void;
public function beforeAttachmentDownload(string $id, string $filename_relative): void;
} I implemented it in the wtf plugin: https://github.com/frdl/frdl-oidplus-wtf-plugin/blob/main/OIDplusPageWTFunctions.class.php#L55 I think I will re-introduce the/a seperate tenant plugin to use the above wtf hooks. I also want to make a wtf OAuth Plugin, now I am not sure to make it tenant, central or system wide...!?? OIDplus::config('example.com')-> I think specially different Database connections are need (if in central/management mode) like If the OIDplus::db('example.com')-> connection is on a different customer space on the server, the (DB-) quota could be managed completly by its Plesk plan. For files, attachments and there quota I would a solution like https://flysystem.thephpleague.com/docs/ to handle filesystem connections for tenants. Flysystem abstracts the filesystem so the tenant could use ...and or connections for RAs and there objects, like tenants of the tenant but without domain/system? |
@wehowski What use-cases would having In my opinion, tenants should not be able to "see" or "access" data of other tenants. |
|
What is the actual use-case where the central system needs to update configuration/data of a tenant system? |
In my use-cases the tenant is a "managed" tenant. I had one use case, I did not remember now fast, I had to perform a (proxy) http request to the tenant domain(s). This could be inconvenient and affect performance. I think it was about to read client DB config/use additional DB connections independent from the central. The (central) system should manage the tenants, there configs and DB connections in another layer. And: Everything ABSTRACTING things (like calling routes, DB Connections, File-Adapters etc.. ) is good in my believe, ... I could manage different DB connections e.g. by own plugins etc. but OIDplus::db('example.com')-> would be nicer and more consistent? However, it is just an idea, maybe for later, the todo stack is full!?! EDIT : One use case would be moving / alias domains... e.g ... |
I think it would be pretty complicated to achieve: This is because the OIDplus class would need to remember not only the own $db, And the baseconfig.inc.php of the tenant system contains lines such as So, very complicated! I'd rather think that it would be good if the class OIDplus would become a non-singleton, then you could have the following code: $oidplus_tenant = new OIDplus();
$oidplus_tenant->forceTenantSubDirName('example.com');
$oidplus_tenant->init(true); // do this after forceTenant(), so that the tenant DB will be loaded
$oidplus_tenant->config()->....
$oidplus_tenant->db()->....
$oidplus_tenant->exit(); But note that this might be a bit slow because the constructon of such an However, this is also a lot of work, because in the complete code, Search: OIDplus::xyz Replace: global $OIDplus:
$OIDplus->xyz Also, no security here, because the new |
Yes, so the tenant could write a raw php config file that orther systems can perform connections withou to load the whole system!?! However, your idea is good! Due to static properties and calls to OIDplus inside the class, an private properties, maybe I have to rewrite the complete class!? class Tenant extends OIDplus
{
public function __construct(?string $tenant = null) {
}
public function exit() {
self::db()->disconnect();
}
} ... |
I made a few experiments to day in order to rename OIDplus to OIDplusSession, and then create a OIDplus class which contains a __callStatic method that forwards all static methods calls from OIDplus to OIDplusSession. With this, everything worked, but the problem is that PHPStan won't accept that, because it cannot see the methods of OIDplus anymore. So I gave up on that idea. Your sounds like a good idea! I think it could work like this, but not 100% sure: class Tenant extends OIDplus
{
public function __construct(?string $tenant = null) {
parent::__construct();
if (!is_null($tenant)) self::forceTenantSubDirName($tenant);
}
public function exit() {
self::db()->disconnect();
}
} I think in the core OIDplus.class.php , I would need to replace all |
Oh, but actually... what happens if Tenant('example.com') calls OIDplusDatabasePlugin, which itself calls OIDplus::baseConfig() ? |
Just tried it. I can't use Dependency Injection, because OIDplus has static methods and is not an instance Inside OIDplus::mailUtils(), the code
So, all static methods would need to become non-static. But this means that ALL EXISTING code cannot use I am out of ideas |
I think we have no good solution to change things. I wish I had designed the classes differently in 2019, and not use that stupid singleton design pattern. But I didn't knew better. I have another idea which is often used in C programming. We could put all (static) class variables in an object that is called Now you could do the following: $bakContext = OIDplus::getCurrentContext(); // make a copy of main system's state
try {
OIDplus::setCurrentContext(new OIDplusContext()); // create a new state
OIDplus::forceTenantSubDirName('example.com'); // switch to tenant
OIDplus::init();
OIDplus::db()->doSomething;
OIDplus::invoke_shutdown();
} finally {
OIDplus::setCurrentContext($bakContext); // switch back to main system
} Disadvantage: You CANNOT work in multiple contexts at the same time. TenantA::config()->setValue('XYZ', TenantB::config()->getValue('XYZ')); This is due to the fact that the whole codebase calls things like What do you think about this solution? Note to myself: If we do this, then I need to check if there are other classes with static variables in the core, which need to go into the context |
git-svn-id: https://svn.viathinksoft.com/svn/oidplus/trunk@1637 02e4d621-2042-4998-a0bc-9ccd24201011
Done. I think this is a good solution to make the best of the situation. It would also allow us to do unit tests someday... With commit 0d6a51c should be able to do this (not tested): $bakContext = OIDplus::getCurrentContext(); // make a copy of main system's state
try {
OIDplus::setCurrentContext(new OIDplusContext()); // create a new state
OIDplus::forceTenantSubDirName('example.com'); // switch to tenant
OIDplus::init();
OIDplus::db()->doSomething;
OIDplus::invoke_shutdown();
} finally {
OIDplus::setCurrentContext($bakContext); // switch back to main system
} |
👍 I will try this out... |
(The GitHub issue has become kind off-topic, I feel like this would need to go to a different issue?) The OIDplusContext solution is actually pretty useful, since the In the latest Git commit, I also give plugins the possibility to write their own stuff to the context. If one of your plugins uses static variables like this (example): static $cache = null; Then you should replace it with this, to make sure that the data gets reset if the context switches, and restored if the context is restored: $cache = &OIDplus::getCurrentContext()->pluginData('1.3.6......pluginoid......', 'MyCache', null);
$cache = 'something'; // writes directly into OIDplusContext, because this is a reference!!! |
If tenant has no own DB (using prefix) we MUST track/limit tenants quotas.
(Or by number of objects?)
Added to IO4 Plugin but maybe introduced to core:
Then it would make sense to introduce a MAX_QUOTA for Tenant Config Value !?
(Later... abstract to "service plans"?)
If quota reached, adding data/upload files should be blocked.
IF we use attachment we should add the files quota to the tenants used resources.
Idea: USE league/flysystem TO ABSTRACT ATTACHMENTS TO REMOTE STORAGES/abstract adapters!?!
The text was updated successfully, but these errors were encountered: