Passed
Push — master ( 45a3bb...2cf7c0 )
by Thomas
03:37
created

EncryptedDBFile   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 37
c 1
b 0
f 0
dl 0
loc 91
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A sendDecryptedFile() 0 23 5
A encryptFileIfNeeded() 0 24 5
A getEncryptedFileInstance() 0 5 1
A isEncrypted() 0 5 1
1
<?php
2
3
namespace LeKoala\Encrypt;
4
5
use Exception;
6
use SilverStripe\Assets\File;
7
use SilverStripe\ORM\DataExtension;
8
use ParagonIE\CipherSweet\CipherSweet;
9
use ParagonIE\CipherSweet\EncryptedFile;
10
11
/**
12
 * Safe and encrypted content file
13
 * Also make sure that files are not public assets! => use htaccess
14
 * @property bool $Encrypted
15
 * @property File|EncryptedDBFile $owner
16
 */
17
class EncryptedDBFile extends DataExtension
18
{
19
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
20
        "Encrypted" => "Boolean",
21
    ];
22
23
    /**
24
     * @return EncryptedFile
25
     */
26
    protected function getEncryptedFileInstance()
27
    {
28
        $engine = EncryptHelper::getCipherSweet();
29
        $encFile = new EncryptedFile($engine);
30
        return $encFile;
31
    }
32
33
    /**
34
     * Check if the actual file on the filesystem is encrypted
35
     * You might also use the Encrypted field that should be accurate
36
     *
37
     * @return boolean
38
     */
39
    public function isEncrypted()
40
    {
41
        $encFile = $this->getEncryptedFileInstance();
42
        $stream = $this->owner->getStream();
0 ignored issues
show
Bug introduced by
The method getStream() does not exist on LeKoala\Encrypt\EncryptedDBFile. ( Ignorable by Annotation )

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

42
        /** @scrutinizer ignore-call */ 
43
        $stream = $this->owner->getStream();

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...
43
        return $encFile->isStreamEncrypted($stream);
44
    }
45
46
    /**
47
     * Output file using regular php
48
     *
49
     * @throws Exception
50
     * @return void
51
     */
52
    public function sendDecryptedFile()
53
    {
54
        if (ob_get_level()) {
55
            ob_end_clean();
56
        }
57
        $stream = $this->owner->getStream();
58
        if ($this->owner->Encrypted) {
59
            $encFile = $this->getEncryptedFileInstance();
60
            $output = fopen('php://temp', 'w+b');
61
62
            // We need to decrypt stream
63
            if ($encFile->isStreamEncrypted($stream)) {
64
                $success = $encFile->decryptStream($stream, $output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $outputFP of ParagonIE\CipherSweet\En...edFile::decryptStream() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

64
                $success = $encFile->decryptStream($stream, /** @scrutinizer ignore-type */ $output);
Loading history...
65
                if (!$success) {
66
                    throw new Exception("Failed to decrypt stream");
67
                }
68
69
                // Rewind first
70
                rewind($output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $handle of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

70
                rewind(/** @scrutinizer ignore-type */ $output);
Loading history...
71
                fpassthru($output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $handle of fpassthru() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

71
                fpassthru(/** @scrutinizer ignore-type */ $output);
Loading history...
72
            }
73
        }
74
        fpassthru($stream);
75
    }
76
77
    /**
78
     * Files are not encrypted automatically
79
     * Calls this method to encrypt them
80
     *
81
     * @throws Exception
82
     * @return void
83
     */
84
    public function encryptFileIfNeeded()
85
    {
86
        $encFile = $this->getEncryptedFileInstance();
87
        $stream = $this->owner->getStream();
88
89
        if (!$encFile->isStreamEncrypted($stream)) {
90
            // php://temp is not a file path, it's a pseudo protocol that always creates a new random temp file when used.
91
            $output = fopen('php://temp', 'wb');
92
            // $success = fwrite($output, 'test');
93
            $success =  $encFile->encryptStream($stream, $output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $outputFP of ParagonIE\CipherSweet\En...edFile::encryptStream() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

93
            $success =  $encFile->encryptStream($stream, /** @scrutinizer ignore-type */ $output);
Loading history...
94
            if (!$success) {
95
                throw new Exception("Failed to encrypt stream");
96
            }
97
            // dont forget to rewind the stream !
98
            rewind($output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $handle of rewind() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

98
            rewind(/** @scrutinizer ignore-type */ $output);
Loading history...
99
            $this->owner->setFromStream($output, $this->owner->getFilename());
0 ignored issues
show
Bug introduced by
The method setFromStream() does not exist on LeKoala\Encrypt\EncryptedDBFile. ( Ignorable by Annotation )

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

99
            $this->owner->/** @scrutinizer ignore-call */ 
100
                          setFromStream($output, $this->owner->getFilename());

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...
Bug introduced by
The method getFilename() does not exist on LeKoala\Encrypt\EncryptedDBFile. ( Ignorable by Annotation )

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

99
            $this->owner->setFromStream($output, $this->owner->/** @scrutinizer ignore-call */ getFilename());

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...
100
            // Mark as encrypted in db
101
            $this->owner->Encrypted =  true;
102
            $this->owner->write();
0 ignored issues
show
Bug introduced by
The method write() does not exist on LeKoala\Encrypt\EncryptedDBFile. ( Ignorable by Annotation )

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

102
            $this->owner->/** @scrutinizer ignore-call */ 
103
                          write();

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...
103
        } elseif ($this->owner->Encrypted) {
104
            // Stream is not encrypted
105
            if ($this->owner->Encrypted) {
106
                $this->owner->Encrypted = false;
107
                $this->owner->write();
108
            }
109
        }
110
    }
111
}
112