Completed
Push — master ( 6e1cad...d0be90 )
by Florent
02:47
created

Encrypter::encryptData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 12
Ratio 100 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 12
loc 12
rs 9.4286
cc 1
eloc 7
nc 1
nop 6
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2015 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace SpomkyLabs\JoseBundle\Service;
13
14
use Jose\Algorithm\JWAManagerInterface;
15
use Jose\Compression\CompressionManagerInterface;
16
use Jose\EncrypterInterface;
17
use Jose\JSONSerializationModes;
18
use Jose\Payload\PayloadConverterManagerInterface;
19
use SpomkyLabs\JoseBundle\Model\JotManagerInterface;
20
21
/**
22
 */
23
final class Encrypter implements EncrypterInterface
24
{
25
    /**
26
     * @var null|\SpomkyLabs\JoseBundle\Model\JotManagerInterface
27
     */
28
    private $jot_manager;
29
30
    /**
31
     * @var \Jose\Encrypter
32
     */
33
    private $encrypter;
34
35
    /**
36
     * Encrypter constructor.
37
     *
38
     * @param \Jose\Algorithm\JWAManagerInterface                   $jwa_manager
39
     * @param \Jose\Payload\PayloadConverterManagerInterface        $payload_converter_manager
40
     * @param \Jose\Compression\CompressionManagerInterface         $compression_manager
41
     * @param \SpomkyLabs\JoseBundle\Model\JotManagerInterface|null $jot_manager
42
     */
43
    public function __construct(
44
        JWAManagerInterface $jwa_manager,
45
        PayloadConverterManagerInterface $payload_converter_manager,
46
        CompressionManagerInterface $compression_manager,
47
        JotManagerInterface $jot_manager = null
48
    ) {
49
        $this->jot_manager = $jot_manager;
50
        $this->encrypter = new \Jose\Encrypter($jwa_manager, $payload_converter_manager, $compression_manager);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function encrypt($input, array $instructions, $serialization, array $shared_protected_header = [], array $shared_unprotected_header = [], $aad = null)
57
    {
58
        if (!$this->jot_manager instanceof JotManagerInterface) {
59
            return $this->encrypter->encrypt($input, $instructions, $serialization, $shared_protected_header, $shared_unprotected_header, $aad);
0 ignored issues
show
Bug introduced by
It seems like $aad defined by parameter $aad on line 56 can also be of type string; however, Jose\Encrypter::encrypt() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
60
        }
61
62 View Code Duplication
        if (1 < count($instructions) && $serialization !== JSONSerializationModes::JSON_SERIALIZATION) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
            $result = [];
64
            foreach($instructions as $instruction) {
65
                $result[] = $this->encryptData($input, [$instruction], $serialization, $shared_protected_header, $shared_unprotected_header, $aad);
66
            }
67
68
            return $result;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $result; (array) is incompatible with the return type declared by the interface Jose\EncrypterInterface::encrypt of type string|string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
69
        } else {
70
            return $this->encryptData($input, $instructions, $serialization, $shared_protected_header, $shared_unprotected_header, $aad);
71
        }
72
    }
73
74
    /**
75
     * Encrypt an input and convert it into a JWE JSON (Compact/Flattened) Serialized representation.
76
     *
77
     * To encrypt the input using different algorithms, the "alg" parameter must be set in the unprotected header of the $instruction.
78
     * Please note that this is not possible when using the algorithms "dir" or "ECDH-ES".
79
     *
80
     * @param \Jose\Object\JWTInterface|\Jose\Object\JWKInterface|\Jose\Object\JWKSetInterface|array|string $input                     A JWKInterface/JWKInterface/JWKSetInterface object
81
     * @param \Jose\Object\EncryptionInstructionInterface[]                                                 $instructions              A list of instructions used to encrypt the input
82
     * @param array                                                                                         $shared_protected_header   Shared protected headers. If the input is a JWTInterface object, this parameter is merged with the protected header of the input.
83
     * @param array                                                                                         $shared_unprotected_header Shared unprotected headers. If the input is a JWTInterface object, this parameter is merged with the unprotected header of the input.
84
     * @param string                                                                                        $serialization             Serialization method.
85
     * @param string|null                                                                                   $aad                       Additional Authentication Data. This parameter is useless if the serialization is JSON_COMPACT_SERIALIZATION.
86
     *
87
     * @throws \Exception
88
     *
89
     * @return string|string[] The JSON (Compact/Flattened) Serialized representation
90
     */
91 View Code Duplication
    private function encryptData($input, array $instructions, $serialization, array $shared_protected_header = [], array $shared_unprotected_header = [], $aad = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
    {
93
        $jot = $this->jot_manager->createJot();
94
        $shared_protected_header['jti'] = $jot->getJti();
95
96
        $jwe = $this->encrypter->encrypt($input, $instructions, $serialization, $shared_protected_header, $shared_unprotected_header, $aad);
0 ignored issues
show
Bug introduced by
It seems like $aad defined by parameter $aad on line 91 can also be of type string; however, Jose\Encrypter::encrypt() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
97
98
        $jot = $jot->withData($jwe);
99
        $this->jot_manager->saveJot($jot);
100
101
        return $jwe;
102
    }
103
}
104