Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b710309
Component Revision: Environment — bootstrap wiring + configuration cl…
chfsx Apr 16, 2026
5f46e19
Component Revision: Database — External/Internal PDO classes + DBLega…
chfsx Apr 16, 2026
6852726
Component Revision: HTTP — bootstrap wiring + HeaderSettings
chfsx Apr 16, 2026
1324853
Component Revision: Filesystem — bootstrap wiring + typed filesystem …
chfsx Apr 16, 2026
b9bb3fb
Component Revision: FileDelivery — bootstrap wiring + FileDeliverySer…
chfsx Apr 16, 2026
bf0574e
Component Revision: FileServices — bootstrap wiring + lazy FileServic…
chfsx Apr 16, 2026
92bc917
Component Revision: ResourceStorage — full bootstrap migration
chfsx Apr 16, 2026
dd64559
Component Revision: Init — AllModernComponents bridge + legacy init c…
chfsx Apr 16, 2026
689fc2c
Component Revision: DI — update Container for bootstrapped services
chfsx Apr 16, 2026
c2131c7
Component Revision: File — adapt to bootstrapped APIs
chfsx Apr 16, 2026
4b356c7
Component Revision: FileUpload — adapt to bootstrapped IRSS + Filesys…
chfsx Apr 16, 2026
08cc2c7
Component Revision: UI — update ExamplesTest for changed bootstrap
chfsx Apr 16, 2026
10895c3
Component Revision: WOPI — adapt to bootstrapped FileDelivery + Files…
chfsx Apr 16, 2026
e0d2415
Component Revision: Init — migrate ini file handling to bootstrapped …
chfsx Apr 16, 2026
6f8163b
Migrate upload pre-processors to component bootstrap
chfsx Apr 16, 2026
2089c5f
[FIX] blacklist empty in some cases
chfsx Apr 16, 2026
a46d670
Migrate StaticURL component to bootstrap; replace ArtifactObjective w…
chfsx Apr 16, 2026
78a93c2
Component Revision: AccessControl — bootstrap wiring for RBAC + acces…
chfsx Apr 24, 2026
e361af0
Component Revision: Logging — bootstrap wiring for logger factory
chfsx Apr 24, 2026
300c0b9
Component Revision: Logging — update ilLoggerFactory type hints to Se…
chfsx Apr 24, 2026
ddbf276
Component Revision: ResourceStorage — replace global \$DIC logger wit…
chfsx Apr 24, 2026
53b9f9d
[FIX] Component Logging needed some more wrappers. please refactor Lo…
chfsx Apr 28, 2026
cb1ab63
[FIX] Logging breaks a lot of tests
chfsx May 5, 2026
9df53aa
Component Revision: revert Logging wrappers and use new infrastructur…
schmitz-ilias Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions components/ILIAS/AccessControl/AccessControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@

namespace ILIAS;

use ILIAS\AccessControl\PublicInterface\Access;
use ILIAS\AccessControl\PublicInterface\RBAC;
use ILIAS\AccessControl\PublicInterface\DefaultRBAC;
use ILIAS\AccessControl\User\UserIdProviderProxy;
use ILIAS\AccessControl\Tree\RepositoryTreeAccessProxy;
use ILIAS\AccessControl\Object\ObjectDataAccessProxy;
use ILIAS\AccessControl\Object\ObjectDefinitionAccessProxy;
use ILIAS\Database\PDO\External;
use ILIAS\HTTP\GlobalHttpState;

class AccessControl implements Component\Component
{
public function init(
Expand All @@ -32,6 +42,55 @@ public function init(
array | \ArrayAccess &$pull,
array | \ArrayAccess &$internal,
): void {
// Public surface
$define[] = Access::class;
$define[] = RBAC::class;

// Internal proxies (concrete classes — no interfaces)
$internal[UserIdProviderProxy::class] = static fn(): UserIdProviderProxy => new UserIdProviderProxy();
$internal[RepositoryTreeAccessProxy::class] = static fn(): RepositoryTreeAccessProxy => new RepositoryTreeAccessProxy();
$internal[ObjectDataAccessProxy::class] = static fn(): ObjectDataAccessProxy => new ObjectDataAccessProxy();
$internal[ObjectDefinitionAccessProxy::class] = static fn(): ObjectDefinitionAccessProxy => new ObjectDefinitionAccessProxy();

// Internal RBAC services (legacy concrete classes)
$internal[\ilRbacReview::class] = static fn(): \ilRbacReview => new \ilRbacReview(
$use[External::class],
$use[\ILIAS\Logging\Logger\LoggerFactoryInterface::class]->getLazy('ac'),
);

$internal[\ilRbacSystem::class] = static fn(): \ilRbacSystem => new \ilRbacSystem(
$internal[UserIdProviderProxy::class],
$use[External::class],
$internal[\ilRbacReview::class],
$internal[RepositoryTreeAccessProxy::class],
$use[GlobalHttpState::class],
$pull[\ILIAS\Refinery\Factory::class],
$internal[ObjectDataAccessProxy::class],
);

$internal[\ilRbacAdmin::class] = static fn(): \ilRbacAdmin => new \ilRbacAdmin(
$use[External::class],
$internal[\ilRbacReview::class],
$use[\ILIAS\Logging\Logger\LoggerFactoryInterface::class]->getLazy('ac'),
);

// Public implementations (in case of RBAC for legacy reasons only)
$implement[RBAC::class] = static fn(): RBAC => new DefaultRBAC(
$internal[\ilRbacReview::class],
$internal[\ilRbacSystem::class],
$internal[\ilRbacAdmin::class],
);

$implement[Access::class] = static fn(): Access => new \ilAccess(
$internal[UserIdProviderProxy::class],
$use[External::class],
$internal[\ilRbacSystem::class],
$internal[RepositoryTreeAccessProxy::class],
$internal[ObjectDefinitionAccessProxy::class],
$use[\ILIAS\Logging\Logger\LoggerFactoryInterface::class]->getLazy('ac'),
);

// Setup agents and assets
$contribute[\ILIAS\Setup\Agent::class] = static fn() =>
new \ilAccessControlSetupAgent(
$pull[\ILIAS\Refinery\Factory::class]
Expand Down
70 changes: 35 additions & 35 deletions components/ILIAS/AccessControl/classes/class.ilAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,24 @@

declare(strict_types=1);

use ILIAS\User\PublicInterface;
use ILIAS\AccessControl\Object\ObjectDefinitionAccessProxy;
use ILIAS\AccessControl\Tree\RepositoryTreeAccessProxy;
use ILIAS\AccessControl\User\UserIdProviderProxy;
use ILIAS\Logging\Logger\LoggerInterface;
use ILIAS\AccessControl\PublicInterface\Access;

/**
* Class ilAccessHandler
* Checks access for ILIAS objects
* Checks access for ILIAS objects.
*
* @author Alex Killing <alex.killing@gmx.de>
* @author Sascha Hofmann <saschahofmann@gmx.de>
*/
class ilAccess implements ilAccessHandler
class ilAccess implements Access
{
private const MAX_CACHE_SIZE = 1000;

protected ilOrgUnitPositionAccess $ilOrgUnitPositionAccess;
protected ?ilOrgUnitPositionAccess $ilOrgUnitPositionAccess = null;
protected array $obj_tree_cache;
protected array $obj_type_cache;
protected array $obj_id_cache;
Expand All @@ -50,26 +57,18 @@ class ilAccess implements ilAccessHandler
protected array $stored_rbac_access = [];
protected array $current_result_element = [];

protected ilRbacSystem $rbacsystem;
protected ilObjUser $user;
protected ilLogger $ac_logger;
protected ilDBInterface $db;
protected ilTree $repositoryTree;
protected ilObjectDefinition $objDefinition;

protected ?ilLanguage $language = null;

public function __construct()
{
global $DIC;

$this->user = $DIC->user();
$this->db = $DIC->database();
$this->rbacsystem = $DIC['rbacsystem'];
public function __construct(
private UserIdProviderProxy $user,
private ilDBInterface $db,
private ilRbacSystem $rbacsystem,
private RepositoryTreeAccessProxy $repositoryTree,
private ObjectDefinitionAccessProxy $objDefinition,
private LoggerInterface $ac_logger
) {
$this->results = [];
$this->current_info = new ilAccessInfo();
$this->repositoryTree = $DIC->repositoryTree();
$this->objDefinition = $DIC['objDefinition'];

// use function enable to switch on/off tests (only cache is used so far)
$this->cache = true;
Expand All @@ -82,10 +81,6 @@ public function __construct()
$this->obj_type_cache = [];
$this->obj_tree_cache = [];
$this->ac_cache = [];

$this->ilOrgUnitPositionAccess = new ilOrgUnitPositionAccess($this);

$this->ac_logger = ilLoggerFactory::getLogger('ac');
}

private function getLanguage(): ilLanguage
Expand Down Expand Up @@ -733,12 +728,17 @@ public function enable(string $a_str, bool $a_bool): void
// OrgUnit Positions
//

private function positionAccess(): \ilOrgUnitPositionAccess
{
return $this->ilOrgUnitPositionAccess ?? $this->ilOrgUnitPositionAccess = new ilOrgUnitPositionAccess($this);
}

/**
* @inheritdoc
*/
public function filterUserIdsForCurrentUsersPositionsAndPermission(array $user_ids, string $permission): array
{
return $this->ilOrgUnitPositionAccess->filterUserIdsForCurrentUsersPositionsAndPermission(
return $this->positionAccess()->filterUserIdsForCurrentUsersPositionsAndPermission(
$user_ids,
$permission
);
Expand All @@ -749,7 +749,7 @@ public function filterUserIdsForCurrentUsersPositionsAndPermission(array $user_i
*/
public function filterUserIdsForUsersPositionsAndPermission(array $user_ids, int $for_user_id, string $permission): array
{
return $this->ilOrgUnitPositionAccess->filterUserIdsForUsersPositionsAndPermission(
return $this->positionAccess()->filterUserIdsForUsersPositionsAndPermission(
$user_ids,
$for_user_id,
$permission
Expand All @@ -761,15 +761,15 @@ public function filterUserIdsForUsersPositionsAndPermission(array $user_ids, int
*/
public function isCurrentUserBasedOnPositionsAllowedTo(string $permission, array $on_user_ids): bool
{
return $this->ilOrgUnitPositionAccess->isCurrentUserBasedOnPositionsAllowedTo($permission, $on_user_ids);
return $this->positionAccess()->isCurrentUserBasedOnPositionsAllowedTo($permission, $on_user_ids);
}

/**
* @inheritdoc
*/
public function isUserBasedOnPositionsAllowedTo(int $which_user_id, string $permission, array $on_user_ids): bool
{
return $this->ilOrgUnitPositionAccess->isUserBasedOnPositionsAllowedTo(
return $this->positionAccess()->isUserBasedOnPositionsAllowedTo(
$which_user_id,
$permission,
$on_user_ids
Expand All @@ -781,39 +781,39 @@ public function isUserBasedOnPositionsAllowedTo(int $which_user_id, string $perm
*/
public function checkPositionAccess(string $pos_perm, int $ref_id): bool
{
return $this->ilOrgUnitPositionAccess->checkPositionAccess($pos_perm, $ref_id);
return $this->positionAccess()->checkPositionAccess($pos_perm, $ref_id);
}

/**
* @inheritdoc
*/
public function checkRbacOrPositionPermissionAccess(string $rbac_perm, string $pos_perm, int $ref_id): bool
{
return $this->ilOrgUnitPositionAccess->checkRbacOrPositionPermissionAccess($rbac_perm, $pos_perm, $ref_id);
return $this->positionAccess()->checkRbacOrPositionPermissionAccess($rbac_perm, $pos_perm, $ref_id);
}

/**
* @inheritdoc
*/
public function filterUserIdsByPositionOfCurrentUser(string $pos_perm, int $ref_id, array $user_ids): array
{
return $this->ilOrgUnitPositionAccess->filterUserIdsByPositionOfCurrentUser($pos_perm, $ref_id, $user_ids);
return $this->positionAccess()->filterUserIdsByPositionOfCurrentUser($pos_perm, $ref_id, $user_ids);
}

/**
* @inheritdoc
*/
public function filterUserIdsByPositionOfUser(int $user_id, string $pos_perm, int $ref_id, array $user_ids): array
{
return $this->ilOrgUnitPositionAccess->filterUserIdsByPositionOfUser($user_id, $pos_perm, $ref_id, $user_ids);
return $this->positionAccess()->filterUserIdsByPositionOfUser($user_id, $pos_perm, $ref_id, $user_ids);
}

/**
* @inheritdoc
*/
public function filterUserIdsByRbacOrPositionOfCurrentUser(string $rbac_perm, string $pos_perm, int $ref_id, array $user_ids): array
{
return $this->ilOrgUnitPositionAccess->filterUserIdsByRbacOrPositionOfCurrentUser(
return $this->positionAccess()->filterUserIdsByRbacOrPositionOfCurrentUser(
$rbac_perm,
$pos_perm,
$ref_id,
Expand All @@ -826,14 +826,14 @@ public function filterUserIdsByRbacOrPositionOfCurrentUser(string $rbac_perm, st
*/
public function hasCurrentUserAnyPositionAccess(int $ref_id): bool
{
return $this->ilOrgUnitPositionAccess->hasCurrentUserAnyPositionAccess($ref_id);
return $this->positionAccess()->hasCurrentUserAnyPositionAccess($ref_id);
}

/**
* @inheritdoc
*/
public function hasUserRBACorAnyPositionAccess(string $rbac_perm, int $ref_id): bool
{
return $this->ilOrgUnitPositionAccess->hasUserRBACorAnyPositionAccess($rbac_perm, $ref_id);
return $this->positionAccess()->hasUserRBACorAnyPositionAccess($rbac_perm, $ref_id);
}
}
18 changes: 7 additions & 11 deletions components/ILIAS/AccessControl/classes/class.ilRbacAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

declare(strict_types=1);

use ILIAS\Logging\Logger\LoggerInterface;

/**
* Class ilRbacAdmin
* Core functions for role based access control.
Expand All @@ -30,21 +32,15 @@
*/
class ilRbacAdmin
{
protected ilDBInterface $db;
protected ilRbacReview $rbacreview;
protected ilLogger $logger;

/**
* Constructor
* @access public
*/
public function __construct()
{
global $DIC;

$this->db = $DIC->database();
$this->rbacreview = $DIC->rbac()->review();
$this->logger = $DIC->logger()->ac();
public function __construct(
protected ilDBInterface $db,
protected ilRbacReview $rbacreview,
protected LoggerInterface $logger
) {
}

public function setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status): void
Expand Down
15 changes: 6 additions & 9 deletions components/ILIAS/AccessControl/classes/class.ilRbacReview.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

declare(strict_types=1);

use ILIAS\Logging\Logger\LoggerInterface;

/**
* class ilRbacReview
* Contains Review functions of core Rbac.
Expand Down Expand Up @@ -45,19 +47,14 @@ class ilRbacReview
protected static array $assigned_users_cache = [];
protected static array $is_assigned_cache = [];

protected ilLogger $log;
protected ilDBInterface $db;

/**
* Constructor
* @access public
*/
public function __construct()
{
global $DIC;

$this->log = ilLoggerFactory::getLogger('ac');
$this->db = $DIC->database();
public function __construct(
protected ilDBInterface $db,
protected LoggerInterface $log
) {
}

/**
Expand Down
44 changes: 24 additions & 20 deletions components/ILIAS/AccessControl/classes/class.ilRbacSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

use ILIAS\HTTP\GlobalHttpState;
use ILIAS\Refinery\Factory;
use ILIAS\AccessControl\User\UserIdProviderProxy;
use ILIAS\Database\PDO\External;
use ILIAS\AccessControl\Tree\RepositoryTreeAccessProxy;
use ILIAS\AccessControl\Object\ObjectDataAccessProxy;

/**
* class ilRbacSystem
Expand All @@ -46,36 +50,36 @@ class ilRbacSystem
// Cache outcomes of calls to checkAccessOfuser
private static array $_checkAccessOfUserCache = [];

protected ilObjUser $user;
protected ilDBInterface $db;
protected ilRbacReview $review;
protected ilObjectDataCache $objectDataCache;
protected ilTree $tree;
protected GlobalHttpState $http;
protected Factory $refinery;


/**
* Constructor
*/
protected function __construct()
public function __construct(
private UserIdProviderProxy $user,
private External $db,
private ilRbacReview $review,
private RepositoryTreeAccessProxy $tree,
private GlobalHttpState $http,
private Factory $refinery,
private ObjectDataAccessProxy $objectDataCache
)
{
global $DIC;

$this->user = $DIC->user();
$this->db = $DIC->database();
$this->review = $DIC->rbac()->review();
$this->objectDataCache = $DIC['ilObjDataCache'];
$this->tree = $DIC->repositoryTree();
$this->http = $DIC->http();
$this->refinery = $DIC->refinery();
}

public static function getInstance(): ilRbacSystem
{
if (self::$instance === null) {
self::$instance = new self();
if (self::$instance !== null) {
return self::$instance;
}
return self::$instance;
global $DIC;
if ($DIC instanceof \Pimple\Container && isset($DIC['rbacsystem'])) {
return self::$instance = $DIC['rbacsystem'];
}
throw new \LogicException(
'ilRbacSystem::getInstance() requires a bootstrapped $DIC[\'rbacsystem\']; '
. 'register a mock via $DIC[\'rbacsystem\'] in tests.'
);
}

/**
Expand Down
Loading
Loading