DecryptAssertionsAction::doExecute()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 57
c 0
b 0
f 0
ccs 37
cts 37
cp 1
rs 8.0048
cc 7
nc 5
nop 1
crap 7

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\Inbound\Response;
13
14
use LightSaml\Action\Profile\AbstractProfileAction;
15
use LightSaml\Error\LightSamlContextException;
16
use LightSaml\Model\Context\DeserializationContext;
17
use LightSaml\Context\Profile\Helper\LogHelper;
18
use LightSaml\Context\Profile\Helper\MessageContextHelper;
19
use LightSaml\Context\Profile\ProfileContext;
20
use LightSaml\Model\Assertion\EncryptedAssertionReader;
21
use LightSaml\Resolver\Credential\CredentialResolverInterface;
22
use LightSaml\SamlConstants;
23
use LightSaml\Credential\CredentialInterface;
24
use LightSaml\Credential\UsageType;
25
use LightSaml\Credential\Criteria\EntityIdCriteria;
26
use LightSaml\Credential\Criteria\MetadataCriteria;
27
use LightSaml\Credential\Criteria\UsageCriteria;
28
use Psr\Log\LoggerInterface;
29
30
class DecryptAssertionsAction extends AbstractProfileAction
31
{
32
    /** @var CredentialResolverInterface */
33
    protected $credentialResolver;
34
35
    /**
36
     * @param LoggerInterface             $logger
37
     * @param CredentialResolverInterface $credentialResolver
38
     */
39 6
    public function __construct(LoggerInterface $logger, CredentialResolverInterface $credentialResolver)
40
    {
41 6
        parent::__construct($logger);
42
43 6
        $this->credentialResolver = $credentialResolver;
44 6
    }
45
46
    /**
47
     * @param ProfileContext $context
48
     */
49 5
    protected function doExecute(ProfileContext $context)
50
    {
51 5
        $response = MessageContextHelper::asResponse($context->getInboundContext());
0 ignored issues
show
Bug introduced by
It seems like $context->getInboundContext() can be null; however, asResponse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
52
53 5
        if (0 === count($response->getAllEncryptedAssertions())) {
54 1
            $this->logger->debug('Response has no encrypted assertions', LogHelper::getActionContext($context, $this));
55
56 1
            return;
57
        }
58
59 4
        $ownEntityDescriptor = $context->getOwnEntityDescriptor();
60
61 4
        $query = $this->credentialResolver->query();
62
        $query
63 4
            ->add(new EntityIdCriteria($ownEntityDescriptor->getEntityID()))
64 4
            ->add(new MetadataCriteria(
65 4
                ProfileContext::ROLE_IDP === $context->getOwnRole()
66 2
                ? MetadataCriteria::TYPE_IDP
67 4
                : MetadataCriteria::TYPE_SP,
68 4
                SamlConstants::PROTOCOL_SAML2
69
            ))
70 4
            ->add(new UsageCriteria(UsageType::ENCRYPTION))
71
        ;
72 4
        $query->resolve();
73 4
        $privateKeys = $query->getPrivateKeys();
74 4
        if (empty($privateKeys)) {
75 1
            $message = 'No credentials resolved for assertion decryption';
76 1
            $this->logger->emergency($message, LogHelper::getActionErrorContext($context, $this));
77 1
            throw new LightSamlContextException($context, $message);
78
        }
79 3
        $this->logger->info('Trusted decryption candidates', LogHelper::getActionContext($context, $this, array(
80
            'credentials' => array_map(function (CredentialInterface $credential) {
81 3
                return sprintf(
82 3
                    "Entity: '%s'; PK X509 Thumb: '%s'",
83 3
                    $credential->getEntityId(),
84 3
                    $credential->getPublicKey() ? $credential->getPublicKey()->getX509Thumbprint() : ''
85
                );
86 3
            }, $privateKeys),
87
        )));
88
89 3
        foreach ($response->getAllEncryptedAssertions() as $index => $encryptedAssertion) {
90 3
            if ($encryptedAssertion instanceof EncryptedAssertionReader) {
91 3
                $name = sprintf('assertion_encrypted_%s', $index);
92
                /** @var DeserializationContext $deserializationContext */
93 3
                $deserializationContext = $context->getInboundContext()->getSubContext($name, DeserializationContext::class);
94 3
                $assertion = $encryptedAssertion->decryptMultiAssertion($privateKeys, $deserializationContext);
0 ignored issues
show
Documentation introduced by
$privateKeys is of type array<integer,object<Lig...l\CredentialInterface>>, but the function expects a array<integer,object<Rob...ecLibs\XMLSecurityKey>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95 3
                $response->addAssertion($assertion);
96
97 3
                $this->logger->info(
98 3
                    'Assertion decrypted',
99 3
                    LogHelper::getActionContext($context, $this, array(
100 3
                        'assertion' => $deserializationContext->getDocument()->saveXML(),
101
                    ))
102
                );
103
            }
104
        }
105 3
    }
106
}
107