Merge pull request #44658 from nextcloud/fix/migrate-away-from-resource-type

fix: Remove obsolete resource typing
pull/41478/merge
Côme Chilliet 2 months ago committed by GitHub
commit 3ad4bbb096
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,6 +1,7 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl> * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl>
* *
@ -27,8 +28,7 @@ namespace OCA\Files_External\Lib\Storage;
* Low level wrapper around the ftp functions that smooths over some difference between servers * Low level wrapper around the ftp functions that smooths over some difference between servers
*/ */
class FtpConnection { class FtpConnection {
/** @var resource|\FTP\Connection */ private \FTP\Connection $connection;
private $connection;
public function __construct(bool $secure, string $hostname, int $port, string $username, string $password) { public function __construct(bool $secure, string $hostname, int $port, string $username, string $password) {
if ($secure) { if ($secure) {
@ -50,10 +50,7 @@ class FtpConnection {
} }
public function __destruct() { public function __destruct() {
if ($this->connection) { ftp_close($this->connection);
ftp_close($this->connection);
}
$this->connection = null;
} }
public function setUtf8Mode(): bool { public function setUtf8Mode(): bool {

@ -240,7 +240,7 @@ class ImageManager {
imagesavealpha($newImage, true); imagesavealpha($newImage, true);
imagealphablending($newImage, true); imagealphablending($newImage, true);
$newWidth = (int)(imagesx($newImage) < 4096 ? imagesx($newImage) : 4096); $newWidth = (imagesx($newImage) < 4096 ? imagesx($newImage) : 4096);
$newHeight = (int)(imagesy($newImage) / (imagesx($newImage) / $newWidth)); $newHeight = (int)(imagesy($newImage) / (imagesx($newImage) / $newWidth));
$outputImage = imagescale($newImage, $newWidth, $newHeight); $outputImage = imagescale($newImage, $newWidth, $newHeight);
if ($outputImage === false) { if ($outputImage === false) {
@ -248,7 +248,7 @@ class ImageManager {
} }
$newTmpFile = $this->tempManager->getTemporaryFile(); $newTmpFile = $this->tempManager->getTemporaryFile();
imageinterlace($outputImage, 1); imageinterlace($outputImage, true);
// Keep jpeg images encoded as jpeg // Keep jpeg images encoded as jpeg
if (str_contains($detectedMimeType, 'image/jpeg')) { if (str_contains($detectedMimeType, 'image/jpeg')) {
if (!imagejpeg($outputImage, $newTmpFile, 90)) { if (!imagejpeg($outputImage, $newTmpFile, 90)) {

@ -188,11 +188,6 @@ class Access extends LDAPUtility {
return false; return false;
} }
$cr = $this->connection->getConnectionResource(); $cr = $this->connection->getConnectionResource();
if (!$this->ldap->isResource($cr)) {
//LDAP not available
$this->logger->debug('LDAP resource not available.', ['app' => 'user_ldap']);
return false;
}
$attr = mb_strtolower($attr, 'UTF-8'); $attr = mb_strtolower($attr, 'UTF-8');
// the actual read attribute later may contain parameters on a ranged // the actual read attribute later may contain parameters on a ranged
// request, e.g. member;range=99-199. Depends on server reply. // request, e.g. member;range=99-199. Depends on server reply.
@ -346,11 +341,6 @@ class Access extends LDAPUtility {
throw new \Exception('LDAP password changes are disabled.'); throw new \Exception('LDAP password changes are disabled.');
} }
$cr = $this->connection->getConnectionResource(); $cr = $this->connection->getConnectionResource();
if (!$this->ldap->isResource($cr)) {
//LDAP not available
$this->logger->debug('LDAP resource not available.', ['app' => 'user_ldap']);
return false;
}
try { try {
// try PASSWD extended operation first // try PASSWD extended operation first
return @$this->invokeLDAPMethod('exopPasswd', $userDN, '', $password) || return @$this->invokeLDAPMethod('exopPasswd', $userDN, '', $password) ||
@ -1110,12 +1100,6 @@ class Access extends LDAPUtility {
) { ) {
// See if we have a resource, in case not cancel with message // See if we have a resource, in case not cancel with message
$cr = $this->connection->getConnectionResource(); $cr = $this->connection->getConnectionResource();
if (!$this->ldap->isResource($cr)) {
// Seems like we didn't find any resource.
// Return an empty array just like before.
$this->logger->debug('Could not search, because resource is missing.', ['app' => 'user_ldap']);
return false;
}
//check whether paged search should be attempted //check whether paged search should be attempted
try { try {
@ -1138,7 +1122,7 @@ class Access extends LDAPUtility {
/** /**
* processes an LDAP paged search operation * processes an LDAP paged search operation
* *
* @param resource|\LDAP\Result|resource[]|\LDAP\Result[] $sr the array containing the LDAP search resources * @param \LDAP\Result|\LDAP\Result[] $sr the array containing the LDAP search resources
* @param int $foundItems number of results in the single search operation * @param int $foundItems number of results in the single search operation
* @param int $limit maximum results to be counted * @param int $limit maximum results to be counted
* @param bool $pagedSearchOK whether a paged search has been executed * @param bool $pagedSearchOK whether a paged search has been executed
@ -1251,7 +1235,7 @@ class Access extends LDAPUtility {
} }
/** /**
* @param resource|\LDAP\Result|resource[]|\LDAP\Result[] $sr * @param \LDAP\Result|\LDAP\Result[] $sr
* @return int * @return int
* @throws ServerNotAvailableException * @throws ServerNotAvailableException
*/ */

@ -86,30 +86,15 @@ use Psr\Log\LoggerInterface;
* @property string ldapAdminGroup * @property string ldapAdminGroup
*/ */
class Connection extends LDAPUtility { class Connection extends LDAPUtility {
/** private ?\LDAP\Connection $ldapConnectionRes = null;
* @var resource|\LDAP\Connection|null private string $configPrefix;
*/ private ?string $configID;
private $ldapConnectionRes = null; private bool $configured = false;
/**
* @var string
*/
private $configPrefix;
/**
* @var ?string
*/
private $configID;
/**
* @var bool
*/
private $configured = false;
/** /**
* @var bool whether connection should be kept on __destruct * @var bool whether connection should be kept on __destruct
*/ */
private $dontDestruct = false; private bool $dontDestruct = false;
/** /**
* @var bool runtime flag that indicates whether supported primary groups are available * @var bool runtime flag that indicates whether supported primary groups are available
@ -241,14 +226,11 @@ class Connection extends LDAPUtility {
} }
/** /**
* @return resource|\LDAP\Connection The LDAP resource * @return \LDAP\Connection The LDAP resource
*/ */
public function getConnectionResource() { public function getConnectionResource(): \LDAP\Connection {
if (!$this->ldapConnectionRes) { if (!$this->ldapConnectionRes) {
$this->init(); $this->init();
} elseif (!$this->ldap->isResource($this->ldapConnectionRes)) {
$this->ldapConnectionRes = null;
$this->establishConnection();
} }
if (is_null($this->ldapConnectionRes)) { if (is_null($this->ldapConnectionRes)) {
$this->logger->error( $this->logger->error(
@ -263,7 +245,7 @@ class Connection extends LDAPUtility {
/** /**
* resets the connection resource * resets the connection resource
*/ */
public function resetConnectionResource() { public function resetConnectionResource(): void {
if (!is_null($this->ldapConnectionRes)) { if (!is_null($this->ldapConnectionRes)) {
@$this->ldap->unbind($this->ldapConnectionRes); @$this->ldap->unbind($this->ldapConnectionRes);
$this->ldapConnectionRes = null; $this->ldapConnectionRes = null;
@ -273,9 +255,8 @@ class Connection extends LDAPUtility {
/** /**
* @param string|null $key * @param string|null $key
* @return string
*/ */
private function getCacheKey($key) { private function getCacheKey($key): string {
$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-'; $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
if (is_null($key)) { if (is_null($key)) {
return $prefix; return $prefix;
@ -332,9 +313,8 @@ class Connection extends LDAPUtility {
* Caches the general LDAP configuration. * Caches the general LDAP configuration.
* @param bool $force optional. true, if the re-read should be forced. defaults * @param bool $force optional. true, if the re-read should be forced. defaults
* to false. * to false.
* @return null
*/ */
private function readConfiguration($force = false) { private function readConfiguration(bool $force = false): void {
if ((!$this->configured || $force) && !is_null($this->configID)) { if ((!$this->configured || $force) && !is_null($this->configID)) {
$this->configuration->readConfiguration(); $this->configuration->readConfiguration();
$this->configured = $this->validateConfiguration(); $this->configured = $this->validateConfiguration();
@ -406,7 +386,7 @@ class Connection extends LDAPUtility {
return $result; return $result;
} }
private function doSoftValidation() { private function doSoftValidation(): void {
//if User or Group Base are not set, take over Base DN setting //if User or Group Base are not set, take over Base DN setting
foreach (['ldapBaseUsers', 'ldapBaseGroups'] as $keyBase) { foreach (['ldapBaseUsers', 'ldapBaseGroups'] as $keyBase) {
$val = $this->configuration->$keyBase; $val = $this->configuration->$keyBase;
@ -461,13 +441,9 @@ class Connection extends LDAPUtility {
} }
} }
/** private function doCriticalValidation(): bool {
* @return bool
*/
private function doCriticalValidation() {
$configurationOK = true; $configurationOK = true;
$errorStr = 'Configuration Error (prefix '. $errorStr = 'Configuration Error (prefix ' . $this->configPrefix . '): ';
(string)$this->configPrefix .'): ';
//options that shall not be empty //options that shall not be empty
$options = ['ldapHost', 'ldapUserDisplayName', $options = ['ldapHost', 'ldapUserDisplayName',
@ -552,7 +528,7 @@ class Connection extends LDAPUtility {
* Validates the user specified configuration * Validates the user specified configuration
* @return bool true if configuration seems OK, false otherwise * @return bool true if configuration seems OK, false otherwise
*/ */
private function validateConfiguration() { private function validateConfiguration(): bool {
if ($this->doNotValidate) { if ($this->doNotValidate) {
//don't do a validation if it is a new configuration with pure //don't do a validation if it is a new configuration with pure
//default values. Will be allowed on changes via __set or //default values. Will be allowed on changes via __set or
@ -575,7 +551,7 @@ class Connection extends LDAPUtility {
* *
* @throws ServerNotAvailableException * @throws ServerNotAvailableException
*/ */
private function establishConnection() { private function establishConnection(): ?bool {
if (!$this->configuration->ldapConfigurationActive) { if (!$this->configuration->ldapConfigurationActive) {
return null; return null;
} }
@ -663,15 +639,18 @@ class Connection extends LDAPUtility {
/** /**
* @param string $host * @param string $host
* @param string $port * @param string $port
* @return bool
* @throws \OC\ServerNotAvailableException * @throws \OC\ServerNotAvailableException
*/ */
private function doConnect($host, $port) { private function doConnect($host, $port): bool {
if ($host === '') { if ($host === '') {
return false; return false;
} }
$this->ldapConnectionRes = $this->ldap->connect($host, $port); $this->ldapConnectionRes = $this->ldap->connect($host, $port) ?: null;
if ($this->ldapConnectionRes === null) {
throw new ServerNotAvailableException('Connection failed');
}
if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { if (!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
throw new ServerNotAvailableException('Could not set required LDAP Protocol version.'); throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');

@ -1374,10 +1374,10 @@ class Group_LDAP extends ABackend implements GroupInterface, IGroupLDAP, IGetDis
* of the current access. * of the current access.
* *
* @param string $gid * @param string $gid
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
* @throws ServerNotAvailableException * @throws ServerNotAvailableException
*/ */
public function getNewLDAPConnection($gid) { public function getNewLDAPConnection($gid): \LDAP\Connection {
$connection = clone $this->access->getConnection(); $connection = clone $this->access->getConnection();
return $connection->getConnectionResource(); return $connection->getConnectionResource();
} }

@ -371,9 +371,9 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP, IGet
* The connection needs to be closed manually. * The connection needs to be closed manually.
* *
* @param string $gid * @param string $gid
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
*/ */
public function getNewLDAPConnection($gid) { public function getNewLDAPConnection($gid): \LDAP\Connection {
return $this->handleRequest($gid, 'getNewLDAPConnection', [$gid]); return $this->handleRequest($gid, 'getNewLDAPConnection', [$gid]);
} }

@ -36,7 +36,7 @@ interface IGroupLDAP {
/** /**
* Return a new LDAP connection for the specified group. * Return a new LDAP connection for the specified group.
* @param string $gid * @param string $gid
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
*/ */
public function getNewLDAPConnection($gid); public function getNewLDAPConnection($gid);
} }

@ -34,7 +34,7 @@ interface ILDAPWrapper {
/** /**
* Bind to LDAP directory * Bind to LDAP directory
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param string $dn an RDN to log in with * @param string $dn an RDN to log in with
* @param string $password the password * @param string $password the password
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
@ -47,14 +47,14 @@ interface ILDAPWrapper {
* connect to an LDAP server * connect to an LDAP server
* @param string $host The host to connect to * @param string $host The host to connect to
* @param string $port The port to connect to * @param string $port The port to connect to
* @return resource|\LDAP\Connection|false a link resource on success, otherwise false * @return \LDAP\Connection|false a link resource on success, otherwise false
*/ */
public function connect($host, $port); public function connect($host, $port);
/** /**
* Retrieve the LDAP pagination cookie * Retrieve the LDAP pagination cookie
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\Result $result LDAP result resource * @param \LDAP\Result $result LDAP result resource
* @param string &$cookie structure sent by LDAP server * @param string &$cookie structure sent by LDAP server
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
* *
@ -64,22 +64,22 @@ interface ILDAPWrapper {
/** /**
* Count the number of entries in a search * Count the number of entries in a search
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\Result $result LDAP result resource * @param \LDAP\Result $result LDAP result resource
* @return int|false number of results on success, false otherwise * @return int|false number of results on success, false otherwise
*/ */
public function countEntries($link, $result); public function countEntries($link, $result);
/** /**
* Return the LDAP error number of the last LDAP command * Return the LDAP error number of the last LDAP command
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @return int error code * @return int error code
*/ */
public function errno($link); public function errno($link);
/** /**
* Return the LDAP error message of the last LDAP command * Return the LDAP error message of the last LDAP command
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @return string error message * @return string error message
*/ */
public function error($link); public function error($link);
@ -95,69 +95,69 @@ interface ILDAPWrapper {
/** /**
* Return first result id * Return first result id
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\Result $result LDAP result resource * @param \LDAP\Result $result LDAP result resource
* @return resource|\LDAP\ResultEntry an LDAP entry resource * @return \LDAP\ResultEntry an LDAP entry resource
* */ * */
public function firstEntry($link, $result); public function firstEntry($link, $result);
/** /**
* Get attributes from a search result entry * Get attributes from a search result entry
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\ResultEntry $result LDAP result resource * @param \LDAP\ResultEntry $result LDAP result resource
* @return array|false containing the results, false on error * @return array|false containing the results, false on error
* */ * */
public function getAttributes($link, $result); public function getAttributes($link, $result);
/** /**
* Get the DN of a result entry * Get the DN of a result entry
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\ResultEntry $result LDAP result resource * @param \LDAP\ResultEntry $result LDAP result resource
* @return string|false containing the DN, false on error * @return string|false containing the DN, false on error
*/ */
public function getDN($link, $result); public function getDN($link, $result);
/** /**
* Get all result entries * Get all result entries
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\Result $result LDAP result resource * @param \LDAP\Result $result LDAP result resource
* @return array|false containing the results, false on error * @return array|false containing the results, false on error
*/ */
public function getEntries($link, $result); public function getEntries($link, $result);
/** /**
* Return next result id * Return next result id
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param resource|\LDAP\ResultEntry $result LDAP result resource * @param \LDAP\ResultEntry $result LDAP result resource
* @return resource|\LDAP\ResultEntry an LDAP entry resource * @return \LDAP\ResultEntry an LDAP entry resource
* */ * */
public function nextEntry($link, $result); public function nextEntry($link, $result);
/** /**
* Read an entry * Read an entry
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param string $baseDN The DN of the entry to read from * @param string $baseDN The DN of the entry to read from
* @param string $filter An LDAP filter * @param string $filter An LDAP filter
* @param array $attr array of the attributes to read * @param array $attr array of the attributes to read
* @return resource|\LDAP\Result an LDAP search result resource * @return \LDAP\Result an LDAP search result resource
*/ */
public function read($link, $baseDN, $filter, $attr); public function read($link, $baseDN, $filter, $attr);
/** /**
* Search LDAP tree * Search LDAP tree
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param string $baseDN The DN of the entry to read from * @param string $baseDN The DN of the entry to read from
* @param string $filter An LDAP filter * @param string $filter An LDAP filter
* @param array $attr array of the attributes to read * @param array $attr array of the attributes to read
* @param int $attrsOnly optional, 1 if only attribute types shall be returned * @param int $attrsOnly optional, 1 if only attribute types shall be returned
* @param int $limit optional, limits the result entries * @param int $limit optional, limits the result entries
* @return resource|\LDAP\Result|false an LDAP search result resource, false on error * @return \LDAP\Result|false an LDAP search result resource, false on error
*/ */
public function search($link, string $baseDN, string $filter, array $attr, int $attrsOnly = 0, int $limit = 0, int $pageSize = 0, string $cookie = ''); public function search($link, string $baseDN, string $filter, array $attr, int $attrsOnly = 0, int $limit = 0, int $pageSize = 0, string $cookie = '');
/** /**
* Replace the value of a userPassword by $password * Replace the value of a userPassword by $password
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param string $userDN the DN of the user whose password is to be replaced * @param string $userDN the DN of the user whose password is to be replaced
* @param string $password the new value for the userPassword * @param string $password the new value for the userPassword
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
@ -166,14 +166,14 @@ interface ILDAPWrapper {
/** /**
* Performs a PASSWD extended operation. * Performs a PASSWD extended operation.
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @return bool|string The generated password if new_password is empty or omitted. Otherwise true on success and false on failure. * @return bool|string The generated password if new_password is empty or omitted. Otherwise true on success and false on failure.
*/ */
public function exopPasswd($link, string $userDN, string $oldPassword, string $password); public function exopPasswd($link, string $userDN, string $oldPassword, string $password);
/** /**
* Sets the value of the specified option to be $value * Sets the value of the specified option to be $value
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @param int $option a defined LDAP Server option * @param int $option a defined LDAP Server option
* @param mixed $value the new value for the option * @param mixed $value the new value for the option
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
@ -182,14 +182,14 @@ interface ILDAPWrapper {
/** /**
* establish Start TLS * establish Start TLS
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
*/ */
public function startTls($link); public function startTls($link);
/** /**
* Unbind from LDAP directory * Unbind from LDAP directory
* @param resource|\LDAP\Connection $link LDAP link resource * @param \LDAP\Connection $link LDAP link resource
* @return bool true on success, false otherwise * @return bool true on success, false otherwise
*/ */
public function unbind($link); public function unbind($link);
@ -205,6 +205,7 @@ interface ILDAPWrapper {
/** /**
* Checks whether the submitted parameter is a resource * Checks whether the submitted parameter is a resource
* @param mixed $resource the resource variable to check * @param mixed $resource the resource variable to check
* @psalm-assert-if-true object $resource
* @return bool true if it is a resource or LDAP object, false otherwise * @return bool true if it is a resource or LDAP object, false otherwise
*/ */
public function isResource($resource); public function isResource($resource);

@ -37,7 +37,7 @@ interface IUserLDAP {
/** /**
* Return a new LDAP connection for the specified user. * Return a new LDAP connection for the specified user.
* @param string $uid * @param string $uid
* @return resource|\LDAP\Connection of the LDAP connection * @return \LDAP\Connection of the LDAP connection
*/ */
public function getNewLDAPConnection($uid); public function getNewLDAPConnection($uid);

@ -360,7 +360,7 @@ class LDAP implements ILDAPWrapper {
/** /**
* Analyzes the returned LDAP error and acts accordingly if not 0 * Analyzes the returned LDAP error and acts accordingly if not 0
* *
* @param resource|\LDAP\Connection $resource the LDAP Connection resource * @param \LDAP\Connection $resource the LDAP Connection resource
* @throws ConstraintViolationException * @throws ConstraintViolationException
* @throws ServerNotAvailableException * @throws ServerNotAvailableException
* @throws \Exception * @throws \Exception

@ -149,7 +149,7 @@ class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
* Return a new LDAP connection resource for the specified user. * Return a new LDAP connection resource for the specified user.
* The connection must be closed manually. * The connection must be closed manually.
* @param string $uid user id * @param string $uid user id
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
* @throws \Exception if user id was not found in LDAP * @throws \Exception if user id was not found in LDAP
*/ */
public function getLDAPConnection($uid) { public function getLDAPConnection($uid) {
@ -163,7 +163,7 @@ class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
* Return a new LDAP connection resource for the specified user. * Return a new LDAP connection resource for the specified user.
* The connection must be closed manually. * The connection must be closed manually.
* @param string $gid group id * @param string $gid group id
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
* @throws \Exception if group id was not found in LDAP * @throws \Exception if group id was not found in LDAP
*/ */
public function getGroupLDAPConnection($gid) { public function getGroupLDAPConnection($gid) {

@ -622,7 +622,7 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
* The cloned connection needs to be closed manually. * The cloned connection needs to be closed manually.
* of the current access. * of the current access.
* @param string $uid * @param string $uid
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
*/ */
public function getNewLDAPConnection($uid) { public function getNewLDAPConnection($uid) {
$connection = clone $this->access->getConnection(); $connection = clone $this->access->getConnection();

@ -438,7 +438,7 @@ class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP
* The connection needs to be closed manually. * The connection needs to be closed manually.
* *
* @param string $uid * @param string $uid
* @return resource|\LDAP\Connection The LDAP connection * @return \LDAP\Connection The LDAP connection
*/ */
public function getNewLDAPConnection($uid) { public function getNewLDAPConnection($uid) {
return $this->handleRequest($uid, 'getNewLDAPConnection', [$uid]); return $this->handleRequest($uid, 'getNewLDAPConnection', [$uid]);

@ -48,8 +48,7 @@ use Psr\Log\LoggerInterface;
class Wizard extends LDAPUtility { class Wizard extends LDAPUtility {
protected static ?IL10N $l = null; protected static ?IL10N $l = null;
protected Access $access; protected Access $access;
/** @var resource|\LDAP\Connection|null */ protected ?\LDAP\Connection $cr = null;
protected $cr;
protected Configuration $configuration; protected Configuration $configuration;
protected WizardResult $result; protected WizardResult $result;
protected LoggerInterface $logger; protected LoggerInterface $logger;
@ -361,7 +360,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($rr)) { if (!$this->ldap->isResource($rr)) {
return false; return false;
} }
/** @var resource|\LDAP\Result $rr */ /** @var \LDAP\Result $rr */
$er = $this->ldap->firstEntry($cr, $rr); $er = $this->ldap->firstEntry($cr, $rr);
$attributes = $this->ldap->getAttributes($cr, $er); $attributes = $this->ldap->getAttributes($cr, $er);
if ($attributes === false) { if ($attributes === false) {
@ -646,10 +645,6 @@ class Wizard extends LDAPUtility {
} }
$cr = $this->access->connection->getConnectionResource(); $cr = $this->access->connection->getConnectionResource();
if (!$this->ldap->isResource($cr)) {
throw new \Exception('connection error');
}
/** @var resource|\LDAP\Connection $cr */
if (mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8') if (mb_strpos($this->access->connection->ldapLoginFilter, '%uid', 0, 'UTF-8')
=== false) { === false) {
@ -819,7 +814,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($rr)) { if (!$this->ldap->isResource($rr)) {
return false; return false;
} }
/** @var resource|\LDAP\Result $rr */ /** @var \LDAP\Result $rr */
$er = $this->ldap->firstEntry($cr, $rr); $er = $this->ldap->firstEntry($cr, $rr);
while ($this->ldap->isResource($er)) { while ($this->ldap->isResource($er)) {
$this->ldap->getDN($cr, $er); $this->ldap->getDN($cr, $er);
@ -866,7 +861,7 @@ class Wizard extends LDAPUtility {
); );
return false; return false;
} }
/** @var resource|\LDAP\Result $rr */ /** @var \LDAP\Result $rr */
$entries = $this->ldap->countEntries($cr, $rr); $entries = $this->ldap->countEntries($cr, $rr);
return ($entries !== false) && ($entries > 0); return ($entries !== false) && ($entries > 0);
} }
@ -929,7 +924,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($rr)) { if (!$this->ldap->isResource($rr)) {
continue; continue;
} }
/** @var resource|\LDAP\Result $rr */ /** @var \LDAP\Result $rr */
$er = $this->ldap->firstEntry($cr, $rr); $er = $this->ldap->firstEntry($cr, $rr);
$attrs = $this->ldap->getAttributes($cr, $er); $attrs = $this->ldap->getAttributes($cr, $er);
$dn = $this->ldap->getDN($cr, $er); $dn = $this->ldap->getDN($cr, $er);
@ -1073,7 +1068,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($cr)) { if (!$this->ldap->isResource($cr)) {
throw new \Exception(self::$l->t('Invalid Host')); throw new \Exception(self::$l->t('Invalid Host'));
} }
/** @var resource|\LDAP\Connection $cr */ /** @var \LDAP\Connection $cr */
//set LDAP options //set LDAP options
$this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3); $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3);
@ -1169,7 +1164,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($cr)) { if (!$this->ldap->isResource($cr)) {
return false; return false;
} }
/** @var resource|\LDAP\Connection $cr */ /** @var \LDAP\Connection $cr */
$lastFilter = null; $lastFilter = null;
if (isset($filters[count($filters) - 1])) { if (isset($filters[count($filters) - 1])) {
$lastFilter = $filters[count($filters) - 1]; $lastFilter = $filters[count($filters) - 1];
@ -1184,7 +1179,7 @@ class Wizard extends LDAPUtility {
if (!$this->ldap->isResource($rr)) { if (!$this->ldap->isResource($rr)) {
continue; continue;
} }
/** @var resource|\LDAP\Result $rr */ /** @var \LDAP\Result $rr */
$entries = $this->ldap->countEntries($cr, $rr); $entries = $this->ldap->countEntries($cr, $rr);
$getEntryFunc = 'firstEntry'; $getEntryFunc = 'firstEntry';
if (($entries !== false) && ($entries > 0)) { if (($entries !== false) && ($entries > 0)) {
@ -1214,9 +1209,7 @@ class Wizard extends LDAPUtility {
$dnReadCount++; $dnReadCount++;
$foundItems = array_merge($foundItems, $newItems); $foundItems = array_merge($foundItems, $newItems);
$dnRead[] = $dn; $dnRead[] = $dn;
} while (($state === self::LRESULT_PROCESSED_SKIP } while ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit);
|| $this->ldap->isResource($entry))
&& ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
} }
} }
@ -1310,9 +1303,9 @@ class Wizard extends LDAPUtility {
} }
/** /**
* @return resource|\LDAP\Connection|false a link resource on success, otherwise false * @return \LDAP\Connection|false a link resource on success, otherwise false
*/ */
private function getConnection() { private function getConnection(): \LDAP\Connection|false {
if (!is_null($this->cr)) { if (!is_null($this->cr)) {
return $this->cr; return $this->cr;
} }

@ -114,6 +114,9 @@ class AccessTest extends TestCase {
$connector = $this->getMockBuilder(Connection::class) $connector = $this->getMockBuilder(Connection::class)
->setConstructorArgs([$lw, '', null]) ->setConstructorArgs([$lw, '', null])
->getMock(); ->getMock();
$connector->expects($this->any())
->method('getConnectionResource')
->willReturn(ldap_connect('ldap://example.com'));
$um = $this->getMockBuilder(Manager::class) $um = $this->getMockBuilder(Manager::class)
->setConstructorArgs([ ->setConstructorArgs([
$this->createMock(IConfig::class), $this->createMock(IConfig::class),
@ -287,6 +290,11 @@ class AccessTest extends TestCase {
->method('isResource') ->method('isResource')
->willReturn(true); ->willReturn(true);
$this->connection
->expects($this->any())
->method('getConnectionResource')
->willReturn(ldap_connect('ldap://example.com'));
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('getAttributes') ->method('getAttributes')
->willReturn(['displayname' => ['bar', 'count' => 1]]); ->willReturn(['displayname' => ['bar', 'count' => 1]]);
@ -469,19 +477,18 @@ class AccessTest extends TestCase {
$this->connection $this->connection
->method('__get') ->method('__get')
->willReturn(true); ->willReturn(true);
$connection = $this->createMock(LDAP::class); $connection = ldap_connect('ldap://example.com');
$this->connection $this->connection
->expects($this->once()) ->expects($this->once())
->method('getConnectionResource') ->method('getConnectionResource')
->willReturn($connection); ->willThrowException(new \OC\ServerNotAvailableException('Connection to LDAP server could not be established'));
$this->ldap $this->ldap
->expects($this->once()) ->expects($this->never())
->method('isResource') ->method('isResource');
->with($connection)
->willReturn(false);
/** @noinspection PhpUnhandledExceptionInspection */ $this->expectException(\OC\ServerNotAvailableException::class);
$this->assertFalse($this->access->setPassword('CN=foo', 'MyPassword')); $this->expectExceptionMessage('Connection to LDAP server could not be established');
$this->access->setPassword('CN=foo', 'MyPassword');
} }
@ -492,16 +499,11 @@ class AccessTest extends TestCase {
$this->connection $this->connection
->method('__get') ->method('__get')
->willReturn(true); ->willReturn(true);
$connection = $this->createMock(LDAP::class); $connection = ldap_connect('ldap://example.com');
$this->connection $this->connection
->expects($this->any()) ->expects($this->any())
->method('getConnectionResource') ->method('getConnectionResource')
->willReturn($connection); ->willReturn($connection);
$this->ldap
->expects($this->once())
->method('isResource')
->with($connection)
->willReturn(true);
$this->ldap $this->ldap
->expects($this->once()) ->expects($this->once())
->method('modReplace') ->method('modReplace')
@ -516,16 +518,11 @@ class AccessTest extends TestCase {
$this->connection $this->connection
->method('__get') ->method('__get')
->willReturn(true); ->willReturn(true);
$connection = $this->createMock(LDAP::class); $connection = ldap_connect('ldap://example.com');
$this->connection $this->connection
->expects($this->any()) ->expects($this->any())
->method('getConnectionResource') ->method('getConnectionResource')
->willReturn($connection); ->willReturn($connection);
$this->ldap
->expects($this->once())
->method('isResource')
->with($connection)
->willReturn(true);
$this->ldap $this->ldap
->expects($this->once()) ->expects($this->once())
->method('modReplace') ->method('modReplace')
@ -559,7 +556,7 @@ class AccessTest extends TestCase {
->expects($this->any()) ->expects($this->any())
->method('isResource') ->method('isResource')
->willReturnCallback(function ($resource) { ->willReturnCallback(function ($resource) {
return is_resource($resource) || is_object($resource); return is_object($resource);
}); });
$this->ldap $this->ldap
->expects($this->any()) ->expects($this->any())

@ -114,7 +114,7 @@ class ConnectionTest extends \Test\TestCase {
$this->ldap->expects($this->exactly(3)) $this->ldap->expects($this->exactly(3))
->method('connect') ->method('connect')
->willReturn('ldapResource'); ->willReturn(ldap_connect('ldap://example.com'));
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('errno') ->method('errno')
@ -173,7 +173,7 @@ class ConnectionTest extends \Test\TestCase {
$this->ldap->expects($this->once()) $this->ldap->expects($this->once())
->method('connect') ->method('connect')
->willReturn('ldapResource'); ->willReturn(ldap_connect('ldap://example.com'));
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('errno') ->method('errno')
@ -221,7 +221,7 @@ class ConnectionTest extends \Test\TestCase {
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('connect') ->method('connect')
->willReturn('ldapResource'); ->willReturn(ldap_connect('ldap://example.com'));
$this->ldap->expects($this->once()) $this->ldap->expects($this->once())
->method('bind') ->method('bind')
@ -264,7 +264,7 @@ class ConnectionTest extends \Test\TestCase {
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('connect') ->method('connect')
->willReturn('ldapResource'); ->willReturn(ldap_connect('ldap://example.com'));
$this->ldap->expects($this->any()) $this->ldap->expects($this->any())
->method('setOption') ->method('setOption')

@ -271,14 +271,15 @@ class LDAPProviderTest extends \Test\TestCase {
$userBackend->expects($this->any()) $userBackend->expects($this->any())
->method('userExists') ->method('userExists')
->willReturn(true); ->willReturn(true);
$ldapConnection = ldap_connect('ldap://example.com');
$userBackend->expects($this->any()) $userBackend->expects($this->any())
->method('getNewLDAPConnection') ->method('getNewLDAPConnection')
->willReturn(true); ->willReturn($ldapConnection);
$server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock());
$ldapProvider = $this->getLDAPProvider($server); $ldapProvider = $this->getLDAPProvider($server);
$this->assertTrue($ldapProvider->getLDAPConnection('existing_user')); $this->assertEquals($ldapConnection, $ldapProvider->getLDAPConnection('existing_user'));
} }
@ -317,14 +318,15 @@ class LDAPProviderTest extends \Test\TestCase {
->method('groupExists') ->method('groupExists')
->willReturn(true); ->willReturn(true);
$ldapConnection = ldap_connect('ldap://example.com');
$groupBackend->expects($this->any()) $groupBackend->expects($this->any())
->method('getNewLDAPConnection') ->method('getNewLDAPConnection')
->willReturn(true); ->willReturn($ldapConnection);
$server = $this->getServerMock($userBackend, $groupBackend); $server = $this->getServerMock($userBackend, $groupBackend);
$ldapProvider = $this->getLDAPProvider($server); $ldapProvider = $this->getLDAPProvider($server);
$this->assertTrue($ldapProvider->getGroupLDAPConnection('existing_group')); $this->assertEquals($ldapConnection, $ldapProvider->getGroupLDAPConnection('existing_group'));
} }

@ -320,7 +320,7 @@ class User_LDAPTest extends TestCase {
->willReturn($mapping); ->willReturn($mapping);
$this->connection->expects($this->any()) $this->connection->expects($this->any())
->method('getConnectionResource') ->method('getConnectionResource')
->willReturn('this is an ldap link'); ->willReturn(ldap_connect('ldap://example.com'));
$this->deletedUsersIndex->expects($this->once()) $this->deletedUsersIndex->expects($this->once())
->method('isUserMarked') ->method('isUserMarked')

@ -84,8 +84,8 @@ class WizardTest extends TestCase {
private function prepareLdapWrapperForConnections(MockObject &$ldap) { private function prepareLdapWrapperForConnections(MockObject &$ldap) {
$ldap->expects($this->once()) $ldap->expects($this->once())
->method('connect') ->method('connect')
//dummy value, usually invalid //dummy value
->willReturn(true); ->willReturn(ldap_connect('ldap://example.com'));
$ldap->expects($this->exactly(3)) $ldap->expects($this->exactly(3))
->method('setOption') ->method('setOption')
@ -173,7 +173,7 @@ class WizardTest extends TestCase {
$ldap->expects($this->any()) $ldap->expects($this->any())
->method('isResource') ->method('isResource')
->willReturnCallback(function ($r) { ->willReturnCallback(function ($r) {
if ($r === true) { if ($r instanceof \LDAP\Connection) {
return true; return true;
} }
if ($r % 24 === 0) { if ($r % 24 === 0) {

@ -16,59 +16,80 @@ namespace FTP {
namespace { namespace {
function ftp_connect(string $hostname, int $port = 21, int $timeout = 90): FTP\Connection|resource|false {} function ftp_connect(string $hostname, int $port = 21, int $timeout = 90): FTP\Connection|false {}
#ifdef HAVE_FTP_SSL #ifdef HAVE_FTP_SSL
function ftp_ssl_connect(string $hostname, int $port = 21, int $timeout = 90): FTP\Connection|resource|false {} function ftp_ssl_connect(string $hostname, int $port = 21, int $timeout = 90): FTP\Connection|false {}
#endif #endif
function ftp_login(FTP\Connection|resource $ftp, string $username, string $password): bool {} function ftp_login(FTP\Connection $ftp, string $username, string $password): bool {}
function ftp_pwd(FTP\Connection|resource $ftp): string|false {} function ftp_pwd(FTP\Connection $ftp): string|false {}
function ftp_cdup(FTP\Connection|resource $ftp): bool {} function ftp_cdup(FTP\Connection $ftp): bool {}
function ftp_chdir(FTP\Connection|resource $ftp, string $directory): bool {} function ftp_chdir(FTP\Connection $ftp, string $directory): bool {}
function ftp_exec(FTP\Connection|resource $ftp, string $command): bool {} function ftp_exec(FTP\Connection $ftp, string $command): bool {}
function ftp_raw(FTP\Connection|resource $ftp, string $command): ?array {}
function ftp_mkdir(FTP\Connection|resource $ftp, string $directory): string|false {} /**
function ftp_rmdir(FTP\Connection|resource $ftp, string $directory): bool {} * @return array<int, string>|null
function ftp_chmod(FTP\Connection|resource $ftp, int $permissions, string $filename): int|false {} * @refcount 1
*/
function ftp_raw(FTP\Connection $ftp, string $command): ?array {}
function ftp_mkdir(FTP\Connection $ftp, string $directory): string|false {}
function ftp_rmdir(FTP\Connection $ftp, string $directory): bool {}
function ftp_chmod(FTP\Connection $ftp, int $permissions, string $filename): int|false {}
/** @param string $response */ /** @param string $response */
function ftp_alloc(FTP\Connection|resource $ftp, int $size, &$response = null): bool {} function ftp_alloc(FTP\Connection $ftp, int $size, &$response = null): bool {}
function ftp_nlist(FTP\Connection|resource $ftp, string $directory): array|false {}
function ftp_rawlist(FTP\Connection|resource $ftp, string $directory, bool $recursive = false): array|false {} /**
function ftp_mlsd(FTP\Connection|resource $ftp, string $directory): array|false {} * @return array<int, string>|false
function ftp_systype(FTP\Connection|resource $ftp): string|false {} * @refcount 1
*/
function ftp_nlist(FTP\Connection $ftp, string $directory): array|false {}
/**
* @return array<int, string>|false
* @refcount 1
*/
function ftp_rawlist(FTP\Connection $ftp, string $directory, bool $recursive = false): array|false {}
/**
* @return array<int, array>|false
* @refcount 1
*/
function ftp_mlsd(FTP\Connection $ftp, string $directory): array|false {}
function ftp_systype(FTP\Connection $ftp): string|false {}
/** @param resource $stream */ /** @param resource $stream */
function ftp_fget(FTP\Connection|resource $ftp, $stream, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): bool {} function ftp_fget(FTP\Connection $ftp, $stream, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): bool {}
/** @param resource $stream */ /** @param resource $stream */
function ftp_nb_fget(FTP\Connection|resource $ftp, $stream, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): int {} function ftp_nb_fget(FTP\Connection $ftp, $stream, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): int {}
function ftp_pasv(FTP\Connection|resource $ftp, bool $enable): bool {} function ftp_pasv(FTP\Connection $ftp, bool $enable): bool {}
function ftp_get(FTP\Connection|resource $ftp, string $local_filename, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): bool {} function ftp_get(FTP\Connection $ftp, string $local_filename, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): bool {}
function ftp_nb_get(FTP\Connection|resource $ftp, string $local_filename, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): int {} function ftp_nb_get(FTP\Connection $ftp, string $local_filename, string $remote_filename, int $mode = FTP_BINARY, int $offset = 0): int|false {}
function ftp_nb_continue(FTP\Connection|resource $ftp): int {} function ftp_nb_continue(FTP\Connection $ftp): int {}
/** @param resource $stream */ /** @param resource $stream */
function ftp_fput(FTP\Connection|resource $ftp, string $remote_filename, $stream, int $mode = FTP_BINARY, int $offset = 0): bool {} function ftp_fput(FTP\Connection $ftp, string $remote_filename, $stream, int $mode = FTP_BINARY, int $offset = 0): bool {}
/** @param resource $stream */ /** @param resource $stream */
function ftp_nb_fput(FTP\Connection|resource $ftp, string $remote_filename, $stream, int $mode = FTP_BINARY, int $offset = 0): int {} function ftp_nb_fput(FTP\Connection $ftp, string $remote_filename, $stream, int $mode = FTP_BINARY, int $offset = 0): int {}
function ftp_put(FTP\Connection|resource $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY, int $offset = 0): bool {} function ftp_put(FTP\Connection $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY, int $offset = 0): bool {}
function ftp_append(FTP\Connection|resource $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY): bool {} function ftp_append(FTP\Connection $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY): bool {}
function ftp_nb_put(FTP\Connection|resource $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY, int $offset = 0): int|false {} function ftp_nb_put(FTP\Connection $ftp, string $remote_filename, string $local_filename, int $mode = FTP_BINARY, int $offset = 0): int|false {}
function ftp_size(FTP\Connection|resource $ftp, string $filename): int {} function ftp_size(FTP\Connection $ftp, string $filename): int {}
function ftp_mdtm(FTP\Connection|resource $ftp, string $filename): int {} function ftp_mdtm(FTP\Connection $ftp, string $filename): int {}
function ftp_rename(FTP\Connection|resource $ftp, string $from, string $to): bool {} function ftp_rename(FTP\Connection $ftp, string $from, string $to): bool {}
function ftp_delete(FTP\Connection|resource $ftp, string $filename): bool {} function ftp_delete(FTP\Connection $ftp, string $filename): bool {}
function ftp_site(FTP\Connection|resource $ftp, string $command): bool {} function ftp_site(FTP\Connection $ftp, string $command): bool {}
function ftp_close(FTP\Connection|resource $ftp): bool {} function ftp_close(FTP\Connection $ftp): bool {}
/** @alias ftp_close */ /** @alias ftp_close */
function ftp_quit(FTP\Connection|resource $ftp): bool {} function ftp_quit(FTP\Connection $ftp): bool {}
/** @param int|bool $value */ /** @param int|bool $value */
function ftp_set_option(FTP\Connection|resource $ftp, int $option, $value): bool {} function ftp_set_option(FTP\Connection $ftp, int $option, $value): bool {}
function ftp_get_option(FTP\Connection|resource $ftp, int $option): int|bool {} function ftp_get_option(FTP\Connection $ftp, int $option): int|bool {}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,5 +1,7 @@
<?php <?php
/** @generate-class-entries */
namespace LDAP { namespace LDAP {
/** /**
@ -25,4 +27,200 @@ namespace LDAP {
final class ResultEntry final class ResultEntry
{ {
} }
}
namespace {
#ifdef HAVE_ORALDAP
function ldap_connect(?string $uri = null, int $port = 389, string $wallet = UNKNOWN, string $password = UNKNOWN, int $auth_mode = GSLC_SSL_NO_AUTH): LDAP\Connection|false {}
#else
function ldap_connect(?string $uri = null, int $port = 389): LDAP\Connection|false {}
#endif
function ldap_unbind(LDAP\Connection $ldap): bool {}
/** @alias ldap_unbind */
function ldap_close(LDAP\Connection $ldap): bool {}
function ldap_bind(LDAP\Connection $ldap, ?string $dn = null, ?string $password = null): bool {}
function ldap_bind_ext(LDAP\Connection $ldap, ?string $dn = null, ?string $password = null, ?array $controls = null): LDAP\Result|false {}
#ifdef HAVE_LDAP_SASL
function ldap_sasl_bind(LDAP\Connection $ldap, ?string $dn = null, ?string $password = null, ?string $mech = null, ?string $realm = null, ?string $authc_id = null, ?string $authz_id = null, ?string $props = null): bool {}
#endif
/** @param LDAP\Connection|array $ldap */
function ldap_read($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {}
/** @param LDAP\Connection|array $ldap */
function ldap_list($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {}
/** @param LDAP\Connection|array $ldap */
function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {}
function ldap_free_result(LDAP\Result $result): bool {}
function ldap_count_entries(LDAP\Connection $ldap, LDAP\Result $result): int {}
function ldap_first_entry(LDAP\Connection $ldap, LDAP\Result $result): LDAP\ResultEntry|false {}
function ldap_next_entry(LDAP\Connection $ldap, LDAP\ResultEntry $entry): LDAP\ResultEntry|false {}
/**
* @return array<int|string, int|array>|false
* @refcount 1
*/
function ldap_get_entries(LDAP\Connection $ldap, LDAP\Result $result): array|false {}
function ldap_first_attribute(LDAP\Connection $ldap, LDAP\ResultEntry $entry): string|false {}
function ldap_next_attribute(LDAP\Connection $ldap, LDAP\ResultEntry $entry): string|false {}
/**
* @return array<int|string, int|string|array>
* @refcount 1
*/
function ldap_get_attributes(LDAP\Connection $ldap, LDAP\ResultEntry $entry): array {}
/**
* @return array<int|string, int|string>|false
* @refcount 1
*/
function ldap_get_values_len(LDAP\Connection $ldap, LDAP\ResultEntry $entry, string $attribute): array|false {}
/**
* @return array<int|string, int|string>|false
* @refcount 1
* @alias ldap_get_values_len
*/
function ldap_get_values(LDAP\Connection $ldap, LDAP\ResultEntry $entry, string $attribute): array|false {}
function ldap_get_dn(LDAP\Connection $ldap, LDAP\ResultEntry $entry): string|false {}
/**
* @return array<int|string, int|string>|false
* @refcount 1
*/
function ldap_explode_dn(string $dn, int $with_attrib): array|false {}
function ldap_dn2ufn(string $dn): string|false {}
function ldap_add(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): bool {}
function ldap_add_ext(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): LDAP\Result|false {}
function ldap_delete(LDAP\Connection $ldap, string $dn, ?array $controls = null): bool {}
function ldap_delete_ext(LDAP\Connection $ldap, string $dn, ?array $controls = null): LDAP\Result|false {}
function ldap_modify_batch(LDAP\Connection $ldap, string $dn, array $modifications_info, ?array $controls = null): bool {}
function ldap_mod_add(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): bool {}
function ldap_mod_add_ext(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): LDAP\Result|false {}
function ldap_mod_replace(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): bool {}
/** @alias ldap_mod_replace */
function ldap_modify(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): bool {}
function ldap_mod_replace_ext(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): LDAP\Result|false {}
function ldap_mod_del(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): bool {}
function ldap_mod_del_ext(LDAP\Connection $ldap, string $dn, array $entry, ?array $controls = null): LDAP\Result|false {}
function ldap_errno(LDAP\Connection $ldap): int {}
function ldap_error(LDAP\Connection $ldap): string {}
function ldap_err2str(int $errno): string {}
function ldap_compare(LDAP\Connection $ldap, string $dn, string $attribute, string $value, ?array $controls = null): bool|int {}
#if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP)
function ldap_rename(LDAP\Connection $ldap, string $dn, string $new_rdn, string $new_parent, bool $delete_old_rdn, ?array $controls = null): bool {}
function ldap_rename_ext(LDAP\Connection $ldap, string $dn, string $new_rdn, string $new_parent, bool $delete_old_rdn, ?array $controls = null): LDAP\Result|false {}
/** @param array|string|int $value */
function ldap_get_option(LDAP\Connection $ldap, int $option, &$value = null): bool {}
/** @param array|string|int|bool $value */
function ldap_set_option(?LDAP\Connection $ldap, int $option, $value): bool {}
function ldap_count_references(LDAP\Connection $ldap, LDAP\Result $result): int {}
function ldap_first_reference(LDAP\Connection $ldap, LDAP\Result $result): LDAP\ResultEntry|false {}
function ldap_next_reference(LDAP\Connection $ldap, LDAP\ResultEntry $entry): LDAP\ResultEntry|false {}
#ifdef HAVE_LDAP_PARSE_REFERENCE
/** @param array $referrals */
function ldap_parse_reference(LDAP\Connection $ldap, LDAP\ResultEntry $entry, &$referrals): bool {}
#endif
#ifdef HAVE_LDAP_PARSE_RESULT
/**
* @param int $error_code
* @param string $matched_dn
* @param string $error_message
* @param array $referrals
* @param array $controls
*/
function ldap_parse_result(LDAP\Connection $ldap, LDAP\Result $result, &$error_code, &$matched_dn = null, &$error_message = null, &$referrals = null, &$controls = null): bool {}
#endif
#endif
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
function ldap_set_rebind_proc(LDAP\Connection $ldap, ?callable $callback): bool {}
#endif
#ifdef HAVE_LDAP_START_TLS_S
function ldap_start_tls(LDAP\Connection $ldap): bool {}
#endif
function ldap_escape(string $value, string $ignore = "", int $flags = 0): string {}
#ifdef STR_TRANSLATION
function ldap_t61_to_8859(string $value): string|false {}
function ldap_8859_to_t61(string $value): string|false {}
#endif
#ifdef HAVE_LDAP_EXTENDED_OPERATION_S
/**
* @param string $response_data
* @param string $response_oid
*/
function ldap_exop(LDAP\Connection $ldap, string $request_oid, ?string $request_data = null, ?array $controls = NULL, &$response_data = UNKNOWN, &$response_oid = null): LDAP\Result|bool {}
#endif
#ifdef HAVE_LDAP_PASSWD
/**
* @param array $controls
*/
function ldap_exop_passwd(LDAP\Connection $ldap, string $user = "", string $old_password = "", string $new_password = "", &$controls = null): string|bool {}
#endif
#ifdef HAVE_LDAP_WHOAMI_S
function ldap_exop_whoami(LDAP\Connection $ldap): string|false {}
#endif
#ifdef HAVE_LDAP_REFRESH_S
function ldap_exop_refresh(LDAP\Connection $ldap, string $dn, int $ttl): int|false {}
#endif
#ifdef HAVE_LDAP_PARSE_EXTENDED_RESULT
/**
* @param string $response_data
* @param string $response_oid
*/
function ldap_parse_exop(LDAP\Connection $ldap, LDAP\Result $result, &$response_data = null, &$response_oid = null): bool {}
#endif
} }

@ -151,6 +151,7 @@ abstract class Avatar implements IAvatar {
/** /**
* Generate png avatar with GD * Generate png avatar with GD
* @throws \Exception when an error occurs in gd calls
*/ */
protected function generateAvatar(string $userDisplayName, int $size, bool $darkTheme): string { protected function generateAvatar(string $userDisplayName, int $size, bool $darkTheme): string {
$text = $this->getAvatarText(); $text = $this->getAvatarText();
@ -158,6 +159,9 @@ abstract class Avatar implements IAvatar {
$backgroundColor = $textColor->alphaBlending(0.1, $darkTheme ? new Color(0, 0, 0) : new Color(255, 255, 255)); $backgroundColor = $textColor->alphaBlending(0.1, $darkTheme ? new Color(0, 0, 0) : new Color(255, 255, 255));
$im = imagecreatetruecolor($size, $size); $im = imagecreatetruecolor($size, $size);
if ($im === false) {
throw new \Exception('Failed to create avatar image');
}
$background = imagecolorallocate( $background = imagecolorallocate(
$im, $im,
$backgroundColor->red(), $backgroundColor->red(),
@ -169,6 +173,9 @@ abstract class Avatar implements IAvatar {
$textColor->green(), $textColor->green(),
$textColor->blue() $textColor->blue()
); );
if ($background === false || $textColor === false) {
throw new \Exception('Failed to create avatar image color');
}
imagefilledrectangle($im, 0, 0, $size, $size, $background); imagefilledrectangle($im, 0, 0, $size, $size, $background);
$font = __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf'; $font = __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf';
@ -191,7 +198,7 @@ abstract class Avatar implements IAvatar {
/** /**
* Calculate real image ttf center * Calculate real image ttf center
* *
* @param resource $image * @param \GdImage $image
* @param string $text text string * @param string $text text string
* @param string $font font path * @param string $font font path
* @param int $size font size * @param int $size font size

@ -59,7 +59,7 @@ class OC_Image implements \OCP\IImage {
// Default quality for webp images // Default quality for webp images
protected const DEFAULT_WEBP_QUALITY = 80; protected const DEFAULT_WEBP_QUALITY = 80;
/** @var false|resource|\GdImage */ /** @var false|\GdImage */
protected $resource = false; // tmp resource. protected $resource = false; // tmp resource.
/** @var int */ /** @var int */
protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident. protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident.
@ -67,20 +67,20 @@ class OC_Image implements \OCP\IImage {
protected $mimeType = 'image/png'; // Default to png protected $mimeType = 'image/png'; // Default to png
/** @var null|string */ /** @var null|string */
protected $filePath = null; protected $filePath = null;
/** @var finfo */ /** @var ?finfo */
private $fileInfo; private $fileInfo = null;
/** @var \OCP\ILogger */ /** @var \OCP\ILogger */
private $logger; private $logger;
/** @var \OCP\IConfig */ /** @var \OCP\IConfig */
private $config; private $config;
/** @var array */ /** @var ?array */
private $exif; private $exif = null;
/** /**
* Constructor. * Constructor.
* *
* @param resource|string|\GdImage $imageRef The path to a local file, a base64 encoded string or a resource created by * @param mixed $imageRef Deprecated, should be null
* an imagecreate* function. * @psalm-assert null $imageRef
* @param \OCP\ILogger $logger * @param \OCP\ILogger $logger
* @param \OCP\IConfig $config * @param \OCP\IConfig $config
* @throws \InvalidArgumentException in case the $imageRef parameter is not null * @throws \InvalidArgumentException in case the $imageRef parameter is not null
@ -107,11 +107,11 @@ class OC_Image implements \OCP\IImage {
/** /**
* Determine whether the object contains an image resource. * Determine whether the object contains an image resource.
* *
* @psalm-assert-if-true \GdImage $this->resource
* @return bool * @return bool
*/ */
public function valid(): bool { public function valid(): bool {
if ((is_resource($this->resource) && get_resource_type($this->resource) === 'gd') || if (is_object($this->resource) && get_class($this->resource) === \GdImage::class) {
(is_object($this->resource) && get_class($this->resource) === \GdImage::class)) {
return true; return true;
} }
@ -134,10 +134,7 @@ class OC_Image implements \OCP\IImage {
*/ */
public function width(): int { public function width(): int {
if ($this->valid()) { if ($this->valid()) {
$width = imagesx($this->resource); return imagesx($this->resource);
if ($width !== false) {
return $width;
}
} }
return -1; return -1;
} }
@ -149,10 +146,7 @@ class OC_Image implements \OCP\IImage {
*/ */
public function height(): int { public function height(): int {
if ($this->valid()) { if ($this->valid()) {
$height = imagesy($this->resource); return imagesy($this->resource);
if ($height !== false) {
return $height;
}
} }
return -1; return -1;
} }
@ -338,25 +332,14 @@ class OC_Image implements \OCP\IImage {
} }
/** /**
* @param resource|\GdImage $resource * @param \GdImage $resource
* @throws \InvalidArgumentException in case the supplied resource does not have the type "gd"
*/ */
public function setResource($resource) { public function setResource(\GdImage $resource): void {
// For PHP<8 $this->resource = $resource;
if (is_resource($resource) && get_resource_type($resource) === 'gd') {
$this->resource = $resource;
return;
}
// PHP 8 has real objects for GD stuff
if (is_object($resource) && get_class($resource) === \GdImage::class) {
$this->resource = $resource;
return;
}
throw new \InvalidArgumentException('Supplied resource is not of type "gd".');
} }
/** /**
* @return false|resource|\GdImage Returns the image resource if any * @return false|\GdImage Returns the image resource if any
*/ */
public function resource() { public function resource() {
return $this->resource; return $this->resource;
@ -394,8 +377,7 @@ class OC_Image implements \OCP\IImage {
$res = imagepng($this->resource); $res = imagepng($this->resource);
break; break;
case "image/jpeg": case "image/jpeg":
/** @psalm-suppress InvalidScalarArgument */ imageinterlace($this->resource, true);
imageinterlace($this->resource, (PHP_VERSION_ID >= 80000 ? true : 1));
$quality = $this->getJpegQuality(); $quality = $this->getJpegQuality();
$res = imagejpeg($this->resource, null, $quality); $res = imagejpeg($this->resource, null, $quality);
break; break;
@ -584,7 +566,7 @@ class OC_Image implements \OCP\IImage {
* It is the responsibility of the caller to position the pointer at the correct place and to close the handle again. * It is the responsibility of the caller to position the pointer at the correct place and to close the handle again.
* *
* @param resource $handle * @param resource $handle
* @return resource|\GdImage|false An image resource or false on error * @return \GdImage|false An image resource or false on error
*/ */
public function loadFromFileHandle($handle) { public function loadFromFileHandle($handle) {
$contents = stream_get_contents($handle); $contents = stream_get_contents($handle);
@ -663,7 +645,7 @@ class OC_Image implements \OCP\IImage {
* Loads an image from a local file. * Loads an image from a local file.
* *
* @param bool|string $imagePath The path to a local file. * @param bool|string $imagePath The path to a local file.
* @return bool|resource|\GdImage An image resource or false on error * @return bool|\GdImage An image resource or false on error
*/ */
public function loadFromFile($imagePath = false) { public function loadFromFile($imagePath = false) {
// exif_imagetype throws "read error!" if file is less than 12 byte // exif_imagetype throws "read error!" if file is less than 12 byte
@ -801,7 +783,7 @@ class OC_Image implements \OCP\IImage {
* Loads an image from a string of data. * Loads an image from a string of data.
* *
* @param string $str A string of image data as read from a file. * @param string $str A string of image data as read from a file.
* @return bool|resource|\GdImage An image resource or false on error * @return bool|\GdImage An image resource or false on error
*/ */
public function loadFromData(string $str) { public function loadFromData(string $str) {
if (!$this->checkImageDataSize($str)) { if (!$this->checkImageDataSize($str)) {
@ -827,7 +809,7 @@ class OC_Image implements \OCP\IImage {
* Loads an image from a base64 encoded string. * Loads an image from a base64 encoded string.
* *
* @param string $str A string base64 encoded string of image data. * @param string $str A string base64 encoded string of image data.
* @return bool|resource|\GdImage An image resource or false on error * @return bool|\GdImage An image resource or false on error
*/ */
public function loadFromBase64(string $str) { public function loadFromBase64(string $str) {
$data = base64_decode($str); $data = base64_decode($str);
@ -868,7 +850,7 @@ class OC_Image implements \OCP\IImage {
/** /**
* @param $maxSize * @param $maxSize
* @return resource|bool|\GdImage * @return bool|\GdImage
*/ */
private function resizeNew(int $maxSize) { private function resizeNew(int $maxSize) {
if (!$this->valid()) { if (!$this->valid()) {
@ -909,7 +891,7 @@ class OC_Image implements \OCP\IImage {
/** /**
* @param int $width * @param int $width
* @param int $height * @param int $height
* @return resource|bool|\GdImage * @return bool|\GdImage
*/ */
public function preciseResizeNew(int $width, int $height) { public function preciseResizeNew(int $width, int $height) {
if (!($width > 0) || !($height > 0)) { if (!($width > 0) || !($height > 0)) {
@ -985,13 +967,13 @@ class OC_Image implements \OCP\IImage {
// preserve transparency // preserve transparency
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null);
imagealphablending($process, false); imagealphablending($process, false);
imagesavealpha($process, true); imagesavealpha($process, true);
} }
imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height); $result = imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height);
if ($process === false) { if ($result === false) {
$this->logger->debug('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']); $this->logger->debug('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']);
return false; return false;
} }
@ -1027,7 +1009,7 @@ class OC_Image implements \OCP\IImage {
* @param int $y Vertical position * @param int $y Vertical position
* @param int $w Width * @param int $w Width
* @param int $h Height * @param int $h Height
* @return resource|\GdImage|false * @return \GdImage|false
*/ */
public function cropNew(int $x, int $y, int $w, int $h) { public function cropNew(int $x, int $y, int $w, int $h) {
if (!$this->valid()) { if (!$this->valid()) {
@ -1042,13 +1024,13 @@ class OC_Image implements \OCP\IImage {
// preserve transparency // preserve transparency
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null);
imagealphablending($process, false); imagealphablending($process, false);
imagesavealpha($process, true); imagesavealpha($process, true);
} }
imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h); $result = imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h);
if ($process === false) { if ($result === false) {
$this->logger->debug(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, ['app' => 'core']); $this->logger->debug(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, ['app' => 'core']);
return false; return false;
} }

@ -27,4 +27,9 @@ namespace OCP;
* @since 24.0.0 * @since 24.0.0
*/ */
interface IStreamImage extends IImage { interface IStreamImage extends IImage {
/**
* @since 24.0.0
* @return false|resource Returns the image resource if any
*/
public function resource();
} }

Loading…
Cancel
Save