User editing and creation by system admin

This commit is contained in:
Deon George 2021-06-19 01:09:34 +10:00
parent 416e79164e
commit e45f366b76
12 changed files with 256 additions and 116 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\User; use App\Models\User;
@ -22,14 +23,28 @@ class UserController extends Controller
$this->authorize('admin',$o); $this->authorize('admin',$o);
$request->validate([ $request->validate([
'email' => 'required|email|unique:users,email,'.($o ? $o->id : NULL), 'email' => 'required|email|unique:users,email,'.($o->exists ? $o->id : 0),
'name' => 'required|min:3',
'pgp_pubkey' => [
'nullable',
'min:64',
//function ($attribute,$value,$fail) { return $fail('Not this time'); }
],
'active' => 'required|boolean',
'admin' => 'required|boolean',
]); ]);
foreach (['name','email','notes'] as $key) foreach (['name','email','pgp_pubkey','active','admin'] as $key)
$o->{$key} = $request->post($key); $o->{$key} = $request->post($key);
if (! $o->exists)
$o->password = base64_encode(random_bytes(20));
$o->save(); $o->save();
if ($o->wasRecentlyCreated)
event(new Registered($o));
return redirect()->action([self::class,'home']); return redirect()->action([self::class,'home']);
} }

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateUsers extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->text('pgp_pubkey')->nullable();
$table->boolean('active')->default(TRUE);
$table->dateTime('last_on')->nullable();
});
Schema::table('systems', function (Blueprint $table) {
$table->dateTime('last_session')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['pgp_pubkey','active','last_on']);
});
Schema::table('systems', function (Blueprint $table) {
$table->dropColumn(['last_session']);
});
}
}

View File

@ -34,15 +34,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-badge"></i></span> <span class="input-group-text"><i class="bi bi-person-badge"></i></span>
<input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" required autocomplete="email" autofocus> <input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('email')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your email is required. Your email is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -53,7 +51,7 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-key-fill"></i></span> <span class="input-group-text"><i class="bi bi-key-fill"></i></span>
<input type="password" class="form-control" id="password" placeholder="Password" name="password" required> <input type="password" class="form-control" id="password" placeholder="Password" name="password" required>
<span class="invalid-feedback"> <span class="invalid-feedback" role="alert">
Your password is required. Your password is required.
</span> </span>
</div> </div>

View File

@ -29,15 +29,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-badge"></i></span> <span class="input-group-text"><i class="bi bi-person-badge"></i></span>
<input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" autocomplete="email" autofocus required> <input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" autocomplete="email" autofocus required>
@error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('email')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your email is required. Your email is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -30,15 +30,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-badge"></i></span> <span class="input-group-text"><i class="bi bi-person-badge"></i></span>
<input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" value="{{ old('email',$email) }}" required autocomplete="email" autofocus> <input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" value="{{ old('email',$email) }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('email')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your email is required. Your email is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -49,15 +47,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-key-fill"></i></span> <span class="input-group-text"><i class="bi bi-key-fill"></i></span>
<input type="password" class="form-control @error('password') is-invalid @enderror" id="password" placeholder="Password" name="password" required> <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" placeholder="Password" name="password" required>
@error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('password')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your password is required. Your password is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -68,9 +64,9 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-key-fill"></i></span> <span class="input-group-text"><i class="bi bi-key-fill"></i></span>
<input type="password" class="form-control" id="password" placeholder="Password Again" name="password_confirmation" required> <input type="password" class="form-control" id="password" placeholder="Password Again" name="password_confirmation" required>
<div class="invalid-feedback"> <span class="invalid-feedback" role="alert">
Please re-enter your password. Please re-enter your password.
</div> </span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -19,15 +19,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-square"></i></span> <span class="input-group-text"><i class="bi bi-person-square"></i></span>
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Full Name" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus> <input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Full Name" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('name')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your name is required. Your name is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -38,15 +36,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-badge"></i></span> <span class="input-group-text"><i class="bi bi-person-badge"></i></span>
<input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" value="{{ old('email') }}" required autocomplete="email"> <input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('email')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
Your email is required. Your email is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -57,18 +53,16 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-key-fill"></i></span> <span class="input-group-text"><i class="bi bi-key-fill"></i></span>
<input type="password" class="form-control @error('password') is-invalid @enderror" id="password" placeholder="Password" name="password" required> <input type="password" class="form-control @error('password') is-invalid @enderror" id="password" placeholder="Password" name="password" required>
@error('password')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('password')
{{ $message }} {{ $message }}
</span>
@else @else
<div class="invalid-feedback">
Your password is required. Your password is required.
</div>
@enderror @enderror
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
@ -76,9 +70,9 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-key-fill"></i></span> <span class="input-group-text"><i class="bi bi-key-fill"></i></span>
<input type="password" class="form-control" id="password_confirmation" placeholder="Password Again" name="password_confirmation" required> <input type="password" class="form-control" id="password_confirmation" placeholder="Password Again" name="password_confirmation" required>
<div class="invalid-feedback"> <span class="invalid-feedback" role="alert">
Please re-enter your password. Please re-enter your password.
</div> </span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -19,15 +19,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-tag-fill"></i></span> <span class="input-group-text"><i class="bi bi-tag-fill"></i></span>
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Name" name="name" value="{{ old('name',$o->name) }}" required @cannot('admin',$o)disabled @endcannot autofocus> <input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Name" name="name" value="{{ old('name',$o->name) }}" required @cannot('admin',$o)disabled @endcannot autofocus>
@error('name')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('name')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A name is required. A name is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
@ -89,7 +87,7 @@
<h2 class="cap">Home Page</h2> <h2 class="cap">Home Page</h2>
<div class="row"> <div class="row">
<div class="col-12" > <div class="col-12">
<label for="homepage" class="form-label">Home Page Text</label> <label for="homepage" class="form-label">Home Page Text</label>
<div style="background-color: #fff;color: #000;"> <div style="background-color: #fff;color: #000;">
<textarea class="form-control" rows=5 id="homepage" name="homepage" placeholder="Home Page..." @cannot('admin',$o)disabled @endcannot>{{ old('homepage',$o->homepage) }}</textarea> <textarea class="form-control" rows=5 id="homepage" name="homepage" placeholder="Home Page..." @cannot('admin',$o)disabled @endcannot>{{ old('homepage',$o->homepage) }}</textarea>

View File

@ -12,7 +12,7 @@
@can('admin') @can('admin')
<dl> <dl>
<dt>Users</dt> <dt>Users</dt>
<dd><a href="{{ url('user/add') }}" >Create</a></dd> <dd><a href="{{ url('user/addedit') }}" >Create</a></dd>
<dd><a href="{{ url('user/list') }}">List</a></dd> <dd><a href="{{ url('user/list') }}">List</a></dd>
</dl> </dl>
@endcan @endcan

View File

@ -19,15 +19,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-tag-fill"></i></span> <span class="input-group-text"><i class="bi bi-tag-fill"></i></span>
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Name" name="name" value="{{ old('name',$o->name) }}" required @cannot('admin',$o)disabled @endcannot autofocus> <input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Name" name="name" value="{{ old('name',$o->name) }}" required @cannot('admin',$o)disabled @endcannot autofocus>
@error('name')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('name')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A name is required. A name is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
@ -51,15 +49,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-globe"></i></span> <span class="input-group-text"><i class="bi bi-globe"></i></span>
<input type="text" class="form-control @error('sysop') is-invalid @enderror" id="sysop" placeholder="Sysop" name="sysop" value="{{ old('sysop',$o->sysop) }}" required @cannot('admin',$o)disabled @endcannot autocomplete="name"> <input type="text" class="form-control @error('sysop') is-invalid @enderror" id="sysop" placeholder="Sysop" name="sysop" value="{{ old('sysop',$o->sysop) }}" required @cannot('admin',$o)disabled @endcannot autocomplete="name">
@error('sysop')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('sysop')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A Sysop's name is required. A Sysop's name is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
@ -68,15 +64,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-globe"></i></span> <span class="input-group-text"><i class="bi bi-globe"></i></span>
<input type="text" class="form-control @error('location') is-invalid @enderror" id="location" placeholder="Location" name="location" value="{{ old('location',$o->location) }}" required @cannot('admin',$o)disabled @endcannot> <input type="text" class="form-control @error('location') is-invalid @enderror" id="location" placeholder="Location" name="location" value="{{ old('location',$o->location) }}" required @cannot('admin',$o)disabled @endcannot>
@error('location')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('location')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
System location is required. System location is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>
@ -103,16 +97,14 @@
<span class="m-0 p-0 input-group-text" style="background-color: #ffffff;"> <span class="m-0 p-0 input-group-text" style="background-color: #ffffff;">
<input type="text" class="form-control @error('port') is-invalid @enderror" id="port" placeholder="port" name="port" value="{{ old('port',$o->port) }}" @cannot('admin',$o)disabled @endcannot> <input type="text" class="form-control @error('port') is-invalid @enderror" id="port" placeholder="port" name="port" value="{{ old('port',$o->port) }}" @cannot('admin',$o)disabled @endcannot>
</span> </span>
@error('address')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('address')
{{ $message }} {{ $message }}
</span>
@enderror @enderror
@error('port') @error('port')
<span class="invalid-feedback" role="alert">
{{ $message }} {{ $message }}
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,111 @@
@extends('layouts.app')
@section('htmlheader_title')
@if($o->exists) Update @else Add @endif User
@endsection
@section('content')
<form class="row g-0 needs-validation" method="post" novalidate>
@csrf
<div class="row">
<div class="col-12">
<div class="greyframe titledbox shadow0xb0">
<h2 class="cap">@if($o->exists) Update @else Add @endif User</h2>
<div class="row">
<div class="col-4">
<label for="name" class="form-label">Name</label>
<div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-tag-fill"></i></span>
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name" placeholder="Name" name="name" value="{{ old('name',$o->name) }}" required @cannot('admin',$o)disabled @endcannot autofocus>
<span class="invalid-feedback" role="alert">
@error('name')
{{ $message }}
@else
A name is required.
@enderror
</span>
</div>
</div>
<div class="col-4">
<label for="active" class="form-label">Active</label>
<div class="input-group">
<div class="btn-group" role="group">
<input type="radio" class="btn-check" name="active" id="active_yes" value="1" required @cannot('admin',$o)disabled @endcannot @if(old('active',$o->active))checked @endif>
<label class="btn btn-outline-success" for="active_yes">Yes</label>
<input type="radio" class="btn-check btn-danger" name="active" id="active_no" value="0" required @cannot('admin',$o)disabled @endcannot @if(! old('active',$o->active))checked @endif>
<label class="btn btn-outline-danger" for="active_no">No</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-4">
<label for="email" class="form-label">Email</label>
<div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-person-badge"></i></span>
<input type="text" class="form-control @error('email') is-invalid @enderror" id="email" placeholder="Email" name="email" value="{{ old('email',$o->email) }}" required @cannot('admin',$o)disabled @endcannot>
<span class="invalid-feedback" role="alert">
@error('email')
{{ $message }}
@else
Email required for login.
@enderror
</span>
</div>
</div>
<div class="col-4">
<label for="admin" class="form-label">Site Admin</label>
<div class="input-group">
<div class="btn-group" role="group" @if($o->id == Auth::user()->id)data-bs-toggle="tooltip" title="You cannot demote yourself" @endif>
<input type="radio" class="btn-check" name="admin" id="admin_yes" value="1" required @cannot('admin',$o)disabled @endcannot @if(old('admin',$o->admin))checked @endif>
<label class="btn btn-outline-success" for="admin_yes">Yes</label>
<input type="radio" class="btn-check btn-danger" name="admin" id="admin_no" value="0" required @if($o->id == Auth::user()->id || Auth::user()->cannot('admin',$o)) disabled @endif @if(! old('admin',$o->admin))checked @endif>
<label class="btn btn-outline-danger" for="admin_no">No</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<label for="pgp_pubkey" class="form-label">PGP Public Key</label>
<textarea class="form-control @error('pgp_pubkey')is-invalid @enderror" rows=3 name="pgp_pubkey" placeholder="PGP Public Key..." @cannot('admin',$o)disabled @endcannot>{{ old('pgp_pubkey',$o->pgp_pubkey) }}</textarea>
<span class="invalid-feedback" role="alert">
@error('pgp_pubkey')
{{ $message }}
@enderror
</span>
</div>
</div>
<div class="row">
<div class="col-12">
<a href="{{ url('ftn/system') }}" class="btn btn-danger">Cancel</a>
@can('admin',$o)
<button type="submit" name="submit" class="btn btn-success mr-0 float-end">@if ($o->exists)Save @else Add @endif</button>
@endcan
</div>
</div>
</div>
</div>
</div>
</form>
@endsection
@section('page-scripts')
@if($o->id == Auth::user()->id)
<script>
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
</script>
@endif
@append

View File

@ -19,15 +19,13 @@
<div class="input-group has-validation"> <div class="input-group has-validation">
<span class="input-group-text"><i class="bi bi-hash"></i></span> <span class="input-group-text"><i class="bi bi-hash"></i></span>
<input type="text" class="form-control @error('zone_id') is-invalid @enderror" id="zone" placeholder="Zone" name="zone_id" value="{{ old('zone_id',$o->zone_id) }}" required @cannot('admin',$o)disabled @endcannot autofocus> <input type="text" class="form-control @error('zone_id') is-invalid @enderror" id="zone" placeholder="Zone" name="zone_id" value="{{ old('zone_id',$o->zone_id) }}" required @cannot('admin',$o)disabled @endcannot autofocus>
@error('zone_id')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('zone_id')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A zone number is required. A zone number is required.
</span>
@enderror @enderror
</span>
</div> </div>
</div> </div>
@ -41,15 +39,13 @@
<option value="{{ $oo->id }}" @if(old('domain_id',$o->domain_id)==$oo->id)selected @endif>{{ $oo->name }}</option> <option value="{{ $oo->id }}" @if(old('domain_id',$o->domain_id)==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach @endforeach
</select> </select>
@error('domain_id')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('domain_id')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A domain is required. A domain is required.
</span>
@enderror @enderror
</span>
<span class="input-helper">Add a <a href="{{ url('ftn/domain/addedit') }}">NEW Domain</a></span> <span class="input-helper">Add a <a href="{{ url('ftn/domain/addedit') }}">NEW Domain</a></span>
</div> </div>
</div> </div>
@ -64,22 +60,20 @@
<option value="{{ $oo->id }}" @if(old('system_id',$o->system_id)==$oo->id)selected @endif>{{ $oo->name }}</option> <option value="{{ $oo->id }}" @if(old('system_id',$o->system_id)==$oo->id)selected @endif>{{ $oo->name }}</option>
@endforeach @endforeach
</select> </select>
@error('system_id')
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@error('system_id')
{{ $message }} {{ $message }}
</span>
@else @else
<span class="invalid-feedback">
A system is required. A system is required.
</span>
@enderror @enderror
</span>
<span class="input-helper">Add a <a href="{{ url('ftn/system/addedit') }}">NEW System</a>. This system is the primary mailer/tosser responsible for managing the zone.</span> <span class="input-helper">Add a <a href="{{ url('ftn/system/addedit') }}">NEW System</a>. This system is the primary mailer/tosser responsible for managing the zone.</span>
</div> </div>
</div> </div>
<div class="col-4"> <div class="col-4">
<label for="active" class="form-label">Active</label> <label for="active" class="form-label">Active</label>
<div class="input-group" > <div class="input-group">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<input type="radio" class="btn-check" name="active" id="active_yes" value="1" required @cannot('admin',$o)disabled @endcannot @if(old('active',$o->active))checked @endif> <input type="radio" class="btn-check" name="active" id="active_yes" value="1" required @cannot('admin',$o)disabled @endcannot @if(old('active',$o->active))checked @endif>
<label class="btn btn-outline-success" for="active_yes">Yes</label> <label class="btn btn-outline-success" for="active_yes">Yes</label>

View File

@ -55,4 +55,6 @@ Route::middleware(['auth','can:admin'])->group(function () {
Route::get('setup',[HomeController::class,'setup']); Route::get('setup',[HomeController::class,'setup']);
Route::get('user/list',[UserController::class,'home']); Route::get('user/list',[UserController::class,'home']);
Route::match(['get','post'],'user/addedit/{o?}',[UserController::class,'add_edit'])
->where('o','[0-9]+');
}); });