Mail routing parent/children, domain name validation, nodelist import changes and other fixes

This commit is contained in:
Deon George
2021-07-26 21:21:58 +10:00
parent 49bc946024
commit b179b1b3e9
15 changed files with 537 additions and 171 deletions

View File

@@ -30,37 +30,150 @@ class Address extends Model
/* RELATIONS */
/**
* Find children dependant on this record
* Find children dependent on this record
*/
public function children()
{
switch (strtolower($this->role)) {
case 'region':
return $this->hasMany(self::class,'region_id','region_id')
->where('zone_id',$this->zone_id)
->where(function($q) {
return $q->where('host_id',0)
->orWhere('role',DomainController::NODE_NC);
})
->where('id','<>',$this->id);
// We have no session data for this address, by definition it has no children
if (! $this->session('sespass'))
return $this->hasMany(self::class,'id','void');
case 'host':
return $this->hasMany(self::class,'host_id','host_id')
switch ($this->role) {
case DomainController::NODE_ZC:
$children = self::select('addresses.*')
->where('zone_id',$this->zone_id);
break;
case DomainController::NODE_RC:
$children = self::select('addresses.*')
->where('zone_id',$this->zone_id)
->where('region_id',$this->region_id);
break;
case DomainController::NODE_NC:
$children = self::select('addresses.*')
->where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->whereNull('hub_id')
->where('id','<>',$this->id);
->where('host_id',$this->host_id);
case 'hub':
return $this->hasMany(self::class,'hub_id','id');
break;
case 'node':
case DomainController::NODE_HC:
// Identify our children.
$children = self::select('addresses.*')
->where('hub_id',$this->id);
break;
case DomainController::NODE_ACTIVE:
case DomainController::NODE_POINT:
// Nodes dont have children, but must return a relationship instance
return $this->hasOne(self::class,NULL,'void');
default:
throw new Exception('Unknown role: '.$this->role);
throw new Exception('Unknown role: '.serialize($this->role));
}
// Remove any children that we have session details for (SAME AS HC)
$sessions = self::select('hubnodes.*')
->join('system_zone',['system_zone.system_id'=>'addresses.system_id','system_zone.zone_id'=>'addresses.zone_id'])
->join('addresses as hubnodes',['hubnodes.zone_id'=>'addresses.zone_id','hubnodes.id'=>'addresses.id'])
->where('addresses.zone_id',$this->zone_id)
->where('addresses.system_id','<>',$this->system_id)
->whereIN('addresses.system_id',$children->get()->pluck('system_id'));
// For each of the session, identify their children
$session_kids = collect();
foreach ($sessions->get() as $so)
$session_kids = $session_kids->merge(($x=$so->children) ? $x->pluck('id') : []);
// ZC's receive all mail, except for defined nodes, and defined hubs/hosts/rcs
return $this->hasMany(self::class,'zone_id','zone_id')
->whereIn('id',$children->get()->pluck('id')->toArray())
->whereNotIn('id',$sessions->get()->pluck('id')->toArray())
->whereNotIn('id',$session_kids->toArray())
->where('system_id','<>',$this->system_id)
->select('addresses.*')
->orderBy('region_id')
->orderBy('host_id')
->orderBy('node_id')
->orderBy('point_id')
->with(['zone.domain']);
}
/**
* Who we send this systems mail to.
*
* @return Address|null
* @throws Exception
*/
public function parent(): ?Address
{
// If we are have session password, then we dont have a parent
if ($this->session('sespass'))
return $this;
switch ($this->role) {
// ZCs dont have parents.
case DomainController::NODE_ZC:
return NULL;
// RC
case DomainController::NODE_RC:
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',0)
->where('host_id',0)
->where('node_id',0)
->single();
break;
// Hosts
case DomainController::NODE_NC:
// See if we have a RC
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',0)
->where('node_id',0)
->single();
if (! $parent) {
// See if we have a RC
$parent = self::where('zone_id',$this->zone_id)
->where('region_id',0)
->where('host_id',0)
->where('node_id',0)
->single();
}
break;
// Hubs
case DomainController::NODE_HC:
// Normal Nodes
case DomainController::NODE_ACTIVE:
// If we are a child of a hub, then check our hub
$parent = (($this->hub_id)
? self::where('id',$this->hub_id)
: self::where('zone_id',$this->zone_id)
->where('region_id',$this->region_id)
->where('host_id',$this->host_id)
->where('node_id',0))
->single();
break;
case DomainController::NODE_POINT:
// @todo Points - if the boss is defined, we should return it.
return NULL;
default:
throw new Exception('Unknown role: '.serialize($this->role));
}
return $parent?->parent();
}
public function system()
@@ -95,23 +208,21 @@ class Address extends Model
return sprintf('%s.%d',$this->getFTN3DAttribute(),$this->point_id);
}
public function getRoleAttribute($value)
public function getRoleNameAttribute(): string
{
switch ($value) {
case DomainController::NODE_ZC;
return 'Zone';
case DomainController::NODE_RC;
return 'Region';
case DomainController::NODE_NC;
return 'Host';
case DomainController::NODE_HC;
return 'Hub';
case DomainController::NODE_PVT;
return 'PVT';
case DomainController::NODE_DOWN;
return 'DOWN';
case NULL:
return 'Node';
switch ($this->role) {
case DomainController::NODE_ACTIVE:
return 'NODE';
case DomainController::NODE_ZC:
return 'ZC';
case DomainController::NODE_RC:
return 'RC';
case DomainController::NODE_NC:
return 'NC';
case DomainController::NODE_HC:
return 'HUB';
case DomainController::NODE_POINT:
return 'POINT';
default:
return '?';
}
@@ -130,17 +241,48 @@ class Address extends Model
{
$ftn = self::parseFTN($ftn);
// Are we looking for a region address
if (($ftn['f'] === 0) && $ftn['p'] === 0) {
$o = (new self)->active()
->select('addresses.*')
->where('zones.zone_id',$ftn['z'])
->where(function($q) use ($ftn) {
return $q
->where(function($q) use ($ftn) {
return $q->where('region_id',$ftn['n'])
->where('host_id',0);
});
})
->where('node_id',$ftn['f'])
->where('point_id',$ftn['p'])
->join('zones',['zones.id'=>'addresses.zone_id'])
->join('domains',['domains.id'=>'zones.domain_id'])
->where('zones.active',TRUE)
->where('domains.active',TRUE)
->where('addresses.active',TRUE)
->when($ftn['d'],function($query,$domain) {
$query->where('domains.name',$domain);
})
->when((! $ftn['d']),function($query) {
$query->where('domains.default',TRUE);
})
->single();
if ($o && $o->system->active)
return $o;
}
$o = (new self)->active()
->select('addresses.*')
->where('zones.zone_id',$ftn['z'])
->where('host_id',$ftn['n'])
->where('node_id',$ftn['f'])
->where('point_id',$ftn['p'])
->join('zones',['zones.id'=>'addresses.zone_id'])
->join('domains',['domains.id'=>'zones.domain_id'])
->where('zones.active',TRUE)
->where('domains.active',TRUE)
->where('addresses.active',TRUE)
->where('node_id',$ftn['f'])
->where('point_id',$ftn['p'])
->when($ftn['d'],function($query,$domain) {
$query->where('domains.name',$domain);
})