Completed
Push — feature/evo-2707-username-code... ( 485f61...933687 )
by
unknown
09:42
created

AbstractHttpStrategy::extractFieldInfo()   D

Complexity

Conditions 9
Paths 6

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 31
rs 4.909
cc 9
eloc 19
nc 6
nop 2
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\HttpFoundation\RequestStack;
13
14
/**
15
 * Class AbstractHttpStrategy
16
 *
17
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
18
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
19
 * @link     http://swisscom.ch
20
 */
21
abstract class AbstractHttpStrategy implements StrategyInterface
22
{
23
    /** @var RequestStack */
24
    protected $requestStack;
25
26
    /** @var string  */
27
    protected $extractUsername;
28
29
    /** @var string  */
30
    protected $extractCoreId;
31
32
    /** @var string  */
33
    protected $clientIdName;
34
35
    /**
36
     * Extracts information from the a request header field.
37
     *
38
     * @param ParameterBag|HeaderBag $header    object representation of the request header.
39
     * @param string                 $fieldname Name of the field to be read.
40
     *
41
     * @return string
42
     */
43
    protected function extractFieldInfo($header, $fieldname)
44
    {
45
        if ($header instanceof ParameterBag || $header instanceof HeaderBag) {
46
            $this->validateField($header, $fieldname);
47
            $bagValue = $header->get($fieldname, '');
48
        } else {
49
            throw new \InvalidArgumentException('Provided request information are not valid.');
50
        }
51
52
        // Get Original requested Value.
53
        if (!$this->extractUsername) {
54
            return $bagValue;
55
        }
56
57
        $pattern = "/((?m)(?<=\b{$this->extractUsername}=)[^,]*)/i";
58
        preg_match($pattern, $bagValue, $matches);
59
        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...
60
            return '';
61
        }
62
        $fieldValue = $matches[0];
63
64
        if ($this->requestStack && $this->extractCoreId && $this->clientIdName) {
65
            $pattern = "/((?m)(?<=\b{$this->extractCoreId}=)[^,]*)/i";
66
            preg_match($pattern, $bagValue, $matches);
67
            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...
68
                $this->requestStack->getCurrentRequest()->attributes->set($this->clientIdName, $matches[0]);
69
            }
70
        }
71
72
        return $fieldValue;
73
    }
74
75
    /**
76
     * Verifies that the provided header has the expected/mandatory fields.
77
     *
78
     * @param ParameterBag|HeaderBag $header    object representation of the request header.
79
     * @param string                 $fieldName Name of the header field to be validated.
80
     *
81
     * @return void
82
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
83
     */
84
    protected function validateField($header, $fieldName)
85
    {
86
        $passed = $header->has($fieldName);
87
88
        // return without exception so we can return a dummy user
89
        if (true === $passed) {
90
            // get rid of anything not a valid character
91
            $authInfo = filter_var($header->get($fieldName), FILTER_SANITIZE_STRING);
92
93
            // get rid of whitespaces
94
            $patterns = array("\r\n", "\n", "\r", "\s", "\t");
95
            $authInfo = str_replace($patterns, "", trim($authInfo));
96
97
            // get rid of control characters
98
            if (empty($authInfo) || $authInfo !== preg_replace('#[[:cntrl:]]#i', '', $authInfo)) {
99
                throw new HttpException(
100
                    Response::HTTP_NETWORK_AUTHENTICATION_REQUIRED,
101
                    'Mandatory header field (' . $fieldName . ') not provided or invalid.'
102
                );
103
            }
104
        }
105
    }
106
107
    /**
108
     * Symfony Container
109
     *
110
     * @param RequestStack $requestStack    request object
111
     * @param string       $extractUsername identifier in posted params
112
     * @param string       $extractCoreId   client specific identifier
113
     * @param string       $idName          save to request attrivute name
114
     * @return void
115
     */
116
    public function setDynamicParameters(RequestStack $requestStack, $extractUsername, $extractCoreId, $idName)
117
    {
118
        $this->requestStack = $requestStack;
119
        $this->extractUsername = $extractUsername;
120
        $this->extractCoreId = $extractCoreId;
121
        $this->clientIdName = $idName;
122
    }
123
}
124