Passed
Pull Request — master (#6)
by Chris
05:44
created

EncryptionService::encryptField()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6.0987

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 11
cts 17
cp 0.6471
rs 8.439
c 0
b 0
f 0
cc 5
eloc 18
nc 7
nop 1
crap 6.0987
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
    /**
46
     * EncryptionService constructor.
47
     * @param EncryptorInterface $encryptor
48
     * @param SerializerInterface $serializer
49
     * @param ContainerInterface $encryptors
50
     * @param ContainerInterface $serializers
51
     */
52 6
    public function __construct(
53
        EncryptorInterface $encryptor,
54
        SerializerInterface $serializer,
55
        ContainerInterface $encryptors,
56
        ContainerInterface $serializers,
57
        ContainerInterface $keys
58
    ) {
59 6
        $this->encryptor = $encryptor;
60 6
        $this->serializer = $serializer;
61 6
        $this->encryptors = $encryptors;
62 6
        $this->serializers = $serializers;
63 6
        $this->keys = $keys;
64 6
    }
65
66 6
    public function decryptField(EncryptedColumnVO $value)
67
    {
68 6
        $initializer = $this->createInitializer($value);
69 6
        $factory = new LazyLoadingValueHolderFactory();
70 6
        $proxy = $factory->createProxy($value->getClassname(), $initializer);
71
72 6
        $this->originalValues[spl_object_hash($proxy)] = $value;
73
74 6
        return $proxy;
75
    }
76
77 6
    public function encryptField($value): EncryptedColumnVO
78
    {
79 6
        if ($value instanceof LazyLoadingInterface) {
80
            /** @var VirtualProxyInterface $value */
81
            // If the value hasn't been decrypted; it hasn't been changed. Don't bother reencrypting unless it
82
            // was encrypted using a different configuration
83
            if (!$value->isProxyInitialized()) {
84
                $original = $this->originalValues[spl_object_hash($value)];
85
                if (
86
                    !$original->needsReencryption($this->encryptor->getIdentifier(), $this->serializer->getIdentifier())
87
                ) {
88
                        return $original;
89
                }
90
            }
91
92
            //we don't want to encrypt a proxy.
93
            $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...
94
        }
95
96 6
        if (!is_object($value)) {
97
            throw new \Exception('This column type only supports encrypting objects');
98
        }
99
100 6
        $key = $this->keys->get('default');
101 6
        $data = $this->encryptor->encrypt($this->serializer->serialize($value), $key);
102
103 6
        return new EncryptedColumnVO(
104 6
            get_class($value),
105 6
            $data,
106 6
            $this->encryptor->getIdentifier(),
107 6
            $this->serializer->getIdentifier(),
108 6
            $key->getIdentifier()
109
        );
110
    }
111
112
    /**
113
     * @param EncryptedColumnVO $value
114
     * @return \Closure
115
     */
116 6
    private function createInitializer(EncryptedColumnVO $value): \Closure
117
    {
118 6
        $serializer = $this->serializers->get($value->getSerializerIdentifier()->toString());
119 6
        $encryptor = $this->encryptors->get($value->getEncryptorIdentifier()->toString());
120 6
        $key = $this->keys->get($value->getKeyIdentifier()->toString());
121
122 6
        return function(& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) use ($serializer, $encryptor, $key, $value) {
123 4
            $initializer = null;
124 4
            $wrappedObject = $serializer->unserialize($encryptor->decrypt($value->getData(), $key));
125
126 4
            return true;
127 6
        };
128
    }
129
}
130