Merge pull request #7568 from mailcow/feat/compose-update

[Web] Update composer libraries
This commit is contained in:
FreddleSpl0it authored and GitHub committed 2026-10-28 12:01:04 +01:00
commit aa7388810c
1299 files changed
+71589 -24462

No files matched your search

+3 -1
View File
@@ -1604,7 +1604,9 @@ function init_db_schema()
"redirect_uri" => "VARCHAR(2000)",
"expires" => "TIMESTAMP NOT NULL",
"scope" => "VARCHAR(4000)",
"id_token" => "VARCHAR(1000)"
"id_token" => "VARCHAR(1000)",
"code_challenge" => "VARCHAR(1000)",
"code_challenge_method" => "VARCHAR(20)"
),
"keys" => array(
"primary" => array(
+1 -1
View File
@@ -10,7 +10,7 @@
"mustangostang/spyc": "^0.6.3",
"directorytree/ldaprecord": "^3.3",
"twig/twig": "^3.0",
"stevenmaguire/oauth2-keycloak": "^4.0",
"stevenmaguire/oauth2-keycloak": "^6.1",
"league/oauth2-client": "^2.7",
"bacon/bacon-qr-code": "^2.0"
},
+825 -472
View File
File diff suppressed because it is too large. Load diff
+1 -4
View File
@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
+34 -12
View File
@@ -12,6 +12,7 @@
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 21);
$opened_path = realpath($opened_path) ?: $opened_path;
$this->handle = fopen($opened_path, $mode);
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
// remove all traces of this stream wrapper once it has been used
stream_wrapper_unregister('composer-bin-proxy');
return (bool) $this->handle;
}
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
public function stream_stat()
{
return fstat($this->handle);
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
include("composer-bin-proxy://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss');
exit(0);
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss');
}
}
include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss';
return include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss';
+34 -12
View File
@@ -12,6 +12,7 @@
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 21);
$opened_path = realpath($opened_path) ?: $opened_path;
$this->handle = fopen($opened_path, $mode);
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
// remove all traces of this stream wrapper once it has been used
stream_wrapper_unregister('composer-bin-proxy');
return (bool) $this->handle;
}
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
public function stream_stat()
{
return fstat($this->handle);
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
include("composer-bin-proxy://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs');
exit(0);
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs');
}
}
include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs';
return include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs';
@@ -0,0 +1,74 @@
name: Test Suite
on:
push:
branches:
- main
pull_request:
jobs:
test:
runs-on: ubuntu-latest
services:
redis:
image: redis
ports:
- 6379:6379
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
mongodb:
image: mongo
ports:
- 27017:27017
myriadb:
image: mariadb
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3808:3808
- 3306:3306
postgres:
image: postgres
env:
POSTGRES_DB: oauth2_server_php
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: --health-cmd="pg_isready -h localhost" --health-interval=10s --health-timeout=5s --health-retries=5
strategy:
matrix:
php: [ 7.2, 7.3, 7.4, "8.0", 8.1, 8.2 ]
name: "PHP ${{ matrix.php }} Unit Test"
steps:
- uses: actions/checkout@v2
- uses: codecov/codecov-action@v1
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mongodb, mbstring, intl, redis, pdo_mysql
- name: Install composer dependencies
uses: nick-invision/retry@v1
with:
timeout_minutes: 10
max_attempts: 3
command: composer install
- name: Run PHPUnit
run: vendor/bin/phpunit -v
phpstan:
name: "PHPStan"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
- name: Install composer dependencies
uses: nick-invision/retry@v1
with:
timeout_minutes: 10
max_attempts: 3
command: composer install
- name: Run PHPStan
run: |
composer require phpstan/phpstan
vendor/bin/phpstan analyse --level=0 src/
@@ -1,8 +1,6 @@
oauth2-server-php
=================
[![Build Status](https://travis-ci.org/bshaffer/oauth2-server-php.svg?branch=master)](https://travis-ci.org/bshaffer/oauth2-server-php)
[![Total Downloads](https://poser.pugx.org/bshaffer/oauth2-server-php/downloads.png)](https://packagist.org/packages/bshaffer/oauth2-server-php)
[![Total Downloads](https://poser.pugx.org/bshaffer/oauth2-server-php/downloads)](https://packagist.org/packages/bshaffer/oauth2-server-php)
View the [complete documentation](https://bshaffer.github.io/oauth2-server-php-docs/)
@@ -16,21 +16,21 @@
"psr-0": { "OAuth2": "src/" }
},
"require":{
"php":">=5.3.9"
"php":">=7.2"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"aws/aws-sdk-php": "~2.8",
"firebase/php-jwt": "~2.2",
"predis/predis": "dev-master",
"phpunit/phpunit": "^7.5||^8.0",
"aws/aws-sdk-php": "^2.8",
"firebase/php-jwt": "^6.4",
"predis/predis": "^1.1",
"thobbs/phpcassa": "dev-master",
"mongodb/mongodb": "^1.1"
"yoast/phpunit-polyfills": "^1.0"
},
"suggest": {
"predis/predis": "Required to use Redis storage",
"thobbs/phpcassa": "Required to use Cassandra storage",
"aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
"firebase/php-jwt": "~2.2 is required to use JWT features",
"firebase/php-jwt": "~v6.4 is required to use JWT features",
"mongodb/mongodb": "^1.1 is required to use MongoDB storage"
}
}
@@ -39,7 +39,7 @@ class Autoloader
* Handles autoloading of classes.
*
* @param string $class - A class name.
* @return boolean - Returns true if the class has been loaded
* @return void
*/
public function autoload($class)
{
@@ -112,7 +112,7 @@ class HttpBasic implements ClientAssertionTypeInterface
*
* @ingroup oauth2_section_2
*/
public function getClientCredentials(RequestInterface $request, ResponseInterface $response = null)
public function getClientCredentials(RequestInterface $request, ?ResponseInterface $response = null)
{
if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
@@ -78,7 +78,7 @@ class AuthorizeController implements AuthorizeControllerInterface
* );
* @endcode
*/
public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ScopeInterface $scopeUtil = null)
public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ?ScopeInterface $scopeUtil = null)
{
$this->clientStorage = $clientStorage;
$this->responseTypes = $responseTypes;
@@ -87,6 +87,7 @@ class AuthorizeController implements AuthorizeControllerInterface
'enforce_state' => true,
'require_exact_redirect_uri' => true,
'redirect_status_code' => 302,
'enforce_pkce' => false,
), $config);
if (is_null($scopeUtil)) {
@@ -47,7 +47,7 @@ class ResourceController implements ResourceControllerInterface
* @param array $config
* @param ScopeInterface $scopeUtil
*/
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ScopeInterface $scopeUtil = null)
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ?ScopeInterface $scopeUtil = null)
{
$this->tokenType = $tokenType;
$this->tokenStorage = $tokenStorage;
@@ -13,7 +13,7 @@ use OAuth2\ResponseInterface;
* @code
* if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
* $response->send(); // authorization failed
* exit();
* die();
* }
* return json_encode($resource); // valid token! Send the stuff!
* @endcode
@@ -54,7 +54,7 @@ class TokenController implements TokenControllerInterface
* @param ScopeInterface $scopeUtil
* @throws InvalidArgumentException
*/
public function __construct(AccessTokenInterface $accessToken, ClientInterface $clientStorage, array $grantTypes = array(), ClientAssertionTypeInterface $clientAssertionType = null, ScopeInterface $scopeUtil = null)
public function __construct(AccessTokenInterface $accessToken, ClientInterface $clientStorage, array $grantTypes = array(), ?ClientAssertionTypeInterface $clientAssertionType = null, ?ScopeInterface $scopeUtil = null)
{
if (is_null($clientAssertionType)) {
foreach ($grantTypes as $grantType) {
@@ -2,6 +2,9 @@
namespace OAuth2\Encryption;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
/**
* Bridge file to use the firebase/php-jwt package for JWT encoding and decoding.
* @author Francis Chuang <francis.chuang@gmail.com>
@@ -10,26 +13,36 @@ class FirebaseJwt implements EncryptionInterface
{
public function __construct()
{
if (!class_exists('\JWT')) {
if (!class_exists(JWT::class)) {
throw new \ErrorException('firebase/php-jwt must be installed to use this feature. You can do this by running "composer require firebase/php-jwt"');
}
}
public function encode($payload, $key, $alg = 'HS256', $keyId = null)
{
return \JWT::encode($payload, $key, $alg, $keyId);
return JWT::encode($payload, $key, $alg, $keyId);
}
public function decode($jwt, $key = null, $allowedAlgorithms = null)
{
try {
//Maintain BC: Do not verify if no algorithms are passed in.
if (!$allowedAlgorithms) {
$key = null;
$tks = \explode('.', $jwt);
if (\count($tks) === 3) {
[$headb64] = $tks;
$headerRaw = JWT::urlsafeB64Decode($headb64);
if (($header = JWT::jsonDecode($headerRaw))) {
$key = new Key($key, $header->alg);
}
}
} elseif(is_array($allowedAlgorithms)) {
$key = new Key($key, $allowedAlgorithms[0]);
} else {
$key = new Key($key, $allowedAlgorithms);
}
return (array)\JWT::decode($jwt, $key, $allowedAlgorithms);
return (array) JWT::decode($jwt, $key);
} catch (\Exception $e) {
return false;
}
@@ -37,11 +50,11 @@ class FirebaseJwt implements EncryptionInterface
public function urlSafeB64Encode($data)
{
return \JWT::urlsafeB64Encode($data);
return JWT::urlsafeB64Encode($data);
}
public function urlSafeB64Decode($b64)
{
return \JWT::urlsafeB64Decode($b64);
return JWT::urlsafeB64Decode($b64);
}
}
@@ -84,6 +84,41 @@ class AuthorizationCode implements GrantTypeInterface
return false;
}
if (isset($authCode['code_challenge']) && $authCode['code_challenge']) {
if (!($code_verifier = $request->request('code_verifier'))) {
$response->setError(400, 'code_verifier_missing', "The PKCE code verifier parameter is required.");
return false;
}
// Validate code_verifier according to RFC-7636
// @see: https://tools.ietf.org/html/rfc7636#section-4.1
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $code_verifier) !== 1) {
$response->setError(400, 'code_verifier_invalid', "The PKCE code verifier parameter is invalid.");
return false;
}
$code_verifier = $request->request('code_verifier');
switch ($authCode['code_challenge_method']) {
case 'S256':
$code_verifier_hashed = strtr(rtrim(base64_encode(hash('sha256', $code_verifier, true)), '='), '+/', '-_');
break;
case 'plain':
$code_verifier_hashed = $code_verifier;
break;
default:
$response->setError(400, 'code_challenge_method_invalid', "Unknown PKCE code challenge method.");
return FALSE;
}
if ($code_verifier_hashed !== $authCode['code_challenge']) {
$response->setError(400, 'code_verifier_mismatch', "The PKCE code verifier parameter does not match the code challenge.");
return FALSE;
}
}
if (!isset($authCode['code'])) {
$authCode['code'] = $code; // used to expire the code after the access token is granted
}
@@ -37,7 +37,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
* @param EncryptionInterface|JWT $jwtUtil - OPTONAL The class used to decode, encode and verify JWTs.
* @param array $config
*/
public function __construct(JwtBearerInterface $storage, $audience, EncryptionInterface $jwtUtil = null, array $config = array())
public function __construct(JwtBearerInterface $storage, $audience, ?EncryptionInterface $jwtUtil = null, array $config = array())
{
$this->storage = $storage;
$this->audience = $audience;
@@ -46,13 +46,13 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
$jwtUtil = new Jwt();
}
$this->config = array_merge(array(
$config = array_merge(array(
'allowed_algorithms' => array('RS256', 'RS384', 'RS512')
), $config);
$this->jwtUtil = $jwtUtil;
$this->allowedAlgorithms = $this->config['allowed_algorithms'];
$this->allowedAlgorithms = $config['allowed_algorithms'];
}
/**
@@ -127,7 +127,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
}
// Check expiration
if (ctype_digit($jwt['exp'])) {
if (ctype_digit((string)$jwt['exp'])) {
if ($jwt['exp'] <= time()) {
$response->setError(400, 'invalid_grant', "JWT has expired");
@@ -141,7 +141,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
// Check the not before time
if ($notBefore = $jwt['nbf']) {
if (ctype_digit($notBefore)) {
if (ctype_digit((string)$notBefore)) {
if ($notBefore > time()) {
$response->setError(400, 'invalid_grant', "JWT cannot be used before the Not Before (nbf) time");
@@ -16,6 +16,16 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
*/
private $nonce;
/**
* @var mixed
*/
protected $code_challenge;
/**
* @var mixed
*/
protected $code_challenge_method;
/**
* Set not authorized response
*
@@ -65,6 +75,10 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
// add the nonce to return with the redirect URI
$params['nonce'] = $this->nonce;
// Add PKCE code challenge.
$params['code_challenge'] = $this->code_challenge;
$params['code_challenge_method'] = $this->code_challenge_method;
return $params;
}
@@ -90,6 +104,32 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
$this->nonce = $nonce;
$code_challenge = $request->query('code_challenge');
$code_challenge_method = $request->query('code_challenge_method');
if ($this->config['enforce_pkce']) {
if (!$code_challenge) {
$response->setError(400, 'missing_code_challenge', 'This application requires you provide a PKCE code challenge');
return false;
}
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $code_challenge) !== 1) {
$response->setError(400, 'invalid_code_challenge', 'The PKCE code challenge supplied is invalid');
return false;
}
if (!in_array($code_challenge_method, array('plain', 'S256'), true)) {
$response->setError(400, 'missing_code_challenge_method', 'This application requires you specify a PKCE code challenge method');
return false;
}
}
$this->code_challenge = $code_challenge;
$this->code_challenge_method = $code_challenge_method;
return true;
}
@@ -30,7 +30,7 @@ class UserInfoController extends ResourceController implements UserInfoControlle
* @param array $config
* @param ScopeInterface $scopeUtil
*/
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ScopeInterface $scopeUtil = null)
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ?ScopeInterface $scopeUtil = null)
{
parent::__construct($tokenType, $tokenStorage, $config, $scopeUtil);
@@ -31,9 +31,9 @@ class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCo
// build the URL to redirect to
$result = array('query' => array());
$params += array('scope' => null, 'state' => null, 'id_token' => null);
$params += array('scope' => null, 'state' => null, 'id_token' => null, 'code_challenge' => null, 'code_challenge_method' => null);
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token']);
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token'], $params['code_challenge'], $params['code_challenge_method']);
if (isset($params['state'])) {
$result['query']['state'] = $params['state'];
@@ -56,10 +56,10 @@ class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCo
* @see http://tools.ietf.org/html/rfc6749#section-4
* @ingroup oauth2_section_4
*/
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null)
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
$code = $this->generateAuthorizationCode();
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token);
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token, $code_challenge, $code_challenge_method);
return $code;
}
@@ -38,7 +38,7 @@ class IdToken implements IdTokenInterface
* @param EncryptionInterface $encryptionUtil
* @throws LogicException
*/
public function __construct(UserClaimsInterface $userClaimsStorage, PublicKeyInterface $publicKeyStorage, array $config = array(), EncryptionInterface $encryptionUtil = null)
public function __construct(UserClaimsInterface $userClaimsStorage, PublicKeyInterface $publicKeyStorage, array $config = array(), ?EncryptionInterface $encryptionUtil = null)
{
$this->userClaimsStorage = $userClaimsStorage;
$this->publicKeyStorage = $publicKeyStorage;
@@ -33,5 +33,5 @@ interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
*
* @ingroup oauth2_section_4
*/
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null);
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null);
}
@@ -34,7 +34,7 @@ class Request implements RequestInterface
*
* @api
*/
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, ?array $headers = null)
{
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content, $headers);
}
@@ -55,7 +55,7 @@ class Request implements RequestInterface
*
* @api
*/
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, ?array $headers = null)
{
$this->request = $request;
$this->query = $query;
@@ -140,11 +140,10 @@ class Response implements ResponseInterface
}
/**
* @param int $statusCode
* @param string $text
* @throws InvalidArgumentException
*/
public function setStatusCode($statusCode, $text = null)
public function setStatusCode(int $statusCode, $text = null)
{
$this->statusCode = (int) $statusCode;
if ($this->isInvalid()) {
@@ -20,10 +20,7 @@ interface ResponseInterface
*/
public function addHttpHeaders(array $httpHeaders);
/**
* @param int $statusCode
*/
public function setStatusCode($statusCode);
public function setStatusCode(int $statusCode);
/**
* @param int $statusCode
@@ -38,7 +38,7 @@ class AccessToken implements AccessTokenInterface
* );
* @endcode
*/
public function __construct(AccessTokenStorageInterface $tokenStorage, RefreshTokenInterface $refreshStorage = null, array $config = array())
public function __construct(AccessTokenStorageInterface $tokenStorage, ?RefreshTokenInterface $refreshStorage = null, array $config = array())
{
$this->tokenStorage = $tokenStorage;
$this->refreshStorage = $refreshStorage;
@@ -26,9 +26,9 @@ class AuthorizationCode implements AuthorizationCodeInterface
// build the URL to redirect to
$result = array('query' => array());
$params += array('scope' => null, 'state' => null);
$params += array('scope' => null, 'state' => null, 'code_challenge' => null, 'code_challenge_method' => null);
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope']);
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['code_challenge'], $params['code_challenge_method']);
if (isset($params['state'])) {
$result['query']['state'] = $params['state'];
@@ -53,10 +53,10 @@ class AuthorizationCode implements AuthorizationCodeInterface
* @see http://tools.ietf.org/html/rfc6749#section-4
* @ingroup oauth2_section_4
*/
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null)
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $code_challenge = null, $code_challenge_method = null)
{
$code = $this->generateAuthorizationCode();
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope);
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, null, $code_challenge, $code_challenge_method);
return $code;
}
@@ -26,7 +26,7 @@ class JwtAccessToken extends AccessToken
* or just the token ID is stored
* @param EncryptionInterface $encryptionUtil -
*/
public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
public function __construct(?PublicKeyInterface $publicKeyStorage = null, ?AccessTokenStorageInterface $tokenStorage = null, ?RefreshTokenInterface $refreshStorage = null, array $config = array(), ?EncryptionInterface $encryptionUtil = null)
{
$this->publicKeyStorage = $publicKeyStorage;
$config = array_merge(array(
@@ -150,7 +150,7 @@ class Server implements ResourceControllerInterface,
*
* @ingroup oauth2_section_7
*/
public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), TokenTypeInterface $tokenType = null, ScopeInterface $scopeUtil = null, ClientAssertionTypeInterface $clientAssertionType = null)
public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), ?TokenTypeInterface $tokenType = null, ?ScopeInterface $scopeUtil = null, ?ClientAssertionTypeInterface $clientAssertionType = null)
{
$storage = is_array($storage) ? $storage : array($storage);
$this->storages = array();
@@ -172,6 +172,7 @@ class Server implements ResourceControllerInterface,
'enforce_state' => true,
'require_exact_redirect_uri' => true,
'allow_implicit' => false,
'enforce_pkce' => false,
'allow_credentials_in_request_body' => true,
'allow_public_clients' => true,
'always_issue_new_refresh_token' => false,
@@ -288,7 +289,7 @@ class Server implements ResourceControllerInterface,
*
* @see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
*/
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response = null)
public function handleUserInfoRequest(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
@@ -314,7 +315,7 @@ class Server implements ResourceControllerInterface,
*
* @ingroup oauth2_section_4
*/
public function handleTokenRequest(RequestInterface $request, ResponseInterface $response = null)
public function handleTokenRequest(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$this->getTokenController()->handleTokenRequest($request, $this->response);
@@ -327,7 +328,7 @@ class Server implements ResourceControllerInterface,
* @param ResponseInterface $response - Response object
* @return mixed
*/
public function grantAccessToken(RequestInterface $request, ResponseInterface $response = null)
public function grantAccessToken(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$value = $this->getTokenController()->grantAccessToken($request, $this->response);
@@ -345,7 +346,7 @@ class Server implements ResourceControllerInterface,
* @param ResponseInterface $response
* @return Response|ResponseInterface
*/
public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response = null)
public function handleRevokeRequest(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$this->getTokenController()->handleRevokeRequest($request, $this->response);
@@ -407,7 +408,7 @@ class Server implements ResourceControllerInterface,
*
* @ingroup oauth2_section_3
*/
public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response = null)
public function validateAuthorizeRequest(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
@@ -421,7 +422,7 @@ class Server implements ResourceControllerInterface,
* @param string $scope - Scope
* @return mixed
*/
public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response = null, $scope = null)
public function verifyResourceRequest(RequestInterface $request, ?ResponseInterface $response = null, $scope = null)
{
$this->response = is_null($response) ? new Response() : $response;
$value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
@@ -434,7 +435,7 @@ class Server implements ResourceControllerInterface,
* @param ResponseInterface $response - Response object
* @return mixed
*/
public function getAccessTokenData(RequestInterface $request, ResponseInterface $response = null)
public function getAccessTokenData(RequestInterface $request, ?ResponseInterface $response = null)
{
$this->response = is_null($response) ? new Response() : $response;
$value = $this->getResourceController()->getAccessTokenData($request, $this->response);
@@ -577,7 +578,7 @@ class Server implements ResourceControllerInterface,
}
}
$config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri')));
$config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri enforce_pkce')));
if ($this->config['use_openid_connect']) {
return new OpenIDAuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
@@ -191,11 +191,11 @@ class Cassandra implements AuthorizationCodeInterface,
* @param string $id_token
* @return bool
*/
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
return $this->setValue(
$this->config['code_key'] . $authorization_code,
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'),
$expires
);
}
@@ -2,6 +2,7 @@
namespace OAuth2\Storage;
use Couchbase;
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
/**
@@ -27,14 +28,18 @@ class CouchbaseDB implements AuthorizationCodeInterface,
public function __construct($connection, $config = array())
{
if ($connection instanceof \Couchbase) {
if (!class_exists(Couchbase::class)) {
throw new \RuntimeException('Missing Couchbase');
}
if ($connection instanceof Couchbase) {
$this->db = $connection;
} else {
if (!is_array($connection) || !is_array($connection['servers'])) {
throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
}
$this->db = new \Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
$this->db = new Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
}
$this->config = array_merge(array(
@@ -173,7 +178,7 @@ class CouchbaseDB implements AuthorizationCodeInterface,
return is_null($code) ? false : $code;
}
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
// if it exists, update it.
if ($this->getAuthorizationCode($code)) {
@@ -185,6 +190,8 @@ class CouchbaseDB implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
));
} else {
$this->setObjectByType('code_table',$code,array(
@@ -195,6 +202,8 @@ class CouchbaseDB implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
));
}
@@ -328,4 +337,4 @@ class CouchbaseDB implements AuthorizationCodeInterface,
//TODO: Needs couchbase implementation.
throw new \Exception('setJti() for the Couchbase driver is currently unimplemented.');
}
}
}
@@ -213,12 +213,12 @@ class DynamoDB implements
}
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
// convert expires to datestring
$expires = date('Y-m-d H:i:s', $expires);
$clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'id_token', 'scope');
$clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method');
$clientData = array_filter($clientData, 'self::isNotEmpty');
$result = $this->client->putItem(array(
@@ -21,7 +21,7 @@ class JwtAccessToken implements JwtAccessTokenInterface
* is not necessary when using this grant type.
* @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
*/
public function __construct(PublicKeyInterface $publicKeyStorage, AccessTokenInterface $tokenStorage = null, EncryptionInterface $encryptionUtil = null)
public function __construct(PublicKeyInterface $publicKeyStorage, ?AccessTokenInterface $tokenStorage = null, ?EncryptionInterface $encryptionUtil = null)
{
$this->publicKeyStorage = $publicKeyStorage;
$this->tokenStorage = $tokenStorage;
@@ -84,4 +84,4 @@ class JwtAccessToken implements JwtAccessTokenInterface
return $tokenData;
}
}
}
@@ -74,9 +74,9 @@ class Memory implements AuthorizationCodeInterface,
), $this->authorizationCodes[$code]);
}
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
$this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token');
$this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method');
return true;
}
@@ -179,7 +179,7 @@ class Mongo implements AuthorizationCodeInterface,
return is_null($code) ? false : $code;
}
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
// if it exists, update it.
if ($this->getAuthorizationCode($code)) {
@@ -192,6 +192,8 @@ class Mongo implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
))
);
} else {
@@ -203,6 +205,8 @@ class Mongo implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
);
$this->collection('code_table')->insert($token);
}
@@ -32,6 +32,9 @@ class MongoDB implements AuthorizationCodeInterface,
public function __construct($connection, $config = array())
{
if (!class_exists(Database::class) || !class_exists(Client::class)) {
throw new \LogicException('Missing MongoDB php extension. Please install mongodb.so');
}
if ($connection instanceof Database) {
$this->db = $connection;
} else {
@@ -167,7 +170,7 @@ class MongoDB implements AuthorizationCodeInterface,
return is_null($code) ? false : $code;
}
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
// if it exists, update it.
if ($this->getAuthorizationCode($code)) {
@@ -180,6 +183,8 @@ class MongoDB implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
))
);
return $result->getMatchedCount() > 0;
@@ -192,6 +197,8 @@ class MongoDB implements AuthorizationCodeInterface,
'expires' => $expires,
'scope' => $scope,
'id_token' => $id_token,
'code_challenge' => $code_challenge,
'code_challenge_method' => $code_challenge_method,
);
$result = $this->collection('code_table')->insertOne($token);
return $result->getInsertedCount() > 0;
@@ -247,7 +247,7 @@ class Pdo implements
* @param string $id_token
* @return bool|mixed
*/
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
if (func_num_args() > 6) {
// we are calling with an id token
@@ -259,12 +259,12 @@ class Pdo implements
// if it exists, update it.
if ($this->getAuthorizationCode($code)) {
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope where authorization_code=:code', $this->config['code_table']));
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, code_challenge=:code_challenge, code_challenge_method=:code_challenge_method where authorization_code=:code', $this->config['code_table']));
} else {
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope)', $this->config['code_table']));
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, code_challenge, code_challenge_method) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :code_challenge, :code_challenge_method)', $this->config['code_table']));
}
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'code_challenge', 'code_challenge_method'));
}
/**
@@ -277,19 +277,19 @@ class Pdo implements
* @param string $id_token
* @return bool
*/
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
// convert expires to datestring
$expires = date('Y-m-d H:i:s', $expires);
// if it exists, update it.
if ($this->getAuthorizationCode($code)) {
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token where authorization_code=:code', $this->config['code_table']));
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token, code_challenge=:code_challenge, code_challenge_method=:code_challenge_method where authorization_code=:code', $this->config['code_table']));
} else {
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token)', $this->config['code_table']));
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token, code_challenge, code_challenge_method) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token, :code_challenge, :code_challenge_method)', $this->config['code_table']));
}
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'));
}
/**
@@ -676,6 +676,8 @@ class Pdo implements
expires TIMESTAMP NOT NULL,
scope VARCHAR(4000),
id_token VARCHAR(1000),
code_challenge VARCHAR(1000),
code_challenge_method VARCHAR(20),
PRIMARY KEY (authorization_code)
);
@@ -95,11 +95,11 @@ class Redis implements AuthorizationCodeInterface,
return $this->getValue($this->config['code_key'] . $code);
}
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
{
return $this->setValue(
$this->config['code_key'] . $authorization_code,
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'),
$expires
);
}
@@ -109,7 +109,7 @@ class Bearer implements TokenTypeInterface
}
$contentType = $request->server('CONTENT_TYPE');
if (false !== $pos = strpos($contentType, ';')) {
if (false !== $pos = strpos((string) $contentType, ';')) {
$contentType = substr($contentType, 0, $pos);
}
@@ -133,7 +133,7 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNotContains('error', $response->getHttpHeader('Location'));
$this->assertStringNotContainsString('error', $response->getHttpHeader('Location'));
}
public function testEnforceScope()
@@ -161,7 +161,7 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertNotContains('error', $response->getHttpHeader('Location'));
$this->assertStringNotContainsString('error', $response->getHttpHeader('Location'));
}
public function testInvalidRedirectUri()
@@ -227,7 +227,7 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
}
public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
@@ -263,7 +263,7 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
}
public function testMultipleRedirectUris()
@@ -278,14 +278,14 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
// call again with different (but still valid) redirect URI
$request->query['redirect_uri'] = 'http://morehazards.com';
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('code', $response->getHttpHeader('Location'));
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
}
/**
@@ -303,7 +303,7 @@ class AuthorizeControllerTest extends TestCase
$server->handleAuthorizeRequest($request, $response = new Response(), true);
$this->assertEquals($response->getStatusCode(), 302);
$this->assertContains('state', $response->getHttpHeader('Location'));
$this->assertStringContainsString('state', $response->getHttpHeader('Location'));
$this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
$parts = parse_url($response->getHttpHeader('Location'));
@@ -421,7 +421,7 @@ class AuthorizeControllerTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertFalse(isset($parts['fake']));
@@ -9,7 +9,7 @@ class FirebaseJwtTest extends TestCase
{
private $privateKey;
public function setUp()
public function setUp(): void
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
@@ -9,7 +9,7 @@ class JwtTest extends TestCase
{
private $privateKey;
public function setUp()
public function setUp(): void
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
@@ -13,7 +13,7 @@ class JwtBearerTest extends TestCase
{
private $privateKey;
public function setUp()
public function setUp(): void
{
$this->privateKey = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
@@ -29,7 +29,7 @@ class CodeIdTokenTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
@@ -87,7 +87,7 @@ class CodeIdTokenTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
@@ -133,7 +133,7 @@ class CodeIdTokenTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('query', $parts);
@@ -52,7 +52,7 @@ class IdTokenTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
@@ -110,7 +110,7 @@ class IdTokenTest extends TestCase
{
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
@@ -31,7 +31,7 @@ class IdTokenTokenTest extends TestCase
$this->assertEquals($response->getStatusCode(), 302);
$location = $response->getHttpHeader('Location');
$this->assertNotContains('error', $location);
$this->assertStringNotContainsString('error', $location);
$parts = parse_url($location);
$this->assertArrayHasKey('fragment', $parts);
@@ -14,7 +14,7 @@ class ResponseTest extends TestCase
));
$string = $response->getResponseBody('xml');
$this->assertContains('<response><foo>bar</foo><halland>oates</halland></response>', $string);
$this->assertStringContainsString('<response><foo>bar</foo><halland>oates</halland></response>', $string);
}
public function testSetRedirect()
@@ -40,20 +40,20 @@ class JwtAccessTokenTest extends TestCase
$this->assertEquals(3600, $delta);
$this->assertEquals($decodedAccessToken['id'], $decodedAccessToken['jti']);
}
public function testExtraPayloadCallback()
{
$jwtconfig = array('jwt_extra_payload_callable' => function() {
return array('custom_param' => 'custom_value');
});
$server = $this->getTestServer($jwtconfig);
$jwtResponseType = $server->getResponseType('token');
$accessToken = $jwtResponseType->createAccessToken('Test Client ID', 123, 'test', false);
$jwt = new Jwt;
$decodedAccessToken = $jwt->decode($accessToken['access_token'], null, false);
$this->assertArrayHasKey('custom_param', $decodedAccessToken);
$this->assertEquals('custom_value', $decodedAccessToken['custom_param']);
}
@@ -162,7 +162,7 @@ class JwtAccessTokenTest extends TestCase
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
$storage = array(
'access_token' => new JwtAccessTokenStorage($memoryStorage),
'access_token' => new JwtAccessTokenStorage($memoryStorage, $memoryStorage),
'client' => $memoryStorage,
'client_credentials' => $memoryStorage,
);
@@ -6,27 +6,26 @@ use OAuth2\Request\TestRequest;
use OAuth2\ResponseType\AuthorizationCode;
use OAuth2\Storage\Bootstrap;
use PHPUnit\Framework\TestCase;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
class ServerTest extends TestCase
{
/**
* @expectedException LogicException OAuth2\Storage\ClientInterface
**/
use ExpectPHPException;
public function testGetAuthorizeControllerWithNoClientStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\ClientInterface');
// must set Client Storage
$server = new Server();
$server->getAuthorizeController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->getAuthorizeController();
}
@@ -34,8 +33,8 @@ class ServerTest extends TestCase
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->getMock('OAuth2\ResponseType\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->createMock('OAuth2\ResponseType\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
@@ -44,21 +43,19 @@ class ServerTest extends TestCase
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->getMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->addResponseType($this->createMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException allow_implicit
**/
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
{
// must set AuthorizationCode or AccessToken / implicit
$this->expectExceptionMessage('allow_implicit');
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
@@ -67,8 +64,8 @@ class ServerTest extends TestCase
{
// must set AuthorizationCode or AccessToken / implicit
$server = new Server(array(), array('allow_implicit' => true));
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
@@ -77,63 +74,55 @@ class ServerTest extends TestCase
{
// must set AccessToken or AuthorizationCode
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\AuthorizationCodeInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\AuthorizationCodeInterface'));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException grant_types
**/
public function testGetTokenControllerWithGrantTypeStorageThrowsException()
{
$this->expectExceptionMessage('grant_types');
$server = new Server();
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\ClientCredentialsInterface
**/
public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\ClientCredentialsInterface');
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\UserCredentialsInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\UserCredentialsInterface'));
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addGrantType($this->getMockBuilder('OAuth2\GrantType\AuthorizationCode')->disableOriginalConstructor()->getMock());
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addGrantType($this->createMock('OAuth2\GrantType\AuthorizationCode'));
$server->getTokenController();
}
/**
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
**/
public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
$server = new Server();
$server->getResourceController();
}
@@ -141,41 +130,35 @@ class ServerTest extends TestCase
public function testGetResourceControllerWithAccessTokenStorage()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
$server->getResourceController();
}
/**
* @expectedException InvalidArgumentException OAuth2\Storage\AccessTokenInterface
**/
public function testAddingStorageWithInvalidClass()
{
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
$server = new Server();
$server->addStorage(new \StdClass());
}
/**
* @expectedException InvalidArgumentException access_token
**/
public function testAddingStorageWithInvalidKey()
{
$this->expectExceptionMessage('access_token');
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
}
/**
* @expectedException InvalidArgumentException OAuth2\Storage\AuthorizationCodeInterface
**/
public function testAddingStorageWithInvalidKeyStorageCombination()
{
$this->expectExceptionMessage('OAuth2\Storage\AuthorizationCodeInterface');
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
}
public function testAddingStorageWithValidKeyOnlySetsThatKey()
{
$server = new Server();
$server->addStorage($this->getMock('OAuth2\Storage\Memory'), 'access_token');
$server->addStorage($this->createMock('OAuth2\Storage\Memory'), 'access_token');
$reflection = new \ReflectionClass($server);
$prop = $reflection->getProperty('storages');
@@ -191,7 +174,7 @@ class ServerTest extends TestCase
public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
{
$server = new Server();
$memory = $this->getMock('OAuth2\Storage\Memory');
$memory = $this->createMock('OAuth2\Storage\Memory');
$server->addStorage($memory, 'client');
$client_credentials = $server->getStorage('client_credentials');
@@ -202,7 +185,7 @@ class ServerTest extends TestCase
public function testAddStorageWithNullValue()
{
$memory = $this->getMock('OAuth2\Storage\Memory');
$memory = $this->createMock('OAuth2\Storage\Memory');
$server = new Server($memory);
$server->addStorage(null, 'refresh_token');
@@ -218,7 +201,7 @@ class ServerTest extends TestCase
public function testNewServerWithNullStorageValue()
{
$memory = $this->getMock('OAuth2\Storage\Memory');
$memory = $this->createMock('OAuth2\Storage\Memory');
$server = new Server(array(
'client_credentials' => $memory,
'refresh_token' => null,
@@ -237,7 +220,7 @@ class ServerTest extends TestCase
public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
{
$server = new Server();
$memory = $this->getMock('OAuth2\Storage\Memory');
$memory = $this->createMock('OAuth2\Storage\Memory');
$server->addStorage($memory, 'client_credentials');
$client = $server->getStorage('client');
@@ -249,10 +232,9 @@ class ServerTest extends TestCase
public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
{
$server = new Server();
$pdo = $this->getMockBuilder('OAuth2\Storage\Pdo')
->disableOriginalConstructor()->getMock();
$pdo = $this->createMock('OAuth2\Storage\Pdo');
$memory = $this->getMock('OAuth2\Storage\Memory');
$memory = $this->createMock('OAuth2\Storage\Memory');
$server->addStorage($pdo, 'client');
$server->addStorage($memory, 'client_credentials');
@@ -266,7 +248,7 @@ class ServerTest extends TestCase
public function testAddingResponseType()
{
$storage = $this->getMock('OAuth2\Storage\Memory');
$storage = $this->createMock('OAuth2\Storage\Memory');
$storage
->expects($this->any())
->method('getClientDetails')
@@ -323,7 +305,7 @@ class ServerTest extends TestCase
'code' => 'testcode',
));
// verify the mock clientAssertionType was called as expected
$clientAssertionType = $this->getMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface', array('validateRequest', 'getClientId'));
$clientAssertionType = $this->createMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface');
$clientAssertionType
->expects($this->once())
->method('validateRequest')
@@ -420,98 +402,84 @@ class ServerTest extends TestCase
$this->assertFalse($used_token, 'the refresh token used is no longer valid');
}
/**
* @expectedException InvalidArgumentException OAuth2\ResponseType\AuthorizationCodeInterface
**/
public function testAddingUnknownResponseTypeThrowsException()
{
$this->expectExceptionMessage('OAuth2\ResponseType\AuthorizationCodeInterface');
$server = new Server();
$server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
$server->addResponseType($this->createMock('OAuth2\ResponseType\ResponseTypeInterface'));
}
/**
* @expectedException LogicException OAuth2\Storage\PublicKeyInterface
**/
public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
{
$this->expectExceptionMessage('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array(), array('use_jwt_access_tokens' => true));
$server->addGrantType($this->getMock('OAuth2\GrantType\GrantTypeInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addGrantType($this->createMock('OAuth2\GrantType\GrantTypeInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
$server->getTokenController();
}
public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$this->assertNotNull($server->getResourceController());
$this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
}
/**
* @expectedException LogicException OAuth2\Storage\ClientInterface
**/
public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$this->expectExceptionMessage('OAuth2\Storage\ClientInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$this->assertNotNull($server->getAuthorizeController());
}
/**
* @expectedException LogicException grant_types
**/
public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$this->expectExceptionMessage('grant_types');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
$server->getTokenController();
}
public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
{
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
$this->assertNotNull($server->getAuthorizeController());
$this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
}
/**
* @expectedException LogicException UserClaims
**/
public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$this->expectExceptionMessage('UserClaims');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$server = new Server($client, array('use_openid_connect' => true));
$server->getAuthorizeController();
}
/**
* @expectedException LogicException PublicKeyInterface
**/
public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OPenID\Storage\UserClaimsInterface');
$this->expectExceptionMessage('PublicKeyInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OPenID\Storage\UserClaimsInterface');
$server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
$server->getAuthorizeController();
}
/**
* @expectedException LogicException issuer
**/
public function testUsingOpenIDConnectWithoutIssuerThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$this->expectExceptionMessage('issuer');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
$server->getAuthorizeController();
@@ -519,9 +487,9 @@ class ServerTest extends TestCase
public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
@@ -533,14 +501,12 @@ class ServerTest extends TestCase
$this->assertNull($server->getResponseType('id_token token'));
}
/**
* @expectedException LogicException OAuth2\ResponseType\AccessTokenInterface
**/
public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$this->expectErrorMessage('OAuth2\ResponseType\AccessTokenInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
@@ -552,9 +518,9 @@ class ServerTest extends TestCase
public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
@@ -570,10 +536,10 @@ class ServerTest extends TestCase
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
@@ -588,17 +554,17 @@ class ServerTest extends TestCase
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
{
$client = $this->getMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
// $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$client = $this->createMock('OAuth2\Storage\ClientInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
// $token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
$server = new Server(array($client, $userclaims, $pubkey), array(
'use_openid_connect' => true,
'issuer' => 'someguy',
'allow_implicit' => true,
));
$token = $this->getMock('OAuth2\ResponseType\AccessTokenInterface');
$token = $this->createMock('OAuth2\ResponseType\AccessTokenInterface');
$server->addResponseType($token, 'token');
$server->getAuthorizeController();
@@ -607,17 +573,15 @@ class ServerTest extends TestCase
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
}
/**
* @expectedException LogicException OAuth2\OpenID\Storage\AuthorizationCodeInterface
**/
public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
{
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->getMock('OAuth2\Storage\AuthorizationCodeInterface');
$client = $this->createMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->createMock('OAuth2\Storage\AuthorizationCodeInterface');
$this->expectErrorMessage('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
'use_openid_connect' => true,
'issuer' => 'someguy'
@@ -630,11 +594,11 @@ class ServerTest extends TestCase
public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
{
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->getMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
$client = $this->createMock('OAuth2\Storage\ClientCredentialsInterface');
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
$authcode = $this->createMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
'use_openid_connect' => true,
@@ -648,7 +612,7 @@ class ServerTest extends TestCase
public function testMultipleValuedResponseTypeOrderDoesntMatter()
{
$responseType = $this->getMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
$responseType = $this->createMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
$server = new Server(array(), array(), array(), array(
'token id_token' => $responseType,
));
@@ -659,7 +623,7 @@ class ServerTest extends TestCase
public function testAddGrantTypeWithoutKey()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')));
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')));
$grantTypes = $server->getGrantTypes();
$this->assertEquals('authorization_code', key($grantTypes));
@@ -668,7 +632,7 @@ class ServerTest extends TestCase
public function testAddGrantTypeWithKey()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
$grantTypes = $server->getGrantTypes();
$this->assertEquals('ac', key($grantTypes));
@@ -677,7 +641,7 @@ class ServerTest extends TestCase
public function testAddGrantTypeWithKeyNotString()
{
$server = new Server();
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
$grantTypes = $server->getGrantTypes();
$this->assertEquals('authorization_code', key($grantTypes));
@@ -2,8 +2,12 @@
namespace OAuth2\Storage;
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
class PdoTest extends BaseTest
{
use ExpectPHPException;
public function testCreatePdoStorageUsingPdoClass()
{
$dsn = sprintf('sqlite:%s', Bootstrap::getInstance()->getSqliteDir());
@@ -30,11 +34,9 @@ class PdoTest extends BaseTest
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
}
/**
* @expectedException InvalidArgumentException dsn
*/
public function testCreatePdoStorageWithoutDSNThrowsException()
{
$this->expectErrorMessage('dsn');
$config = array('username' => 'brent', 'password' => 'brentisaballer');
$storage = new Pdo($config);
}
@@ -35,6 +35,17 @@ class BearerTest extends TestCase
$this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
}
public function testMissingContentTypeExpectsToBeCorrectContent()
{
$bearer = new Bearer();
$request = TestRequest::createPost(array(
'access_token' => 'ThisIsMyAccessToken'
));
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
$this->assertEquals($param, 'ThisIsMyAccessToken');
}
public function testValidRequestUsingAuthorizationHeader()
{
$bearer = new Bearer();
@@ -1,15 +0,0 @@
<?php
require_once(dirname(__FILE__).'/../src/OAuth2/Autoloader.php');
OAuth2\Autoloader::register();
// register test classes
OAuth2\Autoloader::register(dirname(__FILE__).'/lib');
// register vendors if possible
if (file_exists(__DIR__.'/../vendor/autoload.php')) {
require_once(__DIR__.'/../vendor/autoload.php');
}
// remove the dynamoDB database that was created for this build
OAuth2\Storage\Bootstrap::getInstance()->cleanupTravisDynamoDb();
@@ -68,7 +68,7 @@ class Bootstrap
public function getPostgresDriver()
{
try {
$pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres');
$pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres', 'postgres');
return $pdo;
} catch (\PDOException $e) {
@@ -118,7 +118,7 @@ class Bootstrap
if (!$this->mysql) {
$pdo = null;
try {
$pdo = new \PDO('mysql:host=localhost;', 'root');
$pdo = new \PDO('mysql:host=localhost;', 'root', 'root');
} catch (\PDOException $e) {
$this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
}
@@ -352,11 +352,11 @@ class Bootstrap
private function createPostgresDb()
{
if (!`psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'"`) {
`createuser -s -r postgres`;
if (!`PGPASSWORD=postgres psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" -h localhost -U postgres`) {
`PGPASSWORD=postgres createuser -s -r postgres -h localhost -U postgres`;
}
`createdb -O postgres oauth2_server_php`;
`PGPASSWORD=postgres createdb -O postgres oauth2_server_php -h localhost -U postgres`;
}
private function populatePostgresDb(\PDO $pdo)
@@ -366,8 +366,8 @@ class Bootstrap
private function removePostgresDb()
{
if (trim(`psql -l | grep oauth2_server_php | wc -l`)) {
`dropdb oauth2_server_php`;
if (trim(`PGPASSWORD=postgres psql -l -h localhost -U postgres | grep oauth2_server_php | wc -l`)) {
`PGPASSWORD=postgres dropdb oauth2_server_php -h localhost -U postgres`;
}
}
@@ -945,21 +945,6 @@ class Bootstrap
));
}
public function cleanupTravisDynamoDb($prefix = null)
{
if (is_null($prefix)) {
// skip this when not applicable
if (!$this->getEnvVar('TRAVIS') || self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
return;
}
$prefix = sprintf('build_%s_', $this->getEnvVar('TRAVIS_JOB_NUMBER'));
}
$client = $this->getDynamoDbClient();
$this->deleteDynamoDb($client, $prefix);
}
private function getEnvVar($var, $default = null)
{
return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
@@ -4,7 +4,7 @@ Types to use Carbon in Doctrine
## Documentation
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/symfony/)
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/guide/getting-started/symfony.html)
This package is an externalization of [src/Carbon/Doctrine](https://github.com/briannesbitt/Carbon/tree/2.71.0/src/Carbon/Doctrine)
from `nestbot/carbon` package.
@@ -32,5 +32,10 @@
"email": "kylekatarnls@gmail.com"
}
],
"minimum-stability": "dev"
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
}
}
@@ -4,13 +4,14 @@ declare(strict_types=1);
namespace Carbon\Doctrine;
use Carbon\CarbonInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
interface CarbonDoctrineType
{
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string;
public function convertToPHPValue(mixed $value, AbstractPlatform $platform);
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?CarbonInterface;
public function convertToDatabaseValue($value, AbstractPlatform $platform);
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string;
}
@@ -62,7 +62,7 @@ trait CarbonTypeConverter
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if ($value === null) {
return $value;
@@ -79,11 +79,11 @@ trait CarbonTypeConverter
);
}
private function doConvertToPHPValue(mixed $value)
private function doConvertToPHPValue(mixed $value): ?CarbonInterface
{
$class = $this->getCarbonClassName();
if ($value === null || is_a($value, $class)) {
if ($value === null || (is_object($value) && is_a($value, $class))) {
return $value;
}
+19 -1
View File
@@ -26,6 +26,12 @@ use Composer\Semver\VersionParser;
*/
class InstalledVersions
{
/**
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
* @internal
*/
private static $selfDir = null;
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
@@ -322,6 +328,18 @@ class InstalledVersions
self::$installedIsLocalDir = false;
}
/**
* @return string
*/
private static function getSelfDir()
{
if (self::$selfDir === null) {
self::$selfDir = strtr(__DIR__, '\\', '/');
}
return self::$selfDir;
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
@@ -336,7 +354,7 @@ class InstalledVersions
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = strtr(__DIR__, '\\', '/');
$selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
+35 -2
View File
@@ -6,12 +6,45 @@ $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'AllowDynamicProperties' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/AllowDynamicProperties.php',
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
'DateInvalidOperationException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
'DateInvalidTimeZoneException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
'DateMalformedIntervalStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
'DateMalformedPeriodStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
'DateMalformedStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
'DateObjectError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
'DateRangeError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
'DelayedTargetValidation' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/DelayedTargetValidation.php',
'Deprecated' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Deprecated.php',
'Filter\\FilterException' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterException.php',
'Filter\\FilterFailedException' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterFailedException.php',
'NoDiscard' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/NoDiscard.php',
'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php',
'Pdo\\Dblib' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Dblib.php',
'Pdo\\Firebird' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Firebird.php',
'Pdo\\Mysql' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php',
'Pdo\\Odbc' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Odbc.php',
'Pdo\\Pgsql' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Pgsql.php',
'Pdo\\Sqlite' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Sqlite.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Random\\BrokenRandomEngineError' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/BrokenRandomEngineError.php',
'Random\\CryptoSafeEngine' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/CryptoSafeEngine.php',
'Random\\Engine' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/Engine.php',
'Random\\Engine\\Secure' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/Engine/Secure.php',
'Random\\RandomError' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/RandomError.php',
'Random\\RandomException' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/RandomException.php',
'ReflectionConstant' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php',
'RoundingMode' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/RoundingMode.php',
'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
'SensitiveParameter' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameter.php',
'SensitiveParameterValue' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameterValue.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'Time\\Duration' => $vendorDir . '/symfony/polyfill-time/Resources/stubs/Time/Duration.php',
'Time\\TimeException' => $vendorDir . '/symfony/polyfill-time/Resources/stubs/Time/TimeException.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);
+7 -5
View File
@@ -6,16 +6,18 @@ $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'5897ea0ac4cccf14d323035e65887801' => $vendorDir . '/symfony/polyfill-php82/bootstrap.php',
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
'2203a247e6fda86070a5e4e07aed533a' => $vendorDir . '/symfony/clock/Resources/now.php',
'9d2b9fc6db0f153a0a149fefb182415e' => $vendorDir . '/symfony/polyfill-php84/bootstrap.php',
'606a39d89246991a373564698c2d8383' => $vendorDir . '/symfony/polyfill-php85/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'23f09fe3194f8c2f70923f90d6702129' => $vendorDir . '/illuminate/collections/functions.php',
'60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php',
'89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php',
'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php',
+6 -1
View File
@@ -7,12 +7,17 @@ $baseDir = dirname($vendorDir);
return array(
'Twig\\' => array($vendorDir . '/twig/twig/src'),
'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
'Symfony\\Polyfill\\Time\\' => array($vendorDir . '/symfony/polyfill-time'),
'Symfony\\Polyfill\\Php85\\' => array($vendorDir . '/symfony/polyfill-php85'),
'Symfony\\Polyfill\\Php84\\' => array($vendorDir . '/symfony/polyfill-php84'),
'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'),
'Symfony\\Polyfill\\Php82\\' => array($vendorDir . '/symfony/polyfill-php82'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\Clock\\' => array($vendorDir . '/symfony/clock'),
'Stevenmaguire\\OAuth2\\Client\\' => array($vendorDir . '/stevenmaguire/oauth2-keycloak/src'),
'RobThree\\Auth\\' => array($vendorDir . '/robthree/twofactorauth/lib'),
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
+118 -58
View File
@@ -7,16 +7,18 @@ namespace Composer\Autoload;
class ComposerStaticInit873464e4bd965a3168f133248b1b218b
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'5897ea0ac4cccf14d323035e65887801' => __DIR__ . '/..' . '/symfony/polyfill-php82/bootstrap.php',
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
'2203a247e6fda86070a5e4e07aed533a' => __DIR__ . '/..' . '/symfony/clock/Resources/now.php',
'9d2b9fc6db0f153a0a149fefb182415e' => __DIR__ . '/..' . '/symfony/polyfill-php84/bootstrap.php',
'606a39d89246991a373564698c2d8383' => __DIR__ . '/..' . '/symfony/polyfill-php85/bootstrap.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
'23f09fe3194f8c2f70923f90d6702129' => __DIR__ . '/..' . '/illuminate/collections/functions.php',
'60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php',
'89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php',
'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php',
@@ -25,25 +27,30 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
);
public static $prefixLengthsPsr4 = array (
'T' =>
'T' =>
array (
'Twig\\' => 5,
),
'S' =>
'S' =>
array (
'Symfony\\Polyfill\\Php81\\' => 23,
'Symfony\\Polyfill\\Time\\' => 22,
'Symfony\\Polyfill\\Php85\\' => 23,
'Symfony\\Polyfill\\Php84\\' => 23,
'Symfony\\Polyfill\\Php83\\' => 23,
'Symfony\\Polyfill\\Php82\\' => 23,
'Symfony\\Polyfill\\Php80\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Ctype\\' => 23,
'Symfony\\Contracts\\Translation\\' => 30,
'Symfony\\Component\\Translation\\' => 30,
'Symfony\\Component\\Clock\\' => 24,
'Stevenmaguire\\OAuth2\\Client\\' => 28,
),
'R' =>
'R' =>
array (
'RobThree\\Auth\\' => 14,
),
'P' =>
'P' =>
array (
'Psr\\SimpleCache\\' => 16,
'Psr\\Log\\' => 8,
@@ -54,198 +61,218 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
'PhpMimeMailParser\\' => 18,
'PHPMailer\\PHPMailer\\' => 20,
),
'M' =>
'M' =>
array (
'MatthiasMullie\\PathConverter\\' => 29,
'MatthiasMullie\\Minify\\' => 22,
'Mailcow\\' => 8,
),
'L' =>
'L' =>
array (
'League\\OAuth2\\Client\\' => 21,
'LdapRecord\\' => 11,
),
'I' =>
'I' =>
array (
'Illuminate\\Support\\' => 19,
'Illuminate\\Contracts\\' => 21,
),
'H' =>
'H' =>
array (
'Html2Text\\' => 10,
),
'G' =>
'G' =>
array (
'GuzzleHttp\\Psr7\\' => 16,
'GuzzleHttp\\Promise\\' => 19,
'GuzzleHttp\\' => 11,
),
'F' =>
'F' =>
array (
'Firebase\\JWT\\' => 13,
),
'D' =>
'D' =>
array (
'Ddeboer\\Imap\\' => 13,
'DASPRiD\\Enum\\' => 13,
),
'C' =>
'C' =>
array (
'Carbon\\Doctrine\\' => 16,
'Carbon\\' => 7,
),
'B' =>
'B' =>
array (
'BaconQrCode\\' => 12,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'Symfony\\Polyfill\\Php81\\' =>
'Symfony\\Polyfill\\Time\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php81',
0 => __DIR__ . '/..' . '/symfony/polyfill-time',
),
'Symfony\\Polyfill\\Php80\\' =>
'Symfony\\Polyfill\\Php85\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php85',
),
'Symfony\\Polyfill\\Php84\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php84',
),
'Symfony\\Polyfill\\Php83\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
),
'Symfony\\Polyfill\\Php82\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php82',
),
'Symfony\\Polyfill\\Php80\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
),
'Symfony\\Polyfill\\Mbstring\\' =>
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Ctype\\' =>
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Symfony\\Contracts\\Translation\\' =>
'Symfony\\Contracts\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
),
'Symfony\\Component\\Translation\\' =>
'Symfony\\Component\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation',
),
'Stevenmaguire\\OAuth2\\Client\\' =>
'Symfony\\Component\\Clock\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/clock',
),
'Stevenmaguire\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/stevenmaguire/oauth2-keycloak/src',
),
'RobThree\\Auth\\' =>
'RobThree\\Auth\\' =>
array (
0 => __DIR__ . '/..' . '/robthree/twofactorauth/lib',
),
'Psr\\SimpleCache\\' =>
'Psr\\SimpleCache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
),
'Psr\\Log\\' =>
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/src',
),
'Psr\\Http\\Message\\' =>
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-factory/src',
1 => __DIR__ . '/..' . '/psr/http-message/src',
),
'Psr\\Http\\Client\\' =>
'Psr\\Http\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-client/src',
),
'Psr\\Container\\' =>
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Clock\\' =>
'Psr\\Clock\\' =>
array (
0 => __DIR__ . '/..' . '/psr/clock/src',
),
'PhpMimeMailParser\\' =>
'PhpMimeMailParser\\' =>
array (
0 => __DIR__ . '/..' . '/php-mime-mail-parser/php-mime-mail-parser/src',
),
'PHPMailer\\PHPMailer\\' =>
'PHPMailer\\PHPMailer\\' =>
array (
0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src',
),
'MatthiasMullie\\PathConverter\\' =>
'MatthiasMullie\\PathConverter\\' =>
array (
0 => __DIR__ . '/..' . '/matthiasmullie/path-converter/src',
),
'MatthiasMullie\\Minify\\' =>
'MatthiasMullie\\Minify\\' =>
array (
0 => __DIR__ . '/..' . '/matthiasmullie/minify/src',
),
'Mailcow\\' =>
'Mailcow\\' =>
array (
0 => __DIR__ . '/../..' . '/mailcow',
),
'League\\OAuth2\\Client\\' =>
'League\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/league/oauth2-client/src',
),
'LdapRecord\\' =>
'LdapRecord\\' =>
array (
0 => __DIR__ . '/..' . '/directorytree/ldaprecord/src',
),
'Illuminate\\Support\\' =>
'Illuminate\\Support\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/collections',
1 => __DIR__ . '/..' . '/illuminate/macroable',
2 => __DIR__ . '/..' . '/illuminate/conditionable',
),
'Illuminate\\Contracts\\' =>
'Illuminate\\Contracts\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/contracts',
),
'Html2Text\\' =>
'Html2Text\\' =>
array (
0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
),
'GuzzleHttp\\Psr7\\' =>
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'GuzzleHttp\\Promise\\' =>
'GuzzleHttp\\Promise\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
),
'GuzzleHttp\\' =>
'GuzzleHttp\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Firebase\\JWT\\' =>
'Firebase\\JWT\\' =>
array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
),
'Ddeboer\\Imap\\' =>
'Ddeboer\\Imap\\' =>
array (
0 => __DIR__ . '/..' . '/ddeboer/imap/src',
),
'DASPRiD\\Enum\\' =>
'DASPRiD\\Enum\\' =>
array (
0 => __DIR__ . '/..' . '/dasprid/enum/src',
),
'Carbon\\Doctrine\\' =>
'Carbon\\Doctrine\\' =>
array (
0 => __DIR__ . '/..' . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine',
),
'Carbon\\' =>
'Carbon\\' =>
array (
0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
),
'BaconQrCode\\' =>
'BaconQrCode\\' =>
array (
0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src',
),
);
public static $prefixesPsr0 = array (
'O' =>
'O' =>
array (
'OAuth2' =>
'OAuth2' =>
array (
0 => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src',
),
@@ -253,12 +280,45 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
);
public static $classMap = array (
'AllowDynamicProperties' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/AllowDynamicProperties.php',
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
'DateInvalidOperationException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
'DateInvalidTimeZoneException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
'DateMalformedIntervalStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
'DateMalformedPeriodStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
'DateMalformedStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
'DateObjectError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
'DateRangeError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
'DelayedTargetValidation' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/DelayedTargetValidation.php',
'Deprecated' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Deprecated.php',
'Filter\\FilterException' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterException.php',
'Filter\\FilterFailedException' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterFailedException.php',
'NoDiscard' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/NoDiscard.php',
'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php',
'Pdo\\Dblib' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Dblib.php',
'Pdo\\Firebird' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Firebird.php',
'Pdo\\Mysql' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php',
'Pdo\\Odbc' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Odbc.php',
'Pdo\\Pgsql' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Pgsql.php',
'Pdo\\Sqlite' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Sqlite.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Random\\BrokenRandomEngineError' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/BrokenRandomEngineError.php',
'Random\\CryptoSafeEngine' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/CryptoSafeEngine.php',
'Random\\Engine' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/Engine.php',
'Random\\Engine\\Secure' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/Engine/Secure.php',
'Random\\RandomError' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/RandomError.php',
'Random\\RandomException' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/RandomException.php',
'ReflectionConstant' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php',
'RoundingMode' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/RoundingMode.php',
'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
'SensitiveParameter' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameter.php',
'SensitiveParameterValue' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameterValue.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'Time\\Duration' => __DIR__ . '/..' . '/symfony/polyfill-time/Resources/stubs/Time/Duration.php',
'Time\\TimeException' => __DIR__ . '/..' . '/symfony/polyfill-time/Resources/stubs/Time/TimeException.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);
File diff suppressed because it is too large. Load diff
+145 -118
View File
@@ -29,18 +29,18 @@
'dev_requirement' => false,
),
'bshaffer/oauth2-server-php' => array(
'pretty_version' => 'v1.11.1',
'version' => '1.11.1.0',
'reference' => '5a0c8000d4763b276919e2106f54eddda6bc50fa',
'pretty_version' => 'v1.14.2',
'version' => '1.14.2.0',
'reference' => '1c715c2d2f71254d1c683b8c89a0f16b61ccd0d6',
'type' => 'library',
'install_path' => __DIR__ . '/../bshaffer/oauth2-server-php',
'aliases' => array(),
'dev_requirement' => false,
),
'carbonphp/carbon-doctrine-types' => array(
'pretty_version' => '3.2.0',
'version' => '3.2.0.0',
'reference' => '18ba5ddfec8976260ead6e866180bd5d2f71aa1d',
'pretty_version' => '3.2.1',
'version' => '3.2.1.0',
'reference' => '5fa5eacafd9ef47c8c6ab9143fc901ba0194d3dc',
'type' => 'library',
'install_path' => __DIR__ . '/../carbonphp/carbon-doctrine-types',
'aliases' => array(),
@@ -56,18 +56,18 @@
'dev_requirement' => false,
),
'ddeboer/imap' => array(
'pretty_version' => '1.13.1',
'version' => '1.13.1.0',
'reference' => '8b772d04b1deadb5df13782fb78c4b648f77496e',
'pretty_version' => '1.19.0',
'version' => '1.19.0.0',
'reference' => '30800b1cfeacc4add5bb418e40a8b6e95a8a04ac',
'type' => 'library',
'install_path' => __DIR__ . '/../ddeboer/imap',
'aliases' => array(),
'dev_requirement' => false,
),
'directorytree/ldaprecord' => array(
'pretty_version' => 'v3.8.5',
'version' => '3.8.5.0',
'reference' => '00e5f088f8c4028d5f398783cccc2e8119a27a65',
'pretty_version' => 'v3.8.6',
'version' => '3.8.6.0',
'reference' => 'a1cab9f078eb4756fc6fad58caea1e3d11cad0ec',
'type' => 'library',
'install_path' => __DIR__ . '/../directorytree/ldaprecord',
'aliases' => array(),
@@ -80,90 +80,90 @@
),
),
'firebase/php-jwt' => array(
'pretty_version' => 'v6.5.0',
'version' => '6.5.0.0',
'reference' => 'e94e7353302b0c11ec3cfff7180cd0b1743975d2',
'pretty_version' => 'v7.2.1',
'version' => '7.2.1.0',
'reference' => '0501f5729b9e2448516674aff07c7d1727869b8e',
'type' => 'library',
'install_path' => __DIR__ . '/../firebase/php-jwt',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '7.5.0',
'version' => '7.5.0.0',
'reference' => 'b50a2a1251152e43f6a37f0fa053e730a67d25ba',
'pretty_version' => '8.3.1',
'version' => '8.3.1.0',
'reference' => '7d9b1f430bb65ac664e120af227bf9a795ad6333',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => '1.5.2',
'version' => '1.5.2.0',
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598',
'pretty_version' => '3.1.0',
'version' => '3.1.0.0',
'reference' => '094d0ec418eb3b1411ea271a180ec95cae6ae933',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '2.4.5',
'version' => '2.4.5.0',
'reference' => '0454e12ef0cd597ccd2adb036f7bda4e7fface66',
'pretty_version' => '3.2.0',
'version' => '3.2.0.0',
'reference' => 'cdc139396207a5eba10c242d241fb014cb098390',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/collections' => array(
'pretty_version' => 'v10.49.0',
'version' => '10.49.0.0',
'reference' => '6ae9c74fa92d4e1824d1b346cd435e8eacdc3232',
'pretty_version' => 'v12.70.2',
'version' => '12.70.2.0',
'reference' => '83313b009c4afb6f02dbc090bdb67809756eefa2',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/collections',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/conditionable' => array(
'pretty_version' => 'v10.49.0',
'version' => '10.49.0.0',
'reference' => '47c700320b7a419f0d188d111f3bbed978fcbd3f',
'pretty_version' => 'v12.70.2',
'version' => '12.70.2.0',
'reference' => 'ec677967c1f2faf90b8428919124d2184a4c9b49',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/conditionable',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/contracts' => array(
'pretty_version' => 'v10.44.0',
'version' => '10.44.0.0',
'reference' => '8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac',
'pretty_version' => 'v12.70.2',
'version' => '12.70.2.0',
'reference' => 'c16fd7ba7d8e6b8f336639ceb6b7e1ff6ed0efb5',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/macroable' => array(
'pretty_version' => 'v10.49.0',
'version' => '10.49.0.0',
'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27',
'pretty_version' => 'v12.70.2',
'version' => '12.70.2.0',
'reference' => 'e295d62d89dcdb87e2b1bd70dd14d074a0ed73cc',
'type' => 'library',
'install_path' => __DIR__ . '/../illuminate/macroable',
'aliases' => array(),
'dev_requirement' => false,
),
'league/oauth2-client' => array(
'pretty_version' => '2.7.0',
'version' => '2.7.0.0',
'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8',
'pretty_version' => '2.9.1',
'version' => '2.9.1.0',
'reference' => '8cedfef9d01a8d1fd2ecfabb41734b17592c4b71',
'type' => 'library',
'install_path' => __DIR__ . '/../league/oauth2-client',
'aliases' => array(),
'dev_requirement' => false,
),
'matthiasmullie/minify' => array(
'pretty_version' => '1.3.66',
'version' => '1.3.66.0',
'reference' => '45fd3b0f1dfa2c965857c6d4a470bea52adc31a6',
'pretty_version' => '1.3.75',
'version' => '1.3.75.0',
'reference' => '76ba4a5f555fd7bf4aa408af608e991569076671',
'type' => 'library',
'install_path' => __DIR__ . '/../matthiasmullie/minify',
'aliases' => array(),
@@ -194,36 +194,27 @@
'dev_requirement' => false,
),
'nesbot/carbon' => array(
'pretty_version' => '2.72.3',
'version' => '2.72.3.0',
'reference' => '0c6fd108360c562f6e4fd1dedb8233b423e91c83',
'pretty_version' => '3.15.1',
'version' => '3.15.1.0',
'reference' => 'ce0e5636fae7d1e99856eb70cae4c719a284aa08',
'type' => 'library',
'install_path' => __DIR__ . '/../nesbot/carbon',
'aliases' => array(),
'dev_requirement' => false,
),
'paragonie/random_compat' => array(
'pretty_version' => 'v9.99.100',
'version' => '9.99.100.0',
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/random_compat',
'aliases' => array(),
'dev_requirement' => false,
),
'php-mime-mail-parser/php-mime-mail-parser' => array(
'pretty_version' => '7.0.0',
'version' => '7.0.0.0',
'reference' => '9d09a017f3f103fec8456211a4a538b80e0eca0d',
'pretty_version' => '7.1.2',
'version' => '7.1.2.0',
'reference' => '81d84bbc6a73b913110e155e98059526825c7ee3',
'type' => 'library',
'install_path' => __DIR__ . '/../php-mime-mail-parser/php-mime-mail-parser',
'aliases' => array(),
'dev_requirement' => false,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.6.0',
'version' => '6.6.0.0',
'reference' => 'e43bac82edc26ca04b36143a48bde1c051cfd5b1',
'pretty_version' => 'v6.12.0',
'version' => '6.12.0.0',
'reference' => 'd1ac35d784bf9f5e61b424901d5a014967f15b12',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
@@ -254,9 +245,9 @@
'dev_requirement' => false,
),
'psr/http-client' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
@@ -269,9 +260,9 @@
),
),
'psr/http-factory' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
@@ -280,13 +271,13 @@
'psr/http-factory-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
0 => '1.1',
),
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'pretty_version' => '2.0',
'version' => '2.0.0.0',
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
@@ -295,40 +286,31 @@
'psr/http-message-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
0 => '2.0',
),
),
'psr/log' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
'pretty_version' => '3.0.2',
'version' => '3.0.2.0',
'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/simple-cache' => array(
'pretty_version' => '2.0.0',
'version' => '2.0.0.0',
'reference' => '8707bf3cea6f710bf6ef05491234e3ab06f6432a',
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/simple-cache',
'aliases' => array(),
'dev_requirement' => false,
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'type' => 'library',
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
'aliases' => array(),
'dev_requirement' => false,
),
'robthree/twofactorauth' => array(
'pretty_version' => '1.8.1',
'version' => '1.8.1.0',
'reference' => '5afcb45282f1c75562a48d479ecd1732c9bdb11b',
'pretty_version' => '1.8.2',
'version' => '1.8.2.0',
'reference' => '65681de5a324eae05140ac58b08648a60212afc0',
'type' => 'library',
'install_path' => __DIR__ . '/../robthree/twofactorauth',
'aliases' => array(),
@@ -344,72 +326,117 @@
'dev_requirement' => false,
),
'stevenmaguire/oauth2-keycloak' => array(
'pretty_version' => '4.0.0',
'version' => '4.0.0.0',
'reference' => '05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d',
'pretty_version' => '6.1.1',
'version' => '6.1.1.0',
'reference' => '31bb3b1fa15b444212ed43facc898fafc7c2707a',
'type' => 'library',
'install_path' => __DIR__ . '/../stevenmaguire/oauth2-keycloak',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/clock' => array(
'pretty_version' => 'v7.4.21',
'version' => '7.4.21.0',
'reference' => '07437f612dca89c1894c1db04491002b1e798f03',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/clock',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v3.5.0',
'version' => '3.5.0.0',
'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1',
'pretty_version' => 'v3.7.1',
'version' => '3.7.1.0',
'reference' => 'f3202fa1b5097b0af062dc978b32ecf63404e31d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.24.0',
'version' => '1.24.0.0',
'reference' => '30885182c981ab175d4d034db0f6f469898070ab',
'pretty_version' => 'v1.37.0',
'version' => '1.37.0.0',
'reference' => '141046a8f9477948ff284fa65be2095baafb94f2',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec',
'pretty_version' => 'v1.43.3',
'version' => '1.43.3.0',
'reference' => '122889ed24dc000165bcbfd77ec412f15cbdfc6a',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b',
'pretty_version' => 'v1.43.0',
'version' => '1.43.0.0',
'reference' => '9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php81' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c',
'symfony/polyfill-php82' => array(
'pretty_version' => 'v1.43.0',
'version' => '1.43.0.0',
'reference' => '843bbe8b2a7934307b749751eede0f111f5d1cfc',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php81',
'install_path' => __DIR__ . '/../symfony/polyfill-php82',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php83' => array(
'pretty_version' => 'v1.43.0',
'version' => '1.43.0.0',
'reference' => '80ccff923a8d61f73ebe9da0aa94e25232f004ce',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php83',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php84' => array(
'pretty_version' => 'v1.43.0',
'version' => '1.43.0.0',
'reference' => '22c6548499cbe5c5bb072fc0c42312dff062a015',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php84',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php85' => array(
'pretty_version' => 'v1.43.0',
'version' => '1.43.0.0',
'reference' => '86a42cbcc07adc331481a5ab310a4024bfc227f6',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php85',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-time' => array(
'pretty_version' => 'v1.42.0',
'version' => '1.42.0.0',
'reference' => 'ac9f1ed802dd58f37e720388130c088434aa09fc',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-time',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/translation' => array(
'pretty_version' => 'v6.4.3',
'version' => '6.4.3.0',
'reference' => '637c51191b6b184184bbf98937702bcf554f7d04',
'pretty_version' => 'v7.4.17',
'version' => '7.4.17.0',
'reference' => '2ee1e4a3b32a528a642babe041ff7c440b213b4b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/translation-contracts' => array(
'pretty_version' => 'v3.4.1',
'version' => '3.4.1.0',
'reference' => '06450585bf65e978026bda220cdebca3f867fde7',
'pretty_version' => 'v3.7.1',
'version' => '3.7.1.0',
'reference' => 'ccb206b98faccc511ebae8e5fad50f2dc0b30621',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation-contracts',
'aliases' => array(),
@@ -422,9 +449,9 @@
),
),
'twig/twig' => array(
'pretty_version' => 'v3.14.0',
'version' => '3.14.0.0',
'reference' => '126b2c97818dbff0cdf3fbfc881aedb3d40aae72',
'pretty_version' => 'v3.30.0',
'version' => '3.30.0.0',
'reference' => '8c737079b726af72ff8ef3c595be9f6a810ea1ef',
'type' => 'library',
'install_path' => __DIR__ . '/../twig/twig',
'aliases' => array(),
+4 -5
View File
@@ -4,8 +4,8 @@
$issues = array();
if (!(PHP_VERSION_ID >= 80100)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
if (!(PHP_VERSION_ID >= 80200)) {
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
}
if ($issues) {
@@ -19,8 +19,7 @@ if ($issues) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues)
);
}
+3 -3
View File
@@ -17,7 +17,7 @@ return (new PhpCsFixer\Config())
'binary_operator_spaces' => ['default' => 'align_single_space'],
'blank_line_before_statement' => true,
'class_definition' => ['single_item_single_line' => true],
'compact_nullable_typehint' => true,
'compact_nullable_type_declaration' => true,
'concat_space' => ['spacing' => 'one'],
'echo_tag_syntax' => ['format' => 'long'],
'error_suppression' => false,
@@ -39,7 +39,7 @@ return (new PhpCsFixer\Config())
'no_null_property_initialization' => true,
'no_php4_constructor' => true,
'no_superfluous_elseif' => true,
'no_unneeded_curly_braces' => true,
'no_unneeded_braces' => true,
'no_unneeded_final_method' => true,
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
@@ -49,7 +49,7 @@ return (new PhpCsFixer\Config())
'php_unit_set_up_tear_down_visibility' => true,
'php_unit_strict' => true,
'php_unit_test_annotation' => true,
'php_unit_test_case_static_method_calls' => true,
'php_unit_test_case_static_method_calls' => false,
'php_unit_test_class_requires_covers' => false,
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_order' => true,
+20 -22
View File
@@ -2,12 +2,12 @@
[![Latest Stable Version](https://img.shields.io/packagist/v/ddeboer/imap.svg)](https://packagist.org/packages/ddeboer/imap)
[![Downloads](https://img.shields.io/packagist/dt/ddeboer/imap.svg)](https://packagist.org/packages/ddeboer/imap)
[![Integrate](https://github.com/ddeboer/imap/workflows/Integrate/badge.svg?branch=master)](https://github.com/ddeboer/imap/actions)
[![Integrate](https://github.com/ddeboer/imap/workflows/CI/badge.svg)](https://github.com/ddeboer/imap/actions)
[![Code Coverage](https://codecov.io/gh/ddeboer/imap/coverage.svg?branch=master)](https://codecov.io/gh/ddeboer/imap?branch=master)
A PHP IMAP library to read and process e-mails over IMAP protocol, built with robust Object-Oriented architecture.
This library requires PHP >= 7.4 with [IMAP](https://www.php.net/manual/en/book.imap.php),
This library requires PHP >= 8.2 with [IMAP](https://www.php.net/manual/en/book.imap.php),
[iconv](https://www.php.net/manual/en/book.iconv.php) and
[Multibyte String](https://www.php.net/manual/en/book.mbstring.php) extensions installed.
@@ -157,7 +157,7 @@ By the way most of the common search criteria are available and functioning, bro
References:
1. https://stackoverflow.com/questions/36356715/imap-search-unknown-search-criterion-or
1. imap-2007f.tar.gz: `./src/c-client/mail.c` and `./docs/internal.txt`
2. imap-2007f.tar.gz: `./src/c-client/mail.c` and `./docs/internal.txt`
#### Message Properties and Operations
@@ -182,19 +182,29 @@ $message->isDraft();
$message->isSeen();
```
Get message headers as a [\Ddeboer\Imap\Message\Headers](/src/Ddeboer/Imap/Message/Headers.php) object:
Get message headers as a [\Ddeboer\Imap\Message\Headers](/src/Message/Headers.php) object:
```php
$message->getHeaders();
```
Get message body as HTML or plain text:
Get message body as HTML or plain text (only first part):
```php
$message->getBodyHtml(); // Content of text/html part, if present
$message->getBodyText(); // Content of text/plain part, if present
```
Get complete body (all parts):
```php
$body = $message->getCompleteBodyHtml(); // Content of text/html part, if present
if ($body === null) { // If body is null, there are no HTML parts, so let's try getting the text body
$body = $message->getCompleteBodyText(); // Content of text/plain part, if present
}
```
Reading the message body keeps the message as unseen.
If you want to mark the message as seen:
@@ -284,24 +294,12 @@ Mockability is granted by interfaces present for each API.
Dig into [MockabilityTest](tests/MockabilityTest.php) for an example of a
mocked workflow.
## Running the Tests
## Contributing: run the build locally
This library is functionally tested on [Travis CI](https://travis-ci.org/ddeboer/imap)
against a local Dovecot server.
Docker is needed to run the build on your computer.
If you have your own IMAP (test) account, you can run the tests locally by
providing your IMAP credentials:
First command you need to run is `make start-imap-server`, which starts an IMAP server locally.
```bash
$ composer install
$ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="johndoe" IMAP_PASSWORD="p4ssword" vendor/bin/phpunit
```
Then the local build can be triggered with a bare `make`.
You can also copy `phpunit.xml.dist` file to a custom `phpunit.xml` and put
these environment variables in it.
**WARNING** Tests create new mailboxes without removing them.
```
$ docker-compose run tests
```
When you finish the development, stop the local IMAP server with `make stop-imap-server`.
+9 -13
View File
@@ -22,19 +22,20 @@
}
],
"require": {
"php": "^8.0.1",
"php": "~8.2.0 || ~8.3.0",
"ext-dom": "*",
"ext-iconv": "*",
"ext-imap": "*",
"ext-libxml": "*",
"ext-mbstring": "*"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^v3.4.0",
"laminas/laminas-mail": "^2.15.1",
"malukenho/mcbumpface": "^1.1.5",
"phpstan/phpstan": "^1.3.3",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpstan/phpstan-strict-rules": "^1.1.0",
"phpunit/phpunit": "^9.5.11"
"friendsofphp/php-cs-fixer": "^3.38.2",
"laminas/laminas-mail": "^2.25.1",
"phpstan/phpstan": "^1.10.43",
"phpstan/phpstan-phpunit": "^1.3.15",
"phpstan/phpstan-strict-rules": "^1.5.2",
"phpunit/phpunit": "^10.4.2"
},
"autoload": {
"psr-4": {
@@ -45,10 +46,5 @@
"psr-4": {
"Ddeboer\\Imap\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"malukenho/mcbumpface": true
}
}
}
+4 -2
View File
@@ -50,9 +50,11 @@ final class Connection implements ConnectionInterface
public function close(int $flag = 0): bool
{
$stream = $this->resource->getStream();
$this->resource->clearLastMailboxUsedCache();
return \imap_close($this->resource->getStream(), $flag);
return \imap_close($stream, $flag);
}
public function getQuota(string $root = 'INBOX'): array
@@ -61,7 +63,7 @@ final class Connection implements ConnectionInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -6,7 +6,6 @@ namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\CreateMailboxException;
use Ddeboer\Imap\Exception\DeleteMailboxException;
use Ddeboer\Imap\Exception\InvalidResourceException;
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
/**
@@ -31,8 +30,6 @@ interface ConnectionInterface extends \Countable
/**
* Check if the connection is still active.
*
* @throws InvalidResourceException If connection was closed
*/
public function ping(): bool;
@@ -4,6 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Exception;
final class InvalidResourceException extends AbstractException
final class RenameMailboxException extends AbstractException
{
}
+5 -20
View File
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\InvalidResourceException;
use Ddeboer\Imap\Exception\ReopenMailboxException;
use IMAP\Connection;
@@ -13,33 +12,21 @@ use IMAP\Connection;
*/
final class ImapResource implements ImapResourceInterface
{
/**
* @var resource
*/
private $resource;
private ?MailboxInterface $mailbox = null;
private Connection $resource;
private ?MailboxInterface $mailbox;
private static ?string $lastMailboxUsedCache = null;
/**
* Constructor.
*
* @param Connection|resource $resource
*/
public function __construct($resource, MailboxInterface $mailbox = null)
public function __construct(Connection $resource, MailboxInterface $mailbox = null)
{
$this->resource = $resource;
$this->mailbox = $mailbox;
}
public function getStream()
public function getStream(): Connection
{
if (
!$this->resource instanceof Connection
&& (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource))
) {
throw new InvalidResourceException('Supplied resource is not a valid imap resource');
}
$this->initMailbox();
return $this->resource;
@@ -76,10 +63,8 @@ final class ImapResource implements ImapResourceInterface
/**
* Check whether the current mailbox is open.
*
* @param resource $resource
*/
private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
private static function isMailboxOpen(MailboxInterface $mailbox, Connection $resource): bool
{
$currentMailboxName = $mailbox->getFullEncodedName();
if ($currentMailboxName === self::$lastMailboxUsedCache) {
@@ -4,18 +4,14 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use Ddeboer\Imap\Exception\InvalidResourceException;
use IMAP\Connection;
interface ImapResourceInterface
{
/**
* Get IMAP resource stream.
*
* @throws InvalidResourceException
*
* @return resource
*/
public function getStream();
public function getStream(): Connection;
/**
* Clear last mailbox used cache.
+19 -6
View File
@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use DateTimeInterface;
use Ddeboer\Imap\Exception\ImapNumMsgException;
use Ddeboer\Imap\Exception\ImapStatusException;
use Ddeboer\Imap\Exception\InvalidSearchCriteriaException;
use Ddeboer\Imap\Exception\MessageCopyException;
use Ddeboer\Imap\Exception\MessageMoveException;
use Ddeboer\Imap\Exception\RenameMailboxException;
use Ddeboer\Imap\Search\ConditionInterface;
use Ddeboer\Imap\Search\LogicalOperator\All;
@@ -41,6 +41,23 @@ final class Mailbox implements MailboxInterface
return $this->name;
}
public function renameTo(string $name): bool
{
$encodedName = \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8');
$oldFullName = $this->getFullEncodedName();
$newFullName = \preg_replace('/' . \preg_quote(\mb_convert_encoding($this->name, 'UTF7-IMAP', 'UTF-8')) . '$/', $encodedName, $oldFullName);
\assert(null !== $newFullName);
$return = \imap_renamemailbox($this->resource->getStream(), $oldFullName, $newFullName);
if (false === $return) {
throw new RenameMailboxException('Could not rename mailbox');
}
$this->name = $name;
$this->info->name = $newFullName;
return true;
}
public function getEncodedName(): string
{
/** @var string $name */
@@ -104,10 +121,6 @@ final class Mailbox implements MailboxInterface
}
$query = $search->toString();
if (\PHP_VERSION_ID < 80000) {
$descending = (int) $descending;
}
// We need to clear the stack to know whether imap_last_error()
// is related to this imap_search
\imap_errors();
@@ -178,7 +191,7 @@ final class Mailbox implements MailboxInterface
return $this->getMessages();
}
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool
{
$arguments = [
$this->resource->getStream(),
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap;
use DateTimeInterface;
use Ddeboer\Imap\Message\PartInterface;
use Ddeboer\Imap\Search\ConditionInterface;
@@ -20,6 +19,11 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
*/
public function getName(): string;
/**
* Set new mailbox name.
*/
public function renameTo(string $name): bool;
/**
* Get mailbox encoded path.
*/
@@ -92,7 +96,7 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
/**
* Add a message to the mailbox.
*/
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool;
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool;
/**
* Returns a tree of threaded message for the current Mailbox.
+10 -5
View File
@@ -49,7 +49,7 @@ final class Message extends Message\AbstractMessage implements MessageInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -80,7 +80,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
}
$this->messageNumberVerified = true;
$msgno = null;
\set_error_handler(static function (): bool {
return true;
});
@@ -89,7 +88,7 @@ final class Message extends Message\AbstractMessage implements MessageInterface
\restore_error_handler();
if (\is_numeric($msgno) && $msgno > 0) {
if ($msgno > 0) {
$this->imapMsgNo = $msgno;
return;
@@ -133,6 +132,14 @@ final class Message extends Message\AbstractMessage implements MessageInterface
return $this->rawMessage;
}
/**
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void
{
$this->doSaveContent($file, '');
}
public function getHeaders(): Message\Headers
{
if (null === $this->headers) {
@@ -198,8 +205,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
public function maskAsSeen(): bool
{
\trigger_error(\sprintf('%s is deprecated and will be removed in 2.0. Use %s::markAsSeen instead.', __METHOD__, __CLASS__), \E_USER_DEPRECATED);
return $this->markAsSeen();
}
@@ -203,23 +203,86 @@ abstract class AbstractMessage extends AbstractPart
}
/**
* Get body HTML.
* Get first body HTML part.
*/
final public function getBodyHtml(): ?string
{
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
return $htmlParts[0] ?? null;
}
/**
* Get all contents parts of specific subtype (self::SUBTYPE_HTML or self::SUBTYPE_PLAIN).
*
* @return string[]
*/
final public function getAllContentsBySubtype(string $subtype): array
{
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
$parts = [];
/** @var PartInterface $part */
foreach ($iterator as $part) {
if (self::SUBTYPE_HTML === $part->getSubtype()) {
return $part->getDecodedContent();
if ($subtype === $part->getSubtype()) {
$parts[] = $part->getDecodedContent();
}
}
if (\count($parts) > 0) {
return $parts;
}
// If message has no parts and is of right type, return content of message.
if ($subtype === $this->getSubtype()) {
return [$this->getDecodedContent()];
}
return [];
}
/**
* Get body HTML parts.
*
* @return string[]
*/
final public function getBodyHtmlParts(): array
{
return $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
}
/**
* Get all body HTML parts merged into 1 html.
*/
final public function getCompleteBodyHtml(): ?string
{
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
if (1 === \count($htmlParts)) {
return $htmlParts[0];
}
if (0 === \count($htmlParts)) {
return null;
}
\libxml_use_internal_errors(true); // Suppress parse errors, get errors with libxml_get_errors();
$newDom = new \DOMDocument();
$newBody = '';
$newDom->loadHTML(\implode('', $htmlParts));
$bodyTags = $newDom->getElementsByTagName('body');
foreach ($bodyTags as $body) {
foreach ($body->childNodes as $node) {
$newBody .= $newDom->saveHTML($node);
}
}
// If message has no parts and is HTML, return content of message itself.
if (self::SUBTYPE_HTML === $this->getSubtype()) {
return $this->getDecodedContent();
}
$newDom = new \DOMDocument();
$newDom->loadHTML($newBody);
return null;
$completeHtml = $newDom->saveHTML();
return false === $completeHtml ? null : $completeHtml;
}
/**
@@ -227,19 +290,28 @@ abstract class AbstractMessage extends AbstractPart
*/
final public function getBodyText(): ?string
{
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $part) {
if (self::SUBTYPE_PLAIN === $part->getSubtype()) {
return $part->getDecodedContent();
}
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
return $plainParts[0] ?? null;
}
/**
* Get all body PLAIN parts merged into 1 string.
*
* @return null|string Null if message has no PLAIN message parts
*/
final public function getCompleteBodyText(): ?string
{
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
if (1 === \count($plainParts)) {
return $plainParts[0];
}
if (0 === \count($plainParts)) {
return null;
}
// If message has no parts, return content of message itself.
if (self::SUBTYPE_PLAIN === $this->getSubtype()) {
return $this->getDecodedContent();
}
return null;
return \implode("\n", $plainParts);
}
/**
@@ -269,7 +341,7 @@ abstract class AbstractMessage extends AbstractPart
$attachments[] = $childPart;
}
if ($childPart->hasChildren()) {
$attachments = \array_merge($attachments, self::gatherAttachments($childPart));
$attachments = [...$attachments, ...self::gatherAttachments($childPart)];
}
}
@@ -56,8 +56,7 @@ abstract class AbstractPart implements PartInterface
private ?string $encoding = null;
private ?string $disposition = null;
private ?string $description = null;
/** @var null|int|string */
private $bytes;
private string|int|null $bytes;
private ?string $lines = null;
private ?string $content = null;
private ?string $decodedContent = null;
@@ -256,6 +255,26 @@ abstract class AbstractPart implements PartInterface
return $return;
}
/**
* Save raw message content to file.
*
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
final protected function doSaveContent($file, string $partNumber): void
{
$return = \imap_savebody(
$this->resource->getStream(),
$file,
$this->getNumber(),
$partNumber,
\FT_UID | \FT_PEEK
);
if (false === $return) {
throw new ImapFetchbodyException('imap_savebody failed');
}
}
final public function getParts(): array
{
$this->lazyParseStructure();
@@ -265,8 +284,6 @@ abstract class AbstractPart implements PartInterface
/**
* Get current child part.
*
* @return mixed
*/
#[\ReturnTypeWillChange]
final public function current()
@@ -360,7 +377,7 @@ abstract class AbstractPart implements PartInterface
// When the message is not multipart and the body is the attachment content
// Prevents infinite recursion
if (self::isAttachment($this->structure) && !$this instanceof Attachment) {
if (!$this instanceof Attachment && self::isAttachment($this->structure)) {
$this->parts[] = new Attachment($this->resource, $this->getNumber(), '1', $this->structure);
}
@@ -372,12 +389,11 @@ abstract class AbstractPart implements PartInterface
}
foreach ($parts as $key => $partStructure) {
$partNumber = (!$this instanceof Message) ? $this->partNumber . '.' : '';
$partNumber .= (string) ($key + 1);
$partNumber .= $key + 1;
$newPartClass = self::isAttachment($partStructure)
? Attachment::class
: SimplePart::class
;
: SimplePart::class;
$this->parts[] = new $newPartClass($this->resource, $this->getNumber(), $partNumber, $partStructure);
}
@@ -400,9 +416,9 @@ abstract class AbstractPart implements PartInterface
}
if (
'inline' === \strtolower($part->disposition)
'inline' === \strtolower($part->disposition)
&& self::SUBTYPE_PLAIN !== \strtoupper($part->subtype)
&& self::SUBTYPE_HTML !== \strtoupper($part->subtype)
&& self::SUBTYPE_HTML !== \strtoupper($part->subtype)
) {
return true;
}
@@ -427,10 +443,6 @@ abstract class AbstractPart implements PartInterface
}
*/
if (self::SUBTYPE_RFC822 === \strtoupper($part->subtype)) {
return true;
}
return false;
return self::SUBTYPE_RFC822 === \strtoupper($part->subtype);
}
}
@@ -18,6 +18,13 @@ interface BasicMessageInterface extends PartInterface
*/
public function getRawMessage(): string;
/**
* Save the raw message, including all headers, parts, etc. unencoded and unparsed to file.
*
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void;
/**
* Get message headers.
*/
@@ -109,17 +116,45 @@ interface BasicMessageInterface extends PartInterface
public function getReferences(): array;
/**
* Get body HTML.
* Get message parts by type.
*
* @return string[]
*/
public function getAllContentsBySubtype(string $subtype): array;
/**
* Get first body HTML part.
*
* @return null|string Null if message has no HTML message part
*/
public function getBodyHtml(): ?string;
/**
* Get all body HTML parts as array.
*
* @return string[]
*/
public function getBodyHtmlParts(): array;
/**
* Get all body HTML parts merged into 1 html.
*
* @return null|string Null if message has no HTML message parts
*/
public function getCompleteBodyHtml(): ?string;
/**
* Get body text.
*/
public function getBodyText(): ?string;
/**
* Get all body PLAIN parts merged into 1 string.
*
* @return null|string Null if message has no PLAIN message parts
*/
public function getCompleteBodyText(): ?string;
/**
* Get attachments (if any) linked to this e-mail.
*
@@ -38,6 +38,14 @@ final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageIn
return $this->rawMessage;
}
/**
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
*/
public function saveRawMessage($file): void
{
$this->doSaveContent($file, $this->getPartNumber());
}
/**
* Get content part number.
*/
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Message;
use Ddeboer\Imap\Exception\UnsupportedCharsetException;
final class Headers extends Parameters
{
public function __construct(\stdClass $headers)
@@ -14,7 +16,11 @@ final class Headers extends Parameters
$headers = \array_change_key_case((array) $headers);
foreach ($headers as $key => $value) {
$this[$key] = $this->parseHeader($key, $value);
try {
$this[$key] = $this->parseHeader($key, $value);
} catch (UnsupportedCharsetException) {
// safely skip header with unsupported charset
}
}
}
@@ -50,7 +56,6 @@ final class Headers extends Parameters
case 'sender':
case 'return_path':
\assert(\is_array($value));
/** @var \stdClass $address */
foreach ($value as $address) {
if (isset($address->mailbox)) {
$address->host = $address->host ?? null;
@@ -304,7 +304,7 @@ final class Transcoder
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -39,8 +39,8 @@ final class MessageIterator extends \ArrayIterator implements MessageIteratorInt
'The current value "%s" isn\'t an integer and doesn\'t represent a message;'
. ' try to cycle this "%s" with a native php function like foreach or with the method getArrayCopy(),'
. ' or check it by calling the methods valid().',
\is_object($current) ? \get_class($current) : \gettype($current),
static::class
\get_debug_type($current),
self::class
));
}
@@ -4,8 +4,6 @@ declare(strict_types=1);
namespace Ddeboer\Imap\Search;
use DateTimeInterface;
/**
* Represents a date condition.
*/
@@ -19,14 +17,14 @@ abstract class AbstractDate implements ConditionInterface
/**
* The date to be used for the condition.
*/
private DateTimeInterface $date;
private \DateTimeInterface $date;
/**
* Constructor.
*
* @param DateTimeInterface $date optional date for the condition
* @param \DateTimeInterface $date optional date for the condition
*/
public function __construct(DateTimeInterface $date, string $dateFormat = 'j-M-Y')
public function __construct(\DateTimeInterface $date, string $dateFormat = 'j-M-Y')
{
$this->date = $date;
$this->dateFormat = $dateFormat;
+1 -1
View File
@@ -67,7 +67,7 @@ final class Server implements ServerInterface
$errorNumber = 0;
\set_error_handler(static function ($nr, $message) use (&$errorMessage, &$errorNumber): bool {
$errorMessage = $message;
$errorNumber = $nr;
$errorNumber = $nr;
return true;
});
@@ -36,8 +36,8 @@
"psr/log": "*",
"nesbot/carbon": "*",
"psr/simple-cache": "^1.0|^2.0|^3.0",
"illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0",
"illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0"
"illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
"illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
@@ -3,7 +3,9 @@
namespace LdapRecord\Auth;
use Exception;
use LdapRecord\Configuration\ConfigurationException;
use LdapRecord\Configuration\DomainConfiguration;
use LdapRecord\ConnectionException;
use LdapRecord\Events\DispatcherInterface;
use LdapRecord\LdapInterface;
@@ -71,7 +73,7 @@ class Guard
* Attempt binding a user to the LDAP server. Supports sasl and anonymous binding.
*
* @throws BindException
* @throws \LdapRecord\ConnectionException
* @throws ConnectionException
*/
public function bind(?string $username = null, ?string $password = null): void
{
@@ -102,7 +104,7 @@ class Guard
/**
* Authenticate by binding to the LDAP server.
*
* @throws \LdapRecord\ConnectionException
* @throws ConnectionException
*/
protected function authenticate(?string $username = null, ?string $password = null): bool
{
@@ -119,8 +121,8 @@ class Guard
* Bind to the LDAP server using the configured username and password.
*
* @throws BindException
* @throws \LdapRecord\ConnectionException
* @throws \LdapRecord\Configuration\ConfigurationException
* @throws ConnectionException
* @throws ConfigurationException
*/
public function bindAsConfiguredUser(): void
{
@@ -89,7 +89,7 @@ class Connection
/**
* Set the connection configuration.
*
* @throws Configuration\ConfigurationException
* @throws ConfigurationException
*/
public function setConfiguration(DomainConfiguration|array $config = []): void
{
@@ -3,6 +3,8 @@
namespace LdapRecord;
use LDAP\Connection as RawLdapConnection;
use Ldap\Result;
use Ldap\ResultEntry;
class Ldap implements LdapInterface
{
@@ -24,7 +26,7 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-first-entry.php
*
* @param \Ldap\Result $result
* @param Result $result
*/
public function getFirstEntry(mixed $result): mixed
{
@@ -38,7 +40,7 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-next-entry.php
*
* @param \Ldap\ResultEntry $entry
* @param ResultEntry $entry
*/
public function getNextEntry(mixed $entry): mixed
{
@@ -52,7 +54,7 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-get-attributes.php
*
* @param \Ldap\ResultEntry $entry
* @param ResultEntry $entry
*/
public function getAttributes(mixed $entry): array|false
{
@@ -3,6 +3,7 @@
namespace LdapRecord;
use LDAP\Connection;
use LDAP\Result;
/**
* @see https://ldap.com/ldap-oid-reference-guide
@@ -339,7 +340,7 @@ interface LdapInterface
*
* @see http://php.net/manual/en/function.ldap-get-entries.php
*
* @param \LDAP\Result $result
* @param Result $result
*/
public function getEntries(mixed $result): array;
@@ -348,7 +349,7 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-first-entry.php
*
* @param \LDAP\Result $result
* @param Result $result
*/
public function getFirstEntry(mixed $result): mixed;
@@ -357,7 +358,7 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-next-entry.php
*
* @param \LDAP\Result $entry
* @param Result $entry
*/
public function getNextEntry(mixed $entry): mixed;
@@ -366,14 +367,14 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-get-attributes.php
*
* @param \LDAP\Result $entry
* @param Result $entry
*/
public function getAttributes(mixed $entry): array|false;
/**
* Reads all the values of the attribute in the entry in the result.
*
* @param \LDAP\Result $entry
* @param Result $entry
*/
public function getValuesLen(mixed $entry, string $attribute): array|false;
@@ -398,7 +399,7 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-count-entries.php
*
* @param \LDAP\Result $result
* @param Result $result
*/
public function countEntries(mixed $result): int;
@@ -463,7 +464,7 @@ interface LdapInterface
*
* @see http://php.net/manual/en/function.ldap-search.php
*
* @return \LDAP\Result
* @return Result
*/
public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
@@ -472,7 +473,7 @@ interface LdapInterface
*
* @see http://php.net/manual/en/function.ldap-list.php
*
* @return \LDAP\Result
* @return Result
*/
public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
@@ -481,7 +482,7 @@ interface LdapInterface
*
* @see http://php.net/manual/en/function.ldap-read.php
*
* @return \LDAP\Result
* @return Result
*/
public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
@@ -490,7 +491,7 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-parse-result.php
*
* @param \LDAP\Result $result
* @param Result $result
*/
public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false;
@@ -595,7 +596,7 @@ interface LdapInterface
*
* @see https://www.php.net/manual/en/function.ldap-free-result.php
*
* @param \LDAP\Result $result
* @param Result $result
*/
public function freeResult(mixed $result): bool;
@@ -4,6 +4,7 @@ namespace LdapRecord\Models\ActiveDirectory;
use InvalidArgumentException;
use LdapRecord\Connection;
use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\Sid;
use LdapRecord\Models\Entry as BaseEntry;
use LdapRecord\Models\Events\Updated;
@@ -99,7 +100,7 @@ class Entry extends BaseEntry implements ActiveDirectory
/**
* Restore a deleted object.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function restore(?string $newParentDn = null): bool
{
@@ -4,6 +4,7 @@ namespace LdapRecord\Models\ActiveDirectory\Scopes;
use LdapRecord\Models\ActiveDirectory\Entry;
use LdapRecord\Models\Model;
use LdapRecord\Models\ModelNotFoundException;
use LdapRecord\Models\Scope;
use LdapRecord\Query\Model\Builder;
@@ -12,7 +13,7 @@ class InConfigurationContext implements Scope
/**
* Refines the base dn to be inside the configuration context.
*
* @throws \LdapRecord\Models\ModelNotFoundException
* @throws ModelNotFoundException
*/
public function apply(Builder $query, Model $model): void
{
@@ -22,7 +23,7 @@ class InConfigurationContext implements Scope
/**
* Get the LDAP server configuration naming context distinguished name.
*
* @throws \LdapRecord\Models\ModelNotFoundException
* @throws ModelNotFoundException
*/
protected function getConfigurationNamingContext(Model $model)
{
@@ -2,7 +2,9 @@
namespace LdapRecord\Models\Concerns;
/** @mixin \LdapRecord\Models\Model */
use LdapRecord\Models\Model;
/** @mixin Model */
trait CanAuthenticate
{
/**
@@ -6,9 +6,10 @@ use Closure;
use LdapRecord\Events\NullDispatcher;
use LdapRecord\Models\Events;
use LdapRecord\Models\Events\Event;
use LdapRecord\Models\Model;
use LdapRecord\Support\Arr;
/** @mixin \LdapRecord\Models\Model */
/** @mixin Model */
trait HasEvents
{
/**
@@ -4,9 +4,10 @@ namespace LdapRecord\Models\Concerns;
use Closure;
use InvalidArgumentException;
use LdapRecord\Models\Model;
use LdapRecord\Models\Scope;
/** @mixin \LdapRecord\Models\Model */
/** @mixin Model */
trait HasGlobalScopes
{
/**
@@ -5,8 +5,9 @@ namespace LdapRecord\Models\Concerns;
use LdapRecord\ConnectionException;
use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\Password;
use LdapRecord\Models\Model;
/** @mixin \LdapRecord\Models\Model */
/** @mixin Model */
trait HasPassword
{
/**
@@ -2,9 +2,10 @@
namespace LdapRecord\Models\Concerns;
use LdapRecord\Models\Model;
use LdapRecord\Query\Model\Builder;
/** @mixin \LdapRecord\Models\Model */
/** @mixin Model */
trait HasScopes
{
/**
@@ -2,12 +2,14 @@
namespace LdapRecord\Models\Concerns;
use LdapRecord\Models\Model;
/**
* @author Taylor Otwell
*
* @see https://laravel.com
*
* @mixin \LdapRecord\Models\Model
* @mixin Model
*/
trait HidesAttributes
{
@@ -9,6 +9,7 @@ use JsonSerializable;
use LdapRecord\Connection;
use LdapRecord\Container;
use LdapRecord\EscapesValues;
use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\DistinguishedName;
use LdapRecord\Models\Attributes\Guid;
use LdapRecord\Query\Builder as BaseBuilder;
@@ -246,7 +247,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Get the RootDSE (AD schema) record from the directory.
*
* @throws \LdapRecord\Models\ModelNotFoundException
* @throws ModelNotFoundException
*/
public static function getRootDse(?string $connection = null): Model
{
@@ -919,7 +920,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Save the model to the directory without raising any events.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function saveQuietly(array $attributes = []): void
{
@@ -931,7 +932,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Save the model to the directory.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function save(array $attributes = []): void
{
@@ -951,7 +952,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Inserts the model into the directory.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
protected function performInsert(): void
{
@@ -998,7 +999,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Updates the model in the directory.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
protected function performUpdate(): void
{
@@ -1020,7 +1021,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Create the model in the directory.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public static function create(array $attributes = []): static
{
@@ -1035,7 +1036,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* Add an attribute on the model with the given value.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function addAttribute(string $attribute, mixed $value): void
{
@@ -1054,7 +1055,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* Update the model.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function update(array $attributes = []): void
{
@@ -1067,7 +1068,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* Update the model attribute with the specified value.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function replaceAttribute(string $attribute, mixed $value): void
{
@@ -1085,7 +1086,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Destroy the models for the given distinguished names.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public static function destroy(mixed $dns, bool $recursive = false): int
{
@@ -1121,7 +1122,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* not exist or does not contain a distinguished name.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function delete(bool $recursive = false): void
{
@@ -1146,7 +1147,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
/**
* Deletes leaf nodes that are attached to the model.
*
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
protected function deleteLeafNodes(): void
{
@@ -1162,7 +1163,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* Remove an attribute on the model.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function removeAttribute(string $attribute, mixed $value = null): void
{
@@ -1181,7 +1182,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* ["memberuid" => []]
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function removeAttributes(array|string $attributes): void
{
@@ -1238,7 +1239,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
*
* @throws UnexpectedValueException
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function move(Model|string $newParentDn, bool $deleteOldRdn = true): void
{
@@ -1255,7 +1256,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
* Rename the model to a new RDN and new parent.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
* @throws LdapRecordException
*/
public function rename(string $rdn, Model|string|null $newParentDn = null, bool $deleteOldRdn = true): void
{
Loaded 100 of 1299 files, more files were not shown because too many files have changed in this diff. Show more