Page MenuHomeDevCentral

D25.id932.diff
No OneTemporary

D25.id932.diff

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,18 @@
#
# Auth Grove
-#
+#
all: assets vendor
assets:
gulp
-
+
vendor:
composer install
test:
phpunit
+ phpunit tests/standalone/ProxyTest.php
clean:
rm -f storage/framework/sessions/*
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -44,6 +44,7 @@
docker run -t -d \
--link <a MySQL or MariaDB container>:mysql \
-p <the port you want>:80 \
+ -e TRUST_ALL_PROXIES=1 \
-e DB_HOST=mysql \
-e DB_DATABASE=<name of the database> \
-e DB_USERNAME=<login for this database> \
diff --git a/app/Enums/TrustProxyConfigurationMode.php b/app/Enums/TrustProxyConfigurationMode.php
new file mode 100644
--- /dev/null
+++ b/app/Enums/TrustProxyConfigurationMode.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace AuthGrove\Enums;
+
+use Artisaninweb\Enum\Enum;
+
+/**
+ * @method static TrustProxyConfigurationMode ENUM()
+ */
+class TrustProxyConfigurationMode extends Enum {
+ const __default = self::TrustNone;
+
+ const TrustNone = 0;
+ const TrustSome = 1;
+ const TrustAll = 2;
+}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -16,6 +16,7 @@
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'AuthGrove\Http\Middleware\VerifyCsrfToken',
+ 'AuthGrove\Http\Middleware\TrustProxy',
];
/**
diff --git a/app/Http/Middleware/TrustProxy.php b/app/Http/Middleware/TrustProxy.php
new file mode 100644
--- /dev/null
+++ b/app/Http/Middleware/TrustProxy.php
@@ -0,0 +1,59 @@
+<?php namespace AuthGrove\Http\Middleware;
+
+use Illuminate\Contracts\Routing\Middleware;
+use AuthGrove\Enums\TrustProxyConfigurationMode;
+use Config;
+use Closure;
+
+/**
+ * Allow the application to work behind a load balancer or a reverse proxy
+ *
+ * See http://symfony.com/doc/current/cookbook/request/load_balancer_reverse_proxy.html
+ */
+class TrustProxy implements Middleware {
+ /**
+ * Handle an incoming request.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ * @return mixed
+ */
+ public function handle($request, Closure $next)
+ {
+ $proxy = Config::get('app.proxy');
+
+ switch ($mode = self::getConfigurationMode($proxy)) {
+ case TrustProxyConfigurationMode::TrustNone:
+ break;
+
+ case TrustProxyConfigurationMode::TrustSome:
+ $request->setTrustedProxies($proxy);
+ break;
+
+ case TrustProxyConfigurationMode::TrustAll:
+ $remoteAddr = $request->server->get('REMOTE_ADDR');
+ $request->setTrustedProxies([ '127.0.0.1', $remoteAddr ]);
+ break;
+
+ default:
+ throw new ArgumentException("Unhandled configuration mode: $mode");
+ }
+
+ return $next($request);
+ }
+
+ /**
+ * Gets trust proxies configuration mode
+ */
+ public static function getConfigurationMode ($configValue) {
+ if (!is_array($configValue) || !count($configValue)) {
+ return TrustProxyConfigurationMode::TrustNone;
+ }
+
+ if (in_array('*', $configValue)) {
+ return TrustProxyConfigurationMode::TrustAll;
+ }
+
+ return TrustProxyConfigurationMode::TrustSome;
+ }
+}
diff --git a/config/app.php b/config/app.php
--- a/config/app.php
+++ b/config/app.php
@@ -30,6 +30,26 @@
/*
|--------------------------------------------------------------------------
+ | Proxies serving requests
+ |--------------------------------------------------------------------------
+ |
+ | Auth Grove can handle proxy headers like HTTP_X_FORWARDED_PROTO according
+ | your configuration.
+ |
+ | - To always trust forward headers, adds a star entry: ['*']
+ | - To never trust any server, use an empty array: []
+ | - To specify the proxies servers, create an array with each IP.
+ |
+ | If you put Auth Grove on an back-end application server, with a front-end
+ | nginx responsible for SSL termination, you can set the front-end IPs or
+ | blindly trust any remote address with a magic entry '*'.
+ |
+ */
+
+ 'proxy' => env('TRUST_ALL_PROXIES', false) ? ['*'] : [],
+
+ /*
+ |--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
diff --git a/phpunit.xml b/phpunit.xml
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -12,6 +12,7 @@
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/</directory>
+ <exclude>./tests/standalone</exclude>
</testsuite>
</testsuites>
<php>
diff --git a/tests/standalone/ProxyTest.php b/tests/standalone/ProxyTest.php
new file mode 100644
--- /dev/null
+++ b/tests/standalone/ProxyTest.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Tests the bug described in T492: when using a front-end server
+ * with SSL termination, back-end should serve http:// links.
+ */
+class ProxyTest extends TestCase {
+
+ public function testProxiesAndHttpsLinksInteraction () {
+ // These cases should be in one test: if split in several tests,
+ // the application configuration isn't reset correctly and we lost.
+
+ // CASE I
+ //
+ // By default, we don't trust proxies, and we don't receive proxy
+ // information, so links are HTTP.
+ App::make('config')->set('app.proxy', []);
+
+ $this->visit('/')
+ ->see('http://localhost/');
+
+ // This header, if trusted, means we serve HTTPS links.
+ $server = [
+ 'X-Forwarded-Proto' => 'https'
+ ];
+
+ // CASE II
+ // When we don't trust proxies
+ // and reverse proxy tell us it's for HTTPS
+ // we serve HTTP links, ignoring X-Forwarded-Proto.
+ App::make('config')->set('app.proxy', []);
+ $this->get('/', $server);
+ $this->see('http://localhost');
+
+ // CASE III
+ // When we trust all proxies
+ // and reverse proxy tell us it's for HTTPS
+ // we serve HTTP links, according X-Forwarded-Proto.
+ App::make('config')->set('app.proxy', ['*']);
+ $this->get('/', $server);
+ $this->see('https://localhost/');
+
+ // CASE IV
+ // When we don't trust the current proxy
+ // and reverse proxy tell us it's for HTTPS
+ // we serve HTTP links, ignoring X-Forwarded-Proto.
+ App::make('config')->set('app.proxy', ['1.2.3.4']);
+ $this->get('/', $server);
+ $this->see('http://localhost');
+ }
+
+
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 28, 05:25 (10 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2381814
Default Alt Text
D25.id932.diff (6 KB)

Event Timeline