2021-06-17 14:08:30 +00:00
< ? php
namespace App\Http\Controllers ;
2021-08-25 12:13:49 +00:00
use Carbon\Carbon ;
2023-09-08 14:07:46 +00:00
use Illuminate\Database\QueryException ;
2021-06-17 14:08:30 +00:00
use Illuminate\Http\Request ;
2021-08-08 07:27:22 +00:00
use Illuminate\Support\Arr ;
2023-07-23 07:27:52 +00:00
use Illuminate\Support\Collection ;
2021-11-11 11:57:13 +00:00
use Illuminate\Support\Facades\Auth ;
2022-03-14 11:28:54 +00:00
use Illuminate\Support\Facades\DB ;
2023-08-03 07:30:52 +00:00
use Illuminate\Support\Facades\Log ;
2022-03-14 11:28:54 +00:00
use Illuminate\Support\Facades\Notification ;
2021-11-11 11:57:13 +00:00
use Illuminate\Support\ViewErrorBag ;
2021-06-17 14:08:30 +00:00
2023-08-03 07:30:52 +00:00
use App\Classes\FTN\Message ;
2023-09-08 14:07:46 +00:00
use App\Http\Requests\ { AddressMerge , AreafixRequest , SystemRegister };
2023-07-26 09:44:07 +00:00
use App\Jobs\AddressPoll ;
2023-08-03 07:30:52 +00:00
use App\Models\ { Address , Echoarea , Filearea , Netmail , Setup , System , SystemZone , Zone };
2023-07-23 07:27:52 +00:00
use App\Notifications\Netmails\AddressLink ;
2021-07-01 14:25:41 +00:00
use App\Rules\ { FidoInteger , TwoByteInteger };
2021-06-17 14:08:30 +00:00
class SystemController extends Controller
{
2023-08-03 07:30:52 +00:00
private const LOGKEY = 'CSC' ;
2021-06-20 13:03:20 +00:00
/**
* Add an address to a system
*
* @ param Request $request
* @ param System $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function add_address ( Request $request , System $o )
{
2022-03-01 11:07:08 +00:00
// @todo a point address is failing validation
2021-07-04 11:47:23 +00:00
// @todo This should be admin of the zone
2021-06-20 13:03:20 +00:00
$this -> authorize ( 'admin' , $o );
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'address' );
2021-06-20 13:03:20 +00:00
$request -> validate ([
2023-07-29 03:17:36 +00:00
'action' => 'required|in:region,host,node,update' ,
2021-06-20 13:03:20 +00:00
'zone_id' => 'required|exists:zones,id' ,
]);
switch ( $request -> post ( 'action' )) {
case 'region' :
$request -> validate ([
'region_id_new' => [
'required' ,
new TwoByteInteger ,
function ( $attribute , $value , $fail ) {
// Check that the region doesnt already exist
$o = Address :: where ( function ( $query ) use ( $value ) {
return $query -> where ( 'region_id' , $value )
2021-06-25 06:42:12 +00:00
-> where ( 'host_id' , 0 )
2021-06-20 13:03:20 +00:00
-> where ( 'node_id' , 0 )
-> where ( 'point_id' , 0 )
2022-01-24 11:56:13 +00:00
-> where ( 'role' , Address :: NODE_RC );
2021-06-20 13:03:20 +00:00
})
// Check that a host doesnt already exist
-> orWhere ( function ( $query ) use ( $value ) {
return $query -> where ( 'host_id' , $value )
-> where ( 'point_id' , 0 )
2022-01-24 11:56:13 +00:00
-> where ( 'role' , Address :: NODE_NC );
2021-06-20 13:03:20 +00:00
});
if ( $o -> count ()) {
$fail ( 'Region or host already exists' );
}
},
],
]);
$oo = new Address ;
$oo -> zone_id = $request -> post ( 'zone_id' );
$oo -> region_id = $request -> post ( 'region_id_new' );
2021-10-07 12:32:05 +00:00
$oo -> host_id = 0 ;
2021-06-20 13:03:20 +00:00
$oo -> node_id = 0 ;
$oo -> point_id = 0 ;
2022-01-24 11:56:13 +00:00
$oo -> role = Address :: NODE_RC ;
2021-06-20 13:03:20 +00:00
$oo -> active = TRUE ;
$o -> addresses () -> save ( $oo );
break ;
case 'host' :
$request -> validate ([
2021-07-01 14:25:41 +00:00
'region_id' => [ 'required' , new FidoInteger ],
2021-06-20 13:03:20 +00:00
'host_id_new' => [
'required' ,
new TwoByteInteger ,
2021-07-05 13:17:00 +00:00
function ( $attribute , $value , $fail ) use ( $request ) {
2021-06-20 13:03:20 +00:00
// Check that the region doesnt already exist
$o = Address :: where ( function ( $query ) use ( $value ) {
2021-07-18 13:38:18 +00:00
return $query -> where ( function ( $query ) use ( $value ) {
return $query -> where ( 'region_id' , $value )
2022-01-24 11:56:13 +00:00
-> where ( 'role' , Address :: NODE_RC );
2021-07-18 13:38:18 +00:00
})
// Check that a host doesnt already exist
-> orWhere ( function ( $query ) use ( $value ) {
return $query -> where ( 'host_id' , $value )
2022-01-24 11:56:13 +00:00
-> where ( 'role' , Address :: NODE_NC );
2021-07-18 13:38:18 +00:00
});
2021-07-05 13:17:00 +00:00
})
-> where ( 'zone_id' , $request -> post ( 'zone_id' ))
-> where ( 'point_id' , 0 )
-> where ( 'active' , TRUE );
2021-06-20 13:03:20 +00:00
if ( $o -> count ()) {
$fail ( 'Region or host already exists' );
}
},
],
'node_id_new' => [
'required' ,
new TwoByteInteger ,
function ( $attribute , $value , $fail ) use ( $request ) {
// Check that the region doesnt already exist
$o = Address :: where ( function ( $query ) use ( $request , $value ) {
return $query
-> where ( 'host_id' , $request -> post ( 'host_id_new' ))
-> where ( 'node_id' , $value )
-> where ( 'point_id' , 0 )
2022-01-24 11:56:13 +00:00
-> where ( 'role' , Address :: NODE_RC );
2021-06-20 13:03:20 +00:00
});
if ( $o -> count ()) {
$fail ( 'Host already exists' );
}
},
]
]);
2021-07-26 11:21:58 +00:00
// Find the Hub address
// Find the zones <HOST>/0 address, and assign it to this host.
$oo = Address :: where ( 'zone_id' , $request -> zone_id )
-> where ( 'region_id' , $request -> region_id )
-> where ( 'host_id' , $request -> host_id_new )
-> where ( 'node_id' , 0 )
-> where ( 'point_id' , 0 )
-> single ();
// Its not defined, so we'll create it.
if ( ! $oo ) {
$oo = new Address ;
$oo -> forceFill ([
'zone_id' => $request -> zone_id ,
'region_id' => $request -> region_id ,
'host_id' => $request -> host_id_new ,
'node_id' => 0 ,
'point_id' => 0 ,
2022-01-24 11:56:13 +00:00
'role' => Address :: NODE_NC ,
2021-07-26 11:21:58 +00:00
]);
}
$oo -> system_id = $request -> system_id ;
$oo -> active = TRUE ;
$o -> addresses () -> save ( $oo );
2021-06-20 13:03:20 +00:00
$oo = new Address ;
$oo -> zone_id = $request -> post ( 'zone_id' );
2021-06-25 13:38:57 +00:00
$oo -> region_id = $request -> post ( 'region_id' );
2021-06-20 13:03:20 +00:00
$oo -> host_id = $request -> post ( 'host_id_new' );
$oo -> node_id = $request -> post ( 'node_id_new' );
$oo -> point_id = 0 ;
2022-03-01 11:07:08 +00:00
$oo -> role = Address :: NODE_ACTIVE ;
2021-06-20 13:03:20 +00:00
$oo -> active = TRUE ;
$o -> addresses () -> save ( $oo );
break ;
2023-07-29 03:17:36 +00:00
case 'update' :
2021-06-20 13:03:20 +00:00
case 'node' :
$request -> validate ([
2021-07-01 14:25:41 +00:00
'region_id' => [ 'required' , new FidoInteger ],
'host_id' => [ 'required' , new FidoInteger ],
2021-06-20 13:03:20 +00:00
'node_id' => [
'required' ,
new TwoByteInteger ,
function ( $attribute , $value , $fail ) use ( $request ) {
2023-04-15 10:24:53 +00:00
if ( $request -> point_id === 0 ) {
// Check that the host doesnt already exist
$o = Address :: where ( function ( $query ) use ( $request , $value ) {
return $query
-> where ( 'zone_id' , $request -> post ( 'zone_id' ))
-> where ( 'host_id' , $request -> post ( 'host_id' ))
-> where ( 'node_id' , $value )
2023-07-29 03:17:36 +00:00
-> where ( 'point_id' , 0 )
-> where ( 'id' , '<>' , $request -> post ( 'submit' ));
2023-04-15 10:24:53 +00:00
});
if ( $o -> count ()) {
$fail ( sprintf ( 'Host already exists: %s' , $o -> get () -> pluck ( 'ftn' ) -> join ( ',' )));
}
}
},
],
'point_id' => [
'required' ,
function ( $attribute , $value , $fail ) use ( $request ) {
if ( ! is_numeric ( $value ) || $value > DomainController :: NUMBER_MAX )
$fail ( sprintf ( 'Point numbers must be between 0 and %d' , DomainController :: NUMBER_MAX ));
// Check that the host doesnt already exist
2021-06-20 13:03:20 +00:00
$o = Address :: where ( function ( $query ) use ( $request , $value ) {
return $query
2021-07-26 11:53:56 +00:00
-> where ( 'zone_id' , $request -> post ( 'zone_id' ))
2021-06-25 06:42:12 +00:00
-> where ( 'host_id' , $request -> post ( 'host_id' ))
2023-04-15 10:24:53 +00:00
-> where ( 'node_id' , $request -> post ( 'node_id' ))
2023-07-29 03:17:36 +00:00
-> where ( 'point_id' , $value )
-> where ( 'id' , '<>' , $request -> post ( 'submit' ));
2021-06-20 13:03:20 +00:00
});
if ( $o -> count ()) {
2023-04-15 10:24:53 +00:00
$fail ( sprintf ( 'Point already exists: %s' , $o -> get () -> pluck ( 'ftn' ) -> join ( ',' )));
2021-06-20 13:03:20 +00:00
}
2023-04-15 10:24:53 +00:00
}
2021-06-20 13:03:20 +00:00
],
'hub' => 'required|boolean' ,
2021-06-25 06:42:12 +00:00
'hub_id' => 'nullable|exists:addresses,id' ,
2023-07-29 03:17:36 +00:00
'security' => 'required|integer|min:0|max:7' ,
2021-06-20 13:03:20 +00:00
]);
2023-07-29 03:17:36 +00:00
$oo = Address :: findOrNew ( $request -> post ( 'submit' ));
2021-06-20 13:03:20 +00:00
$oo -> zone_id = $request -> post ( 'zone_id' );
2021-06-25 13:38:57 +00:00
$oo -> region_id = $request -> post ( 'region_id' );
2021-06-20 13:03:20 +00:00
$oo -> host_id = $request -> post ( 'host_id' );
$oo -> node_id = $request -> post ( 'node_id' );
$oo -> point_id = $request -> post ( 'point_id' );
2021-06-25 13:38:57 +00:00
$oo -> hub_id = $request -> post ( 'hub_id' ) > 0 ? $request -> post ( 'hub_id' ) : NULL ;
2023-07-29 03:17:36 +00:00
if ( is_null ( $oo -> role ))
$oo -> role = (( ! $oo -> point_id ) && $request -> post ( 'hub' )) ? Address :: NODE_HC : ( $request -> post ( 'point_id' ) ? Address :: NODE_POINT : Address :: NODE_ACTIVE );
$oo -> security = $request -> post ( 'security' );
2021-06-20 13:03:20 +00:00
$oo -> active = TRUE ;
$o -> addresses () -> save ( $oo );
break ;
default :
return redirect () -> back () -> withErrors ([ 'action' => 'Unknown action: ' . $request -> post ( 'action' )]);
}
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> id ));
}
2021-07-04 11:47:23 +00:00
/**
* Add Session details
*
* @ param Request $request
* @ param System $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function add_session ( Request $request , System $o )
{
// @todo This should be admin of the zone
2023-06-23 12:04:10 +00:00
$this -> authorize ( 'update' , $o );
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'session' );
2021-07-04 11:47:23 +00:00
$validate = $request -> validate ([
'zone_id' => 'required|exists:zones,id' ,
'sespass' => 'required|string|min:4' ,
2023-10-04 05:05:46 +00:00
'pktpass' => 'required|string|min:4|max:8' ,
'ticpass' => 'required|string|min:4' ,
2021-07-04 11:47:23 +00:00
'fixpass' => 'required|string|min:4' ,
]);
$zo = Zone :: findOrFail ( $validate [ 'zone_id' ]);
2021-08-13 12:53:59 +00:00
// If this session is for the ZC, it now becomes the default.
2022-01-24 11:56:13 +00:00
if ( $o -> match ( $zo , Address :: NODE_ZC ) -> count ()) {
2021-08-13 12:53:59 +00:00
SystemZone :: where ( 'default' , TRUE ) -> update ([ 'default' => FALSE ]);
$validate [ 'default' ] = TRUE ;
}
2021-07-04 11:47:23 +00:00
$o -> sessions () -> attach ( $zo , $validate );
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> id ));
}
2021-06-17 14:08:30 +00:00
/**
* Add or edit a node
*/
2022-01-01 14:52:21 +00:00
public function add_edit ( SystemRegister $request , System $o )
2021-06-17 14:08:30 +00:00
{
2022-03-14 11:28:54 +00:00
$this -> authorize ( 'update' , $o );
2021-06-17 14:08:30 +00:00
if ( $request -> post ()) {
2023-07-07 13:59:04 +00:00
foreach ([ 'name' , 'location' , 'sysop' , 'hold' , 'phone' , 'address' , 'port' , 'active' , 'method' , 'notes' , 'zt_id' , 'pkt_type' ] as $key )
2021-06-17 14:08:30 +00:00
$o -> { $key } = $request -> post ( $key );
2023-07-26 09:44:07 +00:00
switch ( $request -> post ( 'pollmode' )) {
case 1 : $o -> pollmode = FALSE ; break ;
case 2 : $o -> pollmode = TRUE ; break ;
default : $o -> pollmode = NULL ;
}
$o -> autohold = FALSE ;
2021-06-17 14:08:30 +00:00
$o -> save ();
2023-07-07 13:59:04 +00:00
$mailers = collect ( $request -> post ( 'mailer_details' ))
-> filter ( function ( $item ) { return $item [ 'port' ]; })
-> transform ( function ( $item ) { $item [ 'active' ] = Arr :: get ( $item , 'active' , FALSE ); return $item ; });
$o -> mailers () -> sync ( $mailers );
2021-06-17 14:08:30 +00:00
return redirect () -> action ([ self :: class , 'home' ]);
}
2022-11-01 05:39:58 +00:00
$o -> load ([ 'addresses.zone.domain' , 'addresses.system' , 'sessions.domain' , 'sessions.systems' ]);
2021-07-26 11:21:58 +00:00
2022-03-14 11:28:54 +00:00
return view ( 'system.addedit' )
2022-01-01 14:52:21 +00:00
-> with ( 'action' , $o -> exists ? 'update' : 'create' )
2022-03-14 11:28:54 +00:00
-> with ( 'o' , $o );
2021-06-17 14:08:30 +00:00
}
2023-09-08 14:07:46 +00:00
public function address_merge ( AddressMerge $request , int $id )
{
if ( $request -> validated ()) {
DB :: beginTransaction ();
// Find all echomail seenbys
$x = DB :: update ( 'update echomail_seenby set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
// Find all echomail paths
$x = DB :: update ( 'update echomail_path set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
// Find all echomails
$x = DB :: update ( 'update echomails set fftn_id=? where fftn_id=?' ,[ $request -> dst , $request -> src ]);
// Find all netmails
$x = DB :: update ( 'update netmails set fftn_id=? where fftn_id=?' ,[ $request -> dst , $request -> src ]);
// Find all netmails
$x = DB :: update ( 'update netmails set tftn_id=? where tftn_id=?' ,[ $request -> dst , $request -> src ]);
// Find all nodelist
$x = DB :: update ( 'update address_nodelist set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
// Find all file seenbys
$x = DB :: update ( 'update file_seenby set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
// Find all files
$x = DB :: update ( 'update files set fftn_id=? where fftn_id=?' ,[ $request -> dst , $request -> src ]);
$src = Address :: withTrashed () -> findOrFail ( $request -> src );
// Resubscribe echoareas
try {
$x = DB :: update ( 'update address_echoarea set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
} catch ( QueryException $e ) {
DB :: rollback ();
return back () -> withInput () -> withErrors ( 'error' , sprintf ( 'You may need to remove %s:%s (%d) from echoareas' , $src -> ftn , $src -> system -> name , $src -> id ));
}
// Resubscribe fileareas
try {
$x = DB :: update ( 'update address_filearea set address_id=? where address_id=?' ,[ $request -> dst , $request -> src ]);
} catch ( QueryException $e ) {
DB :: rollback ();
return back () -> withInput () -> withErrors ( 'error' , sprintf ( 'You may need to remove %s:%s (%d) from fileareas' , $src -> ftn , $src -> system -> name , $src -> id ));
}
if ( $src -> forceDelete ()) {
DB :: commit ();
return redirect () -> to ( 'address/merge/' . $request -> dst );
} else {
return back () -> withInput () -> withErrors ( 'error' , sprintf ( 'Address [%s] didnt delete?' , $src -> ftn ));
DB :: rollBack ();
}
}
$o = Address :: withTrashed ()
-> findOrFail ( $id );
$oo = Address :: withTrashed ()
-> where ( 'zone_id' , $o -> zone_id )
-> where ( 'host_id' , $o -> host_id )
-> where ( 'node_id' , $o -> node_id )
-> where ( 'point_id' , $o -> point_id )
-> get ();
2023-09-11 12:57:29 +00:00
if ( $o -> zone -> domain -> flatten )
$oo = $oo -> merge ( Address :: withTrashed ()
-> whereIn ( 'zone_id' , $o -> zone -> domain -> zones -> pluck ( 'id' ))
-> where ( 'host_id' , $o -> host_id )
-> where ( 'node_id' , $o -> node_id )
-> where ( 'point_id' , $o -> point_id )
-> get ()
);
2023-09-08 14:07:46 +00:00
return view ( 'system/address-merge' )
-> with ( 'o' , $o )
-> with ( 'oo' , $oo );
}
2022-01-04 13:34:33 +00:00
public function api_address ( Request $request , System $o ) : Collection
{
2023-07-19 06:51:40 +00:00
return Address :: select ([ ' addresses . id ',' addresses . zone_id ',' region_id ',' host_id ',' node_id ',' point_id ' ])
2022-01-04 13:34:33 +00:00
-> leftjoin ( 'zones' ,[ 'zones.id' => 'addresses.zone_id' ])
-> where ( 'addresses.system_id' , $o -> id )
-> where ( 'zones.domain_id' , $request -> domain_id )
2022-11-20 00:47:46 +00:00
-> withTrashed ()
2022-01-04 13:34:33 +00:00
-> FTNorder ()
-> get ()
2023-07-19 06:51:40 +00:00
-> map ( function ( $item ) { return [ 'id' => ( string ) $item -> id , 'value' => $item -> ftn4d ]; });
2022-01-04 13:34:33 +00:00
}
2023-07-29 03:17:36 +00:00
public function api_address_get ( Address $o )
{
return $o ;
}
2021-11-11 11:57:13 +00:00
/**
* Systems with no owners
*/
public function api_orphan ( Request $request ) : Collection
{
return System :: select ([ 'id' , 'name' ])
-> leftjoin ( 'system_user' ,[ 'system_user.system_id' => 'systems.id' ])
-> whereNull ( 'user_id' )
-> where ( 'systems.name' , 'ilike' , '%' . $request -> term . '%' )
-> orderBy ( 'name' )
-> get ();
}
2022-03-14 11:28:54 +00:00
/**
* Identify all the addresses from systems that are not owned by a user
*
* @ param Request $request
* @ return Collection
*/
public function api_orphan_address ( Request $request ) : Collection
{
$result = collect ();
list ( $zone_id , $host_id , $node_id , $point_id , $domain ) = sscanf ( $request -> query ( 'term' ), '%d:%d/%d.%d@%s' );
# Look for Systems
foreach ( Address :: select ([ 'addresses.id' , 'systems.name' , DB :: raw ( 'systems.id AS system_id' ), 'zones.zone_id' , 'region_id' , 'host_id' , 'node_id' , 'point_id' , 'addresses.zone_id' ])
-> join ( 'zones' ,[ 'zones.id' => 'addresses.zone_id' ])
-> rightjoin ( 'systems' ,[ 'systems.id' => 'addresses.system_id' ])
-> when ( $zone_id || $host_id || $node_id , function ( $query ) use ( $zone_id , $host_id , $node_id ) {
return $query
-> when ( $zone_id , function ( $q , $zone_id ) { return $q -> where ( 'zones.zone_id' , $zone_id ); })
-> where ( function ( $q ) use ( $host_id ) {
return $q
-> when ( $host_id , function ( $q , $host_id ) { return $q -> where ( 'region_id' , $host_id ); })
-> when ( $host_id , function ( $q , $host_id ) { return $q -> orWhere ( 'host_id' , $host_id ); });
})
-> when ( $node_id , function ( $q , $node_id ) { return $q -> where ( 'node_id' , $node_id ); });
})
-> orWhere ( 'systems.name' , 'ilike' , '%' . $request -> query ( 'term' ) . '%' )
-> orderBy ( 'systems.name' )
-> get () as $o )
{
$result -> push ([ 'id' => $o -> id , 'name' => sprintf ( '%s (%s)' , $o -> ftn3d , $o -> name ), 'category' => 'Systems' ]);
}
return $result ;
}
2023-08-03 07:30:52 +00:00
public function areafix ( AreafixRequest $request , System $o , Zone $zo )
{
if ( $request -> post ()) {
$no = new Netmail ;
foreach ( $request -> safe () as $item => $value )
$no -> { $item } = $value ;
$no -> from = auth :: user () -> name ;
$no -> msg .= " \r " ;
$no -> datetime = Carbon :: now ();
$no -> tzoffset = $no -> datetime -> utcOffset ();
$no -> flags = ( Message :: FLAG_LOCAL | Message :: FLAG_PRIVATE | Message :: FLAG_CRASH );
$no -> cost = 0 ;
$no -> tearline = sprintf ( '%s (%04X)' , Setup :: PRODUCT_NAME , Setup :: PRODUCT_ID );
$no -> save ();
2023-09-19 03:54:35 +00:00
Log :: info ( sprintf ( '%s:= Areafix to [%s], scheduling a poll' , self :: LOGKEY , $no -> tftn -> ftn ));
2023-08-03 07:30:52 +00:00
AddressPoll :: dispatch ( $no -> tftn );
return redirect () -> back () -> with ( 'success' , 'Areafix/Filefix sent' );
}
return view ( 'system.areafix' )
-> with ( 'zo' , $zo )
-> with ( 'ao' , $o -> match ( $zo ) -> first ())
-> with ( 'o' , $o )
-> with ( 'setup' , Setup :: findOrFail ( config ( 'app.id' )));
}
2021-07-01 14:25:41 +00:00
/**
* Delete address assigned to a host
*
* @ param Address $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function del_address ( Address $o )
{
2021-07-04 11:47:23 +00:00
// @todo This should be admin of the zone
2021-07-01 14:25:41 +00:00
$this -> authorize ( 'admin' , $o );
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'address' );
2021-07-01 14:25:41 +00:00
$sid = $o -> system_id ;
2021-07-02 13:19:50 +00:00
$o -> active = FALSE ;
$o -> save ();
2021-07-01 14:25:41 +00:00
$o -> delete ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $sid ));
}
2023-07-06 08:43:32 +00:00
/**
* Demo an address NC -> node
*
* @ param Address $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function dem_address ( Address $o )
{
// @todo This should be admin of the zone
$this -> authorize ( 'admin' , $o );
session () -> flash ( 'accordion' , 'address' );
// Make sure that no other system has this address active.
if ( $o -> role === Address :: NODE_ACTIVE )
return redirect () -> back () -> withErrors ([ 'demaddress' => sprintf ( '%s cannot be demoted any more' , $o -> ftn3D )]);
$o -> role = ( $o -> role << 1 );
$o -> save ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> system_id ));
}
2021-07-04 11:47:23 +00:00
/**
* Delete address assigned to a host
*
* @ param Address $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function del_session ( System $o , Zone $zo )
{
$this -> authorize ( 'admin' , $zo );
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'session' );
2021-07-04 11:47:23 +00:00
$o -> sessions () -> detach ( $zo );
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> id ));
}
2021-08-25 12:13:49 +00:00
/**
* Update the systems echoareas
*
* @ param Request $request
* @ param System $o
2021-09-06 13:39:32 +00:00
* @ return \Illuminate\Contracts\Foundation\Application | \Illuminate\Contracts\View\Factory | \Illuminate\Contracts\View\View | \Illuminate\Http\RedirectResponse
2021-08-25 12:13:49 +00:00
*/
public function echoareas ( Request $request , System $o )
{
2022-01-04 13:34:33 +00:00
$ao = $o -> addresses -> firstWhere ( 'id' , $request -> address_id );
2021-08-25 12:13:49 +00:00
2023-06-27 07:39:11 +00:00
if (( $request -> method () === 'POST' ) && $request -> post ()) {
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'echoarea' );
2022-11-20 00:47:46 +00:00
if ( $ao -> trashed () && collect ( $request -> get ( 'id' )) -> diff ( $ao -> echoareas -> pluck ( 'id' )) -> count ())
return redirect () -> back () -> withErrors ( sprintf ( 'Address [%s] has been deleted, cannot add additional echos' , $ao -> ftn3d ));
2021-08-25 12:13:49 +00:00
// Ensure we have session details for this address.
if ( ! $ao -> session ( 'sespass' ))
return redirect () -> back () -> withErrors ( 'System doesnt belong to this network' );
2022-01-04 13:34:33 +00:00
$ao -> echoareas () -> syncWithPivotValues ( $request -> get ( 'id' ,[]),[ 'subscribed' => Carbon :: now ()]);
2021-08-25 12:13:49 +00:00
2023-06-27 07:39:11 +00:00
return redirect () -> back () -> with ( 'success' , 'Echoareas updated' );
2021-08-25 12:13:49 +00:00
}
2023-09-16 14:14:46 +00:00
// @todo Allow a NC/RC/ZC to override
2021-08-25 12:13:49 +00:00
$eo = Echoarea :: active ()
2022-01-04 13:34:33 +00:00
-> where ( 'domain_id' , $ao -> zone -> domain_id )
2023-09-16 14:14:46 +00:00
-> where ( function ( $query ) use ( $ao ) {
return $query
-> whereRaw ( sprintf ( '(security&7) <= %d' , $ao -> security )) // write
-> orWhereRaw ( sprintf ( '((security>>3)&7) <= %d' , $ao -> security )); // read
})
2021-08-25 12:13:49 +00:00
-> orderBy ( 'name' )
-> get ();
return view ( 'system.widget.echoarea' )
-> with ( 'o' , $o )
-> with ( 'ao' , $ao )
-> with ( 'echoareas' , $eo );
}
2022-11-01 11:24:36 +00:00
/**
* Update the systems fileareas
*
* @ param Request $request
* @ param System $o
* @ return \Illuminate\Contracts\Foundation\Application | \Illuminate\Contracts\View\Factory | \Illuminate\Contracts\View\View | \Illuminate\Http\RedirectResponse
*/
public function fileareas ( Request $request , System $o )
{
$ao = $o -> addresses -> firstWhere ( 'id' , $request -> address_id );
2023-06-27 07:39:11 +00:00
if (( $request -> method () === 'POST' ) && $request -> post ()) {
2022-11-01 11:24:36 +00:00
session () -> flash ( 'accordion' , 'filearea' );
// Ensure we have session details for this address.
if ( ! $ao -> session ( 'sespass' ))
return redirect () -> back () -> withErrors ( 'System doesnt belong to this network' );
$ao -> fileareas () -> syncWithPivotValues ( $request -> get ( 'id' ,[]),[ 'subscribed' => Carbon :: now ()]);
2023-06-27 07:39:11 +00:00
return redirect () -> back () -> with ( 'success' , 'Fileareas updated' );
2022-11-01 11:24:36 +00:00
}
2023-09-16 14:14:46 +00:00
// @todo Allow a NC/RC/ZC to override
2022-11-01 11:24:36 +00:00
$fo = Filearea :: active ()
-> where ( 'domain_id' , $ao -> zone -> domain_id )
2023-09-16 14:14:46 +00:00
-> where ( function ( $query ) use ( $ao ) {
return $query
-> whereRaw ( sprintf ( '(security&7) <= %d' , $ao -> security )) // write
-> orWhereRaw ( sprintf ( '((security>>3)&7) <= %d' , $ao -> security )); // read
})
2022-11-01 11:24:36 +00:00
-> orderBy ( 'name' )
-> get ();
return view ( 'system.widget.filearea' )
-> with ( 'o' , $o )
-> with ( 'ao' , $ao )
-> with ( 'fileareas' , $fo );
}
2021-11-11 11:57:13 +00:00
public function home ()
{
return view ( 'system.home' );
}
2021-08-08 07:27:22 +00:00
/**
* Move address to another system
*
* @ param Request $request
* @ param System $so
* @ param Address $o
2021-08-13 12:53:59 +00:00
* @ return \Illuminate\Contracts\Foundation\Application | \Illuminate\Contracts\View\Factory | \Illuminate\Contracts\View\View | \Illuminate\Http\RedirectResponse
2021-08-08 07:27:22 +00:00
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function mov_address ( Request $request , System $so , Address $o )
{
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'address' );
2021-08-08 07:27:22 +00:00
// Quick check that this address belongs to this system
2023-06-27 07:39:11 +00:00
if ( $so -> addresses -> search ( function ( $item ) use ( $o ) { return $item -> id === $o -> id ; }) === FALSE )
2021-08-08 07:27:22 +00:00
abort ( 404 );
if ( $request -> post ()) {
$this -> authorize ( 'admin' , $o );
$validated = $request -> validate ([
'system_id' => 'required|exists:systems,id' ,
'remove' => 'nullable|boolean' ,
'remsess' => 'nullable|boolean|exclude_if:remove,1' ,
]);
$o -> system_id = $validated [ 'system_id' ];
$o -> save ();
if ( Arr :: get ( $validated , 'remove' )) {
$so -> sessions () -> detach ( $o -> zone );
2023-08-01 02:56:45 +00:00
$so -> mailers () -> detach ();
2023-10-04 04:58:46 +00:00
$so -> users () -> detach ();
2021-08-08 07:27:22 +00:00
$so -> delete ();
} elseif ( Arr :: get ( $validated , 'remsess' )) {
$so -> sessions () -> detach ( $o -> zone );
}
return redirect () -> to ( 'ftn/system/addedit/' . $validated [ 'system_id' ]);
}
return view ( 'system.moveaddr' )
-> with ( 'o' , $o );
}
2021-07-04 11:47:23 +00:00
public function ours ()
{
return view ( 'system.ours' );
}
2023-07-06 08:43:32 +00:00
/**
* Promote an address node -> NC
*
* @ param Address $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function pro_address ( Address $o )
{
// @todo This should be admin of the zone
$this -> authorize ( 'admin' , $o );
session () -> flash ( 'accordion' , 'address' );
// Make sure that no other system has this address active.
if ( $o -> role === Address :: NODE_NC )
return redirect () -> back () -> withErrors ([ 'proaddress' => sprintf ( '%s cannot be promoted any more' , $o -> ftn3D )]);
$o -> role = ( $o -> role >> 1 );
$o -> save ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> system_id ));
}
2021-07-01 14:25:41 +00:00
/**
* Suspend address assigned to a host
*
* @ param Address $o
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function sus_address ( Address $o )
{
2021-07-04 11:47:23 +00:00
// @todo This should be admin of the zone
2021-07-01 14:25:41 +00:00
$this -> authorize ( 'admin' , $o );
2021-08-25 12:13:49 +00:00
session () -> flash ( 'accordion' , 'address' );
2021-07-01 14:25:41 +00:00
2023-06-17 09:14:16 +00:00
// Make sure that no other system has this address active.
if ( ! $o -> active && ( $x = Address :: where ([
'zone_id' => $o -> zone_id ,
'host_id' => $o -> host_id ,
'node_id' => $o -> node_id ,
'point_id' => $o -> point_id ,
'active' => TRUE ,
]) -> single ())) {
return redirect () -> back () -> withErrors ([ 'susaddress' => sprintf ( '%s is already active on system [<a href="%s">%s</a>]' , $o -> ftn , url ( 'ftn/system/addedit' , $x -> system_id ), $x -> system -> name )]);
}
2021-07-01 14:25:41 +00:00
$o -> active = ( ! $o -> active );
$o -> save ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> system_id ));
}
2022-11-19 01:02:13 +00:00
/**
* Recover a deleted address
*
* @ param int $id
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function rec_address ( int $id )
{
$o = Address :: onlyTrashed () -> findOrFail ( $id );
// @todo This should be admin of the zone
$this -> authorize ( 'admin' , $o );
session () -> flash ( 'accordion' , 'address' );
$o -> restore ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> system_id ));
}
/**
* Recover a deleted address
*
* @ param int $id
* @ return \Illuminate\Http\RedirectResponse
* @ throws \Illuminate\Auth\Access\AuthorizationException
*/
public function pur_address ( int $id )
{
$o = Address :: onlyTrashed () -> findOrFail ( $id );
// @todo This should be admin of the zone
$this -> authorize ( 'admin' , $o );
session () -> flash ( 'accordion' , 'address' );
$o -> forceDelete ();
return redirect () -> to ( sprintf ( 'ftn/system/addedit/%d' , $o -> system_id ));
}
2023-08-10 01:09:55 +00:00
// @todo Can this be consolidated with system_register()
2022-12-04 02:30:38 +00:00
public function system_link ( Request $request )
{
if ( ! $request -> system_id )
return redirect ( 'user/system/register' );
$s = Setup :: findOrFail ( config ( 'app.id' )) -> system ;
$so = System :: findOrFail ( $request -> system_id );
$ca = NULL ;
$la = NULL ;
2023-06-23 11:28:29 +00:00
foreach ( $s -> akas as $ao ) {
2022-12-11 09:17:24 +00:00
if (( $ca = $so -> match ( $ao -> zone )) -> count ())
2022-12-04 02:30:38 +00:00
break ;
}
2023-07-26 09:44:07 +00:00
if ( $ca -> count () && $la = $ca -> pop ()) {
2023-07-23 07:27:52 +00:00
Notification :: route ( 'netmail' , $la ) -> notify ( new AddressLink ( Auth :: user ()));
2023-07-26 09:44:07 +00:00
AddressPoll :: dispatch ( $la ) -> delay ( 15 );
}
2022-12-04 02:30:38 +00:00
return view ( 'user.system.register_send' )
-> with ( 'la' , $la )
-> with ( 'o' , $so );
}
2021-11-11 11:57:13 +00:00
/**
2023-04-14 09:47:33 +00:00
* Register a system , or link to an existing system
2021-11-11 11:57:13 +00:00
*/
2022-01-01 14:52:21 +00:00
public function system_register ( SystemRegister $request )
2021-06-17 14:08:30 +00:00
{
2022-03-14 11:28:54 +00:00
// Step 1, show the user a form to select an existing defined system
if ( $request -> isMethod ( 'GET' ))
return view ( 'user.system.register' );
2023-10-05 00:11:21 +00:00
if ( $request -> action === 'register' && $request -> name && is_numeric ( $request -> name ))
2022-12-04 02:30:38 +00:00
return view ( 'user.system.widget.register_confirm' )
2023-10-05 00:11:21 +00:00
-> with ( 'o' , System :: findOrFail ( $request -> name ));
2022-12-04 02:30:38 +00:00
2023-10-05 00:11:21 +00:00
$o = System :: findOrNew ( is_numeric ( $request -> system_id ) ? $request -> system_id : NULL );
2021-11-11 11:57:13 +00:00
2022-03-14 11:28:54 +00:00
// If the system exists, and we are 'register', we'll start the address claim process
2023-04-14 09:47:33 +00:00
if ( $o -> exists && $request -> action === 'Link' ) {
2022-03-14 11:28:54 +00:00
$validate = Setup :: findOrFail ( config ( 'app.id' )) -> system -> inMyZones ( $o -> addresses );
// If we have addresses, we'll trigger the routed netmail
2023-08-10 01:09:55 +00:00
if ( $validate -> count ()) {
Notification :: route ( 'netmail' , $x = $validate -> first ()) -> notify ( new AddressLink ( Auth :: user ()));
AddressPoll :: dispatch ( $x ) -> delay ( 15 );
}
2022-03-14 11:28:54 +00:00
2022-12-04 02:30:38 +00:00
return view ( 'user.system.widget.register_send' )
2022-03-14 11:28:54 +00:00
-> with ( 'validate' , $validate )
-> with ( 'o' , $o );
}
// If the system doesnt exist, we'll create it
2021-11-11 11:57:13 +00:00
if ( ! $o -> exist ) {
$o -> sysop = Auth :: user () -> name ;
2023-07-07 13:59:04 +00:00
foreach ([ 'name' , 'zt_id' , 'location' , 'phone' , 'method' , 'address' , 'port' ] as $item )
2021-11-11 11:57:13 +00:00
if ( $request -> { $item })
$o -> { $item } = $request -> { $item };
$o -> active = TRUE ;
}
if ( $request -> post ( 'submit' )) {
Auth :: user () -> systems () -> save ( $o );
2022-01-01 14:52:21 +00:00
// @todo if the system already exists and part of one of our networks, we'll need to send the registration email to confirm the address.
2021-11-11 11:57:13 +00:00
// @todo mark the system (or addresses) as "pending" at this stage until it is confirmed
return redirect () -> to ( url ( 'ftn/system/addedit' , $o -> id ));
}
2022-01-01 14:52:21 +00:00
// Re-flash our previously input data
if ( $request -> old )
session () -> flashInput ( $request -> old );
2021-11-11 11:57:13 +00:00
return view ( 'system.widget.form-system' )
2022-01-01 14:52:21 +00:00
-> with ( 'action' , $request -> action )
2021-11-11 11:57:13 +00:00
-> with ( 'o' , $o )
-> with ( 'errors' , new ViewErrorBag );
2021-06-17 14:08:30 +00:00
}
2022-11-25 10:44:03 +00:00
public function view ( System $o )
{
2023-04-15 03:34:08 +00:00
$o -> load ([ 'addresses' ]);
2022-11-25 10:44:03 +00:00
return view ( 'system.view' )
-> with ( 'o' , $o );
}
2022-03-14 11:28:54 +00:00
}