Compare commits

...

3 Commits

Author SHA1 Message Date
Deon George 7b225d8fc0 Attempt to catch dns query failures
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 36s Details
Create Docker Image / Build Docker Image (arm64) (push) Successful in 1m37s Details
Create Docker Image / Final Docker Image Manifest (push) Successful in 11s Details
2024-04-16 22:01:09 +09:30
Deon George ff7ab68a54 Added filefix rescan 2024-04-16 22:00:41 +09:30
Deon George a2ff2df9f3 Move security evaluations for File/Echoareas back to model 2024-04-16 21:28:35 +09:30
9 changed files with 137 additions and 8 deletions

View File

@ -360,7 +360,7 @@ class Tic extends FTNBase
// Validate sender is permitted to write
// @todo Send a notification
if (! $this->file->filearea->sec_write || ($this->file->fftn->security < $this->file->filearea->sec_write))
if (! $this->file->filearea->can_write($this->file->fftn->security))
throw new NoWriteSecurityException(sprintf('Node [%s] doesnt have enough security to write to [%s] (%d)',$this->file->fftn->ftn,$this->file->filearea->name,$this->file->fftn->security));
// If the file create time is blank, we'll take the files

View File

@ -52,14 +52,15 @@ class Rescan extends Command
throw new \Exception(sprintf('FTN [%s] is not subscribed to [%s]',$ao->ftn,$eao->name));
// Check that an FTN can read the area
if (! $eao->sec_read || ($ao->security < $eao->sec_read))
throw new \Exception(sprintf('FTN [%s] doesnt have permission to received [%s]',$ao->ftn,$eao->name));
if (! $eao->can_read($ao->security))
throw new \Exception(sprintf('FTN [%s] doesnt have permission to receive [%s]',$ao->ftn,$eao->name));
foreach (Echomail::select('id')
->where('echoarea_id',$eao->id)
->when($this->argument('days'),function($query) {
return $query->where('created_at','>=',Carbon::now()->subDays($this->argument('days'))->startOfDay());
})
->orderBy('datetime')
->cursor() as $eo) {
// Echomail hasnt been exported before

View File

@ -0,0 +1,90 @@
<?php
namespace App\Console\Commands\Filefix;
use Carbon\Carbon;
use Illuminate\Console\Command;
use App\Models\{Address,Filearea,File};
class Rescan extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'filefix:rescan {ftn} {area} {file?}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Resend some files to a node';
/**
* Execute the console command.
*
* @return mixed
* @throws \Exception
*/
public function handle()
{
$ao = Address::findFtn($this->argument('ftn'));
if (! $ao)
throw new \Exception('FTN not found: '.$this->argument('ftn'));
// Check that the area belongs to the domain for the FTN
if (! $this->argument('area'))
throw new \Exception('Areaname is required');
$fao = Filearea::where('name',$this->argument('area'))->singleOrFail();
if ($fao->domain_id !== $ao->zone->domain_id)
throw new \Exception(sprintf('File area [%s] is not in domain [%s] for FTN [%s]',$fao->name,$ao->zone->domain->name,$ao->ftn));
// Check that the user is subscribed
if (! $ao->fileareas->contains($fao->id))
throw new \Exception(sprintf('FTN [%s] is not subscribed to [%s]',$ao->ftn,$fao->name));
// Check that an FTN can read the area
if (! $fao->can_read($ao->security))
throw new \Exception(sprintf('FTN [%s] doesnt have permission to receive [%s]',$ao->ftn,$fao->name));
foreach (File::select('id')
->where('filearea_id',$fao->id)
->when($this->argument('file'),function($query) {
return $query->where('name','=',$this->argument('days'));
})
->orderBy('datetime')
->cursor() as $fo) {
// File hasnt been exported before
if (! $fo->seenby->count()) {
$fo->seenby()->attach($ao->id,['export_at'=>Carbon::now()]);
$this->info(sprintf('Exported [%d] to [%s]',$fo->id,$ao->ftn3d));
} else {
$export = $fo->seenby->where('id',$ao->id)->pop();
// File is pending export
if ($export && $export->pivot->export_at && is_null($export->pivot->sent_at) && is_null($export->pivot->sent_pkt)) {
$this->warn(sprintf('Not exporting [%d] already queued for [%s]',$fo->id,$ao->ftn3d));
// File has been exported
} elseif ($export) {
$fo->seenby()->updateExistingPivot($ao,['export_at'=>Carbon::now(),'sent_at'=>NULL]);
$this->info(sprintf('Re-exported [%d] to [%s]',$fo->id,$ao->ftn3d));
// File has not been exported
} else {
$fo->seenby()->attach($ao,['export_at'=>Carbon::now(),'sent_at'=>NULL]);
$this->info(sprintf('Exported [%d] to [%s]',$fo->id,$ao->ftn3d));
}
}
}
return self::SUCCESS;
}
}

View File

@ -127,6 +127,10 @@ class AddressPoll implements ShouldQueue, ShouldBeUnique
} catch (SocketException $e) {
Log::error(sprintf('%s:! Unable to connect to [%s]: %s',self::LOGKEY,$this->ao->ftn,$e->getMessage()));
break;
} catch (\ErrorException $e) {
Log::error(sprintf('%s:! Unable to connect to [%s]: %s',self::LOGKEY,$this->ao->ftn,$e->getMessage()));
break;
}
}

View File

@ -343,7 +343,7 @@ class MessageProcess implements ShouldQueue
}
// Can the system send messages to this area?
if (! $ea->sec_write || ($this->pktsrc->security < $ea->sec_write)) {
if (! $ea->can_write($this->pktsrc->security)) {
Log::alert(sprintf('%s:! FTN [%s] is not allowed to post [%s] to [%s].',self::LOGKEY,$this->pktsrc->ftn,$this->msg->msgid,$ea->name));
if (! $this->msg->rescanned->count())
Notification::route('netmail',$this->pktsrc)->notify(new EchoareaNoWrite($this->msg));

View File

@ -149,7 +149,7 @@ final class Echomail extends Model implements Packet
$exportto = ($x=$model
->echoarea
->addresses
->filter(function($item) use ($model) { return $item->security >= $model->echoarea->sec_read; }))
->filter(function($item) use ($model) { return $model->echoarea->can_read($item->security); }))
->pluck('id')
->diff($seenby);

View File

@ -155,7 +155,7 @@ class File extends Model
$exportto = $model
->filearea
->addresses
->filter(function($item) use ($model) { return $item->security >= $model->filearea->sec_read; })
->filter(function($item) use ($model) { return $model->filearea->can_read($item->security); })
->pluck('id')
->diff($seenby);

View File

@ -7,6 +7,39 @@ namespace App\Traits;
trait AreaSecurity
{
/**
* Does the security level provide read or write access
*
* @param int $sec
* @return bool
*/
public function can_access(int $sec): bool
{
return $this->can_read($sec) || $this->can_write($sec);
}
/**
* Does the security level provide read access
*
* @param int $sec
* @return bool
*/
public function can_read(int $sec): bool
{
return $this->active && (($sec >= ($x=$this->getSecReadAttribute())) && $x);
}
/**
* Does the security level provide write access
*
* @param int $sec
* @return bool
*/
public function can_write(int $sec): bool
{
return $this->active && (($sec >= ($x=$this->getSecWriteAttribute())) && $x);
}
public function getSecReadAttribute(): int
{
return ($this->security>>3) & 0x7;

View File

@ -56,12 +56,12 @@
->sortBy('name')) as $o)
<tr>
<th class="nowrap">
<a href="{{ url('domain/view',[$o->id]) }}">{{ $o->name }}</a> <small>({{ $sec=$user->systems->pluck('akas')->flatten()->filter(function($item) use ($o) { return $item->zone->domain_id === $o->id; })->max('security') ?? '-' }})</small><br><br>
<a href="{{ url('domain/view',[$o->id]) }}">{{ $o->name }}</a> <small>({{ ($sec=$user->systems->pluck('akas')->flatten()->filter(function($item) use ($o) { return $item->zone->domain_id === $o->id; })->max('security') ?: 0) ?? '-' }})</small><br><br>
{{ ($sub=$user->systems->pluck('akas')->flatten()->pluck('echoareas')->flatten()->filter(function($item) use ($o) { return $item->domain_id === $o->id; }))->count() }} <small>Subscribed</small>
</th>
<td>
@foreach ($o->echoareas->sortBy('name') as $eo)
<span style="@if (($sec < $eo->sec_read) || ($sec < $eo->sec_write) || ! $eo->active) color: red; @elseif($sub->where('name',$eo->name)->count()) color: green; @endif">{{ $eo->name }}</span>
<span style="@if(! $eo->active) color: gray; @elseif(! $eo->can_access($sec)) color: red; @elseif($sub->where('name',$eo->name)->count()) color: green; @endif">{{ $eo->name }}</span>
@endforeach
</td>
</tr>
@ -113,6 +113,7 @@
--}}
</style>
@append
@section('page-scripts')
@js('highcharts')