Repository: Ensure that we'll internally only work with virtual table names
refs #10367
This commit is contained in:
parent
f88bd525f1
commit
36340aafa6
|
@ -102,15 +102,13 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
/**
|
||||
* Set the objectClass where to look for users
|
||||
*
|
||||
* Sets also the base table name for the underlying repository.
|
||||
*
|
||||
* @param string $userClass
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUserClass($userClass)
|
||||
{
|
||||
$this->baseTable = $this->userClass = $this->getNormedAttribute($userClass);
|
||||
$this->userClass = $this->getNormedAttribute($userClass);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -216,13 +214,10 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ProgrammingError In case either $this->userNameAttribute or $this->userClass has not been set yet
|
||||
* @throws ProgrammingError In case $this->userNameAttribute has not been set yet
|
||||
*/
|
||||
protected function initializeQueryColumns()
|
||||
{
|
||||
if ($this->userClass === null) {
|
||||
throw new ProgrammingError('It is required to set the objectClass where to look for users first');
|
||||
}
|
||||
if ($this->userNameAttribute === null) {
|
||||
throw new ProgrammingError('It is required to set a attribute name where to find a user\'s name first');
|
||||
}
|
||||
|
@ -240,7 +235,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
}
|
||||
|
||||
return array(
|
||||
$this->userClass => array(
|
||||
'user' => array(
|
||||
'user' => $this->userNameAttribute,
|
||||
'user_name' => $this->userNameAttribute,
|
||||
'is_active' => $isActiveAttribute,
|
||||
|
@ -269,15 +264,9 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
* Initialize this repository's conversion rules
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ProgrammingError In case $this->userClass has not been set yet
|
||||
*/
|
||||
protected function initializeConversionRules()
|
||||
{
|
||||
if ($this->userClass === null) {
|
||||
throw new ProgrammingError('It is required to set the objectClass where to look for users first');
|
||||
}
|
||||
|
||||
if ($this->ds->getCapabilities()->isActiveDirectory()) {
|
||||
$stateConverter = 'user_account_control';
|
||||
} else {
|
||||
|
@ -285,7 +274,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
}
|
||||
|
||||
return array(
|
||||
$this->userClass => array(
|
||||
'user' => array(
|
||||
'is_active' => $stateConverter,
|
||||
'created_at' => 'generalized_time',
|
||||
'last_modified' => 'generalized_time'
|
||||
|
@ -330,14 +319,26 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
}
|
||||
|
||||
/**
|
||||
|
||||
* @param Inspection $info Optional inspection to fill with diagnostic info
|
||||
* Validate that the requested table exists
|
||||
*
|
||||
* @throws AuthenticationException When authentication is not possible
|
||||
* This will return $this->userClass in case $table equals "user".
|
||||
*
|
||||
* @param string $table The table to validate
|
||||
* @param RepositoryQuery $query An optional query to pass as context
|
||||
* (unused by the base implementation)
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws ProgrammingError In case the given table does not exist
|
||||
*/
|
||||
public function assertAuthenticationPossible(Inspection $insp = null)
|
||||
public function requireTable($table, RepositoryQuery $query = null)
|
||||
{
|
||||
$table = parent::requireTable($table, $query);
|
||||
if ($table === 'user') {
|
||||
$table = $this->userClass;
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -359,17 +360,16 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
|||
->getQuery()
|
||||
->setUsePagedResults(false)
|
||||
->fetchDn();
|
||||
|
||||
if ($userDn === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$testCredentialsResult = $this->ds->testCredentials($userDn, $password);
|
||||
if ($testCredentialsResult) {
|
||||
$validCredentials = $this->ds->testCredentials($userDn, $password);
|
||||
if ($validCredentials) {
|
||||
$user->setAdditional('ldap_dn', $userDn);
|
||||
}
|
||||
|
||||
return $testCredentialsResult;
|
||||
return $validCredentials;
|
||||
} catch (LdapException $e) {
|
||||
throw new AuthenticationException(
|
||||
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
||||
|
|
|
@ -211,15 +211,13 @@ class LdapUserGroupBackend extends LdapRepository implements UserGroupBackendInt
|
|||
/**
|
||||
* Set the objectClass where to look for groups
|
||||
*
|
||||
* Sets also the base table name for the underlying repository.
|
||||
*
|
||||
* @param string $groupClass
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setGroupClass($groupClass)
|
||||
{
|
||||
$this->baseTable = $this->groupClass = $this->getNormedAttribute($groupClass);
|
||||
$this->groupClass = $this->getNormedAttribute($groupClass);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -382,16 +380,17 @@ class LdapUserGroupBackend extends LdapRepository implements UserGroupBackendInt
|
|||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ProgrammingError In case either $this->groupNameAttribute or $this->groupClass has not been set yet
|
||||
* @throws ProgrammingError In case either $this->groupNameAttribute or
|
||||
* $this->groupMemberAttribute has not been set yet
|
||||
*/
|
||||
protected function initializeQueryColumns()
|
||||
{
|
||||
if ($this->groupClass === null) {
|
||||
throw new ProgrammingError('It is required to set the objectClass where to look for groups first');
|
||||
}
|
||||
if ($this->groupNameAttribute === null) {
|
||||
throw new ProgrammingError('It is required to set a attribute name where to find a group\'s name first');
|
||||
}
|
||||
if ($this->groupMemberAttribute === null) {
|
||||
throw new ProgrammingError('It is required to set a attribute name where to find a group\'s members first');
|
||||
}
|
||||
|
||||
if ($this->ds->getCapabilities()->isActiveDirectory()) {
|
||||
$createdAtAttribute = 'whenCreated';
|
||||
|
@ -409,7 +408,7 @@ class LdapUserGroupBackend extends LdapRepository implements UserGroupBackendInt
|
|||
'created_at' => $createdAtAttribute,
|
||||
'last_modified' => $lastModifiedAttribute
|
||||
);
|
||||
return array($this->groupClass => $columns, $this->groupClass => $columns);
|
||||
return array('group' => $columns, 'group_membership' => $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -432,7 +431,8 @@ class LdapUserGroupBackend extends LdapRepository implements UserGroupBackendInt
|
|||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ProgrammingError In case $this->groupClass has not been set yet
|
||||
* @throws ProgrammingError In case either $this->groupClass or $this->groupMemberAttribute
|
||||
* has not been set yet
|
||||
*/
|
||||
protected function initializeConversionRules()
|
||||
{
|
||||
|
@ -444,13 +444,17 @@ class LdapUserGroupBackend extends LdapRepository implements UserGroupBackendInt
|
|||
}
|
||||
|
||||
$rules = array(
|
||||
$this->groupClass => array(
|
||||
'group' => array(
|
||||
'created_at' => 'generalized_time',
|
||||
'last_modified' => 'generalized_time'
|
||||
),
|
||||
'group_membership' => array(
|
||||
'created_at' => 'generalized_time',
|
||||
'last_modified' => 'generalized_time'
|
||||
)
|
||||
);
|
||||
if (! $this->isAmbiguous($this->groupClass, $this->groupMemberAttribute)) {
|
||||
$rules[$this->groupClass][] = 'user_name';
|
||||
$rules['group']['user_name'] = 'user_name';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
|
|
@ -468,8 +468,8 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
* This does not check whether any conversion for the given table is available if $column is not given, as it
|
||||
* may be possible that columns from another table where joined in which would otherwise not being converted.
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $column
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -477,10 +477,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
{
|
||||
if ($column !== null) {
|
||||
if ($this->validateQueryColumnAssociation($table, $column)) {
|
||||
return parent::providesValueConversion(
|
||||
$this->removeTablePrefix($this->clearTableAlias($table)),
|
||||
$column
|
||||
);
|
||||
return parent::providesValueConversion($table, $column);
|
||||
}
|
||||
|
||||
if (($tableName = $this->findTableName($column))) {
|
||||
|
@ -513,11 +510,9 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
protected function getConverter($table, $name, $context, RepositoryQuery $query = null)
|
||||
{
|
||||
if (
|
||||
($query !== null && $this->validateQueryColumnAssociation($table, $name))
|
||||
|| ($query === null && $this->validateStatementColumnAssociation($table, $name))
|
||||
! ($query !== null && $this->validateQueryColumnAssociation($table, $name))
|
||||
&& !($query === null && $this->validateStatementColumnAssociation($table, $name))
|
||||
) {
|
||||
$table = $this->removeTablePrefix($this->clearTableAlias($table));
|
||||
} else {
|
||||
$table = $this->findTableName($name);
|
||||
if (! $table) {
|
||||
throw new ProgrammingError('Column name validation seems to have failed. Did you require the column?');
|
||||
|
@ -584,44 +579,17 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
return $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this repository's query columns of the given table mapped to their respective aliases
|
||||
*
|
||||
* @param array|string $table
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ProgrammingError In case $table does not exist
|
||||
*/
|
||||
public function requireAllQueryColumns($table)
|
||||
{
|
||||
return parent::requireAllQueryColumns($this->removeTablePrefix($this->clearTableAlias($table)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query column name for the given alias or null in case the alias does not exist
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $alias
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function resolveQueryColumnAlias($table, $alias)
|
||||
{
|
||||
return parent::resolveQueryColumnAlias($this->removeTablePrefix($this->clearTableAlias($table)), $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the alias for the given query column name or null in case the query column name does not exist
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $column
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function reassembleQueryColumnAlias($table, $column)
|
||||
{
|
||||
$alias = parent::reassembleQueryColumnAlias($this->removeTablePrefix($this->clearTableAlias($table)), $column);
|
||||
$alias = parent::reassembleQueryColumnAlias($table, $column);
|
||||
if (
|
||||
$alias === null
|
||||
&& !$this->validateQueryColumnAssociation($table, $column)
|
||||
|
@ -633,29 +601,13 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
return $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given query column name or alias is available in the given table
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $column
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateQueryColumnAssociation($table, $column)
|
||||
{
|
||||
return parent::validateQueryColumnAssociation(
|
||||
$this->removeTablePrefix($this->clearTableAlias($table)),
|
||||
$column
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the given column is a valid query target and return it or the actual name if it's an alias
|
||||
*
|
||||
* Attempts to join the given column from a different table if its association to the given table cannot be
|
||||
* verified.
|
||||
*
|
||||
* @param array|string $table The table where to look for the column or alias
|
||||
* @param string $table The table where to look for the column or alias
|
||||
* @param string $name The name or alias of the column to validate
|
||||
* @param RepositoryQuery $query An optional query to pass as context,
|
||||
* if not given no join will be attempted
|
||||
|
@ -667,7 +619,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
public function requireQueryColumn($table, $name, RepositoryQuery $query = null)
|
||||
{
|
||||
if ($query === null || $this->validateQueryColumnAssociation($table, $name)) {
|
||||
return parent::requireQueryColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name, $query);
|
||||
return parent::requireQueryColumn($table, $name, $query);
|
||||
}
|
||||
|
||||
return $this->joinColumn($name, $table, $query);
|
||||
|
@ -679,7 +631,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
* Attempts to join the given column from a different table if its association to the given table cannot be
|
||||
* verified.
|
||||
*
|
||||
* @param array|string $table The table where to look for the column or alias
|
||||
* @param string $table The table where to look for the column or alias
|
||||
* @param string $name The name or alias of the column to validate
|
||||
* @param RepositoryQuery $query An optional query to pass as context,
|
||||
* if not given the column is considered being used for a statement filter
|
||||
|
@ -695,7 +647,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
}
|
||||
|
||||
if ($this->validateQueryColumnAssociation($table, $name)) {
|
||||
return parent::requireFilterColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name, $query);
|
||||
return parent::requireFilterColumn($table, $name, $query);
|
||||
}
|
||||
|
||||
return $this->joinColumn($name, $table, $query);
|
||||
|
@ -704,8 +656,8 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
/**
|
||||
* Return the statement column name for the given alias or null in case the alias does not exist
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $alias
|
||||
* @param string $table
|
||||
* @param string $alias
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
|
@ -716,7 +668,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
return $statementAliasColumnMap[$alias];
|
||||
}
|
||||
|
||||
$prefixedAlias = $this->removeTablePrefix($this->clearTableAlias($table)) . '.' . $alias;
|
||||
$prefixedAlias = $table . '.' . $alias;
|
||||
if (isset($statementAliasColumnMap[$prefixedAlias])) {
|
||||
return $statementAliasColumnMap[$prefixedAlias];
|
||||
}
|
||||
|
@ -725,8 +677,8 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
/**
|
||||
* Return the alias for the given statement column name or null in case the statement column does not exist
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $column
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
|
@ -737,7 +689,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
return $statementColumnAliasMap[$column];
|
||||
}
|
||||
|
||||
$prefixedColumn = $this->removeTablePrefix($this->clearTableAlias($table)) . '.' . $column;
|
||||
$prefixedColumn = $table . '.' . $column;
|
||||
if (isset($statementColumnAliasMap[$prefixedColumn])) {
|
||||
return $statementColumnAliasMap[$prefixedColumn];
|
||||
}
|
||||
|
@ -746,34 +698,32 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
/**
|
||||
* Return whether the given alias or statement column name is available in the given table
|
||||
*
|
||||
* @param array|string $table
|
||||
* @param string $alias
|
||||
* @param string $table
|
||||
* @param string $alias
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateStatementColumnAssociation($table, $alias)
|
||||
{
|
||||
$tableName = $this->removeTablePrefix($this->clearTableAlias($table));
|
||||
|
||||
$statementAliasTableMap = $this->getStatementAliasTableMap();
|
||||
if (isset($statementAliasTableMap[$alias])) {
|
||||
return $statementAliasTableMap[$alias] === $tableName;
|
||||
return $statementAliasTableMap[$alias] === $table;
|
||||
}
|
||||
|
||||
$statementColumnTableMap = $this->getStatementColumnTableMap();
|
||||
if (isset($statementColumnTableMap[$alias])) {
|
||||
return $statementColumnTableMap[$alias] === $tableName;
|
||||
return $statementColumnTableMap[$alias] === $table;
|
||||
}
|
||||
|
||||
$prefixedAlias = $tableName . '.' . $alias;
|
||||
$prefixedAlias = $table . '.' . $alias;
|
||||
return isset($statementAliasTableMap[$prefixedAlias]) || isset($statementColumnTableMap[$prefixedAlias]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given column name or alias of the given table is a valid statement column
|
||||
*
|
||||
* @param array|string $table The table where to look for the column or alias
|
||||
* @param string $name The column name or alias to check
|
||||
* @param string $table The table where to look for the column or alias
|
||||
* @param string $name The column name or alias to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -784,7 +734,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
&& $this->reassembleStatementColumnAlias($table, $name) === null)
|
||||
|| !$this->validateStatementColumnAssociation($table, $name)
|
||||
) {
|
||||
return parent::hasStatementColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name);
|
||||
return parent::hasStatementColumn($table, $name);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -793,8 +743,8 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
/**
|
||||
* Validate that the given column is a valid statement column and return it or the actual name if it's an alias
|
||||
*
|
||||
* @param array|string $table The table for which to require the column
|
||||
* @param string $name The name or alias of the column to validate
|
||||
* @param string $table The table for which to require the column
|
||||
* @param string $name The name or alias of the column to validate
|
||||
*
|
||||
* @return string The given column's name
|
||||
*
|
||||
|
@ -807,15 +757,11 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
} elseif (($alias = $this->reassembleStatementColumnAlias($table, $name)) !== null) {
|
||||
$column = $name;
|
||||
} else {
|
||||
return parent::requireStatementColumn($this->removeTablePrefix($this->clearTableAlias($table)), $name);
|
||||
return parent::requireStatementColumn($table, $name);
|
||||
}
|
||||
|
||||
if (! $this->validateStatementColumnAssociation($table, $alias)) {
|
||||
throw new StatementException(
|
||||
'Statement column "%s" not found in table "%s"',
|
||||
$name,
|
||||
$this->removeTablePrefix($this->clearTableAlias($table))
|
||||
);
|
||||
throw new StatementException('Statement column "%s" not found in table "%s"', $name, $table);
|
||||
}
|
||||
|
||||
return $column;
|
||||
|
@ -829,7 +775,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
* The method is called with the same parameters but in reversed order.
|
||||
*
|
||||
* @param string $name The alias or column name to join into $target
|
||||
* @param array|string $target The table to join $name into
|
||||
* @param string $target The table to join $name into
|
||||
* @param RepositoryQUery $query The query to apply the JOIN-clause on
|
||||
*
|
||||
* @return string The resolved alias or $name
|
||||
|
@ -843,7 +789,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
throw new ProgrammingError(
|
||||
'Unable to find a valid table for column "%s" to join into "%s"',
|
||||
$name,
|
||||
$this->removeTablePrefix($this->clearTableAlias($target))
|
||||
$target
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -861,7 +807,7 @@ abstract class DbRepository extends Repository implements Extensible, Updatable,
|
|||
throw new ProgrammingError(
|
||||
'Unable to join table "%s" into "%s". Method "%s" not found',
|
||||
$tableName,
|
||||
$this->removeTablePrefix($this->clearTableAlias($target)),
|
||||
$target,
|
||||
$joinMethod
|
||||
);
|
||||
}
|
||||
|
|
|
@ -79,8 +79,9 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
|
|||
*/
|
||||
public function from($target, array $columns = null)
|
||||
{
|
||||
$target = $this->repository->requireTable($target, $this);
|
||||
$this->query = $this->repository->getDataSource()->select()->from($target);
|
||||
$this->query = $this->repository->getDataSource()->select()->from(
|
||||
$this->repository->requireTable($target, $this)
|
||||
);
|
||||
$this->query->columns($this->prepareQueryColumns($target, $columns));
|
||||
$this->target = $target;
|
||||
return $this;
|
||||
|
|
Loading…
Reference in New Issue