/** Datei: plugins/tenants/hooks/model/saved_users.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * * @hook model::saved->users * @param mixed $result save result * @param string $table Current Database Table Name * @param object $query Database\QueryBuilder Object * * @since 1.0.0 File is created */ use ARUNOX\Core\Auth; use ARUNOX\Plugins\Users; use ARUNOX\Database\QueryBuilder; if( $result === FALSE ) return $result; $user = Users\Model::get( $result ); if( !$user->tenant_id ) return $result; $hash = Auth::createHash( $user->email ); $DBname = "admin"; $table = "tenants_systems_users"; $where = [ "tenant_id" => $user->tenant_id, "system_id" => SYSTEM->id, "user_id" => $user->id, ]; $data = array_merge( $where, [ "hash" => $hash ] ); $exists = QueryBuilder::select( $table ) ->addWhere( $where ) ->using( $DBname ) ->fetch(); // show( $exists, $data, $user ); if( $exists ) $mapping = QueryBuilder::update( $table, $data, $where ); else $mapping = QueryBuilder::insert( $table, $data ); $mapping = $mapping->using( $DBname )->execute(); // show( $result, $mapping, $user ); return $result; /** Datei: plugins/tenants/hooks/model/query.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * * @hook model::query * @param object $query Database\QueryBuilder Object * @param string $table Current Database Table Name * * @since 1.0.0 File is created */ use ARUNOX\Database; use ARUNOX\Plugins\Users; use ARUNOX\Plugins\Tenants; if( $table == Tenants\Model::getTable() ) return $query->using("admin"); if( $table == Tenants\Systems\Model::getTable() ) return $query->using("admin"); if( in_array( $query->database->getConfig("name"), [ "default", "admin" ] ) ) { return $query; } // show( $query->database->getConfig("name") ); if( Users\Model::isSuperadmin() || !Users\Model::isLoggedIn() ) return $query; if( !SYSTEM->type->isTenantShared() ) return $query; if( !Database::existsTable( "{$query->table}_meta" ) ) return $query; if( Database::columnExists( $query->table, "origin_id" ) ) { $mainTable = $query->table; $mainTable = explode( "_", $mainTable ); $subTable = array_pop( $mainTable ); $mainTable = implode( "_", $mainTable ); $query->addWhere([ "tenant_id__query" => [ "table" => "{$mainTable}_meta", "on" => "{$mainTable}_meta.origin_id = {$query->table}.origin_id", "CONDITIONS" => [ "meta_key" => "tenant_id", "meta_value" => Users\Model::getTenantId(), ] ] ]); return $query; } $query->addWhere([ "tenant_id__meta" => Users\Model::getTenantId() ] ); return $query; /** Datei: plugins/tenants/hooks/router/dispatch-after_users.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ use ARUNOX\Core\Hooks; use ARUNOX\Plugins\REST; use ARUNOX\Plugins\Users; Hooks::add('router::dispatch->after->patch.users.{id}.status', function( $result, $route, $id ) { if( !REST\Response::hasUpdater() ) return $result; $response = REST\Response::response(); $user = Users\Model::get( $id ); $referer = $route["request"]->getReferer("path"); if( !$user ) return $result; if( !preg_match( "/^tenants/", $referer ) ) return $result; foreach( $response as &$item ) { if( $item->type !== "updater" ) continue; $uuid = base64_decode( $item->updater ); $uuid = explode( ":", $uuid ); if( $uuid[1] != "/api/v1/users" ) continue; $uuid[1] = "/api/v1/tenants/{$user->tenant_id}/users"; $uuid = implode( ":", $uuid ); $uuid = base64_encode( $uuid ); $item->updater = $uuid; break; } return $response; }); Hooks::add('router::dispatch->after->delete.users.{id}', function( $result, $route, $id ) { if( !REST\Response::hasRoute() ) return $result; $response = REST\Response::response(); $user = Users\Model::get( $id ); $referer = $route["request"]->getReferer("path"); if( !$user ) return $result; if( !preg_match( "/^tenants/", $referer ) ) return $result; foreach( $response as &$item ) { if( $item->type !== "route" ) continue; $item->route = "/tenants/{$user->tenant_id}#users"; } return $response; }); /** Datei: plugins/tenants/hooks/router/dispatch-before_login.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * * @hook router::dispatch->before->post.login * @param mixed $route current route data * @param object $request current request data * * @since 1.0.0 File is created */ use ARUNOX\Core\Auth; use ARUNOX\Plugins\REST; use ARUNOX\Plugins\Users; use ARUNOX\Database\QueryBuilder; if( !SYSTEM->type->isTenantIsolated() ) return; $post = $request->getBodyParams(); $hash = Auth::createHash( $post["email"] ); $DBname = "admin"; $data = QueryBuilder::select("tenants_systems_users") ->addWhere([ "system_id" => SYSTEM->id, "hash" => $hash, ]) ->using( $DBname ) ->fetch(); // show( $data, "X" ); if( !$data ) { REST\Response::addNotify( "danger", "NO SYSTEM/USER FOUND" ); REST\Response::setTemplate( "login" ); REST\Response::jsonResponse( 401 )->send(); } // show( $post, $hash, $data, "X" ); $data = QueryBuilder::select("tenants_systems") ->addWhere([ "system_id" => SYSTEM->id, "tenant_id" => $data->tenant_id, ]) ->using( $DBname ) ->fetch(); if( !$data ) { REST\Response::addNotify( "danger", "NO SYSTEM/TENANT FOUND" ); REST\Response::setTemplate( "login" ); REST\Response::jsonResponse( 401 )->send(); } if( !$data->db_name ) { REST\Response::addNotify( "danger", "NO DATABASE FOUND" ); REST\Response::setTemplate( "login" ); REST\Response::jsonResponse( 401 )->send(); } SYSTEM->setDBName( $data->db_name ); SYSTEM->connect(); return $route; /** Datei: plugins/tenants/hooks/init.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * * @hook config::loaded * @param array $REQUEST Typically contains the data provided by $_REQUEST * * @since 1.0.0 File is created */ use ARUNOX\Plugins\REST; use ARUNOX\Plugins\Users; use ARUNOX\Plugins\Systems; use ARUNOX\Plugins\Tenants; if( !defined( "SYSTEM" ) ) return; if( !Users\Model::isLoggedIn() || !SYSTEM || SYSTEM->type->isAdmin() ) return; $DBname = "admin"; $DBstatus = SYSTEM->db_status; $data = Tenants\Systems\Model::get([ "system_id" => SYSTEM->id, "tenant_id" => Users\Model::getTenantId(), ]); if( !$data || $data->status->isInactive() ) { Users\Model::removeCurrent(); if( PUBLIC_SCRIPT_NAME == PUBLIC_SCRIPT_NAME_API ) { Users\API\v1\Controller::restConfigLogin(); // show("X"); REST\Response::addNotify( "danger", "NO SYSTEM FOUND" ); REST\Response::jsonResponse( 401 )->send(); } return; } if( SYSTEM->type->isTenantShared() ) return; if( $data->db_status->getValue() < Systems\DBStatus::AdminMissing ) { Users\Model::removeCurrent(); if( PUBLIC_SCRIPT_NAME == PUBLIC_SCRIPT_NAME_API ) { if( $data->db_status->getValue() <= Systems\DBStatus::Failed ) { REST\Response::addNotify( "danger", "FATAL DATABASE ERROR", NULL, 0 ); } if( $data->db_status->getValue() == Systems\DBStatus::Installing ) { REST\Response::addNotify( "warning", "INSTALLING SYSTEM...", NULL, 0 ); } if( $data->db_status->getValue() == Systems\DBStatus::Maintenance ) { REST\Response::addNotify( "warning", "SYSTEM IS UNDER MAINTENANCE...", NULL, 0 ); } Users\API\v1\Controller::restConfigLogin(); REST\Response::jsonResponse( 503 )->send(); } return; } if( !$data->db_name ) { Users\Model::removeCurrent(); return; } SYSTEM->connect( $data->db_name );