Update on security, user to edit their own system

This commit is contained in:
Deon George 2024-05-18 08:27:17 +10:00
parent 29710c37c2
commit 59ec5f5a0c
8 changed files with 85 additions and 39 deletions

View File

@ -3,7 +3,9 @@
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\QueryException;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
@ -14,7 +16,7 @@ use Illuminate\Support\Facades\Notification;
use Illuminate\Support\ViewErrorBag;
use App\Classes\FTN\Message;
use App\Http\Requests\{AddressMerge,AreafixRequest,SystemRegister};
use App\Http\Requests\{AddressMerge,AreafixRequest,SystemRegister,SystemSessionRequest};
use App\Jobs\AddressPoll;
use App\Models\{Address,Echoarea,Echomail,Filearea,Netmail,Setup,System,Zone};
use App\Notifications\Netmails\AddressLink;
@ -29,8 +31,6 @@ class SystemController extends Controller
*/
public function add_edit(SystemRegister $request,System $o)
{
$this->authorize('update',$o);
if ($request->post()) {
foreach (['name','location','sysop','hold','phone','address','port','active','method','notes','zt_id','pkt_type','heartbeat'] as $key)
$o->{$key} = $request->post($key);
@ -836,26 +836,14 @@ class SystemController extends Controller
/**
* Add Session details
*
* @param Request $request
* @param SystemSessionRequest $request
* @param System $o
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function session_add(Request $request,System $o)
public function session_add(SystemSessionRequest $request,System $o)
{
// @todo This should be admin of the zone
$this->authorize('update',$o);
session()->flash('accordion','session');
$validate = $request->validate([
'zone_id' => 'required|exists:zones,id',
'sespass' => 'required|string|min:4',
'pktpass' => 'required|string|min:4|max:8',
'ticpass' => 'required|string|min:4',
'fixpass' => 'required|string|min:4',
]);
$zo = Zone::findOrFail($validate['zone_id']);
$zo = Zone::findOrFail($request->zone_id);
/*
// @todo Disabling this, it needs improvement. If the new node is the ZC it becomes the default for the zone (and therefore remove all defaults from other addresses in the same zone), otherwise default should be false
@ -866,7 +854,7 @@ class SystemController extends Controller
}
*/
$o->sessions()->attach($zo,$validate);
$o->sessions()->attach($zo,$request->validated());
return redirect()->to(sprintf('system/addedit/%d',$o->id));
}
@ -874,9 +862,10 @@ class SystemController extends Controller
/**
* Delete address assigned to a host
*
* @param Address $o
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
* @param System $o
* @param Zone $zo
* @return RedirectResponse
* @throws AuthorizationException
*/
public function session_del(System $o,Zone $zo)
{

View File

@ -22,17 +22,14 @@ class SystemRegister extends FormRequest
*/
public function authorize(Request $request)
{
$this->so = new System;
if (! $request->post())
return TRUE;
if (is_numeric($request->name)) {
$this->so = System::findOrNew($request->name);
// Cannot claim this site
if ($this->route('o')->id === Setup::findOrFail(config('app.id'))->system_id)
return FALSE;
// Cannot claim this site
if ($this->so->id === Setup::findOrFail(config('app.id'))->system_id)
return FALSE;
}
return Gate::allows(is_numeric($request->name) && $this->so->users->count() ? 'update' : 'register',$this->so);
return Gate::allows($this->route('o')->users->count() ? 'update_nn' : 'register',$this->route('o'));
}
public function messages(): array

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class SystemSessionRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
session()->flash('accordion','session');
return Gate::allows('update_nn',$this->route('o'));
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'zone_id' => 'required|exists:zones,id',
'sespass' => 'required|string|min:4',
'pktpass' => 'required|string|min:4|max:8',
'ticpass' => 'required|string|min:4',
'fixpass' => 'required|string|min:4',
];
}
}

View File

@ -110,7 +110,8 @@ class System extends Model
public function sessions()
{
return $this->belongsToMany(Zone::class)
->withPivot(['sespass','pktpass','ticpass','fixpass','zt_ipv4','zt_ipv6','default']);
->withPivot(['sespass','pktpass','ticpass','fixpass','zt_ipv4','zt_ipv6','default'])
->dontCache();
}
/**

View File

@ -6,6 +6,21 @@ use Illuminate\Auth\Access\HandlesAuthorization;
use App\Models\{System,User};
/**
* This handles updating system records
*
* Authorisation is defined by function_role_only, where
* - function = create,delete,update
* - role = admin,zc,rc,nc,hc,nn,pt
* - only = only that role can do (no hierarchy permission)
* ie:
* - admin - only site admin can do (user = admin)
* - zc - only ZC can perform (user has an address that is a ZC)
* - rc - only RC (or ZC) ...
* - hc - only HC (or ZC/RC) ...
* - nn - only NN (or ZC/RC/HC) ...
* - pt - only PT (or ZC/RC/HC/NN) ...
*/
class SystemPolicy
{
use HandlesAuthorization;
@ -49,7 +64,7 @@ class SystemPolicy
* @param System $system
* @return bool
*/
public function update(User $user, System $system): bool
public function update_nn(User $user,System $system): bool
{
// Site Admins can always edit
if ($user->isAdmin())
@ -59,7 +74,8 @@ class SystemPolicy
if (! $system->exists)
return FALSE;
return $system->users->contains($user)
&& (($system->addresses->count() === 0) || ($system->addresses->where('validated',TRUE)->count()));
// @todo Permit ZC, RC, NC, HUB user
return $system->users->contains($user) && $system->akas->count();
}
}

View File

@ -217,7 +217,9 @@
@if(($x=$oo->systems->where('pivot.default',TRUE))->count() && ($x->first()->id !== $o->id))
<i class="bi bi-dash-square"></i>
@else
<span class="default" itemid="{{ $oo->id }}"><i class="bi bi-{{ $x->count() ? 'check-square' : 'square' }}"></i></span>
@can('admin')
<span class="default" itemid="{{ $oo->id }}"><i class="bi bi-{{ $x->count() ? 'check-square' : 'square' }}"></i></span>
@endcan
@endif
</td>
<td>{{ $oo->pivot->sespass }}</td>
@ -603,6 +605,7 @@
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function () {
@can('admin')
$('.default').click(function () {
var item = this;
icon = $(item).find('i');
@ -634,6 +637,7 @@
cache: false
})
});
@endcan
$('data.validated').on('click',function(item) {
that = $(this);
var values = item.delegateTarget.value.split(':');

View File

@ -42,7 +42,7 @@
<tbody>
@foreach (\App\Models\System::active()->with(['addresses.zone.domain'])->get() as $oo)
<tr>
<td><a href="{{ url('system/addedit',[$oo->id]) }}" @cannot('update',$oo)class="disabled" @endcannot>{{ $oo->id }}</a></td>
<td><a href="{{ url('system/addedit',[$oo->id]) }}" @cannot('update_nn',$oo)class="disabled" @endcannot>{{ $oo->id }}</a></td>
<td>{{ $oo->name }} @if(! $oo->active)<span class="float-end"><small>[i]</small></span>@endif</td>
<td>{{ $oo->sysop }}</td>
<td>{{ $oo->location }}</td>

View File

@ -1,6 +1,10 @@
<!-- $o = System::class -->
@if(($x=\App\Models\Zone::active()
->whereIn('id',$o->zones->pluck('id'))
@php
use App\Models\Zone;
@endphp
@if(($x=Zone::active()
->whereIn('id',$o->addresses->pluck('zone.id'))
->whereNotIn('id',$o->sessions->pluck('id'))
->with(['domain'])
->get())->count())