mirror of
https://github.com/wallabag/wallabag.git
synced 2025-02-28 08:26:29 +00:00
Merge pull request #7947 from wallabag/migrate-from-guzzle-to-symfony-httpclient
Migrate from Guzzle to Symfony HttpClient
This commit is contained in:
commit
8e0b9d4d94
14 changed files with 661 additions and 1303 deletions
|
@ -32,7 +32,6 @@ class AppKernel extends Kernel
|
||||||
new BabDev\PagerfantaBundle\BabDevPagerfantaBundle(),
|
new BabDev\PagerfantaBundle\BabDevPagerfantaBundle(),
|
||||||
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
|
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
|
||||||
new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
|
new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
|
||||||
new Http\HttplugBundle\HttplugBundle(),
|
|
||||||
new Sentry\SentryBundle\SentryBundle(),
|
new Sentry\SentryBundle\SentryBundle(),
|
||||||
new Twig\Extra\TwigExtraBundle\TwigExtraBundle(),
|
new Twig\Extra\TwigExtraBundle\TwigExtraBundle(),
|
||||||
new Symfony\WebpackEncoreBundle\WebpackEncoreBundle(),
|
new Symfony\WebpackEncoreBundle\WebpackEncoreBundle(),
|
||||||
|
|
|
@ -48,6 +48,10 @@ framework:
|
||||||
X-Accept: 'application/json'
|
X-Accept: 'application/json'
|
||||||
request_html_function.client:
|
request_html_function.client:
|
||||||
scope: '.*'
|
scope: '.*'
|
||||||
|
browser.client:
|
||||||
|
scope: '.*'
|
||||||
|
verify_host: false
|
||||||
|
verify_peer: false
|
||||||
|
|
||||||
# Twig Configuration
|
# Twig Configuration
|
||||||
twig:
|
twig:
|
||||||
|
@ -452,17 +456,6 @@ sensio_framework_extra:
|
||||||
router:
|
router:
|
||||||
annotations: false
|
annotations: false
|
||||||
|
|
||||||
httplug:
|
|
||||||
clients:
|
|
||||||
wallabag:
|
|
||||||
factory: Wallabag\Helper\HttpClientFactory
|
|
||||||
config:
|
|
||||||
defaults:
|
|
||||||
timeout: 10
|
|
||||||
plugins: ['httplug.plugin.logger']
|
|
||||||
discovery:
|
|
||||||
client: false
|
|
||||||
|
|
||||||
# define custom entity so we can override length attribute to fix utf8mb4 issue
|
# define custom entity so we can override length attribute to fix utf8mb4 issue
|
||||||
craue_config:
|
craue_config:
|
||||||
entity_name: Wallabag\Entity\InternalSetting
|
entity_name: Wallabag\Entity\InternalSetting
|
||||||
|
|
|
@ -191,11 +191,17 @@ services:
|
||||||
tags:
|
tags:
|
||||||
- { name: doctrine.event_subscriber }
|
- { name: doctrine.event_subscriber }
|
||||||
|
|
||||||
|
psr18.wallabag.client:
|
||||||
|
class: Symfony\Component\HttpClient\Psr18Client
|
||||||
|
arguments:
|
||||||
|
$client: '@Wallabag\HttpClient\WallabagClient'
|
||||||
|
|
||||||
Graby\Graby:
|
Graby\Graby:
|
||||||
arguments:
|
arguments:
|
||||||
$config:
|
$config:
|
||||||
error_message: '%wallabag.fetching_error_message%'
|
error_message: '%wallabag.fetching_error_message%'
|
||||||
error_message_title: '%wallabag.fetching_error_message_title%'
|
error_message_title: '%wallabag.fetching_error_message_title%'
|
||||||
|
$client: '@psr18.wallabag.client'
|
||||||
calls:
|
calls:
|
||||||
- [ setLogger, [ "@logger" ] ]
|
- [ setLogger, [ "@logger" ] ]
|
||||||
tags:
|
tags:
|
||||||
|
@ -205,9 +211,6 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$config: {}
|
$config: {}
|
||||||
|
|
||||||
wallabag.http_client:
|
|
||||||
alias: 'httplug.client.wallabag'
|
|
||||||
|
|
||||||
Wallabag\SiteConfig\GrabySiteConfigBuilder:
|
Wallabag\SiteConfig\GrabySiteConfigBuilder:
|
||||||
tags:
|
tags:
|
||||||
- { name: monolog.logger, channel: graby }
|
- { name: monolog.logger, channel: graby }
|
||||||
|
@ -216,11 +219,9 @@ services:
|
||||||
Wallabag\SiteConfig\SiteConfigBuilder:
|
Wallabag\SiteConfig\SiteConfigBuilder:
|
||||||
alias: Wallabag\SiteConfig\GrabySiteConfigBuilder
|
alias: Wallabag\SiteConfig\GrabySiteConfigBuilder
|
||||||
|
|
||||||
GuzzleHttp\Cookie\CookieJar: ~
|
Symfony\Component\BrowserKit\HttpBrowser:
|
||||||
|
arguments:
|
||||||
Wallabag\Helper\HttpClientFactory:
|
$client: '@browser.client'
|
||||||
calls:
|
|
||||||
- ['addSubscriber', ['@Wallabag\Guzzle\AuthenticatorSubscriber']]
|
|
||||||
|
|
||||||
RulerZ\RulerZ:
|
RulerZ\RulerZ:
|
||||||
alias: rulerz
|
alias: rulerz
|
||||||
|
|
|
@ -29,8 +29,6 @@ $config
|
||||||
'mnapoli/piwik-twig-extension',
|
'mnapoli/piwik-twig-extension',
|
||||||
'ocramius/proxy-manager',
|
'ocramius/proxy-manager',
|
||||||
'pagerfanta/twig',
|
'pagerfanta/twig',
|
||||||
'php-http/client-common',
|
|
||||||
'php-http/httplug',
|
|
||||||
'php-http/mock-client',
|
'php-http/mock-client',
|
||||||
'phpstan/extension-installer',
|
'phpstan/extension-installer',
|
||||||
'phpstan/phpstan',
|
'phpstan/phpstan',
|
||||||
|
@ -39,13 +37,11 @@ $config
|
||||||
'phpstan/phpstan-symfony',
|
'phpstan/phpstan-symfony',
|
||||||
'psr/http-client',
|
'psr/http-client',
|
||||||
'psr/http-factory',
|
'psr/http-factory',
|
||||||
'psr/http-message',
|
|
||||||
'rulerz-php/doctrine-orm',
|
'rulerz-php/doctrine-orm',
|
||||||
'scheb/2fa-qr-code',
|
'scheb/2fa-qr-code',
|
||||||
'scheb/2fa-trusted-device',
|
'scheb/2fa-trusted-device',
|
||||||
'shipmonk/composer-dependency-analyser',
|
'shipmonk/composer-dependency-analyser',
|
||||||
'symfony/asset',
|
'symfony/asset',
|
||||||
'symfony/browser-kit',
|
|
||||||
'symfony/css-selector',
|
'symfony/css-selector',
|
||||||
'symfony/doctrine-bridge',
|
'symfony/doctrine-bridge',
|
||||||
'symfony/google-mailer',
|
'symfony/google-mailer',
|
||||||
|
@ -57,10 +53,8 @@ $config
|
||||||
'twig/string-extra',
|
'twig/string-extra',
|
||||||
], [ErrorType::UNUSED_DEPENDENCY])
|
], [ErrorType::UNUSED_DEPENDENCY])
|
||||||
->ignoreErrorsOnPackages([
|
->ignoreErrorsOnPackages([
|
||||||
'guzzlehttp/streams',
|
|
||||||
'monolog/monolog',
|
'monolog/monolog',
|
||||||
'symfony/filesystem',
|
'symfony/filesystem',
|
||||||
'symfony/http-client',
|
|
||||||
], [ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV])
|
], [ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV])
|
||||||
->ignoreErrorsOnPackages([
|
->ignoreErrorsOnPackages([
|
||||||
'dama/doctrine-test-bundle',
|
'dama/doctrine-test-bundle',
|
||||||
|
|
|
@ -75,9 +75,7 @@
|
||||||
"friendsofsymfony/oauth-server-bundle": "dev-master#dc8ff343363cf794d30eb1a123610d186a43f162",
|
"friendsofsymfony/oauth-server-bundle": "dev-master#dc8ff343363cf794d30eb1a123610d186a43f162",
|
||||||
"friendsofsymfony/rest-bundle": "^3.6",
|
"friendsofsymfony/rest-bundle": "^3.6",
|
||||||
"friendsofsymfony/user-bundle": "^3.2.1",
|
"friendsofsymfony/user-bundle": "^3.2.1",
|
||||||
"guzzlehttp/guzzle": "^5.3.4",
|
|
||||||
"guzzlehttp/psr7": "^2.6.2",
|
"guzzlehttp/psr7": "^2.6.2",
|
||||||
"guzzlehttp/streams": "^3.0",
|
|
||||||
"html2text/html2text": "^4.3.1",
|
"html2text/html2text": "^4.3.1",
|
||||||
"incenteev/composer-parameter-handler": "^2.2",
|
"incenteev/composer-parameter-handler": "^2.2",
|
||||||
"j0k3r/graby": "^2.4.5",
|
"j0k3r/graby": "^2.4.5",
|
||||||
|
@ -99,10 +97,6 @@
|
||||||
"pagerfanta/twig": "^3.8",
|
"pagerfanta/twig": "^3.8",
|
||||||
"php-amqplib/php-amqplib": "^3.6.1",
|
"php-amqplib/php-amqplib": "^3.6.1",
|
||||||
"php-amqplib/rabbitmq-bundle": "^2.14.0",
|
"php-amqplib/rabbitmq-bundle": "^2.14.0",
|
||||||
"php-http/client-common": "^2.7.1",
|
|
||||||
"php-http/guzzle5-adapter": "^2.0",
|
|
||||||
"php-http/httplug": "^2.4",
|
|
||||||
"php-http/httplug-bundle": "^1.32",
|
|
||||||
"pragmarx/recovery": "^0.2.1",
|
"pragmarx/recovery": "^0.2.1",
|
||||||
"predis/predis": "^2.2.2",
|
"predis/predis": "^2.2.2",
|
||||||
"psr/http-client": "^1.0.3",
|
"psr/http-client": "^1.0.3",
|
||||||
|
@ -122,6 +116,7 @@
|
||||||
"spiriitlabs/form-filter-bundle": "^10.0",
|
"spiriitlabs/form-filter-bundle": "^10.0",
|
||||||
"stof/doctrine-extensions-bundle": "^1.11.0",
|
"stof/doctrine-extensions-bundle": "^1.11.0",
|
||||||
"symfony/asset": "^5.4.35",
|
"symfony/asset": "^5.4.35",
|
||||||
|
"symfony/browser-kit": "^5.4.35",
|
||||||
"symfony/config": "^5.4.35",
|
"symfony/config": "^5.4.35",
|
||||||
"symfony/console": "^5.4.35",
|
"symfony/console": "^5.4.35",
|
||||||
"symfony/dependency-injection": "^5.4.35",
|
"symfony/dependency-injection": "^5.4.35",
|
||||||
|
@ -182,7 +177,6 @@
|
||||||
"phpstan/phpstan-symfony": "^1.3.7",
|
"phpstan/phpstan-symfony": "^1.3.7",
|
||||||
"phpunit/phpunit": "^9.6.17",
|
"phpunit/phpunit": "^9.6.17",
|
||||||
"shipmonk/composer-dependency-analyser": "^1.7",
|
"shipmonk/composer-dependency-analyser": "^1.7",
|
||||||
"symfony/browser-kit": "^5.4.35",
|
|
||||||
"symfony/css-selector": "^5.4.35",
|
"symfony/css-selector": "^5.4.35",
|
||||||
"symfony/debug-bundle": "^5.4.35",
|
"symfony/debug-bundle": "^5.4.35",
|
||||||
"symfony/maker-bundle": "^1.43",
|
"symfony/maker-bundle": "^1.43",
|
||||||
|
|
751
composer.lock
generated
751
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "1f0877b1f0f7fc3b074786b51d772cb6",
|
"content-hash": "a85056bec7fa90b9be4aa16c34464c0e",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "babdev/pagerfanta-bundle",
|
"name": "babdev/pagerfanta-bundle",
|
||||||
|
@ -2980,63 +2980,6 @@
|
||||||
},
|
},
|
||||||
"time": "2015-05-14T08:18:23+00:00"
|
"time": "2015-05-14T08:18:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "guzzlehttp/guzzle",
|
|
||||||
"version": "5.3.4",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/guzzle.git",
|
|
||||||
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b87eda7a7162f95574032da17e9323c9899cb6b2",
|
|
||||||
"reference": "b87eda7a7162f95574032da17e9323c9899cb6b2",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"guzzlehttp/ringphp": "^1.1",
|
|
||||||
"php": ">=5.4.0",
|
|
||||||
"react/promise": "^2.2"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"phpunit/phpunit": "^4.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
|
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"keywords": [
|
|
||||||
"client",
|
|
||||||
"curl",
|
|
||||||
"framework",
|
|
||||||
"http",
|
|
||||||
"http client",
|
|
||||||
"rest",
|
|
||||||
"web service"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
|
||||||
"source": "https://github.com/guzzle/guzzle/tree/5.3"
|
|
||||||
},
|
|
||||||
"time": "2019-10-30T09:32:00+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/psr7",
|
"name": "guzzlehttp/psr7",
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
|
@ -3153,117 +3096,6 @@
|
||||||
],
|
],
|
||||||
"time": "2024-07-18T11:15:46+00:00"
|
"time": "2024-07-18T11:15:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "guzzlehttp/ringphp",
|
|
||||||
"version": "1.1.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/RingPHP.git",
|
|
||||||
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b",
|
|
||||||
"reference": "5e2a174052995663dd68e6b5ad838afd47dd615b",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"guzzlehttp/streams": "~3.0",
|
|
||||||
"php": ">=5.4.0",
|
|
||||||
"react/promise": "~2.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"phpunit/phpunit": "~4.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"ext-curl": "Guzzle will use specific adapters if cURL is present"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.1-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\Ring\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/RingPHP/issues",
|
|
||||||
"source": "https://github.com/guzzle/RingPHP/tree/1.1.1"
|
|
||||||
},
|
|
||||||
"abandoned": true,
|
|
||||||
"time": "2018-07-31T13:22:33+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "guzzlehttp/streams",
|
|
||||||
"version": "3.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/streams.git",
|
|
||||||
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
|
|
||||||
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.4.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "~4.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.0-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"GuzzleHttp\\Stream\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Provides a simple abstraction over streams of data",
|
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"keywords": [
|
|
||||||
"Guzzle",
|
|
||||||
"stream"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/guzzle/streams/issues",
|
|
||||||
"source": "https://github.com/guzzle/streams/tree/master"
|
|
||||||
},
|
|
||||||
"abandoned": true,
|
|
||||||
"time": "2014-10-12T19:18:40+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "hoa/compiler",
|
"name": "hoa/compiler",
|
||||||
"version": "3.17.08.08",
|
"version": "3.17.08.08",
|
||||||
|
@ -6511,74 +6343,6 @@
|
||||||
},
|
},
|
||||||
"time": "2024-10-02T11:20:13+00:00"
|
"time": "2024-10-02T11:20:13+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-http/guzzle5-adapter",
|
|
||||||
"version": "2.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/guzzle5-adapter.git",
|
|
||||||
"reference": "cce48360b1f8a3467bd94e853e6107aa4532008e"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/guzzle5-adapter/zipball/cce48360b1f8a3467bd94e853e6107aa4532008e",
|
|
||||||
"reference": "cce48360b1f8a3467bd94e853e6107aa4532008e",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"guzzlehttp/guzzle": "^5.1",
|
|
||||||
"php": "^7.0",
|
|
||||||
"php-http/discovery": "^1.0",
|
|
||||||
"php-http/httplug": "^2.0"
|
|
||||||
},
|
|
||||||
"provide": {
|
|
||||||
"php-http/client-implementation": "1.0",
|
|
||||||
"psr/http-client-implementation": "1.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"guzzlehttp/ringphp": "^1.1",
|
|
||||||
"php-http/client-integration-tests": "^2.0",
|
|
||||||
"phpunit/phpunit": "^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.0-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Adapter\\Guzzle5\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Eric GELOEN",
|
|
||||||
"email": "geloen.eric@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle 5 HTTP Adapter",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"Guzzle",
|
|
||||||
"http"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/guzzle5-adapter/issues",
|
|
||||||
"source": "https://github.com/php-http/guzzle5-adapter/tree/2.0.0"
|
|
||||||
},
|
|
||||||
"abandoned": "php-http/guzzle7-adapter",
|
|
||||||
"time": "2019-02-05T12:28:45+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "php-http/httplug",
|
"name": "php-http/httplug",
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
|
@ -6636,169 +6400,6 @@
|
||||||
},
|
},
|
||||||
"time": "2024-09-23T11:39:58+00:00"
|
"time": "2024-09-23T11:39:58+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-http/httplug-bundle",
|
|
||||||
"version": "1.34.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/HttplugBundle.git",
|
|
||||||
"reference": "87c61d27c025dd9d699a2208a6d06be58061e433"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/HttplugBundle/zipball/87c61d27c025dd9d699a2208a6d06be58061e433",
|
|
||||||
"reference": "87c61d27c025dd9d699a2208a6d06be58061e433",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.3 || ^8.0",
|
|
||||||
"php-http/client-common": "^1.9 || ^2.0",
|
|
||||||
"php-http/client-implementation": "^1.0",
|
|
||||||
"php-http/discovery": "^1.14",
|
|
||||||
"php-http/httplug": "^2.0",
|
|
||||||
"php-http/logger-plugin": "^1.1",
|
|
||||||
"php-http/message": "^1.13",
|
|
||||||
"php-http/message-factory": "^1.0.2",
|
|
||||||
"php-http/stopwatch-plugin": "^1.2",
|
|
||||||
"psr/http-message": "^1.0 || ^2.0",
|
|
||||||
"symfony/config": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/http-kernel": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/options-resolver": "^4.4 || ^5.0 || ^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"php-http/cache-plugin": "<1.7.0",
|
|
||||||
"php-http/curl-client": "<2.0",
|
|
||||||
"php-http/guzzle6-adapter": "<1.1",
|
|
||||||
"php-http/socket-client": "<2.0",
|
|
||||||
"php-http/throttle-plugin": "<1.1"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"guzzlehttp/psr7": "^1.7 || ^2.0",
|
|
||||||
"matthiasnoback/symfony-config-test": "^4.3 || ^5.0",
|
|
||||||
"matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0",
|
|
||||||
"nyholm/nsa": "^1.1",
|
|
||||||
"nyholm/psr7": "^1.2.1",
|
|
||||||
"php-http/cache-plugin": "^1.7",
|
|
||||||
"php-http/mock-client": "^1.2",
|
|
||||||
"php-http/promise": "^1.0",
|
|
||||||
"phpunit/phpunit": "^9.6",
|
|
||||||
"symfony/browser-kit": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/cache": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/http-foundation": "^4.4.19 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/stopwatch": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"symfony/web-profiler-bundle": "^4.4.19 || ^5.0 || ^6.0 || ^7.0",
|
|
||||||
"twig/twig": "^1.41 || ^2.10 || ^3.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"php-http/cache-plugin": "To configure clients that cache responses",
|
|
||||||
"php-http/mock-client": "Add this to your require-dev section to mock HTTP responses easily",
|
|
||||||
"twig/twig": "Add this to your require-dev section when using the WebProfilerBundle"
|
|
||||||
},
|
|
||||||
"type": "symfony-bundle",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\HttplugBundle\\": "src/"
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/Resources/MyPsr18TestClient.php"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "David Buchmann",
|
|
||||||
"email": "mail@davidbu.ch"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tobias Nyholm",
|
|
||||||
"email": "tobias.nyholm@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony integration for HTTPlug",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"adapter",
|
|
||||||
"bundle",
|
|
||||||
"discovery",
|
|
||||||
"factory",
|
|
||||||
"http",
|
|
||||||
"httplug",
|
|
||||||
"message",
|
|
||||||
"php-http"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/HttplugBundle/issues",
|
|
||||||
"source": "https://github.com/php-http/HttplugBundle/tree/1.34.3"
|
|
||||||
},
|
|
||||||
"time": "2024-09-01T08:25:40+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "php-http/logger-plugin",
|
|
||||||
"version": "1.3.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/logger-plugin.git",
|
|
||||||
"reference": "bf47eb5cb379962d276c94da14861669c2313563"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/logger-plugin/zipball/bf47eb5cb379962d276c94da14861669c2313563",
|
|
||||||
"reference": "bf47eb5cb379962d276c94da14861669c2313563",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.0 || ^8.0",
|
|
||||||
"php-http/client-common": "^1.9 || ^2.0",
|
|
||||||
"php-http/message": "^1.0",
|
|
||||||
"psr/log": "^1.0 || ^2 || ^3",
|
|
||||||
"symfony/polyfill-php73": "^1.17"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpspec/phpspec": "^5.1 || ^6.0"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.2-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Client\\Common\\Plugin\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PSR-3 Logger plugin for HTTPlug",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"http",
|
|
||||||
"httplug",
|
|
||||||
"logger",
|
|
||||||
"plugin"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/logger-plugin/issues",
|
|
||||||
"source": "https://github.com/php-http/logger-plugin/tree/1.3.1"
|
|
||||||
},
|
|
||||||
"time": "2024-09-01T06:51:51+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "php-http/message",
|
"name": "php-http/message",
|
||||||
"version": "1.16.2",
|
"version": "1.16.2",
|
||||||
|
@ -6975,64 +6576,6 @@
|
||||||
},
|
},
|
||||||
"time": "2024-03-15T13:55:21+00:00"
|
"time": "2024-03-15T13:55:21+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "php-http/stopwatch-plugin",
|
|
||||||
"version": "1.4.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-http/stopwatch-plugin.git",
|
|
||||||
"reference": "11862cfbc719afade4ff407964ab3fbfe9ec2baa"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-http/stopwatch-plugin/zipball/11862cfbc719afade4ff407964ab3fbfe9ec2baa",
|
|
||||||
"reference": "11862cfbc719afade4ff407964ab3fbfe9ec2baa",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": "^7.3 || ^8.0",
|
|
||||||
"php-http/client-common": "^1.9 || ^2.0",
|
|
||||||
"symfony/stopwatch": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"guzzlehttp/psr7": "^2.1",
|
|
||||||
"symfony/phpunit-bridge": "^6.4.1"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.3-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Http\\Client\\Common\\Plugin\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Márk Sági-Kazár",
|
|
||||||
"email": "mark.sagikazar@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Stopwatch plugin for HTTPlug",
|
|
||||||
"homepage": "http://httplug.io",
|
|
||||||
"keywords": [
|
|
||||||
"http",
|
|
||||||
"httplug",
|
|
||||||
"plugin",
|
|
||||||
"stopwatch"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-http/stopwatch-plugin/issues",
|
|
||||||
"source": "https://github.com/php-http/stopwatch-plugin/tree/1.4.2"
|
|
||||||
},
|
|
||||||
"time": "2023-12-05T14:36:57+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "phpdocumentor/reflection-common",
|
"name": "phpdocumentor/reflection-common",
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
|
@ -8126,78 +7669,6 @@
|
||||||
},
|
},
|
||||||
"time": "2019-03-08T08:55:37+00:00"
|
"time": "2019-03-08T08:55:37+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "react/promise",
|
|
||||||
"version": "v2.11.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/reactphp/promise.git",
|
|
||||||
"reference": "1a8460931ea36dc5c76838fec5734d55c88c6831"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/1a8460931ea36dc5c76838fec5734d55c88c6831",
|
|
||||||
"reference": "1a8460931ea36dc5c76838fec5734d55c88c6831",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.4.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"files": [
|
|
||||||
"src/functions_include.php"
|
|
||||||
],
|
|
||||||
"psr-4": {
|
|
||||||
"React\\Promise\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Jan Sorgalla",
|
|
||||||
"email": "jsorgalla@gmail.com",
|
|
||||||
"homepage": "https://sorgalla.com/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Christian Lück",
|
|
||||||
"email": "christian@clue.engineering",
|
|
||||||
"homepage": "https://clue.engineering/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Cees-Jan Kiewiet",
|
|
||||||
"email": "reactphp@ceesjankiewiet.nl",
|
|
||||||
"homepage": "https://wyrihaximus.net/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Chris Boden",
|
|
||||||
"email": "cboden@gmail.com",
|
|
||||||
"homepage": "https://cboden.dev/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
|
||||||
"keywords": [
|
|
||||||
"promise",
|
|
||||||
"promises"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/reactphp/promise/issues",
|
|
||||||
"source": "https://github.com/reactphp/promise/tree/v2.11.0"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://opencollective.com/reactphp",
|
|
||||||
"type": "open_collective"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2023-11-16T16:16:50+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "rulerz-php/doctrine-orm",
|
"name": "rulerz-php/doctrine-orm",
|
||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
|
@ -9325,6 +8796,78 @@
|
||||||
],
|
],
|
||||||
"time": "2024-10-22T13:05:35+00:00"
|
"time": "2024-10-22T13:05:35+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/browser-kit",
|
||||||
|
"version": "v5.4.45",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/browser-kit.git",
|
||||||
|
"reference": "03cce39764429e07fbab9b989a1182a24578341d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/03cce39764429e07fbab9b989a1182a24578341d",
|
||||||
|
"reference": "03cce39764429e07fbab9b989a1182a24578341d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/dom-crawler": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/polyfill-php80": "^1.16"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/css-selector": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/http-client": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/mime": "^4.4|^5.0|^6.0",
|
||||||
|
"symfony/process": "^4.4|^5.0|^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/process": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\BrowserKit\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/browser-kit/tree/v5.4.45"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-10-22T13:05:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/cache",
|
"name": "symfony/cache",
|
||||||
"version": "v5.4.46",
|
"version": "v5.4.46",
|
||||||
|
@ -18533,6 +18076,78 @@
|
||||||
],
|
],
|
||||||
"time": "2023-11-13T13:48:05+00:00"
|
"time": "2023-11-13T13:48:05+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "react/promise",
|
||||||
|
"version": "v2.11.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/reactphp/promise.git",
|
||||||
|
"reference": "1a8460931ea36dc5c76838fec5734d55c88c6831"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/reactphp/promise/zipball/1a8460931ea36dc5c76838fec5734d55c88c6831",
|
||||||
|
"reference": "1a8460931ea36dc5c76838fec5734d55c88c6831",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/functions_include.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"React\\Promise\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jan Sorgalla",
|
||||||
|
"email": "jsorgalla@gmail.com",
|
||||||
|
"homepage": "https://sorgalla.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Christian Lück",
|
||||||
|
"email": "christian@clue.engineering",
|
||||||
|
"homepage": "https://clue.engineering/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Cees-Jan Kiewiet",
|
||||||
|
"email": "reactphp@ceesjankiewiet.nl",
|
||||||
|
"homepage": "https://wyrihaximus.net/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Chris Boden",
|
||||||
|
"email": "cboden@gmail.com",
|
||||||
|
"homepage": "https://cboden.dev/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"promise",
|
||||||
|
"promises"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/reactphp/promise/issues",
|
||||||
|
"source": "https://github.com/reactphp/promise/tree/v2.11.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://opencollective.com/reactphp",
|
||||||
|
"type": "open_collective"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-11-16T16:16:50+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "react/socket",
|
"name": "react/socket",
|
||||||
"version": "v1.16.0",
|
"version": "v1.16.0",
|
||||||
|
@ -19720,78 +19335,6 @@
|
||||||
},
|
},
|
||||||
"time": "2024-12-30T12:31:04+00:00"
|
"time": "2024-12-30T12:31:04+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "symfony/browser-kit",
|
|
||||||
"version": "v5.4.45",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/browser-kit.git",
|
|
||||||
"reference": "03cce39764429e07fbab9b989a1182a24578341d"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/03cce39764429e07fbab9b989a1182a24578341d",
|
|
||||||
"reference": "03cce39764429e07fbab9b989a1182a24578341d",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=7.2.5",
|
|
||||||
"symfony/dom-crawler": "^4.4|^5.0|^6.0",
|
|
||||||
"symfony/polyfill-php80": "^1.16"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"symfony/css-selector": "^4.4|^5.0|^6.0",
|
|
||||||
"symfony/http-client": "^4.4|^5.0|^6.0",
|
|
||||||
"symfony/mime": "^4.4|^5.0|^6.0",
|
|
||||||
"symfony/process": "^4.4|^5.0|^6.0"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/process": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Component\\BrowserKit\\": ""
|
|
||||||
},
|
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "https://symfony.com/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
|
|
||||||
"homepage": "https://symfony.com",
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/symfony/browser-kit/tree/v5.4.45"
|
|
||||||
},
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"url": "https://symfony.com/sponsor",
|
|
||||||
"type": "custom"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://github.com/fabpot",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
|
||||||
"type": "tidelift"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"time": "2024-10-22T13:05:35+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "symfony/css-selector",
|
"name": "symfony/css-selector",
|
||||||
"version": "v5.4.45",
|
"version": "v5.4.45",
|
||||||
|
@ -20407,9 +19950,9 @@
|
||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"ext-xml": "*"
|
"ext-xml": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": {},
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
"php": "7.4.29"
|
"php": "7.4.29"
|
||||||
},
|
},
|
||||||
"plugin-api-version": "2.3.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Wallabag\Guzzle;
|
|
||||||
|
|
||||||
use GuzzleHttp\Event\BeforeEvent;
|
|
||||||
use GuzzleHttp\Event\CompleteEvent;
|
|
||||||
use GuzzleHttp\Event\SubscriberInterface;
|
|
||||||
use GuzzleHttp\Message\RequestInterface;
|
|
||||||
use Psr\Log\LoggerAwareInterface;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Psr\Log\NullLogger;
|
|
||||||
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
|
||||||
use Wallabag\SiteConfig\SiteConfig;
|
|
||||||
use Wallabag\SiteConfig\SiteConfigBuilder;
|
|
||||||
|
|
||||||
class AuthenticatorSubscriber implements SubscriberInterface, LoggerAwareInterface
|
|
||||||
{
|
|
||||||
// avoid loop when login failed which can just be a bad login/password
|
|
||||||
// after 2 attempts, we skip the login
|
|
||||||
public const MAX_RETRIES = 2;
|
|
||||||
private int $retries = 0;
|
|
||||||
|
|
||||||
/** @var SiteConfigBuilder */
|
|
||||||
private $configBuilder;
|
|
||||||
|
|
||||||
/** @var LoginFormAuthenticator */
|
|
||||||
private $authenticator;
|
|
||||||
|
|
||||||
/** @var LoggerInterface */
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AuthenticatorSubscriber constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(SiteConfigBuilder $configBuilder, LoginFormAuthenticator $authenticator)
|
|
||||||
{
|
|
||||||
$this->configBuilder = $configBuilder;
|
|
||||||
$this->authenticator = $authenticator;
|
|
||||||
$this->logger = new NullLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLogger(LoggerInterface $logger): void
|
|
||||||
{
|
|
||||||
$this->logger = $logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEvents(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'before' => ['loginIfRequired'],
|
|
||||||
'complete' => ['loginIfRequested'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loginIfRequired(BeforeEvent $event)
|
|
||||||
{
|
|
||||||
$config = $this->buildSiteConfig($event->getRequest());
|
|
||||||
if (false === $config || !$config->requiresLogin()) {
|
|
||||||
$this->logger->debug('loginIfRequired> will not require login');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$client = $event->getClient();
|
|
||||||
|
|
||||||
if (!$this->authenticator->isLoggedIn($config, $client)) {
|
|
||||||
$this->logger->debug('loginIfRequired> user is not logged in, attach authenticator');
|
|
||||||
|
|
||||||
$emitter = $client->getEmitter();
|
|
||||||
$emitter->detach($this);
|
|
||||||
$this->authenticator->login($config, $client);
|
|
||||||
$emitter->attach($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loginIfRequested(CompleteEvent $event)
|
|
||||||
{
|
|
||||||
$config = $this->buildSiteConfig($event->getRequest());
|
|
||||||
if (false === $config || !$config->requiresLogin()) {
|
|
||||||
$this->logger->debug('loginIfRequested> will not require login');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$body = $event->getResponse()->getBody();
|
|
||||||
|
|
||||||
if (
|
|
||||||
null === $body
|
|
||||||
|| '' === $body->getContents()
|
|
||||||
) {
|
|
||||||
$this->logger->debug('loginIfRequested> empty body, ignoring');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$isLoginRequired = $this->authenticator->isLoginRequired($config, $body);
|
|
||||||
|
|
||||||
$this->logger->debug('loginIfRequested> retry #' . $this->retries . ' with login ' . ($isLoginRequired ? '' : 'not ') . 'required');
|
|
||||||
|
|
||||||
if ($isLoginRequired && $this->retries < self::MAX_RETRIES) {
|
|
||||||
$client = $event->getClient();
|
|
||||||
|
|
||||||
$emitter = $client->getEmitter();
|
|
||||||
$emitter->detach($this);
|
|
||||||
$this->authenticator->login($config, $client);
|
|
||||||
$emitter->attach($this);
|
|
||||||
|
|
||||||
$event->retry();
|
|
||||||
|
|
||||||
++$this->retries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return SiteConfig|false
|
|
||||||
*/
|
|
||||||
private function buildSiteConfig(RequestInterface $request)
|
|
||||||
{
|
|
||||||
return $this->configBuilder->buildForHost($request->getHost());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Wallabag\Helper;
|
|
||||||
|
|
||||||
use GuzzleHttp\Client as GuzzleClient;
|
|
||||||
use GuzzleHttp\Cookie\CookieJar;
|
|
||||||
use GuzzleHttp\Event\SubscriberInterface;
|
|
||||||
use Http\Adapter\Guzzle5\Client as GuzzleAdapter;
|
|
||||||
use Http\Client\HttpClient;
|
|
||||||
use Http\HttplugBundle\ClientFactory\ClientFactory;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds and configures the HTTP client.
|
|
||||||
*/
|
|
||||||
class HttpClientFactory implements ClientFactory
|
|
||||||
{
|
|
||||||
/** @var SubscriberInterface[] */
|
|
||||||
private $subscribers = [];
|
|
||||||
|
|
||||||
/** @var CookieJar */
|
|
||||||
private $cookieJar;
|
|
||||||
|
|
||||||
private $restrictedAccess;
|
|
||||||
private $logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpClientFactory constructor.
|
|
||||||
*
|
|
||||||
* @param string $restrictedAccess This param is a kind of boolean. Values: 0 or 1
|
|
||||||
*/
|
|
||||||
public function __construct(CookieJar $cookieJar, $restrictedAccess, LoggerInterface $logger)
|
|
||||||
{
|
|
||||||
$this->cookieJar = $cookieJar;
|
|
||||||
$this->restrictedAccess = $restrictedAccess;
|
|
||||||
$this->logger = $logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a subscriber to the HTTP client.
|
|
||||||
*/
|
|
||||||
public function addSubscriber(SubscriberInterface $subscriber)
|
|
||||||
{
|
|
||||||
$this->subscribers[] = $subscriber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Input an array of configuration to be able to create a HttpClient.
|
|
||||||
*
|
|
||||||
* @return HttpClient
|
|
||||||
*/
|
|
||||||
public function createClient(array $config = [])
|
|
||||||
{
|
|
||||||
$this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]);
|
|
||||||
|
|
||||||
if (0 === (int) $this->restrictedAccess) {
|
|
||||||
return new GuzzleAdapter(new GuzzleClient($config));
|
|
||||||
}
|
|
||||||
|
|
||||||
// we clear the cookie to avoid websites who use cookies for analytics
|
|
||||||
$this->cookieJar->clear();
|
|
||||||
if (!isset($config['defaults']['cookies'])) {
|
|
||||||
// need to set the (shared) cookie jar
|
|
||||||
$config['defaults']['cookies'] = $this->cookieJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
$guzzle = new GuzzleClient($config);
|
|
||||||
foreach ($this->subscribers as $subscriber) {
|
|
||||||
$guzzle->getEmitter()->attach($subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GuzzleAdapter($guzzle);
|
|
||||||
}
|
|
||||||
}
|
|
95
src/HttpClient/Authenticator.php
Normal file
95
src/HttpClient/Authenticator.php
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Wallabag\HttpClient;
|
||||||
|
|
||||||
|
use GuzzleHttp\Psr7\Uri;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
use Psr\Log\LoggerAwareInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
||||||
|
use Wallabag\SiteConfig\SiteConfig;
|
||||||
|
use Wallabag\SiteConfig\SiteConfigBuilder;
|
||||||
|
|
||||||
|
class Authenticator implements LoggerAwareInterface
|
||||||
|
{
|
||||||
|
/** @var SiteConfigBuilder */
|
||||||
|
private $configBuilder;
|
||||||
|
|
||||||
|
/** @var LoginFormAuthenticator */
|
||||||
|
private $authenticator;
|
||||||
|
|
||||||
|
/** @var LoggerInterface */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
public function __construct(SiteConfigBuilder $configBuilder, LoginFormAuthenticator $authenticator)
|
||||||
|
{
|
||||||
|
$this->configBuilder = $configBuilder;
|
||||||
|
$this->authenticator = $authenticator;
|
||||||
|
$this->logger = new NullLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLogger(LoggerInterface $logger): void
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loginIfRequired(string $url): bool
|
||||||
|
{
|
||||||
|
$config = $this->buildSiteConfig(new Uri($url));
|
||||||
|
if (false === $config || !$config->requiresLogin()) {
|
||||||
|
$this->logger->debug('loginIfRequired> will not require login');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->authenticator->isLoggedIn($config)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug('loginIfRequired> user is not logged in, attach authenticator');
|
||||||
|
|
||||||
|
$this->authenticator->login($config);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loginIfRequested(ResponseInterface $response): bool
|
||||||
|
{
|
||||||
|
$config = $this->buildSiteConfig(new Uri($response->getInfo('url')));
|
||||||
|
if (false === $config || !$config->requiresLogin()) {
|
||||||
|
$this->logger->debug('loginIfRequested> will not require login');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = $response->getContent();
|
||||||
|
|
||||||
|
if ('' === $body) {
|
||||||
|
$this->logger->debug('loginIfRequested> empty body, ignoring');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isLoginRequired = $this->authenticator->isLoginRequired($config, $body);
|
||||||
|
|
||||||
|
$this->logger->debug('loginIfRequested> retry with login ' . ($isLoginRequired ? '' : 'not ') . 'required');
|
||||||
|
|
||||||
|
if (!$isLoginRequired) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->authenticator->login($config);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SiteConfig|false
|
||||||
|
*/
|
||||||
|
private function buildSiteConfig(UriInterface $uri)
|
||||||
|
{
|
||||||
|
return $this->configBuilder->buildForHost($uri->getHost());
|
||||||
|
}
|
||||||
|
}
|
84
src/HttpClient/WallabagClient.php
Normal file
84
src/HttpClient/WallabagClient.php
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Wallabag\HttpClient;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||||
|
use Symfony\Component\HttpClient\HttpClient;
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
|
||||||
|
|
||||||
|
class WallabagClient implements HttpClientInterface
|
||||||
|
{
|
||||||
|
private $restrictedAccess;
|
||||||
|
private HttpClientInterface $httpClient;
|
||||||
|
private HttpBrowser $browser;
|
||||||
|
private Authenticator $authenticator;
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
|
public function __construct($restrictedAccess, HttpBrowser $browser, Authenticator $authenticator, LoggerInterface $logger)
|
||||||
|
{
|
||||||
|
$this->restrictedAccess = $restrictedAccess;
|
||||||
|
$this->browser = $browser;
|
||||||
|
$this->authenticator = $authenticator;
|
||||||
|
$this->logger = $logger;
|
||||||
|
|
||||||
|
$this->httpClient = HttpClient::create([
|
||||||
|
'timeout' => 10,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function request(string $method, string $url, array $options = []): ResponseInterface
|
||||||
|
{
|
||||||
|
$this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]);
|
||||||
|
|
||||||
|
if (0 === (int) $this->restrictedAccess) {
|
||||||
|
return $this->httpClient->request($method, $url, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
$login = $this->authenticator->loginIfRequired($url);
|
||||||
|
|
||||||
|
if (!$login) {
|
||||||
|
return $this->httpClient->request($method, $url, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $cookieHeader = $this->getCookieHeader($url)) {
|
||||||
|
$options['headers']['cookie'] = $cookieHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->httpClient->request($method, $url, $options);
|
||||||
|
|
||||||
|
$login = $this->authenticator->loginIfRequested($response);
|
||||||
|
|
||||||
|
if (!$login) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $cookieHeader = $this->getCookieHeader($url)) {
|
||||||
|
$options['headers']['cookie'] = $cookieHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->httpClient->request($method, $url, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stream($responses, ?float $timeout = null): ResponseStreamInterface
|
||||||
|
{
|
||||||
|
return $this->httpClient->stream($responses, $timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCookieHeader(string $url): ?string
|
||||||
|
{
|
||||||
|
$cookies = [];
|
||||||
|
|
||||||
|
foreach ($this->browser->getCookieJar()->allRawValues($url) as $name => $value) {
|
||||||
|
$cookies[] = $name . '=' . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([] === $cookies) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('; ', $cookies);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
namespace Wallabag\SiteConfig;
|
namespace Wallabag\SiteConfig;
|
||||||
|
|
||||||
use GuzzleHttp\ClientInterface;
|
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||||
use GuzzleHttp\Cookie\CookieJar;
|
|
||||||
use Symfony\Component\DomCrawler\Crawler;
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
||||||
|
|
||||||
class LoginFormAuthenticator
|
class LoginFormAuthenticator
|
||||||
{
|
{
|
||||||
|
private HttpBrowser $browser;
|
||||||
private ExpressionLanguage $expressionLanguage;
|
private ExpressionLanguage $expressionLanguage;
|
||||||
|
|
||||||
public function __construct(AuthenticatorProvider $authenticatorProvider)
|
public function __construct(HttpBrowser $browser, AuthenticatorProvider $authenticatorProvider)
|
||||||
{
|
{
|
||||||
|
$this->browser = $browser;
|
||||||
$this->expressionLanguage = new ExpressionLanguage(null, [$authenticatorProvider]);
|
$this->expressionLanguage = new ExpressionLanguage(null, [$authenticatorProvider]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,17 +23,14 @@ class LoginFormAuthenticator
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function login(SiteConfig $siteConfig, ClientInterface $guzzle)
|
public function login(SiteConfig $siteConfig)
|
||||||
{
|
{
|
||||||
$postFields = [
|
$postFields = [
|
||||||
$siteConfig->getUsernameField() => $siteConfig->getUsername(),
|
$siteConfig->getUsernameField() => $siteConfig->getUsername(),
|
||||||
$siteConfig->getPasswordField() => $siteConfig->getPassword(),
|
$siteConfig->getPasswordField() => $siteConfig->getPassword(),
|
||||||
] + $this->getExtraFields($siteConfig);
|
] + $this->getExtraFields($siteConfig);
|
||||||
|
|
||||||
$guzzle->post(
|
$this->browser->request('POST', $siteConfig->getLoginUri(), $postFields);
|
||||||
$siteConfig->getLoginUri(),
|
|
||||||
['body' => $postFields, 'allow_redirects' => true, 'verify' => false]
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -42,17 +40,14 @@ class LoginFormAuthenticator
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isLoggedIn(SiteConfig $siteConfig, ClientInterface $guzzle)
|
public function isLoggedIn(SiteConfig $siteConfig)
|
||||||
{
|
{
|
||||||
if (($cookieJar = $guzzle->getDefaultOption('cookies')) instanceof CookieJar) {
|
foreach ($this->browser->getCookieJar()->all() as $cookie) {
|
||||||
/** @var \GuzzleHttp\Cookie\SetCookie $cookie */
|
|
||||||
foreach ($cookieJar as $cookie) {
|
|
||||||
// check required cookies
|
// check required cookies
|
||||||
if ($cookie->getDomain() === $siteConfig->getHost()) {
|
if ($cookie->getDomain() === $siteConfig->getHost()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,314 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Tests\Wallabag\Guzzle;
|
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Event\BeforeEvent;
|
|
||||||
use GuzzleHttp\Event\CompleteEvent;
|
|
||||||
use GuzzleHttp\Message\Request;
|
|
||||||
use GuzzleHttp\Message\Response;
|
|
||||||
use GuzzleHttp\Stream\Stream;
|
|
||||||
use GuzzleHttp\Subscriber\Mock;
|
|
||||||
use Monolog\Handler\TestHandler;
|
|
||||||
use Monolog\Logger;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Wallabag\Guzzle\AuthenticatorSubscriber;
|
|
||||||
use Wallabag\SiteConfig\ArraySiteConfigBuilder;
|
|
||||||
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
|
||||||
|
|
||||||
class AuthenticatorSubscriberTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testGetEvents()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$subscriber = new AuthenticatorSubscriber(
|
|
||||||
new ArraySiteConfigBuilder(),
|
|
||||||
$authenticator
|
|
||||||
);
|
|
||||||
$events = $subscriber->getEvents();
|
|
||||||
|
|
||||||
$this->assertArrayHasKey('before', $events);
|
|
||||||
$this->assertArrayHasKey('complete', $events);
|
|
||||||
$this->assertSame('loginIfRequired', $events['before'][0]);
|
|
||||||
$this->assertSame('loginIfRequested', $events['complete'][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequiredNotRequired()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(BeforeEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequired($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequired> will not require login', $records[0]['message']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequiredWithNotLoggedInUser()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$authenticator->expects($this->once())
|
|
||||||
->method('isLoggedIn')
|
|
||||||
->willReturn(false);
|
|
||||||
|
|
||||||
$authenticator->expects($this->once())
|
|
||||||
->method('login');
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => ['requiresLogin' => true]]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$response = new Response(
|
|
||||||
200,
|
|
||||||
['content-type' => 'text/html'],
|
|
||||||
Stream::factory('')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response]));
|
|
||||||
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(BeforeEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getClient')
|
|
||||||
->willReturn($guzzle);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequired($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequired> user is not logged in, attach authenticator', $records[0]['message']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequestedNotRequired()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(CompleteEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequested($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequested> will not require login', $records[0]['message']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequestedNotRequested()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$authenticator->expects($this->once())
|
|
||||||
->method('isLoginRequired')
|
|
||||||
->willReturn(false);
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
|
||||||
'requiresLogin' => true,
|
|
||||||
'notLoggedInXpath' => '//html',
|
|
||||||
]]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$response = new Response(
|
|
||||||
200,
|
|
||||||
['content-type' => 'text/html'],
|
|
||||||
Stream::factory('<html><body/></html>')
|
|
||||||
);
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(CompleteEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getResponse')
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequested($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequested> retry #0 with login not required', $records[0]['message']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequestedRequested()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$authenticator->expects($this->once())
|
|
||||||
->method('isLoginRequired')
|
|
||||||
->willReturn(true);
|
|
||||||
|
|
||||||
$authenticator->expects($this->once())
|
|
||||||
->method('login');
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
|
||||||
'requiresLogin' => true,
|
|
||||||
'notLoggedInXpath' => '//html',
|
|
||||||
]]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$response = new Response(
|
|
||||||
200,
|
|
||||||
['content-type' => 'text/html'],
|
|
||||||
Stream::factory('<html><body/></html>')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response]));
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(CompleteEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getResponse')
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$event->expects($this->any())
|
|
||||||
->method('getClient')
|
|
||||||
->willReturn($guzzle);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequested($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequested> retry #0 with login required', $records[0]['message']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginIfRequestedRedirect()
|
|
||||||
{
|
|
||||||
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
|
||||||
'requiresLogin' => true,
|
|
||||||
'notLoggedInXpath' => '//html',
|
|
||||||
]]);
|
|
||||||
$subscriber = new AuthenticatorSubscriber($builder, $authenticator);
|
|
||||||
|
|
||||||
$logger = new Logger('foo');
|
|
||||||
$handler = new TestHandler();
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
$subscriber->setLogger($logger);
|
|
||||||
|
|
||||||
$response = new Response(
|
|
||||||
301,
|
|
||||||
[],
|
|
||||||
Stream::factory('')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response]));
|
|
||||||
$request = new Request('GET', 'http://www.example.com');
|
|
||||||
|
|
||||||
$event = $this->getMockBuilder(CompleteEvent::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getResponse')
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$event->expects($this->once())
|
|
||||||
->method('getRequest')
|
|
||||||
->willReturn($request);
|
|
||||||
|
|
||||||
$event->expects($this->any())
|
|
||||||
->method('getClient')
|
|
||||||
->willReturn($guzzle);
|
|
||||||
|
|
||||||
$subscriber->loginIfRequested($event);
|
|
||||||
|
|
||||||
$records = $handler->getRecords();
|
|
||||||
|
|
||||||
$this->assertCount(1, $records);
|
|
||||||
$this->assertSame('loginIfRequested> empty body, ignoring', $records[0]['message']);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
namespace Tests\Wallabag\SiteConfig;
|
namespace Tests\Wallabag\SiteConfig;
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Message\Response;
|
|
||||||
use GuzzleHttp\Stream\Stream;
|
|
||||||
use GuzzleHttp\Subscriber\Mock;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\BrowserKit\HttpBrowser;
|
||||||
use Symfony\Component\HttpClient\MockHttpClient;
|
use Symfony\Component\HttpClient\MockHttpClient;
|
||||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
use Wallabag\ExpressionLanguage\AuthenticatorProvider;
|
||||||
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
||||||
use Wallabag\SiteConfig\SiteConfig;
|
use Wallabag\SiteConfig\SiteConfig;
|
||||||
|
@ -17,16 +16,6 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLoginPost()
|
public function testLoginPost()
|
||||||
{
|
{
|
||||||
$response = new Response(
|
|
||||||
200,
|
|
||||||
['content-type' => 'text/html'],
|
|
||||||
Stream::factory('')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response]));
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse('', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$siteConfig = new SiteConfig([
|
$siteConfig = new SiteConfig([
|
||||||
'host' => 'example.com',
|
'host' => 'example.com',
|
||||||
'loginUri' => 'http://example.com/login',
|
'loginUri' => 'http://example.com/login',
|
||||||
|
@ -40,25 +29,23 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
$res = $auth->login($siteConfig, $guzzle);
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
|
$res = $auth->login($siteConfig);
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoginPostWithExtraFieldsButEmptyHtml()
|
public function testLoginPostWithExtraFieldsButEmptyHtml()
|
||||||
{
|
{
|
||||||
$response = new Response(
|
|
||||||
200,
|
|
||||||
['content-type' => 'text/html'],
|
|
||||||
Stream::factory('<html></html>')
|
|
||||||
);
|
|
||||||
$guzzle = new Client();
|
|
||||||
$guzzle->getEmitter()->attach(new Mock([$response, $response]));
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$siteConfig = new SiteConfig([
|
$siteConfig = new SiteConfig([
|
||||||
'host' => 'example.com',
|
'host' => 'example.com',
|
||||||
'loginUri' => 'http://example.com/login',
|
'loginUri' => 'http://example.com/login',
|
||||||
|
@ -73,9 +60,17 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
$res = $auth->login($siteConfig, $guzzle);
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
|
$res = $auth->login($siteConfig);
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
@ -83,49 +78,6 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
// testing preg_match
|
// testing preg_match
|
||||||
public function testLoginPostWithExtraFieldsWithRegex()
|
public function testLoginPostWithExtraFieldsWithRegex()
|
||||||
{
|
{
|
||||||
$response = $this->getMockBuilder(Response::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getBody')
|
|
||||||
->willReturn(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'));
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getStatusCode')
|
|
||||||
->willReturn(200);
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'), ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$client = $this->getMockBuilder(Client::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('post')
|
|
||||||
->with(
|
|
||||||
$this->equalTo('https://aoc.media/wp-admin/admin-ajax.php'),
|
|
||||||
$this->equalTo([
|
|
||||||
'body' => [
|
|
||||||
'nom' => 'johndoe',
|
|
||||||
'password' => 'unkn0wn',
|
|
||||||
'security' => 'c506c1b8bc',
|
|
||||||
'action' => 'login_user',
|
|
||||||
],
|
|
||||||
'allow_redirects' => true,
|
|
||||||
'verify' => false,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('get')
|
|
||||||
->with(
|
|
||||||
$this->equalTo('https://aoc.media/'),
|
|
||||||
$this->equalTo([])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$siteConfig = new SiteConfig([
|
$siteConfig = new SiteConfig([
|
||||||
'host' => 'aoc.media',
|
'host' => 'aoc.media',
|
||||||
'loginUri' => 'https://aoc.media/wp-admin/admin-ajax.php',
|
'loginUri' => 'https://aoc.media/wp-admin/admin-ajax.php',
|
||||||
|
@ -139,78 +91,44 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
$res = $auth->login($siteConfig, $client);
|
$browser = $this->getMockBuilder(HttpBrowser::class)
|
||||||
|
->setConstructorArgs([$browserClient])
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoginPostWithExtraFieldsWithData()
|
|
||||||
{
|
|
||||||
$response = $this->getMockBuilder(Response::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
->getMock();
|
||||||
|
$browser->expects($this->any())
|
||||||
$response->expects($this->any())
|
->method('request')
|
||||||
->method('getBody')
|
|
||||||
->willReturn(file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
|
||||||
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getStatusCode')
|
|
||||||
->willReturn(200);
|
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient([new MockResponse(file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'), ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']])]);
|
|
||||||
|
|
||||||
$client = $this->getMockBuilder(Client::class)
|
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('post')
|
|
||||||
->with(
|
->with(
|
||||||
$this->equalTo('https://compte.nextinpact.com/Account/Login'),
|
$this->equalTo('POST'),
|
||||||
|
$this->equalTo('https://aoc.media/wp-admin/admin-ajax.php'),
|
||||||
$this->equalTo([
|
$this->equalTo([
|
||||||
'body' => [
|
'nom' => 'johndoe',
|
||||||
'UserName' => 'johndoe',
|
|
||||||
'Password' => 'unkn0wn',
|
|
||||||
'__RequestVerificationToken' => 's6x2QcnQDUL92mkKSi_JuUBXcgUYx_Plf-KyQ2eJypKAjQZIeTvaFHOsfEdTrcSXt3dt2CW39V7r9V16LUtvjszodAU1',
|
|
||||||
'returnUrl' => 'https://www.nextinpact.com/news/102835-pour-cour-comptes-fonctionnement-actuel-vote-par-internet-nest-pas-satisfaisant.htm',
|
|
||||||
],
|
|
||||||
'allow_redirects' => true,
|
|
||||||
'verify' => false,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$client->expects($this->any())
|
|
||||||
->method('get')
|
|
||||||
->with(
|
|
||||||
$this->equalTo('https://compte.nextinpact.com/Account/Login?http://www.nextinpact.com/'),
|
|
||||||
$this->equalTo([
|
|
||||||
'headers' => [
|
|
||||||
'X-Requested-With' => 'XMLHttpRequest',
|
|
||||||
],
|
|
||||||
])
|
|
||||||
)
|
|
||||||
->willReturn($response);
|
|
||||||
|
|
||||||
$siteConfig = new SiteConfig([
|
|
||||||
'host' => 'nextinpact.com',
|
|
||||||
'loginUri' => 'https://compte.nextinpact.com/Account/Login',
|
|
||||||
'usernameField' => 'UserName',
|
|
||||||
'passwordField' => 'Password',
|
|
||||||
'extraFields' => [
|
|
||||||
'__RequestVerificationToken' => '@=xpath(\'//form[@action="/Account/Login"]/input[@name="__RequestVerificationToken"]\', request_html(\'https://compte.nextinpact.com/Account/Login?http://www.nextinpact.com/\', {\'headers\': {\'X-Requested-With\':\'XMLHttpRequest\'}}))',
|
|
||||||
'returnUrl' => 'https://www.nextinpact.com/news/102835-pour-cour-comptes-fonctionnement-actuel-vote-par-internet-nest-pas-satisfaisant.htm',
|
|
||||||
],
|
|
||||||
'username' => 'johndoe',
|
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
'security' => 'c506c1b8bc',
|
||||||
|
'action' => 'login_user',
|
||||||
|
])
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
$requestHtmlFunctionResponse = $this->getMockBuilder(ResponseInterface::class)->getMock();
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
$requestHtmlFunctionResponse->expects($this->any())
|
||||||
$res = $auth->login($siteConfig, $client);
|
->method('getContent')
|
||||||
|
->willReturn(file_get_contents(__DIR__ . '/../fixtures/aoc.media.html'))
|
||||||
|
;
|
||||||
|
$requestHtmlFunctionClient = $this->getMockBuilder(HttpClientInterface::class)->getMock();
|
||||||
|
$requestHtmlFunctionClient->expects($this->any())
|
||||||
|
->method('request')
|
||||||
|
->with(
|
||||||
|
$this->equalTo('GET'),
|
||||||
|
$this->equalTo('https://aoc.media/'),
|
||||||
|
)
|
||||||
|
->willReturn($requestHtmlFunctionResponse)
|
||||||
|
;
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
|
$res = $auth->login($siteConfig);
|
||||||
|
|
||||||
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
$this->assertInstanceOf(LoginFormAuthenticator::class, $res);
|
||||||
}
|
}
|
||||||
|
@ -225,10 +143,16 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'password' => 'unkn0wn',
|
'password' => 'unkn0wn',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient();
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-login.html'));
|
||||||
|
|
||||||
$this->assertFalse($loginRequired);
|
$this->assertFalse($loginRequired);
|
||||||
|
@ -245,10 +169,16 @@ class LoginFormAuthenticatorTest extends TestCase
|
||||||
'notLoggedInXpath' => '//h2[@class="title_reserve_article"]',
|
'notLoggedInXpath' => '//h2[@class="title_reserve_article"]',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$mockHttpClient = new MockHttpClient();
|
$browserResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$browserClient = new MockHttpClient([$browserResponse]);
|
||||||
|
$browser = new HttpBrowser($browserClient);
|
||||||
|
|
||||||
|
$requestHtmlFunctionResponse = new MockResponse('<html></html>', ['http_code' => 200, 'response_headers' => ['content-type' => 'text/html']]);
|
||||||
|
$requestHtmlFunctionClient = new MockHttpClient([$requestHtmlFunctionResponse]);
|
||||||
|
$authenticatorProvider = new AuthenticatorProvider($requestHtmlFunctionClient);
|
||||||
|
|
||||||
|
$auth = new LoginFormAuthenticator($browser, $authenticatorProvider);
|
||||||
|
|
||||||
$authenticatorProvider = new AuthenticatorProvider($mockHttpClient);
|
|
||||||
$auth = new LoginFormAuthenticator($authenticatorProvider);
|
|
||||||
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-article.html'));
|
$loginRequired = $auth->isLoginRequired($siteConfig, file_get_contents(__DIR__ . '/../fixtures/nextinpact-article.html'));
|
||||||
|
|
||||||
$this->assertTrue($loginRequired);
|
$this->assertTrue($loginRequired);
|
||||||
|
|
239
tests/Tests/Wallabag/HttpClient/AuthenticatorTest.php
Normal file
239
tests/Tests/Wallabag/HttpClient/AuthenticatorTest.php
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Wallabag\HttpClient;
|
||||||
|
|
||||||
|
use Monolog\Handler\TestHandler;
|
||||||
|
use Monolog\Logger;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
use Wallabag\HttpClient\Authenticator;
|
||||||
|
use Wallabag\SiteConfig\ArraySiteConfigBuilder;
|
||||||
|
use Wallabag\SiteConfig\LoginFormAuthenticator;
|
||||||
|
|
||||||
|
class AuthenticatorTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testLoginIfRequiredNotRequired()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequired('http://www.example.com');
|
||||||
|
|
||||||
|
$this->assertFalse($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequired> will not require login', $records[0]['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginIfRequiredWithNotLoggedInUser()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$authenticator->expects($this->once())
|
||||||
|
->method('isLoggedIn')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$authenticator->expects($this->once())
|
||||||
|
->method('login');
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => ['requiresLogin' => true]]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequired('http://www.example.com');
|
||||||
|
|
||||||
|
$this->assertTrue($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequired> user is not logged in, attach authenticator', $records[0]['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginIfRequestedNotRequired()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => []]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$response = $this->getMockBuilder(ResponseInterface::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getInfo')
|
||||||
|
->with($this->equalTo('url'))
|
||||||
|
->willReturn('http://www.example.com');
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequested($response);
|
||||||
|
|
||||||
|
$this->assertFalse($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequested> will not require login', $records[0]['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginIfRequestedNotRequested()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$authenticator->expects($this->once())
|
||||||
|
->method('isLoginRequired')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
||||||
|
'requiresLogin' => true,
|
||||||
|
'notLoggedInXpath' => '//html',
|
||||||
|
]]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$response = $this->getMockBuilder(ResponseInterface::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getInfo')
|
||||||
|
->with($this->equalTo('url'))
|
||||||
|
->willReturn('http://www.example.com');
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getContent')
|
||||||
|
->willReturn('<html><body/></html>');
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequested($response);
|
||||||
|
|
||||||
|
$this->assertFalse($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequested> retry with login not required', $records[0]['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginIfRequestedRequested()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$authenticator->expects($this->once())
|
||||||
|
->method('isLoginRequired')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$authenticator->expects($this->once())
|
||||||
|
->method('login');
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
||||||
|
'requiresLogin' => true,
|
||||||
|
'notLoggedInXpath' => '//html',
|
||||||
|
]]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$response = $this->getMockBuilder(ResponseInterface::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getInfo')
|
||||||
|
->with($this->equalTo('url'))
|
||||||
|
->willReturn('http://www.example.com');
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getContent')
|
||||||
|
->willReturn('<html><body/></html>');
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequested($response);
|
||||||
|
|
||||||
|
$this->assertTrue($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequested> retry with login required', $records[0]['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginIfRequestedRedirect()
|
||||||
|
{
|
||||||
|
$authenticator = $this->getMockBuilder(LoginFormAuthenticator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$builder = new ArraySiteConfigBuilder(['example.com' => [
|
||||||
|
'requiresLogin' => true,
|
||||||
|
'notLoggedInXpath' => '//html',
|
||||||
|
]]);
|
||||||
|
$subscriber = new Authenticator($builder, $authenticator);
|
||||||
|
|
||||||
|
$logger = new Logger('foo');
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$subscriber->setLogger($logger);
|
||||||
|
|
||||||
|
$response = $this->getMockBuilder(ResponseInterface::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getInfo')
|
||||||
|
->with($this->equalTo('url'))
|
||||||
|
->willReturn('http://www.example.com');
|
||||||
|
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('getContent')
|
||||||
|
->willReturn('');
|
||||||
|
|
||||||
|
$login = $subscriber->loginIfRequested($response);
|
||||||
|
|
||||||
|
$this->assertFalse($login);
|
||||||
|
|
||||||
|
$records = $handler->getRecords();
|
||||||
|
|
||||||
|
$this->assertCount(1, $records);
|
||||||
|
$this->assertSame('loginIfRequested> empty body, ignoring', $records[0]['message']);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue