Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
23 / 23 |
BasicAuthentication | |
100.00% |
1 / 1 |
|
100.00% |
2 / 2 |
12 | |
100.00% |
23 / 23 |
__construct | |
100.00% |
1 / 1 |
10 | |
100.00% |
20 / 20 |
|||
logout | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
1 | <?php |
2 | |
3 | namespace Miniframe\Middleware; |
4 | |
5 | use Miniframe\Core\AbstractMiddleware; |
6 | use Miniframe\Core\Config; |
7 | use Miniframe\Core\Request; |
8 | use Miniframe\Core\Response; |
9 | use Miniframe\Response\RedirectResponse; |
10 | use Miniframe\Response\UnauthorizedResponse; |
11 | |
12 | /** |
13 | * Basic HTTP Authentication class |
14 | * |
15 | * This middleware adds basic HTTP authentication to your application. |
16 | */ |
17 | class BasicAuthentication extends AbstractMiddleware |
18 | { |
19 | /** |
20 | * Forces the user to be logged in |
21 | * |
22 | * @param Request $request Reference to the Request object. |
23 | * @param Config $config Reference to the Config object. |
24 | */ |
25 | public function __construct(Request $request, Config $config) |
26 | { |
27 | parent::__construct($request, $config); |
28 | |
29 | // Don't do authentication on shell requests |
30 | if ($request->isShellRequest()) { |
31 | return; |
32 | } |
33 | |
34 | // Check if the current path is part of the exclusion list |
35 | $fullPath = '/' . implode('/', $request->getPath()); // $_SERVER['REQUEST_URI'] can't be used since |
36 | // that doesn't apply on Console requests |
37 | $excludeList = $config->has('authentication', 'exclude') ? $config->get('authentication', 'exclude') : []; |
38 | foreach ($excludeList as $excludePath) { |
39 | $regex = '/^' . str_replace(['?', '\\*'], ['.', '.*?'], preg_quote($excludePath, '/')) . '$/'; |
40 | if (preg_match($regex, $fullPath)) { |
41 | return; |
42 | } |
43 | } |
44 | |
45 | // Fetches the realm |
46 | $realm = $this->config->get('authentication', 'realm'); |
47 | |
48 | // Check if we have credentials |
49 | if (!$request->getServer('PHP_AUTH_USER') || !$request->getServer('PHP_AUTH_PW')) { |
50 | throw new UnauthorizedResponse($realm); |
51 | } |
52 | |
53 | // Fetch user table |
54 | $userTable = $config->get('authentication', 'user'); |
55 | if (!is_array($userTable)) { |
56 | throw new \RuntimeException('The usertable is invalid. Please check your configuration.'); |
57 | } |
58 | |
59 | // Is the username valid? |
60 | if (!isset($userTable[$request->getServer('PHP_AUTH_USER')])) { |
61 | throw new UnauthorizedResponse($realm); |
62 | } |
63 | |
64 | // Is the password valid? |
65 | if (!password_verify($request->getServer('PHP_AUTH_PW'), $userTable[$request->getServer('PHP_AUTH_USER')])) { |
66 | throw new UnauthorizedResponse($realm); |
67 | } |
68 | |
69 | // We passed the BasicAuthentication middleware, continue. |
70 | } |
71 | |
72 | /** |
73 | * Returns a response that forces the user to log out |
74 | * |
75 | * @return Response |
76 | */ |
77 | public function logout(): Response |
78 | { |
79 | $url = $this->request->isHttpsRequest() ? 'https' : 'http'; |
80 | $url .= '://logout@' . $this->request->getServer('HTTP_HOST') . $this->config->get('framework', 'base_href'); |
81 | return new RedirectResponse($url); |
82 | } |
83 | } |