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
![]() |
|||
18 | |||
19 | private static $plural_name = 'Security Checks'; |
||
0 ignored issues
–
show
|
|||
20 | |||
21 | private static $table_name = 'HealthCheckProviderSecurity'; |
||
0 ignored issues
–
show
|
|||
22 | |||
23 | ####################### |
||
24 | ### Model Section |
||
25 | ####################### |
||
26 | |||
27 | private static $db = [ |
||
0 ignored issues
–
show
|
|||
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
|
|||
37 | 'Editor' => Member::class, |
||
38 | ]; |
||
39 | |||
40 | ####################### |
||
41 | ### Further DB Field Details |
||
42 | ####################### |
||
43 | |||
44 | private static $default_sort = [ |
||
0 ignored issues
–
show
|
|||
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
|
|||
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
|
|||
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
|
|||
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 | */ |
||
95 | public function getTitle(): string |
||
96 | { |
||
97 | return 'Retrieval attempt from "' . $this->IpAddress . '" using "' . $this->Secret . '" as key'; |
||
98 | } |
||
99 | |||
100 | ####################### |
||
101 | ### can Section |
||
102 | ####################### |
||
103 | |||
104 | public function canCreate($member = null, $context = []) |
||
105 | { |
||
106 | return false; |
||
107 | } |
||
108 | |||
109 | public function canDelete($member = null) |
||
110 | { |
||
111 | return false; |
||
112 | } |
||
113 | |||
114 | public function canEdit($member = null) |
||
115 | { |
||
116 | return $this->DefinitelyNotOk ? false : parent::canEdit($member); |
||
0 ignored issues
–
show
The property
DefinitelyNotOk does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity . Since you implemented __get , consider adding a @property annotation.
![]() |
|||
117 | } |
||
118 | |||
119 | ####################### |
||
120 | ### write Section |
||
121 | ####################### |
||
122 | |||
123 | protected function onBeforeWrite() |
||
124 | { |
||
125 | parent::onBeforeWrite(); |
||
126 | if (! $this->EditorID) { |
||
127 | $user = Security::getCurrentUser(); |
||
128 | if ($user) { |
||
0 ignored issues
–
show
|
|||
129 | $this->EditorID = Security::getCurrentUser()->ID; |
||
0 ignored issues
–
show
|
|||
130 | } |
||
131 | } |
||
132 | if (! $this->Secret) { |
||
133 | $this->Secret = 'Careful: no key set - ' . mt_rand(0, 9999999999999999); |
||
0 ignored issues
–
show
|
|||
134 | } |
||
135 | if (! $this->IpAddress) { |
||
136 | $this->IpAddress = 'Careful: no IP Set'; |
||
0 ignored issues
–
show
|
|||
137 | } |
||
138 | if ($this->DefinitelyNotOk) { |
||
0 ignored issues
–
show
The property
DefinitelyNotOk does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity . Since you implemented __get , consider adding a @property annotation.
![]() |
|||
139 | $this->Allowed = false; |
||
0 ignored issues
–
show
|
|||
140 | } |
||
141 | } |
||
142 | |||
143 | protected function onAfterWrite() |
||
144 | { |
||
145 | parent::onAfterWrite(); |
||
146 | if ($this->AllowAllData) { |
||
0 ignored issues
–
show
The property
AllowAllData does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity . Since you implemented __get , consider adding a @property annotation.
![]() |
|||
147 | $items = HealthCheckItemProvider::get()->filter(['Include' => false]); |
||
148 | foreach ($items as $item) { |
||
149 | $item->Include = true; |
||
150 | $item->write(); |
||
151 | } |
||
152 | } |
||
153 | } |
||
154 | |||
155 | ####################### |
||
156 | ### CMS Edit Section |
||
157 | ####################### |
||
158 | |||
159 | public function getCMSFields() |
||
160 | { |
||
161 | $fields = parent::getCMSFields(); |
||
162 | $fields->addFieldsToTab( |
||
163 | 'Root.Main', |
||
164 | [ |
||
165 | ReadonlyField::create('Secret', 'Secret Key'), |
||
166 | ReadonlyField::create('IpAddress', 'IP'), |
||
167 | ReadonlyField::create('AccessCount', 'Access Count'), |
||
168 | CheckboxField::create('Allowed', 'Allow this IP with this Key? If unsure, please double-check!') |
||
169 | ->setDescription('Make sure that you are OK with both the key and the IP address to ensure security.'), |
||
170 | CheckboxField::create('DefinitelyNotOk', 'Check if you think this is a bad request') |
||
171 | ->setDescription('Careful, checking this will stop any future retrievals with this key and IP.'), |
||
172 | CheckboxField::create('AllowAllData', 'Check this box to allow access to all for any IPs granted access') |
||
173 | ->setDescription('Carefully consider if you are ok with this'), |
||
174 | ] |
||
175 | ); |
||
176 | |||
177 | return $fields; |
||
178 | } |
||
179 | |||
180 | protected static function get_object_from_filter(string $key, string $ip): HealthCheckProviderSecurity |
||
181 | { |
||
182 | $filter = [ |
||
183 | 'Secret' => $key, |
||
184 | 'IpAddress' => $ip, |
||
185 | ]; |
||
186 | |||
187 | //we make sure we get the last one! Just in case there is more one. |
||
188 | /** @var HealthCheckProviderSecurity|null $obj */ |
||
189 | $obj = HealthCheckProviderSecurity::get()->filter($filter)->last(); |
||
190 | if (! $obj) { |
||
0 ignored issues
–
show
|
|||
191 | $obj = HealthCheckProviderSecurity::create($filter); |
||
192 | } |
||
193 | ++$obj->AccessCount; |
||
0 ignored issues
–
show
The property
AccessCount does not exist on Sunnysideup\HealthCheckP...thCheckProviderSecurity . Since you implemented __get , consider adding a @property annotation.
![]() |
|||
194 | |||
195 | $obj->write(); |
||
196 | |||
197 | return $obj; |
||
198 | } |
||
199 | } |
||
200 |