Passed
Push — master ( 21a99a...da6cff )
by Nicolaas
08:06
created

HealthCheckProviderSecurity::onAfterWrite()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Sunnysideup\HealthCheckProvider\Model;
4
5
use SilverStripe\Forms\CheckboxField;
6
use SilverStripe\Forms\ReadonlyField;
7
use SilverStripe\ORM\DataObject;
8
use SilverStripe\Security\Member;
9
use SilverStripe\Security\Security;
10
11
class HealthCheckProviderSecurity extends DataObject
12
{
13
    #######################
14
    ### Names Section
15
    #######################
16
17
    private static $singular_name = 'Security Check';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
18
19
    private static $plural_name = 'Security Checks';
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
20
21
    private static $table_name = 'HealthCheckProviderSecurity';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
22
23
    #######################
24
    ### Model Section
25
    #######################
26
27
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
28
        'Secret' => 'Varchar(255)',
29
        'IpAddress' => 'Varchar(64)',
30
        'Allowed' => 'Boolean',
31
        'AllowAllData' => 'Boolean',
32
        'DefinitelyNotOk' => 'Boolean',
33
        'AccessCount' => 'Int',
34
    ];
35
36
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
37
        'Editor' => Member::class,
38
    ];
39
40
    #######################
41
    ### Further DB Field Details
42
    #######################
43
44
    private static $default_sort = [
0 ignored issues
show
introduced by
The private property $default_sort is not used, and could be removed.
Loading history...
45
        'Allowed' => 'DESC',
46
        'Created' => 'DESC',
47
    ];
48
49
    #######################
50
    ### Field Names and Presentation Section
51
    #######################
52
53
    private static $field_labels = [
0 ignored issues
show
introduced by
The private property $field_labels is not used, and could be removed.
Loading history...
54
        'Secret' => 'Api Key Provided by Retriever',
55
        'IpAddress' => 'IP Address of Retriever',
56
        'Allowed' => 'Allow this key from this IP address?',
57
        'Editor' => 'Report Editor',
58
        'EditorID' => 'Report Editor',
59
    ];
60
61
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
62
        'Created' => 'First Access',
63
        'Allowed.Nice' => 'Allow',
64
        'Editor.Title' => 'Editor',
65
        'Secret' => 'Api Key Provided',
66
        'IpAddress' => 'IP',
67
        'AccessCount' => 'Access Count',
68
    ];
69
70
    #######################
71
    ### Casting Section
72
    #######################
73
74
    private static $casting = [
0 ignored issues
show
introduced by
The private property $casting is not used, and could be removed.
Loading history...
75
        'Title' => 'Varchar',
76
    ];
77
78
    public static function check(string $key, string $ip): bool
79
    {
80
        $obj = self::get_object_from_filter($key, $ip);
81
82
        return (bool) $obj->Allowed;
83
    }
84
85
    public static function get_editor_id(string $key, string $ip): int
86
    {
87
        $obj = self::get_object_from_filter($key, $ip);
88
89
        return (int) $obj->EditorID;
90
    }
91
92
    /**
93
     * casted variable
94
     * @return string
95
     */
96
    public function getTitle(): string
97
    {
98
        return 'Retrieval attempt from "' . $this->IpAddress . '" using "' . $this->Secret . '" as key';
99
    }
100
101
    #######################
102
    ### can Section
103
    #######################
104
105
    public function canCreate($member = null, $context = [])
106
    {
107
        return false;
108
    }
109
110
    public function canDelete($member = null)
111
    {
112
        return false;
113
    }
114
115
    public function canEdit($member = null)
116
    {
117
        return $this->DefinitelyNotOk ? false : parent::canEdit($member);
0 ignored issues
show
Bug Best Practice introduced by
The property DefinitelyNotOk does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity. Since you implemented __get, consider adding a @property annotation.
Loading history...
118
    }
119
120
    #######################
121
    ### write Section
122
    #######################
123
124
    public function onBeforeWrite()
125
    {
126
        parent::onBeforeWrite();
127
        if (! $this->EditorID) {
128
            $user = Security::getCurrentUser();
129
            if ($user) {
0 ignored issues
show
introduced by
$user is of type SilverStripe\Security\Member, thus it always evaluated to true.
Loading history...
130
                $this->EditorID = Security::getCurrentUser()->ID;
0 ignored issues
show
Bug Best Practice introduced by
The property EditorID does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
131
            }
132
        }
133
        if (! $this->Secret) {
134
            $this->Secret = 'Careful: no key set - ' . mt_rand(0, 9999999999999999);
0 ignored issues
show
Bug Best Practice introduced by
The property Secret does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
135
        }
136
        if (! $this->IpAddress) {
137
            $this->IpAddress = 'Careful: no IP Set';
0 ignored issues
show
Bug Best Practice introduced by
The property IpAddress does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
138
        }
139
        if ($this->DefinitelyNotOk) {
0 ignored issues
show
Bug Best Practice introduced by
The property DefinitelyNotOk does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity. Since you implemented __get, consider adding a @property annotation.
Loading history...
140
            $this->Allowed = false;
0 ignored issues
show
Bug Best Practice introduced by
The property Allowed does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
141
        }
142
    }
143
144
    public function onAfterWrite()
145
    {
146
        parent::onAfterWrite();
147
        if($this->AllowAllData) {
0 ignored issues
show
Bug Best Practice introduced by
The property AllowAllData does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity. Since you implemented __get, consider adding a @property annotation.
Loading history...
148
            $items = HealthCheckItemProvider::get()->filter(['Include' => false]);
149
            foreach($items as $item) {
150
                $item->Include = true;
151
                $item->write();
152
            }
153
        }
154
    }
155
156
    #######################
157
    ### CMS Edit Section
158
    #######################
159
160
    public function getCMSFields()
161
    {
162
        $fields = parent::getCMSFields();
163
        $fields->addFieldsToTab(
164
            'Root.Main',
165
            [
166
                ReadonlyField::create('Secret', 'Secret Key'),
167
                ReadonlyField::create('IpAddress', 'IP'),
168
                ReadonlyField::create('AccessCount', 'Access Count'),
169
                CheckboxField::create('Allowed', 'Allow this IP with this Key?  If unsure, please double-check!')
170
                    ->setDescription('Make sure that you are OK with both the key and the IP address to ensure security.'),
171
                CheckboxField::create('AllowAllData', 'Check this box to allow access to all for any IPs granted access')
172
                    ->setDescription('Carefully consider if you are ok with this'),
173
                CheckboxField::create('DefinitelyNotOk', 'Check if you think this is a bad request')
174
                    ->setDescription('Careful, checking this will stop any future retrievals with this key and IP.'),
175
            ]
176
        );
177
178
        return $fields;
179
    }
180
181
    protected static function get_object_from_filter(string $key, string $ip): HealthCheckProviderSecurity
182
    {
183
        $filter = [
184
            'Secret' => $key,
185
            'IpAddress' => $ip,
186
        ];
187
188
        //we make sure we get the last one! Just in case there is more one.
189
        /** @var HealthCheckProviderSecurity|null */
190
        $obj = HealthCheckProviderSecurity::get()->filter($filter)->last();
191
        if (! $obj) {
0 ignored issues
show
introduced by
$obj is of type SilverStripe\ORM\DataObject, thus it always evaluated to true.
Loading history...
192
            $obj = HealthCheckProviderSecurity::create($filter);
193
        }
194
        $obj->AccessCount++;
195
196
        $obj->write();
197
198
        return $obj;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $obj returns the type SilverStripe\ORM\DataObject which includes types incompatible with the type-hinted return Sunnysideup\HealthCheckP...thCheckProviderSecurity.
Loading history...
199
    }
200
}
201