Correctly storing netmail flags (intransit, local, recv) with senders ID and packet name

This commit is contained in:
Deon George 2023-07-15 10:46:19 +10:00
parent 7bf957df3a
commit 61ab0614b6
7 changed files with 187 additions and 36 deletions

View File

@ -161,9 +161,9 @@ final class Receive extends Item
try {
// Dispatch job.
if ($queue)
MessageProcess::dispatch($msg,$f->pktName());
MessageProcess::dispatch($msg,$f->pktName(),$this->ao);
else
MessageProcess::dispatchSync($msg,$f->pktName());
MessageProcess::dispatchSync($msg,$f->pktName(),$this->ao);
} catch (\Exception $e) {
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));

View File

@ -19,7 +19,7 @@ class PacketProcess extends Command
protected $signature = 'packet:process'
.' {file : Packet to process}'
.' {--N|nobot : Dont process bots}'
.' {ftn? : System the packet is from}';
.' {ftn : System the packet is from}';
/**
* The console command description.
@ -37,18 +37,18 @@ class PacketProcess extends Command
public function handle()
{
$f = new File($this->argument('file'));
$s = $this->argument('ftn') ? Address::findFTN($this->argument('ftn'))->system : NULL;
$a = Address::findFTN($this->argument('ftn'));
foreach ($f as $packet) {
foreach (Packet::process($packet,$f->itemName(),$f->itemSize(),$s) as $msg) {
foreach (Packet::process($packet,$f->itemName(),$f->itemSize(),$a->system) as $msg) {
// @todo Quick check that the packet should be processed by us.
// @todo validate that the packet's zone is in the domain.
$this->info(sprintf('Processing message from [%s] with msgid [%s] in (%s)',$msg->fboss,$msg->msgid,$f->pktName()));
// Dispatch job.
Job::dispatchSync($msg,$f->pktName(),$this->option('nobot'));
Job::dispatchSync($msg,$f->pktName(),$a,$this->option('nobot'));
}
}
}
}
}

View File

@ -11,7 +11,7 @@ use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use App\Classes\FTN\{Message,Process};
use App\Models\{Echoarea,Echomail,Netmail,Setup};
use App\Models\{Address,Echoarea,Echomail,Netmail,Setup};
class MessageProcess implements ShouldQueue
{
@ -19,16 +19,17 @@ class MessageProcess implements ShouldQueue
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private Address $sender;
private Message $msg;
private bool $skipbot;
private string $packet;
public function __construct(Message $msg,string $packet,bool $skipbot=FALSE)
public function __construct(Message $msg,string $packet,Address $sender,bool $skipbot=FALSE)
{
// Some checks
$this->msg = $msg;
$this->skipbot = $skipbot;
$this->packet = $packet;
$this->sender = $sender;
$this->skipbot = $skipbot;
}
/**
@ -41,7 +42,7 @@ class MessageProcess implements ShouldQueue
// If we are a netmail
if ($this->msg->isNetmail()) {
Log::info(sprintf('%s:Processing Netmail [%s] to (%s) [%s] from (%s) [%s].',
Log::info(sprintf('%s:- Processing Netmail [%s] to (%s) [%s] from (%s) [%s].',
self::LOGKEY,
$this->msg->msgid,
$this->msg->user_to,$this->msg->tftn,
@ -49,12 +50,44 @@ class MessageProcess implements ShouldQueue
));
// @todo Enable checks to reject old messages
// @todo Enable checks to reject duplicate
// Check for duplicate messages
// FTS-0009.001
if ($this->msg->msgid) {
$o = Netmail::where('msgid',$this->msg->msgid)
->where('fftn_id',($x=$this->msg->fboss_o) ? $x->id : NULL)
->where('datetime','>',Carbon::now()->subYears(3))
->single();
Log::debug(sprintf('%s:- Checking for duplicate from host id [%d].',self::LOGKEY,($x=$this->msg->fboss_o) ? $x->id : NULL));
if ($o) {
Log::alert(sprintf('%s:! Duplicate netmail [%s] in [%s] from (%s) [%s] to (%s) - ignorning.',
self::LOGKEY,
$this->msg->msgid,
$this->msg->echoarea,
$this->msg->user_from,$this->msg->fftn,
$this->msg->user_to,
));
if (! $o->msg_crc)
$o->msg_crc = md5($this->msg->message);
$o->save();
return;
}
}
// @todo Enable checks to see if this is a file request or file send
$o = $this->create_netmail($this->msg);
$o->recv_pkt = $this->packet;
$o->set_pkt = $this->packet;
$o->set_sender = $this->sender;
$o->set_path = $this->msg->pathaddress;
// Strip any local flag
$o->flags &= ~Message::FLAG_LOCAL;
// Determine if the message is to this system, or in transit
if ($ftns->search(function($item) { return $this->msg->tftn === $item->ftn; }) !== FALSE) {
@ -67,7 +100,7 @@ class MessageProcess implements ShouldQueue
if (! $this->skipbot)
foreach (config('process.robots') as $class) {
if ($processed = $class::handle($this->msg)) {
$o->local = TRUE;
$o->flags |= Message::FLAG_RECD;
$o->save();
break;
@ -76,16 +109,16 @@ class MessageProcess implements ShouldQueue
// We'll ignore messages from *fix users
if (in_array(strtolower($this->msg->user_from),['filefix','areafix'])) {
$o->local = TRUE;
$o->flags |= Message::FLAG_RECD;
$o->save();
Log::info(sprintf('%s:Ignoring Netmail [%d-%s] to the Hub from (%s) [%s] - its from a bot.',
Log::alert(sprintf('%s:! Ignoring Netmail [%s] to the Hub from (%s:%s) - its from a bot [%d].',
self::LOGKEY,
$o->id,
$this->msg->msgid,
$this->msg->user_from,
$this->msg->fftn)
);
$this->msg->fftn,
$o->id,
));
$processed = TRUE;
}
@ -98,7 +131,7 @@ class MessageProcess implements ShouldQueue
'Á ÀÄÙÀÄÙÀÄÙÀÄÙ Á '
];
Log::info(sprintf('Netmail to the Hub from (%s) [%s] but no users here.',$this->msg->user_from,$this->msg->fftn));
Log::alert(sprintf('%s:! Netmail to the Hub from (%s) [%s] but no users here.',self::LOGKEY,$this->msg->user_from,$this->msg->fftn));
$reply = "Your Netmail was not processed by the hub and cannot be delivered to anybody (as there are no users here).\r";
@ -146,20 +179,21 @@ class MessageProcess implements ShouldQueue
// @todo In transit loop checking
// @todo In transit TRACE response
$o->flags |= Message::FLAG_INTRANSIT;
$o->save();
Log::info(sprintf('%s:Netmail [%d-%s] in transit to (%s) [%s] from (%s) [%s].',
Log::info(sprintf('%s:= Netmail [%s] in transit to (%s:%s) from (%s:%s) [%d].',
self::LOGKEY,
$o->id,
$this->msg->msgid,
$this->msg->user_to,$this->msg->tftn,
$this->msg->user_from,$this->msg->fftn,
$o->id,
));
}
// Else we are echomail
} else {
Log::debug(sprintf('%s: - Looking for echomail area [%s] for mail from [%s]',self::LOGKEY,$this->msg->echoarea,$this->msg->fboss));
Log::debug(sprintf('%s:- Looking for echomail area [%s] for mail from [%s]',self::LOGKEY,$this->msg->echoarea,$this->msg->fboss));
if (! $this->msg->fboss_o) {
Log::error(sprintf('%s:! Cannot process message for echomail area [%s] for mail from [%s] with msgid [%s] - no boss object?',self::LOGKEY,$this->msg->echoarea,$this->msg->fboss,$this->msg->msgid));
@ -175,7 +209,7 @@ class MessageProcess implements ShouldQueue
return;
}
Log::debug(sprintf('%s: - Processing echomail [%s] in [%s].',self::LOGKEY,$this->msg->msgid,$this->msg->echoarea));
Log::debug(sprintf('%s:- Processing echomail [%s] in [%s].',self::LOGKEY,$this->msg->msgid,$this->msg->echoarea));
// Check for duplicate messages
// FTS-0009.001
@ -185,7 +219,7 @@ class MessageProcess implements ShouldQueue
->where('datetime','>',Carbon::now()->subYears(3))
->single();
Log::debug(sprintf('%s: - Checking for duplicate from host id [%d].',self::LOGKEY,($x=$this->msg->fboss_o) ? $x->id : NULL));
Log::debug(sprintf('%s:- Checking for duplicate from host id [%d].',self::LOGKEY,($x=$this->msg->fboss_o) ? $x->id : NULL));
if ($o) {
Log::alert(sprintf('%s:! Duplicate echomail [%s] in [%s] from (%s) [%s] to (%s) - updating seenby.',
@ -254,10 +288,11 @@ class MessageProcess implements ShouldQueue
$o->rogue_path = $this->msg->rogue_path;
$o->set_path = $this->msg->pathaddress;
$o->set_seenby = $this->msg->seenaddress;
// Record receiving packet and sender
$o->save();
Log::info(sprintf('%s: - Echomail [%s] in [%s] from (%s) [%s] to (%s) - [%s].',
Log::info(sprintf('%s:= Echomail [%s] in [%s] from (%s) [%s] to (%s) - [%s].',
self::LOGKEY,
$this->msg->msgid,
$this->msg->echoarea,

View File

@ -191,7 +191,7 @@ class Address extends Model
public function echomails()
{
return $this->belongsToMany(Echomail::class,'echomail_seenby')
->withPivot(['sent_at','export_at','packet']);
->withPivot(['export_at','sent_at','sent_pkt']);
}
public function echomail_from()
@ -743,6 +743,6 @@ class Address extends Model
*/
public function session(string $type): ?string
{
return ($x=$this->system->sessions->where('id',$this->zone_id)->first()) ? $x->pivot->{$type} : NULL;
return ($this->exists && ($x=$this->system->sessions->where('id',$this->zone_id)->first())) ? $x->pivot->{$type} : NULL;
}
}

View File

@ -5,6 +5,7 @@ namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
@ -14,6 +15,8 @@ use App\Classes\FTN\Message;
use App\Interfaces\Packet;
use App\Traits\{EncodeUTF8,MsgID};
// @deprecated recv_pkt now in netmail_path
// @deprecated local - use flags
final class Netmail extends Model implements Packet
{
private const LOGKEY = 'MN-';
@ -21,6 +24,8 @@ final class Netmail extends Model implements Packet
use SoftDeletes,EncodeUTF8,MsgID;
private Collection $set_path;
private Address $set_sender;
private string $set_pkt;
private const cast_utf8 = [
'to',
@ -44,6 +49,8 @@ final class Netmail extends Model implements Packet
{
switch ($key) {
case 'set_path':
case 'set_pkt':
case 'set_sender':
$this->{$key} = $value;
break;
@ -60,7 +67,12 @@ final class Netmail extends Model implements Packet
// Save the Path
$ppoid = NULL;
if (isset($model->set_path))
if (isset($model->set_path)) {
// If there are no details (Mystic), we'll create a blank
if (! $model->set_path->count()) {
$model->set_path->push(['node'=>$model->set_sender,'datetime'=>Carbon::now(),'program'=>'Unknown']);
}
foreach ($model->set_path as $path) {
$po = DB::select('INSERT INTO netmail_path (netmail_id,address_id,parent_id,datetime,program) VALUES (?,?,?,?,?) RETURNING id',[
$model->id,
@ -72,6 +84,15 @@ final class Netmail extends Model implements Packet
$ppoid = $po[0]->id;
}
if (isset($model->set_pkt) && isset($model->set_sender)) {
DB::update('UPDATE netmail_path set recv_pkt=?,recv_id=? where address_id=?',[
$model->set_pkt,
$model->set_sender->id,
Arr::get($model->set_path->last(),'node')->id,
]);
}
}
});
}
@ -87,7 +108,13 @@ final class Netmail extends Model implements Packet
public function path()
{
return $this->belongsToMany(Address::class,'netmail_path')
->withPivot(['id','parent_id','datetime','program']);
->withPivot(['id','parent_id','datetime','program','recv_pkt','recv_id']);
}
public function received()
{
return $this->belongsToMany(Address::class,'netmail_path','netmail_id','recv_id')
->withPivot(['id','parent_id','datetime','program','recv_pkt','recv_id']);
}
public function tftn()

View File

@ -0,0 +1,71 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
/*
Schema::create('system_transfers',function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string('packet')->nullable();
$table->bigInteger('file_id')->nullable();
$table->foreign('file_id')->references('id')->on('files');
$table->bigInteger('address_id');
$table->foreign('address_id')->references('id')->on('addresses');
$table->unique(['address_id','packet']);
$table->unique(['address_id','file_id']);
});
*/
Schema::table('netmails',function (Blueprint $table) {
$table->bigInteger('send_id')->nullable()->after('send_pkt');
$table->foreign('send_id')->references('id')->on('addresses');
});
Schema::table('netmail_path',function (Blueprint $table) {
$table->string('recv_pkt')->nullable();
$table->bigInteger('recv_id')->nullable();
$table->foreign('recv_id')->references('id')->on('addresses');
$table->unique(['recv_id','netmail_id']);
});
DB::statement('ALTER TABLE echomail_seenby RENAME COLUMN packet TO sent_pkt');
Schema::table('echomail_seenby',function (Blueprint $table) {
$table->bigInteger('sent_id')->nullable();
$table->foreign('sent_id')->references('id')->on('addresses');
$table->unique(['sent_id','echomail_id']);
});
Schema::table('echomail_path',function (Blueprint $table) {
$table->string('recv_pkt')->nullable();
$table->bigInteger('recv_id')->nullable();
$table->foreign('recv_id')->references('id')->on('addresses');
$table->unique(['recv_id','echomail_id']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//Schema::dropIfExists('system_transfers');
}
};

View File

@ -1,6 +1,6 @@
<div class="row">
<div class="col-4">
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->to) !!}</strong>@if ($msg instanceof \App\Models\Netmail)(<strong class="highlight">{{ $msg->tftn->ftn }}</strong>)@endif
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->to) !!}</strong> @if ($msg instanceof \App\Models\Netmail)(<strong class="highlight">{{ $msg->tftn->ftn }}</strong>)@endif
</div>
<div class="col-4">
DATE: <strong class="highlight">{{ $msg->datetime->format('Y-m-d H:i:s') }}</strong>
@ -43,8 +43,26 @@
</div>
@endif
<div class="row pb-2">
<div class="col-8">
PATH: <br><strong class="highlight">{!! optimize_path($msg->pathorder())->join('</strong> -> <strong class="highlight">') !!}</strong>
@if ($msg->flags & \App\Classes\FTN\Message::FLAG_LOCAL)
<div class="row pb-2">
<div class="col-8">
<strong class="highlight">Local message</strong>
</div>
</div>
</div>
@elseif ($msg->flags & (\App\Classes\FTN\Message::FLAG_INTRANSIT|\App\Classes\FTN\Message::FLAG_RECD))
<div class="row pb-2">
<div class="col-8">
PATH: <br><strong class="highlight">{!! optimize_path($msg->pathorder())->join('</strong> -> <strong class="highlight">') !!}</strong>
</div>
</div>
<div class="row pb-2">
<div class="col-8">
RECEIVED:
@foreach ($msg->received as $path)
<strong class="highlight">{{ $path->pivot->recv_pkt }}</strong> by <strong class="highlight">{{ $path->ftn }}</strong> {{ $msg->created_at }}
@endforeach
</div>
</div>
@endif