Index

AccessController

MMO\oauth\controllers · 1 symbol · generated 5 Oct 2026

class

AccessController

AccessController.php:36
class MMO\oauth\controllers\AccessController extends MMO\core\classes\aController
Namespace
MMO\oauth\controllers
Extends
aController
Todo
implements route to get a token from a client and set the token in the authorization header

Index

CSRF_KEY
allowAnonymous
allowUserCreationWithCode
anonymousScopes
clients
codeAuthentifiers
dataControllers
heldScopes
holder
loginTpl
privateCollections
privateKey
publicKey
rightsCollections
rightsScope
route
superScope
user
carriesRights($entity)Tell if $entity carries rights: a role (any change), a client whose scopes or roles changed, a token, an entity of
checkCommitRights($entity)Check that the client of a data api request can write $entity, if it carries rights or is private (carriesRights, $privateCollections): it held $rightsScope (or it changes its own pr…
checkCommitScopes($entity)Check that the user can commit $entity's changes: its status, its creation, its changes or its removal
collectionValue($values, $collection)
doLogin($route)
extractUser($route)
filterPrivate($query)Leave out of a data api listing what $privateCollections keep from a client without the rights: a collection none, the tokens of others, and opacify the other clients of a collection self,…
forgotPassword($route)
getCodeAuthentifier()
getRedirectUri($route, $default)
getUser()
hasUserScope($uid)Check if user or anonymous user has a given scope
hideRecursiveContent($contents, $required)Hide recursively the children content base on user scopes: pages.{path}, and the scopes the content and its parents ask besides (Content::$scopes: admin for a folder of administration pages)
holds($scope)Tell if the client of the request held $scope when the request started: what it changed since (its own role, its own scopes) is left aside
holdsRights()
isDataApi()Tell if the current route is one of the generic data api ($dataControllers), which serves any collection by its name and writes whatever properties its client sends
isLeftToItsModule($value)Tell if the rights on an entity, or on a collection, are its module's to check (iGuarded): everywhere but in the routes of the generic data api ($dataControllers), where the data.* scop…
isOwn($entity)
isUserAllowed($uids)Check if user or anonymous user is allowed to do something
listRecursiveContentScope($request, $content)
login($route)
loginJSON($route)
logout($route)
onCommit($commit)
onPageContents($pageContents)Filter content using scopes pages.*
onQuery($query)
onRoute($route)
onScopes($request)
opacifyPrivateReferences($entity, $depth)Opacify the entities of a private collection ($privateCollections) that $entity references, but the client's own: a group listing its users shows their uid and title only.
privacyOf($collection)
renderNoToken($route, $exception)
resetPassword($route)
routeCreateUser($route)
routeGetUserConfig($route)
routePutUserConfig($route)
routeScopes($route)

Constants1

CSRF_KEY

const CSRF_KEY = 'loginCSRF'

Properties17

allowAnonymous

bool $allowAnonymous = true
Type
bool

allowUserCreationWithCode

protected bool $allowUserCreationWithCode = false
Type
bool

anonymousScopes

array $anonymousScopes = []
Type
array

codeAuthentifiers

?MMO\core\entities\Collection $codeAuthentifiers = null
Type
null | Collection

dataControllers

array $dataControllers = […2 items]
Type
array

heldScopes

protected ?array $heldScopes = null
Type
null | array

holder

protected ?MMO\oauth\interfaces\iClient $holder = null
Type
null | iClient

loginTpl

string $loginTpl = 'login.phtml'
Type
string

privateCollections

array $privateCollections = []
Type
array

privateKey

MMO\oauth\keys\PrivateKey $privateKey
Type
PrivateKey

publicKey

MMO\oauth\keys\PublicKey $publicKey
Type
PublicKey

rightsCollections

array $rightsCollections = []
Type
array

rightsScope

string $rightsScope = 'sudo'
Type
string
See
$privateCollections in full. An application whose administrators hold another scope names it (admin)

route

protected MMO\core\server\Route $route
Type
Route

superScope

string $superScope = 'sudo'
Type
string

user

protected ?MMO\oauth\interfaces\iClient $user = null
Type
null | iClient

Methods36

carriesRights($entity)

AccessController.php:200

Tell if $entity carries rights: a role (any change), a client whose scopes or roles changed, a token, an entity of

protected function carriesRights(MMO\core\interfaces\iEntity $entity): bool
See
$rightsCollections
$entityiEntity
returnsbool

checkCommitRights($entity)

AccessController.php:215

Check that the client of a data api request can write $entity, if it carries rights or is private (carriesRights, $privateCollections): it held $rightsScope (or it changes its own private entity, but not its rights), and, without $superScope, it neither changes its own rights nor writes rights granting that scope

protected function checkCommitRights(MMO\core\interfaces\iEntity $entity): void
$entityiEntity
returnsvoid
throws(403) if it cannot: the attempt is logged
$this->checkCommitRights($role); // a client without `admin` that gave its own role `admin: true`: refused

checkCommitScopes($entity)

AccessController.php:460

Check that the user can commit $entity's changes: its status, its creation, its changes or its removal

protected function checkCommitScopes(MMO\core\interfaces\iEntity $entity): void
$entityiEntity
returnsvoid
throwsif it cannot
$this->checkCommitScopes($order); // an order created needs `data.main.orders.{id}#create`

collectionValue($values, $collection)

AccessController.php:180
protected function collectionValue(array $values, MMO\core\interfaces\iCollection $collection): mixed
$valuesarray
$collectioniCollection
returnsmixedthe value $values gives $collection, or null
$this->collectionValue(['data.main.users' => 'self'], $users); // 'self'

extractUser($route)

AccessController.php:288
#[MMO\core\attributes\APIRoute('**', order: -100, options: ['hidden' => true])] function extractUser(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

filterPrivate($query)

AccessController.php:242

Leave out of a data api listing what $privateCollections keep from a client without the rights: a collection none, the tokens of others, and opacify the other clients of a collection self, wherever they are referenced

protected function filterPrivate(MMO\core\entities\Query $query): void
$queryQuery
returnsvoid
throws(403) for a collection none

forgotPassword($route)

AccessController.php:512
#[MMO\core\attributes\APIRoute('POST|login/forgot?login=email', 'reset password when forgotten', order: -300, mediaTypes: ['html'])] function forgotPassword(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

hideRecursiveContent($contents, $required)

AccessController.php:384

Hide recursively the children content base on user scopes: pages.{path}, and the scopes the content and its parents ask besides (Content::$scopes: admin for a folder of administration pages)

protected function hideRecursiveContent(array $contents, string $required = ''): void
$contentsarray
$required = ''stringthe scopes its parents ask, space-separated
returnsvoid
$this->hideRecursiveContent($contents); // `admin/mongo` hidden to a role with `pages` but not `admin`

holds($scope)

AccessController.php:159

Tell if the client of the request held $scope when the request started: what it changed since (its own role, its own scopes) is left aside

function holds(string $scope): bool
$scopestring
returnsbool
$this->holds('admin'); // false for a client that gave itself `admin` in this request

isDataApi()

AccessController.php:144

Tell if the current route is one of the generic data api ($dataControllers), which serves any collection by its name and writes whatever properties its client sends

function isDataApi(): bool
returnsbool
$this->isDataApi(); // true in `PUT data/main/roles.json`, false in mmo.edms' upload

isLeftToItsModule($value)

AccessController.php:134

Tell if the rights on an entity, or on a collection, are its module's to check (iGuarded): everywhere but in the routes of the generic data api ($dataControllers), where the data.* scopes decide, as for any other

function isLeftToItsModule(MMO\core\interfaces\iEntity|MMO\core\interfaces\iCollection $value): bool
$valueiEntity | iCollection
returnsbool
$this->isLeftToItsModule($file); // true in mmo.edms' routes, false in RepositoryController's `data/main/files.json`

isOwn($entity)

AccessController.php:190
protected function isOwn(MMO\core\interfaces\iEntity $entity): bool
$entityiEntity
returnsbooltrue if $entity is the client of the request, or one of its tokens

listRecursiveContentScope($request, $content)

AccessController.php:476
protected function listRecursiveContentScope( MMO\oauth\events\ScopesList $request, MMO\client\entities\Content $content ): void
$requestScopesList
$contentContent
returnsvoid

login($route)

AccessController.php:582
#[MMO\core\attributes\APIRoute('login', 'login a user using a password', order: -200, mediaTypes: ['html'])] function login(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

loginJSON($route)

AccessController.php:576
#[MMO\core\attributes\APIRoute('GET|login.json?username={username}&password={password}', 'login a user using a password and get a token in a json file', order: -200, mediaTypes: ['json'])] function loginJSON(MMO\core\server\Route $route): MMO\core\server\Response
$routeRoute
returnsResponse

logout($route)

AccessController.php:506
#[MMO\core\attributes\APIRoute('logout', 'logout current user', order: -300, mediaTypes: ['html'])] function logout(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

onCommit($commit)

AccessController.php:436
#[MMO\core\attributes\Listen('MMO\\core\\events\\Commit', order: 1000)] function onCommit(MMO\core\events\Commit $commit): void
$commitCommit
returnsvoid

onPageContents($pageContents)

AccessController.php:398

Filter content using scopes pages.*

#[MMO\core\attributes\Listen('MMO\\client\\events\\PageContents', order: 1000)] function onPageContents(MMO\client\events\PageContents $pageContents): void
$pageContentsPageContents
returnsvoid

onQuery($query)

AccessController.php:405
#[MMO\core\attributes\Listen('MMO\\core\\entities\\Query', order: 1000)] function onQuery(MMO\core\entities\Query $query): void
$queryQuery
returnsvoid

onScopes($request)

AccessController.php:484
#[MMO\core\attributes\Listen('MMO\\oauth\\events\\ScopesList')] function onScopes(MMO\oauth\events\ScopesList $request): void
$requestScopesList
returnsvoid

opacifyPrivateReferences($entity, $depth)

AccessController.php:268

Opacify the entities of a private collection ($privateCollections) that $entity references, but the client's own: a group listing its users shows their uid and title only. Embedded entities are looked into

protected function opacifyPrivateReferences(MMO\core\classes\aEntity $entity, int $depth = 3): void
$entityaEntity
$depth = 3inthow deep embedded entities are looked into
returnsvoid

resetPassword($route)

AccessController.php:533
#[MMO\core\attributes\APIRoute('POST|login/reset', 'endpoint to reset password', order: -300, mediaTypes: ['html'])] function resetPassword(MMO\core\server\Route $route): void
$routeRoute
returnsvoid

routeCreateUser($route)

AccessController.php:671
#[MMO\core\attributes\APIRoute('POST|user/create', 'create a user', body: […8 items])] function routeCreateUser(MMO\core\server\Route $route): MMO\core\server\Response
$routeRoute
returnsResponse

routeGetUserConfig($route)

AccessController.php:704
#[MMO\core\attributes\APIRoute('GET|user/config.json', 'get user configuration', mediaTypes: ['json'])] function routeGetUserConfig(MMO\core\server\Route $route): MMO\core\server\Response
$routeRoute
returnsResponse

routePutUserConfig($route)

AccessController.php:689
#[MMO\core\attributes\APIRoute('PUT|user/config.json', 'set user configuration', mediaTypes: ['json'])] function routePutUserConfig(MMO\core\server\Route $route)
$routeRoute
returns

routeScopes($route)

AccessController.php:716
#[MMO\core\attributes\APIRoute('user/scopes.json?uid={?uid}', 'get scopes for current user', mediaTypes: ['json'])] function routeScopes(MMO\core\server\Route $route): array
$routeRoute
returnsarray
Inherited members (55)
ConstantsDeclared byDescription
ALERTiLogLevelAlert: Action must be taken immediately.
ALLiLogLevelMask for all
ALL_PLUSiLogLeveldebug everything
BACKTRACEiLogLevel
CRITICALiLogLevelCritical: Critical conditions.
DEBUGiLogLevelDebug: Detailed debug information.
DEEPiLogLeveldebug everything with arguments
EMERGENCYiLogLevelEmergency: System is unusable.
ERRORiLogLevelError: Runtime errors that do not require immediate action but should typically be logged and monitored.
ERROR_PLUSiLogLevelMask for all error
FATALiLogLevelMask for all fatal error
INFOiLogLevelInfo: Interesting events.
INFO_PLUSiLogLevelMask for all errors/warning/notices/info
MEMORYiLogLevelinclude backtrace object
NOTICEiLogLevelNotice: Normal but significant events.
NOTICE_PLUSiLogLevelMask for all errors/warning/notices/info
TRACEiLogLevelinclude backtrace as origins
WARNINGiLogLevelWarning: Exceptional occurrences that are not errors.
WARNING_PLUSiLogLevelMask for all errors and warnings
PropertiesDeclared byDescription
verbosityaModule
MethodsDeclared byDescription
alert($message, $context)aModuleAction must be taken immediately.
backtraces($message, $context)aModuleForce-log a message at INFO level together with a full stack trace/memory snapshot (iLogLevel::BACKTRACE), bypassing the verbosity mask entirely (any non-zero verbosity is enough to trigger it).
Configure($config)aModuleMerge $config into this module's configuration in the shared Configuration.
critical($message, $context)aModuleCritical conditions. No-op if CRITICAL is currently filtered out by the verbosity mask.
debug($message, $context)aModuleDetailed debug information.
debugName()aModuleHuman-readable identifier used as the default {origin} in this instance's log messages.
DefaultConfig()aModuleThe config a module starts from before anything loaded via Configuration is merged in.
emergency($message, $context)aModuleSystem is unusable. No-op if EMERGENCY is currently filtered out by the verbosity mask.
error($message, $context)aModuleRuntime errors that do not require immediate action but should typically be logged and monitored.
ExtractRoutes($config)aControllerExtract all the APIRoute from this class, regardless of the fact they are registered in the application
getVerbosity()aModule
HasRoutes()aControllerTells if any APIRoute are registered in the application
info($message, $context)aModuleInteresting events. No-op if INFO is currently filtered out by the verbosity mask.
Instantiate($config)aModule(Re)create the shared instance immediately, configured with $config merged into the class's existing config.
IsShared()aModule
Link($method, $data)aControllerBuild a Link (URL + label/icon/description/title, taken from the route's APIRoute metadata) for a registered route.
log($level, $message, $context)aModuleLogs with an arbitrary level.
notice($message, $context)aModuleNormal but significant events.
offsetExists($key)aModule\ArrayAccess::offsetExists -- tells whether $key is a declared property at all, regardless of whether it is currently readable/writable through array access.
offsetGet($key)aModule\ArrayAccess::offsetGet -- reads a property directly, unless it has a #[Serialize(serialize: 'methodName')] attribute, in which case that zero-argument method is called instead (e.g.
offsetSet($key, $value)aModule\ArrayAccess::offsetSet -- sets a property directly, unless it has a #[Serialize(unserialize: 'methodName')] attribute, in which case that method is called with $value instead (e.g.
offsetUnset($key)aModule\ArrayAccess::offsetUnset -- equivalent to $module[$key] = null.
Route($method)aControllerGet a registered APIRoute WARNING: if this class was not registered in the application, it will return null.
Routes()aControllerGet a list of registered APIRoutes (from this class) in the application WARNING: if this class was not registered in the application, it will return an empty array.
serialize($path, $serializer)aModule\MMO\core\interfaces\iSerializable::serialize -- exports every property (via
setVerbosity($verb)aModuleSet the current verbosity mask, replacing whatever it was before.
Shared()aModuleGet the shared instance, creating (and configuring) it on first call.
testVerbosity($level)aModuleTest whether a given level (or set of levels) is currently enabled by this instance's verbosity mask.
traitUnshare($serialize)aModuleRemove the shared instance, so the next Shared() call creates a fresh one.
unserialize($data, $path, $instances)aModule\MMO\core\interfaces\iSerializable::unserialize -- merges $data onto DefaultConfig, runs it through the (possibly overridden) constructor, then applies each resulting value to its property (via
Unshare($serialize)aModuleLike tSingleton::Unshare, but also disconnects this module's instance from every event it was listening to (via Event::DisconnectListeners) before dropping it.
Url($method, $data)aControllerBuild the URL for a registered route, filling in any {placeholder} from $data.
warning($message, $context)aModuleExceptional occurrences that are not errors.
__construct($config)aModuleprotected constructor, so it is not possible to do new Module(...) called by the serialization process just before being injected with data.
__wakeup()aControllerCalled automatically right after the controller's shared instance is built (aModule::unserialize): registers onRoute as a Route listener with a low priority (-10), so it…