EncryptionService::encryptField()   B
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 7.4572

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 8.439
c 0
b 0
f 0
ccs 7
cts 13
cp 0.5385
cc 5
eloc 18
nc 7
nop 1
crap 7.4572
1
<?php
2
3
namespace Carnage\EncryptedColumn\Service;
4
5
use Carnage\EncryptedColumn\Encryptor\EncryptorInterface;
6
use Carnage\EncryptedColumn\Serializer\SerializerInterface;
7
use Carnage\EncryptedColumn\ValueObject\EncryptedColumn as EncryptedColumnVO;
8
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
9
use ProxyManager\Proxy\LazyLoadingInterface;
10
use ProxyManager\Proxy\VirtualProxyInterface;
11
use Psr\Container\ContainerInterface;
12
13
class EncryptionService
14
{
15
    /**
16
     * @var EncryptorInterface
17
     */
18
    private $encryptor;
19
    
20
    /**
21
     * @var SerializerInterface
22
     */
23
    private $serializer;
24
25
    /**
26
     * @var EncryptedColumnVO[]
27
     */
28
    private $originalValues = [];
29
30
    /**
31
     * @var ContainerInterface
32
     */
33
    private $encryptors;
34
35
    /**
36
     * @var ContainerInterface
37
     */
38
    private $serializers;
39
40
    /**
41
     * @var ContainerInterface
42
     */
43
    private $keys;
44
45
    public function __construct(
46
        EncryptorInterface $encryptor,
47 5
        SerializerInterface $serializer,
48
        ContainerInterface $encryptors,
49
        ContainerInterface $serializers,
50
        ContainerInterface $keys
51
    ) {
52
        $this->encryptor = $encryptor;
53 5
        $this->serializer = $serializer;
54 5
        $this->encryptors = $encryptors;
55 5
        $this->serializers = $serializers;
56 5
        $this->keys = $keys;
57 5
    }
58
59 5
    public function decryptField(EncryptedColumnVO $value)
60
    {
61 5
        $initializer = $this->createInitializer($value);
62 5
        $factory = new LazyLoadingValueHolderFactory();
63 5
        $proxy = $factory->createProxy($value->getClassname(), $initializer);
64
65 5
        $this->originalValues[spl_object_hash($proxy)] = $value;
66
67 5
        return $proxy;
68
    }
69
70 5
    public function encryptField($value): EncryptedColumnVO
71
    {
72 5
        if ($value instanceof LazyLoadingInterface) {
73
            /** @var VirtualProxyInterface $value */
74
            // If the value hasn't been decrypted; it hasn't been changed. Don't bother reencrypting unless it
75
            // was encrypted using a different configuration
76
            if (!$value->isProxyInitialized()) {
77
                $original = $this->originalValues[spl_object_hash($value)];
78
                if (
79
                    !$original->needsReencryption($this->encryptor->getIdentifier(), $this->serializer->getIdentifier())
80
                ) {
81
                        return $original;
82
                }
83
            }
84
85
            //we don't want to encrypt a proxy.
86
            $value = $value->getWrappedValueHolderValue();
0 ignored issues
show
Bug introduced by
The method getWrappedValueHolderValue() does not seem to exist on object<ProxyManager\Proxy\LazyLoadingInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87
        }
88
89 5
        if (!is_object($value)) {
90
            throw new \Exception('This column type only supports encrypting objects');
91
        }
92
93 5
        $key = $this->keys->get('default');
94
        $data = $this->encryptor->encrypt($this->serializer->serialize($value), $key);
95 5
96
        return new EncryptedColumnVO(
97
            get_class($value),
98 5
            $data,
99 5
            $this->encryptor->getIdentifier(),
100
            $this->serializer->getIdentifier(),
101
            $key->getIdentifier()
102
        );
103
    }
104
105
    /**
106
     * @param EncryptedColumnVO $value
107 5
     * @return \Closure
108
     */
109 5
    private function createInitializer(EncryptedColumnVO $value): \Closure
110 5
    {
111
        $serializer = $this->serializers->get($value->getSerializerIdentifier()->toString());
112 5
        $encryptor = $this->encryptors->get($value->getEncryptorIdentifier()->toString());
113 3
        $key = $this->keys->get($value->getKeyIdentifier()->toString());
114 3
115
        return function(& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($serializer, $encryptor, $key, $value) {
116 3
            $initializer = null;
117 5
            $wrappedObject = $serializer->unserialize($encryptor->decrypt($value->getData(), $key));
118
119
            return true;
120
        };
121
    }
122
}
123