ResolveEndpointBaseAction::doExecute()   B
last analyzed

Complexity

Conditions 6
Paths 11

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 57
c 0
b 0
f 0
ccs 36
cts 36
cp 1
rs 8.3158
cc 6
nc 11
nop 1
crap 6

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the LightSAML-Core package.
5
 *
6
 * (c) Milos Tomic <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace LightSaml\Action\Profile\Outbound\Message;
13
14
use LightSaml\Action\Profile\AbstractProfileAction;
15
use LightSaml\Context\Profile\Helper\LogHelper;
16
use LightSaml\Context\Profile\ProfileContext;
17
use LightSaml\Error\LightSamlContextException;
18
use LightSaml\Model\Metadata\EndpointReference;
19
use LightSaml\Model\Metadata\IdpSsoDescriptor;
20
use LightSaml\Model\Metadata\SpSsoDescriptor;
21
use LightSaml\Model\Protocol\AuthnRequest;
22
use LightSaml\Resolver\Endpoint\Criteria\BindingCriteria;
23
use LightSaml\Resolver\Endpoint\Criteria\DescriptorTypeCriteria;
24
use LightSaml\Resolver\Endpoint\Criteria\IndexCriteria;
25
use LightSaml\Resolver\Endpoint\Criteria\LocationCriteria;
26
use LightSaml\Resolver\Endpoint\Criteria\ServiceTypeCriteria;
27
use LightSaml\Resolver\Endpoint\EndpointResolverInterface;
28
use LightSaml\Criteria\CriteriaSet;
29
use LightSaml\SamlConstants;
30
use Psr\Log\LoggerInterface;
31
32
/**
33
 * Determines to which endpoint outbound message will be sent.
34
 */
35
abstract class ResolveEndpointBaseAction extends AbstractProfileAction
36
{
37
    /** @var EndpointResolverInterface */
38
    protected $endpointResolver;
39
40
    /**
41
     * @param LoggerInterface           $logger
42
     * @param EndpointResolverInterface $endpointResolver
43
     */
44 12
    public function __construct(LoggerInterface $logger, EndpointResolverInterface $endpointResolver)
45
    {
46 12
        parent::__construct($logger);
47
48 12
        $this->endpointResolver = $endpointResolver;
49 12
    }
50
51
    /**
52
     * @param ProfileContext $context
53
     */
54 12
    protected function doExecute(ProfileContext $context)
55
    {
56 12
        if ($context->getEndpointContext()->getEndpoint()) {
57 1
            $this->logger->debug(
58 1
                sprintf(
59 1
                    'Endpoint already set with location "%s" and binding "%s"',
60 1
                    $context->getEndpoint()->getLocation(),
61 1
                    $context->getEndpoint()->getBinding()
62
                ),
63 1
                LogHelper::getActionContext($context, $this, array(
64 1
                    'endpointLocation' => $context->getEndpoint()->getLocation(),
65 1
                    'endpointBinding' => $context->getEndpoint()->getBinding(),
66
                ))
67
            );
68
69 1
            return;
70
        }
71
72 11
        $criteriaSet = $this->getCriteriaSet($context);
73
74 10
        $message = $context->getInboundContext()->getMessage();
75 10
        if ($message instanceof AuthnRequest) {
76 7
            if (null !== $message->getAssertionConsumerServiceIndex()) {
77 1
                $criteriaSet->add(new IndexCriteria($message->getAssertionConsumerServiceIndex()));
78
            }
79 7
            if (null !== $message->getAssertionConsumerServiceURL()) {
80 1
                $criteriaSet->add(new LocationCriteria($message->getAssertionConsumerServiceURL()));
81
            }
82
        }
83
84 10
        $candidates = $this->endpointResolver->resolve($criteriaSet, $context->getPartyEntityDescriptor()->getAllEndpoints());
85
        /** @var EndpointReference $endpointReference */
86 10
        $endpointReference = array_shift($candidates);
87
88 10
        if (null == $endpointReference) {
89 1
            $message = sprintf(
90 1
                "Unable to determine endpoint for entity '%s'",
91 1
                $context->getPartyEntityDescriptor()->getEntityID()
92
            );
93 1
            $this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
94 1
            throw new LightSamlContextException($context, $message);
95
        }
96
97 9
        $this->logger->debug(
98 9
            sprintf(
99 9
                'Endpoint resolved to location "%s" and binding "%s"',
100 9
                $endpointReference->getEndpoint()->getLocation(),
101 9
                $endpointReference->getEndpoint()->getBinding()
102
            ),
103 9
            LogHelper::getActionContext($context, $this, array(
104 9
                'endpointLocation' => $endpointReference->getEndpoint()->getLocation(),
105 9
                'endpointBinding' => $endpointReference->getEndpoint()->getBinding(),
106
            ))
107
        );
108
109 9
        $context->getEndpointContext()->setEndpoint($endpointReference->getEndpoint());
110 9
    }
111
112
    /**
113
     * @param ProfileContext $context
114
     *
115
     * @return CriteriaSet
116
     */
117 11
    protected function getCriteriaSet(ProfileContext $context)
118
    {
119 11
        $criteriaSet = new CriteriaSet();
120
121 11
        $bindings = $this->getBindings($context);
122 11
        if ($bindings) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $bindings 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...
123 11
            $criteriaSet->add(new BindingCriteria($bindings));
124
        }
125
126 11
        $descriptorType = $this->getDescriptorType($context);
127 10
        if ($descriptorType) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $descriptorType of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
128 10
            $criteriaSet->add(new DescriptorTypeCriteria($descriptorType));
129
        }
130
131 10
        $serviceType = $this->getServiceType($context);
132 10
        if ($serviceType) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $serviceType of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
133 6
            $criteriaSet->add(new ServiceTypeCriteria($serviceType));
134
        }
135
136 10
        return $criteriaSet;
137
    }
138
139
    /**
140
     * @param ProfileContext $context
141
     *
142
     * @return string[]
143
     */
144 11
    protected function getBindings(ProfileContext $context)
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
145
    {
146
        return array(
147 11
            SamlConstants::BINDING_SAML2_HTTP_POST,
148
            SamlConstants::BINDING_SAML2_HTTP_REDIRECT,
149
        );
150
    }
151
152
    /**
153
     * @param ProfileContext $context
154
     *
155
     * @return string|null
156
     */
157 7
    protected function getDescriptorType(ProfileContext $context)
158
    {
159 7
        return ProfileContext::ROLE_IDP == $context->getOwnRole()
160 6
            ? SpSsoDescriptor::class
161 7
            : IdpSsoDescriptor::class;
162
    }
163
164
    /**
165
     * @param ProfileContext $context
166
     *
167
     * @return string|null
168
     */
169 4
    protected function getServiceType(ProfileContext $context)
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
170
    {
171 4
        return;
172
    }
173
}
174