Removed API key feature
Removed API key generation feature in preparation for JWT authentication
This commit is contained in:
parent
587f695fe1
commit
230eda1974
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class ApiKey extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected $fillable = [
|
|
||||||
'name',
|
|
||||||
'status',
|
|
||||||
'discriminator',
|
|
||||||
'last_used',
|
|
||||||
'secret',
|
|
||||||
'owner_user_id'
|
|
||||||
];
|
|
||||||
|
|
||||||
public function user()
|
|
||||||
{
|
|
||||||
return $this->belongsTo('App\User', 'owner_user_id', 'id');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\ApiKey;
|
|
||||||
use App\Http\Requests\CreateApiKeyRequest;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
|
|
||||||
class ApiKeyController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$this->authorize('viewAny', ApiKey::class);
|
|
||||||
|
|
||||||
return view('dashboard.administration.keys')
|
|
||||||
->with('keys', ApiKey::all());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
*/
|
|
||||||
public function store(CreateApiKeyRequest $request)
|
|
||||||
{
|
|
||||||
$this->authorize('create', ApiKey::class);
|
|
||||||
|
|
||||||
$discriminator = "#" . bin2hex(random_bytes(7));
|
|
||||||
$secret = bin2hex(random_bytes(32));
|
|
||||||
|
|
||||||
$key = ApiKey::create([
|
|
||||||
'name' => $request->keyName,
|
|
||||||
'discriminator' => $discriminator,
|
|
||||||
'secret' => Hash::make($secret),
|
|
||||||
'status' => 'active',
|
|
||||||
'owner_user_id' => Auth::user()->id
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($key)
|
|
||||||
{
|
|
||||||
$request->session()->flash('success', __('Key successfully registered!'));
|
|
||||||
$request->session()->flash('finalKey', $discriminator . '.' . $secret);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('An error occurred whilst trying to create an API key.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function revokeKey(Request $request, ApiKey $key)
|
|
||||||
{
|
|
||||||
$this->authorize('update', $key);
|
|
||||||
|
|
||||||
if ($key->status == 'active')
|
|
||||||
{
|
|
||||||
$key->status = 'disabled';
|
|
||||||
$key->save();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('Key already revoked.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Key revoked. Apps using this key will stop working.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy($id)
|
|
||||||
{
|
|
||||||
$key = ApiKey::findOrFail($id);
|
|
||||||
$this->authorize('delete', $key);
|
|
||||||
|
|
||||||
$key->delete();
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Key deleted successfully. Apps using this key will stop working.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class CreateApiKeyRequest extends FormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function authorize()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'keyName' => 'required|string'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -365,12 +365,6 @@ return [
|
|||||||
'url' => '/admin/devtools',
|
'url' => '/admin/devtools',
|
||||||
'can' => 'admin.developertools.use',
|
'can' => 'admin.developertools.use',
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'text' => 'API Keys',
|
|
||||||
'icon' => 'fas fa-user-shield',
|
|
||||||
'can' => 'admin.settings.view',
|
|
||||||
'route' => 'keys.index'
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ApiKeys extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
// API keys can only access resources the owner's account can access
|
|
||||||
Schema::create('api_keys', function (Blueprint $table) {
|
|
||||||
|
|
||||||
$table->id();
|
|
||||||
$table->string('discriminator');
|
|
||||||
$table->string('secret');
|
|
||||||
$table->enum('status', ['disabled', 'active']);
|
|
||||||
$table->bigInteger('owner_user_id')->unsigned();
|
|
||||||
|
|
||||||
$table->foreign('owner_user_id')
|
|
||||||
->references('id')
|
|
||||||
->on('users')
|
|
||||||
->cascadeOnDelete()
|
|
||||||
->cascadeOnUpdate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddLinkedAccountsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -1,134 +0,0 @@
|
|||||||
@extends('adminlte::page')
|
|
||||||
|
|
||||||
@section('title', config('app.name') . ' | Key Administration')
|
|
||||||
|
|
||||||
@section('content_header')
|
|
||||||
|
|
||||||
<h4>{{__('messages.adm')}} / API Key Administration</h4>
|
|
||||||
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('js')
|
|
||||||
|
|
||||||
<x-global-errors></x-global-errors>
|
|
||||||
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
|
|
||||||
<x-modal id="createKeyModal" modal-label="createKeyModalLabel" modal-title="New API Key" include-close-button="true">
|
|
||||||
|
|
||||||
<form id="createKey" method="post" action="{{ route('keys.store') }}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name">Give your new API key a name to easily identify it.</label>
|
|
||||||
<input type="text" name="keyName" class="form-control" id="name" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<x-slot name="modalFooter">
|
|
||||||
<button onclick="$('#createKey').submit()" type="button" class="btn btn-success"><i class="fas fa-key"></i> Register new key</button>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
</x-modal>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="alert alert-primary">
|
|
||||||
<p><i class="fas fa-info-circle"></i> You can use the key discriminator to identify it's API calls in the logs.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (session()->has('finalKey'))
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<div class="alert alert-success">
|
|
||||||
<p><i class="fas fa-key"></i> This is your API key: {{ session('finalKey') }}</p>
|
|
||||||
<p>Please copy it <b>now</b> as it'll only appear once.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<x-card id="adminKeys" card-title="API Key Monitoring & Administration" footer-style="text-center">
|
|
||||||
|
|
||||||
<x-slot name="cardHeader">
|
|
||||||
<p class="card-text">Here, you can view and manage all API keys created by users in the app. You can't, however, use this page to access someone else's account.</p>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
|
|
||||||
@if(!$keys->isEmpty())
|
|
||||||
<table class="table table-borderless">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Discriminator</th>
|
|
||||||
<th>Owner</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Last Used</th>
|
|
||||||
<th>Last Modified</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
@foreach($keys as $key)
|
|
||||||
<tr>
|
|
||||||
<td>{{ $key->name }}</td>
|
|
||||||
<td id="discr{{$key->id}}">{{ $key->discriminator }}</td>
|
|
||||||
<td><a href="{{ route('showSingleProfile', ['user' => $key->user->id]) }}">{{ $key->user->name }}</a></td>
|
|
||||||
<td><span class="badge badge-{{ ($key->status == 'disabled') ? 'danger' : 'primary' }}">{{ ($key->status == 'disabled') ? 'Revoked' : 'Active' }}</span></td>
|
|
||||||
<td><span class="badge badge-{{ ($key->last_used == null) ? 'danger' : 'primary' }}">{{ ($key->last_used == null) ? 'No recent activity' : $key->last_used }}</span></td>
|
|
||||||
<td><span class="badge badge-primary">{{ $key->updated_at }}</span></td>
|
|
||||||
<td>
|
|
||||||
@if ($key->status == 'active')
|
|
||||||
<form class="d-inline-block" action="{{ route('revokeKey', ['key' => $key->id]) }}" method="post">
|
|
||||||
@csrf
|
|
||||||
@method('PATCH')
|
|
||||||
<button type="submit" class="btn btn-danger btn-sm ml-2"><i class="fas fa-lock"></i> Revoke</button>
|
|
||||||
</form>
|
|
||||||
@else
|
|
||||||
<button disabled type="button" class="btn btn-danger btn-sm ml-2"><i class="fas fa-lock"></i> Revoke</button>
|
|
||||||
@endif
|
|
||||||
<form class="d-inline-block" action="{{ route('keys.destroy', ['key' => $key->id]) }}" method="post">
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="btn btn-danger btn-sm ml-2"><i class="fas fa-trash"></i> Delete</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
@else
|
|
||||||
<div class="alert alert-success">
|
|
||||||
<p><i class="fa fa-info-circle"></i> No API keys have been registered yet.</p>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
<x-slot name="cardFooter">
|
|
||||||
<button onclick="$('#createKeyModal').modal('show')" type="button" class="btn btn-secondary ml-2"><i class="fas fa-plus"></i> New API Key</button>
|
|
||||||
<button type="button" onclick="window.location.href='/admin/maintenance/system-logs'" class="btn btn-secondary ml-2"><i class="fas fa-clipboard"></i> Search Logs</button>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
</x-card>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@stop
|
|
||||||
|
|
||||||
|
|
||||||
@section('footer')
|
|
||||||
@include('breadcrumbs.dashboard.footer')
|
|
||||||
@stop
|
|
@ -241,8 +241,6 @@ Route::group(['prefix' => LaravelLocalization::setLocale(), 'middleware' => ['lo
|
|||||||
Route::get('settings', [OptionsController::class, 'index'])
|
Route::get('settings', [OptionsController::class, 'index'])
|
||||||
->name('showSettings');
|
->name('showSettings');
|
||||||
|
|
||||||
Route::resource('keys', ApiKeyController::class);
|
|
||||||
|
|
||||||
Route::patch('keys/revoke/{key}', [ApiKeyController::class, 'revokeKey'])
|
Route::patch('keys/revoke/{key}', [ApiKeyController::class, 'revokeKey'])
|
||||||
->name('revokeKey');
|
->name('revokeKey');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user