EncryptedSearchFilter   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 67
c 1
b 0
f 0
dl 0
loc 155
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getEncryptedField() 0 4 1
A isEmpty() 0 5 3
A excludeMany() 0 25 2
A setModifiers() 0 8 2
A applyMany() 0 9 1
A getCaseSensitive() 0 3 1
A excludeOne() 0 14 1
A getEncryptedValue() 0 11 3
A applyOne() 0 13 1
A getDbName() 0 5 1
1
<?php
2
3
namespace LeKoala\Encrypt;
4
5
use Exception;
6
use SilverStripe\ORM\DB;
7
use InvalidArgumentException;
8
use SilverStripe\ORM\DataQuery;
9
use ParagonIE\CipherSweet\CipherSweet;
10
use ParagonIE\CipherSweet\EncryptedField;
11
use SilverStripe\ORM\Filters\SearchFilter;
12
13
/**
14
 * A filter that helps searching against a full blind index
15
 * This can return false positive and is NOT recommended
16
 * @deprecated
17
 */
18
class EncryptedSearchFilter extends SearchFilter
19
{
20
    /**
21
     * @param array<string> $modifiers
22
     * @return void
23
     */
24
    public function setModifiers(array $modifiers)
25
    {
26
        if (!empty($modifiers)) {
27
            throw new InvalidArgumentException(
28
                get_class($this) . ' does not accept ' . implode(', ', $modifiers) . ' as modifiers'
29
            );
30
        }
31
        parent::setModifiers($modifiers);
32
    }
33
34
    protected function getCaseSensitive()
35
    {
36
        return null;
37
    }
38
39
    public function getDbName()
40
    {
41
        $column = parent::getDbName();
42
        $column = str_replace('"', '', $column);
43
        return '"' . $column . 'BlindIndex"';
44
    }
45
46
    /**
47
     * @param CipherSweet $engine
48
     * @param bool $fashHash
49
     * @return EncryptedField
50
     */
51
    public function getEncryptedField($engine = null, $fashHash = null)
52
    {
53
        $singleton = singleton($this->model);
54
        return $singleton->dbObject($this->name)->getEncryptedField($engine, $fashHash);
55
    }
56
57
    /**
58
     * Accessor for the current value to be filtered on.
59
     *
60
     * @return string
61
     */
62
    public function getEncryptedValue()
63
    {
64
        $plaintext = $this->getValue();
65
        if (is_array($plaintext)) {
66
            throw new Exception("Array value are not supported");
67
        }
68
        $value = $this->getEncryptedField()->getBlindIndex($plaintext, $this->name . EncryptedDBField::INDEX_SUFFIX);
69
        if (is_array($value)) {
70
            return $value['value'];
71
        }
72
        return $value;
73
    }
74
75
    /**
76
     * Applies an exact match (equals) on a field value.
77
     *
78
     * @return DataQuery
79
     */
80
    protected function applyOne(DataQuery $query)
81
    {
82
        $this->model = $query->applyRelation($this->relation);
83
        $where = DB::get_conn()->comparisonClause(
84
            $this->getDbName(),
85
            '',
86
            true, // exact?
87
            false, // negate?
88
            $this->getCaseSensitive(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getCaseSensitive() targeting LeKoala\Encrypt\Encrypte...ter::getCaseSensitive() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
89
            true
90
        );
91
        $array = array($where => $this->getEncryptedValue());
92
        return $query->where($array);
93
    }
94
95
    /**
96
     * Applies an exact match (equals) on a field value against multiple
97
     * possible values.
98
     *
99
     * @return DataQuery
100
     */
101
    protected function applyMany(DataQuery $query)
102
    {
103
        $this->model = $query->applyRelation($this->relation);
104
        $caseSensitive = $this->getCaseSensitive();
0 ignored issues
show
Unused Code introduced by
The assignment to $caseSensitive is dead and can be removed.
Loading history...
Bug introduced by
Are you sure the assignment to $caseSensitive is correct as $this->getCaseSensitive() targeting LeKoala\Encrypt\Encrypte...ter::getCaseSensitive() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
105
        $values = [$this->getEncryptedValue()];
106
        $column = $this->getDbName();
107
        $placeholders = DB::placeholders($values);
108
        return $query->where(array(
109
            "$column IN ($placeholders)" => $values
110
        ));
111
    }
112
113
    /**
114
     * Excludes an exact match (equals) on a field value.
115
     *
116
     * @return DataQuery
117
     */
118
    protected function excludeOne(DataQuery $query)
119
    {
120
        $this->model = $query->applyRelation($this->relation);
121
        $column = $this->getDbName();
122
        $where = DB::get_conn()->comparisonClause(
123
            $column,
124
            '',
125
            true, // exact?
126
            true, // negate?
127
            $this->getCaseSensitive(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getCaseSensitive() targeting LeKoala\Encrypt\Encrypte...ter::getCaseSensitive() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
128
            true
129
        );
130
        $array = array($where => $this->getEncryptedValue());
131
        return $query->where($array);
132
    }
133
134
    /**
135
     * Excludes an exact match (equals) on a field value against multiple
136
     * possible values.
137
     *
138
     * @return DataQuery
139
     */
140
    protected function excludeMany(DataQuery $query)
141
    {
142
        $this->model = $query->applyRelation($this->relation);
143
        $caseSensitive = $this->getCaseSensitive();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $caseSensitive is correct as $this->getCaseSensitive() targeting LeKoala\Encrypt\Encrypte...ter::getCaseSensitive() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
144
        $values = [$this->getEncryptedValue()];
145
        $column = $this->getDbName();
146
        if ($caseSensitive === null) {
0 ignored issues
show
introduced by
The condition $caseSensitive === null is always true.
Loading history...
147
            $placeholders = DB::placeholders($values);
148
            return $query->where(array(
149
                "$column NOT IN ($placeholders)" => $values
150
            ));
151
        } else {
152
            // Generate reusable comparison clause
153
            $comparisonClause = DB::get_conn()->comparisonClause(
154
                $column,
155
                '',
156
                true, // exact?
157
                true, // negate?
158
                $this->getCaseSensitive(),
159
                true
160
            );
161
            // Since query connective is ambiguous, use AND explicitly here
162
            $count = count($values);
163
            $predicate = implode(' AND ', array_fill(0, $count, $comparisonClause));
164
            return $query->where(array($predicate => $values));
165
        }
166
    }
167
168
    public function isEmpty()
169
    {
170
        /** @var array<mixed>|string|null $v */
171
        $v = $this->getValue();
172
        return $v === array() || $v === null || $v === '';
173
    }
174
}
175