Passed
Pull Request — master (#225)
by Jaime Pérez
02:34
created

EncryptedElementTrait::fromUnencryptedElement()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 27
c 1
b 0
f 0
nc 11
nop 2
dl 0
loc 41
rs 7.3166

How to fix   Complexity   

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
declare(strict_types=1);
4
5
namespace SAML2\XML;
6
7
use DOMElement;
8
use RobRichards\XMLSecLibs\XMLSecEnc;
9
use RobRichards\XMLSecLibs\XMLSecurityKey;
10
use SAML2\Utils;
11
use SAML2\XML\xenc\EncryptedData;
12
use SAML2\XML\xenc\EncryptedKey;
13
use Webmozart\Assert\Assert;
14
15
/**
16
 * Trait aggregating functionality for encrypted elements.
17
 *
18
 * @package simplesamlphp/saml2
19
 */
20
trait EncryptedElementTrait
21
{
22
23
    /**
24
     * The current encrypted ID.
25
     *
26
     * @var \SAML2\XML\xenc\EncryptedData
27
     * @psalm-suppress PropertyNotSetInConstructor
28
     */
29
    protected $encryptedData;
30
31
    /**
32
     * A list of encrypted keys.
33
     *
34
     * @var \SAML2\XML\xenc\EncryptedKey[]
35
     */
36
    protected $encryptedKeys = [];
37
38
39
    /**
40
     * Constructor for encrypted elements.
41
     *
42
     * @param \SAML2\XML\xenc\EncryptedData $encryptedData The EncryptedData object.
43
     * @param \SAML2\XML\xenc\EncryptedKey[] $encryptedKeys An array of zero or more EncryptedKey objects.
44
     */
45
    public function __construct(EncryptedData $encryptedData, array $encryptedKeys)
46
    {
47
        $this->setEncryptedData($encryptedData);
48
        $this->setEncryptedKeys($encryptedKeys);
49
    }
50
51
52
    /**
53
     * Get the EncryptedData object.
54
     *
55
     * @return \SAML2\XML\xenc\EncryptedData
56
     */
57
    public function getEncryptedData(): EncryptedData
58
    {
59
        return $this->encryptedData;
60
    }
61
62
63
    /**
64
     * @param \SAML2\XML\xenc\EncryptedData $encryptedData
65
     */
66
    protected function setEncryptedData(EncryptedData $encryptedData): void
67
    {
68
        $this->encryptedData = $encryptedData;
69
    }
70
71
72
    /**
73
     * Get the array of EncryptedKey objects
74
     *
75
     * @return \SAML2\XML\xenc\EncryptedKey[]
76
     */
77
    public function getEncryptedKeys(): array
78
    {
79
        return $this->encryptedKeys;
80
    }
81
82
83
    /**
84
     * @param \SAML2\XML\xenc\EncryptedKey[] $encryptedKeys
85
     */
86
    protected function setEncryptedKeys(array $encryptedKeys): void
87
    {
88
        Assert::allIsInstanceOf(
89
            $encryptedKeys,
90
            EncryptedKey::class,
91
            'All encrypted keys in <' . $this->getQualifiedName() . '> must be an instance of EncryptedKey.'
0 ignored issues
show
Bug introduced by
It seems like getQualifiedName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
            'All encrypted keys in <' . $this->/** @scrutinizer ignore-call */ getQualifiedName() . '> must be an instance of EncryptedKey.'
Loading history...
92
        );
93
        $this->encryptedKeys = $encryptedKeys;
94
    }
95
96
97
    /**
98
     * Create an encrypted element from a given unencrypted element and a key.
99
     *
100
     * @param \SAML2\XML\AbstractXMLElement $element
101
     * @param \RobRichards\XMLSecLibs\XMLSecurityKey $key
102
     *
103
     * @return \SAML2\EncryptedElementInterface
0 ignored issues
show
Bug introduced by
The type SAML2\EncryptedElementInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
104
     * @throws \Exception
105
     */
106
    public static function fromUnencryptedElement(
107
        AbstractXMLElement $element,
108
        XMLSecurityKey $key
109
    ): EncryptedElementInterface {
110
        $xml = $element->toXML();
111
112
        Utils::getContainer()->debugMessage($xml, 'encrypt');
113
114
        $enc = new XMLSecEnc();
115
        $enc->setNode($xml);
116
        $enc->type = XMLSecEnc::Element;
117
118
        switch ($key->type) {
119
            case XMLSecurityKey::TRIPLEDES_CBC:
120
            case XMLSecurityKey::AES128_CBC:
121
            case XMLSecurityKey::AES192_CBC:
122
            case XMLSecurityKey::AES256_CBC:
123
                $symmetricKey = $key;
124
                break;
125
126
            case XMLSecurityKey::RSA_1_5:
127
            case XMLSecurityKey::RSA_SHA1:
128
            case XMLSecurityKey::RSA_SHA256:
129
            case XMLSecurityKey::RSA_SHA384:
130
            case XMLSecurityKey::RSA_SHA512:
131
            case XMLSecurityKey::RSA_OAEP_MGF1P:
132
                $symmetricKey = new XMLSecurityKey(XMLSecurityKey::AES128_CBC);
133
                $symmetricKey->generateSessionKey();
134
135
                $enc->encryptKey($key, $symmetricKey);
136
137
                break;
138
139
            default:
140
                throw new \Exception('Unknown key type for encryption: ' . $key->type);
141
        }
142
143
        $dom = $enc->encryptNode($symmetricKey);
144
        /** @var \SAML2\XML\xenc\EncryptedData $encData */
145
        $encData = EncryptedData::fromXML($dom);
146
        return new static($encData, []);
1 ignored issue
show
Bug Best Practice introduced by
The expression return new static($encData, array()) returns the type SAML2\XML\EncryptedElementTrait which is incompatible with the type-hinted return SAML2\XML\EncryptedElementInterface.
Loading history...
147
    }
148
149
150
    /**
151
     * @inheritDoc
152
     * @return \SAML2\XML\AbstractXMLElement
153
     */
154
    public static function fromXML(DOMElement $xml): object
155
    {
156
        Assert::same($xml->localName, self::getClassName(static::class));
157
        Assert::same($xml->namespaceURI, static::NS);
1 ignored issue
show
Bug introduced by
The constant SAML2\XML\EncryptedElementTrait::NS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
158
159
        $ed = EncryptedData::getChildrenOfClass($xml);
160
        Assert::count($ed, 1, 'No more or less than one EncryptedData element allowed in ' .
161
            AbstractXMLElement::getClassName(static::class) . '.');
162
163
        $ek = EncryptedKey::getChildrenOfClass($xml);
164
165
        return new static($ed[0], $ek);
1 ignored issue
show
Bug Best Practice introduced by
The expression return new static($ed[0], $ek) returns the type SAML2\XML\EncryptedElementTrait which is incompatible with the documented return type SAML2\XML\AbstractXMLElement.
Loading history...
166
    }
167
168
169
    /**
170
     * @inheritDoc
171
     */
172
    public function toXML(DOMElement $parent = null): DOMElement
173
    {
174
        $e = $this->instantiateParentElement($parent);
0 ignored issues
show
Bug introduced by
It seems like instantiateParentElement() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

174
        /** @scrutinizer ignore-call */ 
175
        $e = $this->instantiateParentElement($parent);
Loading history...
175
176
        $this->encryptedData->toXML($e);
177
178
        foreach ($this->encryptedKeys as $key) {
179
            $key->toXML($e);
180
        }
181
182
        return $e;
183
    }
184
}
185