Skip to content

Commit

Permalink
Merge pull request #2 from konsulting/feature__multiple_passwords
Browse files Browse the repository at this point in the history
Allow multiple blockade codes
  • Loading branch information
rdarcy1 authored Apr 8, 2019
2 parents 5f9ff70 + 72a5bcc commit 088e429
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 13 deletions.
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
],
"require": {
"php": "^5.6 | ^7.0",
"laravel/framework": "~5.3|~5.4|~5.5"
"laravel/framework": "^5.3"
},
"require-dev": {
"phpunit/phpunit": "^5.6|^6.0",
"orchestra/testbench": "~3.0",
"phpunit/phpunit": "^7.5",
"orchestra/testbench": "~3.8",
"orchestra/testbench-browser-kit": "~3.1"
},
"autoload": {
Expand Down
64 changes: 64 additions & 0 deletions config/blockade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,73 @@
<?php

return [
/*
|--------------------------------------------------------------------------
| Blockade key
|--------------------------------------------------------------------------
|
| This value sets the name of the HTTP request parameter to which the
| code is assigned when making a request. E.g. if the key is `dev`
| and code is `letmein`, your request would be /page?dev=letmein.
|
*/
'key' => 'dev',

/*
|--------------------------------------------------------------------------
| Blockade code
|--------------------------------------------------------------------------
|
| The main pass code that is required to pass the blockade. If using
| multiple pass codes, this must be a comma-separated list (defined
| as a single string). Set to `false` to disable blockade.
|
*/
'code' => env('BLOCKADE_CODE', false),

/*
|--------------------------------------------------------------------------
| Allow multiple codes
|--------------------------------------------------------------------------
|
| Whether or not to allow multiple codes to be set. If true, the codes
| must be specified as a single string containing a comma-delimited
| list. Codes are trimmed before comparison.
|
*/
'multiple_codes' => env('BLOCKADE_MULTIPLE_CODES', false),

/*
|--------------------------------------------------------------------------
| Show form on blocked view
|--------------------------------------------------------------------------
|
| Whether or not to show a password text input for bypassing the blockade
| on the blocked view. If disabled, you can still pass the blockade by
| appending the code to the URL (see Blockade key above).
|
*/
'show_form' => false,

/*
|--------------------------------------------------------------------------
| Not-blocked list
|--------------------------------------------------------------------------
|
| The URLs excluded from the blockade (so will never be blocked). Should
| be an array of strings, and may use wildcard patterns.
|
*/
'not_blocked' => [],

/*
|--------------------------------------------------------------------------
| Not-forced-secure list
|--------------------------------------------------------------------------
|
| The URLs excluded from the force-secure checks. Should be an array of
| strings, and may use wildcard patterns.
|
*/
'not_secure' => [],
];
1 change: 0 additions & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
Expand Down
8 changes: 5 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Blockade

* A simple block for your [Laravel](https://laravel.com) app to prevent access without a known code, and to force to https if you wish.*
A simple block for your [Laravel](https://laravel.com) app to prevent access without a known code, and to force to https if you wish.*

## Installation

* Install Blockade using composer: `composer require konsulting/laravel-blockade`

* If you are using Laravel 5.5, the package will make the serivce provider available for auto-discovery.
* If you are using Laravel 5.5, the package will make the service provider available for auto-discovery.
If you are using an earlier version of Laravel, add Blockade's Service Provider to `config/app.php`

```php
Expand Down Expand Up @@ -40,12 +40,14 @@ _Only add the middleware you want to use._

## Configuration Options

There is a small set of configuration options.
There is a small set of configuration options. See the `blockade.php` config file for more information.

**key** - the variable name for the 'unlock code' to be used when checking is the site is blocked.

**code** - the code that allows access, it can be set using the environment variable `BLOCKADE_CODE` in the `.env` file

**multiple_codes** - whether or not to allow multiple codes to be used (specified as a comma-delimited list). Defaults to `false`

**show_form** - should Blockade show a form for the user to enter the code? defaults to `false`

**not_blocked** - an array of url patterns that should not be blocked
Expand Down
70 changes: 64 additions & 6 deletions src/IsBlocked.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,57 @@
namespace Konsulting\Laravel\Blockade;

use Closure;
use Illuminate\Session\Store;
use Illuminate\Http\Request;
use Illuminate\Session\Store as SessionStore;

class IsBlocked
{
/** @var SessionStore */
protected $session;

/**
* The blockade pass code.
*
* @var string
*/
protected $code;

/**
* The URL parameter through which the blockade code may be supplied.
*
* @var string
*/
protected $key;

/**
* The list of URLs to exclude from the block.
*
* @var string[]
*/
protected $exclude;

public function __construct(Store $session)
/**
* Whether we should be checking against a single code, or a comma-delimited list.
*
* @var bool
*/
protected $allowMultipleCodes;

public function __construct(SessionStore $session)
{
$this->session = $session;

$this->key = config('blockade.key', 'dev');
$this->code = config('blockade.code', false);
$this->exclude = config('blockade.not_blocked', []);
$this->allowMultipleCodes = config('blockade.multiple_codes', false);
}

/**
* Handle an incoming request.
* Check if we should proceed to the route, or display the blocked view.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
Expand All @@ -40,13 +68,19 @@ public function handle($request, Closure $next)
return redirect($this->urlWithKeyStripped($request));
}

if ($this->session->get($this->key, false) !== $this->code) {
if (! $this->codeIsValid()) {
return response(view('blockade::is_blocked'), 200);
}

return $next($request);
}

/**
* Check if the current route is excluded from the block.
*
* @param Request $request
* @return bool
*/
protected function isExcludedFromBlock($request)
{
if ($this->code == false) {
Expand All @@ -62,10 +96,34 @@ protected function isExcludedFromBlock($request)
return false;
}

/**
* Get the current URL with the blockade key parameter removed.
*
* @param Request $request
* @return string
*/
protected function urlWithKeyStripped($request)
{
$query = $request->except($this->key);

return $request->path() . ($query ? '?' . http_build_query($query) : '');
}

/**
* Check if the supplied code is valid.
*
* @return bool
*/
protected function codeIsValid()
{
$codeToCheck = $this->session->get($this->key, false);

if ($this->allowMultipleCodes) {
$referenceCodes = array_map('trim', explode(',', $this->code));

return in_array($codeToCheck, $referenceCodes, true);
}

return $codeToCheck === $this->code;
}
}
23 changes: 23 additions & 0 deletions tests/BlockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,27 @@ public function test_it_doesnt_block_access_to_a_non_blocked_route()
$this->visitRoute('not-blocked')
->see('Not Blocked');
}

/** @dataProvider passwordProvider */
public function test_it_accepts_multiple_codes($code, $shouldPass, $enableMultipleCodes = true)
{
$this->app['config']->set('blockade.code', 'pass1, pass 2');
$this->app['config']->set('blockade.multiple_codes', $enableMultipleCodes);
$this->visitRoute('home', ['dev' => $code]);

$method = $shouldPass ? 'see' : 'dontSee';
$this->$method('Home');
}

public function passwordProvider()
{
return [
['pass1', true],
['pass 2', true],
[' pass 2 ', true],
['pass1, pass 2', false],
['pass1, pass 2', true, false],
['pass1', false, false],
];
}
}

0 comments on commit 088e429

Please sign in to comment.