diff --git a/src/app/Http/Controllers/API/V4/PolicyController.php b/src/app/Http/Controllers/API/V4/PolicyController.php --- a/src/app/Http/Controllers/API/V4/PolicyController.php +++ b/src/app/Http/Controllers/API/V4/PolicyController.php @@ -19,8 +19,6 @@ { $data = \request()->input(); - list($local, $domainName) = explode('@', $data['recipient']); - $request = new \App\Policy\Greylist\Request($data); $shouldDefer = $request->shouldDefer(); diff --git a/src/app/IP4Net.php b/src/app/IP4Net.php --- a/src/app/IP4Net.php +++ b/src/app/IP4Net.php @@ -20,21 +20,11 @@ 'updated_at' ]; - public static function getNet($ip, $mask = 32) + public static function getNet($ip) { - $query = " - SELECT id FROM ip4nets - WHERE INET_ATON(net_number) <= INET_ATON(?) - AND INET_ATON(net_broadcast) >= INET_ATON(?) - ORDER BY INET_ATON(net_number), net_mask DESC LIMIT 1 - "; - - $results = DB::select($query, [$ip, $ip]); - - if (sizeof($results) == 0) { - return null; - } - - return \App\IP4Net::find($results[0]->id); + $where = 'INET_ATON(net_number) <= INET_ATON(?) and INET_ATON(net_broadcast) >= INET_ATON(?)'; + return IP4Net::whereRaw($where, [$ip, $ip]) + ->orderByRaw('INET_ATON(net_number), net_mask DESC') + ->first(); } } diff --git a/src/app/IP6Net.php b/src/app/IP6Net.php --- a/src/app/IP6Net.php +++ b/src/app/IP6Net.php @@ -20,21 +20,11 @@ 'updated_at' ]; - public static function getNet($ip, $mask = 128) + public static function getNet($ip) { - $query = " - SELECT id FROM ip6nets - WHERE INET6_ATON(net_number) <= INET6_ATON(?) - AND INET6_ATON(net_broadcast) >= INET6_ATON(?) - ORDER BY INET6_ATON(net_number), net_mask DESC LIMIT 1 - "; - - $results = DB::select($query, [$ip, $ip]); - - if (sizeof($results) == 0) { - return null; - } - - return \App\IP6Net::find($results[0]->id); + $where = 'INET6_ATON(net_number) <= INET6_ATON(?) and INET6_ATON(net_broadcast) >= INET6_ATON(?)'; + return IP6Net::whereRaw($where, [$ip, $ip]) + ->orderByRaw('INET6_ATON(net_number), net_mask DESC') + ->first(); } } diff --git a/src/app/Policy/Greylist/Request.php b/src/app/Policy/Greylist/Request.php --- a/src/app/Policy/Greylist/Request.php +++ b/src/app/Policy/Greylist/Request.php @@ -64,8 +64,6 @@ public function shouldDefer() { - $deferIfPermit = true; - list($this->netID, $this->netType) = \App\Utils::getNetFromAddress($this->request['client_address']); if (!$this->netID) { @@ -106,49 +104,14 @@ ); } - // see if all recipients and their domains are opt-outs - $enabled = false; - + // See if the recipient opted-out of the feature + $enabled = true; if ($recipient) { - $setting = Setting::where( - [ - 'object_id' => $this->recipientID, - 'object_type' => $this->recipientType, - 'key' => 'greylist_enabled' - ] - )->first(); - - if (!$setting) { - $domain = $recipient->domain(); - - if ($domain) { - $setting = Setting::where( - [ - 'object_id' => $recipient->domain()->id, - 'object_type' => \App\Domain::class, - 'key' => 'greylist_enabled' - ] - )->first(); - - if (!$setting) { - $enabled = true; - } else { - if ($setting->{'value'} !== 'false') { - $enabled = true; - } - } - } else { - $enabled = true; - } - } else { - if ($setting->{'value'} !== 'false') { - $enabled = true; - } - } - } else { - $enabled = true; + $enabled = $recipient->getSetting('greylist_enabled') !== 'false'; } + // FIXME: Shouldn't we bail-out (return early) if there's no $recipient? + // the following block is to maintain statistics and state ... $entries = Connect::where( [ @@ -228,8 +191,21 @@ ->orderBy('updated_at') ->first(); - if (!$connect) { - $connect = Connect::create( + $deferIfPermit = true; + + if ($connect) { + $connect->connect_count += 1; + + // TODO: The period of time for which the greylisting persists is configurable. + if ($connect->created_at < $this->timestamp->copy()->subMinutes(5)) { + $deferIfPermit = false; + + $connect->greylisting = false; + } + + $connect->save(); + } else { + Connect::create( [ 'sender_local' => $this->senderLocal, 'sender_domain' => $this->senderDomain, @@ -238,24 +214,12 @@ 'recipient_hash' => $this->recipientHash, 'recipient_id' => $this->recipientID, 'recipient_type' => $this->recipientType, - 'connect_count' => 0, 'created_at' => $this->timestamp, 'updated_at' => $this->timestamp ] ); } - $connect->connect_count += 1; - - // TODO: The period of time for which the greylisting persists is configurable. - if ($connect->created_at < $this->timestamp->copy()->subMinutes(5)) { - $deferIfPermit = false; - - $connect->greylisting = false; - } - - $connect->save(); - return $deferIfPermit; } @@ -282,8 +246,6 @@ private function recipientFromRequest() { - $recipient = null; - $recipients = \App\Utils::findObjectsByRecipientAddress($this->request['recipient']); if (sizeof($recipients) > 1) { diff --git a/src/app/Policy/Greylist/Setting.php b/src/app/Policy/Greylist/Setting.php deleted file mode 100644 --- a/src/app/Policy/Greylist/Setting.php +++ /dev/null @@ -1,17 +0,0 @@ -getSetting('greylist_enabled') !== 'false'; + $config['greylist_enabled'] = $this->getSetting('greylist_enabled') !== 'false'; return $config; } @@ -30,7 +32,7 @@ $errors = []; foreach ($config as $key => $value) { - if ($key == 'greylisting') { + if ($key == 'greylist_enabled') { $this->setSetting('greylist_enabled', $value ? 'true' : 'false'); } else { $errors[$key] = \trans('validation.invalid-config-parameter'); diff --git a/src/app/Utils.php b/src/app/Utils.php --- a/src/app/Utils.php +++ b/src/app/Utils.php @@ -46,28 +46,12 @@ public static function countryForIP($ip) { if (strpos($ip, ':') === false) { - $query = " - SELECT country FROM ip4nets - WHERE INET_ATON(net_number) <= INET_ATON(?) - AND INET_ATON(net_broadcast) >= INET_ATON(?) - ORDER BY INET_ATON(net_number), net_mask DESC LIMIT 1 - "; + $net = \App\IP4Net::getNet($ip); } else { - $query = " - SELECT id FROM ip6nets - WHERE INET6_ATON(net_number) <= INET6_ATON(?) - AND INET6_ATON(net_broadcast) >= INET6_ATON(?) - ORDER BY INET6_ATON(net_number), net_mask DESC LIMIT 1 - "; + $net = \App\IP6Net::getNet($ip); } - $nets = \Illuminate\Support\Facades\DB::select($query, [$ip, $ip]); - - if (sizeof($nets) > 0) { - return $nets[0]->country; - } - - return 'CH'; + return $net && $net->country ? $net->country : 'CH'; } /** diff --git a/src/database/migrations/2021_08_25_120000_drop_greylist_settings_table.php b/src/database/migrations/2021_08_25_120000_drop_greylist_settings_table.php new file mode 100644 --- /dev/null +++ b/src/database/migrations/2021_08_25_120000_drop_greylist_settings_table.php @@ -0,0 +1,43 @@ +bigIncrements('id'); + $table->bigInteger('object_id'); + $table->string('object_type', 16); + $table->string('key', 64); + $table->text('value'); + $table->timestamps(); + + $table->index(['object_id', 'object_type', 'key'], 'ook_idx'); + } + ); + } +} diff --git a/src/resources/vue/Admin/User.vue b/src/resources/vue/Admin/User.vue --- a/src/resources/vue/Admin/User.vue +++ b/src/resources/vue/Admin/User.vue @@ -312,10 +312,10 @@