Completed
Push — feature/evo-2707-username-code... ( 3f6cd5...485f61 )
by
unknown
18:12 queued 08:04
created

AbstractHttpStrategy::setContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * abstract strategy for checking auth against parts of the request
4
 */
5
6
namespace Graviton\SecurityBundle\Authentication\Strategies;
7
8
use Symfony\Component\HttpFoundation\HeaderBag;
9
use Symfony\Component\HttpFoundation\ParameterBag;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Exception\HttpException;
12
use Symfony\Component\DependencyInjection\Container;
13
use Symfony\Component\HttpFoundation\RequestStack;
14
15
/**
16
 * Class AbstractHttpStrategy
17
 *
18
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
19
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
20
 * @link     http://swisscom.ch
21
 */
22
abstract class AbstractHttpStrategy implements StrategyInterface
23
{
24
    /** @var Container */
25
    protected $container;
26
27
    /**
28
     * Extracts information from the a request header field.
29
     *
30
     * @param ParameterBag|HeaderBag $header    object representation of the request header.
31
     * @param string                 $fieldname Name of the field to be read.
32
     *
33
     * @return string
34
     */
35
    protected function extractFieldInfo($header, $fieldname)
36
    {
37
        if ($header instanceof ParameterBag || $header instanceof HeaderBag) {
38
            $this->validateField($header, $fieldname);
39
            $bagValue = $header->get($fieldname, '');
40
        } else {
41
            throw new \InvalidArgumentException('Provided request information are not valid.');
42
        }
43
44
        // Cookie value can be a coma separated string
45
        $extractField = $this->container->getParameter('graviton.security.core_extract_username');
46
47
        // Get Original requested Value.
48
        if (!$extractField) {
49
            return $bagValue;
50
        }
51
52
        $pattern = "/((?m)(?<=\b{$extractField}=)[^,]*)/i";
53
        preg_match($pattern,$bagValue, $matches);
54
        if ( !$matches ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
55
            return '';
56
        }
57
        $fieldValue = $matches[0];
58
59
        if (($clientIdName = $this->container->getParameter('graviton.security.core_id_name'))
60
            && ($extractId = $this->container->getParameter('graviton.security.core_extract_core_id')))
61
        {
62
            $pattern = "/((?m)(?<=\b{$extractId}=)[^,]*)/i";
63
            preg_match($pattern, $bagValue, $matches);
64
            if ( $matches ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matches of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
65
                /** @var RequestStack $requestStack */
66
                $requestStack = $this->container->get('request_stack');
67
                $requestStack->getCurrentRequest()->attributes->set($clientIdName, $matches[0]);
68
            }
69
        }
70
71
        return $fieldValue;
72
    }
73
74
    /**
75
     * Verifies that the provided header has the expected/mandatory fields.
76
     *
77
     * @param ParameterBag|HeaderBag $header    object representation of the request header.
78
     * @param string                 $fieldName Name of the header field to be validated.
79
     *
80
     * @return void
81
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
82
     */
83
    protected function validateField($header, $fieldName)
84
    {
85
        $passed = $header->has($fieldName);
86
87
        // return without exception so we can return a dummy user
88
        if (true === $passed) {
89
            // get rid of anything not a valid character
90
            $authInfo = filter_var($header->get($fieldName), FILTER_SANITIZE_STRING);
91
92
            // get rid of whitespaces
93
            $patterns = array("\r\n", "\n", "\r", "\s", "\t");
94
            $authInfo = str_replace($patterns, "", trim($authInfo));
95
96
            // get rid of control characters
97
            if (empty($authInfo) || $authInfo !== preg_replace('#[[:cntrl:]]#i', '', $authInfo)) {
98
                throw new HttpException(
99
                    Response::HTTP_NETWORK_AUTHENTICATION_REQUIRED,
100
                    'Mandatory header field (' . $fieldName . ') not provided or invalid.'
101
                );
102
            }
103
        }
104
    }
105
106
    /**
107
     * @param Container $container
108
     */
109
    public function setContainer(Container $container) {
110
        $this->container = $container;
111
    }
112
}
113