]> BookStack Code Mirror - bookstack/commitdiff
Started webhook implementation
authorDan Brown <redacted>
Tue, 7 Dec 2021 14:55:11 +0000 (14:55 +0000)
committerDan Brown <redacted>
Tue, 7 Dec 2021 14:55:11 +0000 (14:55 +0000)
12 files changed:
app/Actions/Webhook.php [new file with mode: 0644]
app/Http/Controllers/RoleController.php
app/Http/Controllers/WebhookController.php [new file with mode: 0644]
database/factories/WebhookFactory.php [new file with mode: 0644]
database/migrations/2021_12_07_111343_create_webhooks_table.php [new file with mode: 0644]
resources/icons/webhooks.svg [new file with mode: 0644]
resources/lang/en/settings.php
resources/views/settings/audit.blade.php
resources/views/settings/parts/navbar-with-version.blade.php
resources/views/settings/parts/navbar.blade.php
resources/views/settings/webhooks/index.blade.php [new file with mode: 0644]
routes/web.php

diff --git a/app/Actions/Webhook.php b/app/Actions/Webhook.php
new file mode 100644 (file)
index 0000000..6939b54
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+
+namespace BookStack\Actions;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class Webhook extends Model
+{
+    use HasFactory;
+}
index 7ba52d486f539955c159ecc5d9d10d8051ad9830..25b2a5851f88c6802964be60a113577d2fd46f8f 100644 (file)
@@ -23,7 +23,7 @@ class RoleController extends Controller
     /**
      * Show a listing of the roles in the system.
      */
-    public function list()
+    public function index()
     {
         $this->checkPermission('user-roles-manage');
         $roles = $this->permissionsRepo->getAllRoles();
diff --git a/app/Http/Controllers/WebhookController.php b/app/Http/Controllers/WebhookController.php
new file mode 100644 (file)
index 0000000..8745bf9
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+namespace BookStack\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+class WebhookController extends Controller
+{
+    /**
+     * Show all webhooks configured in the system.
+     */
+    public function index()
+    {
+        return view('settings.webhooks.index');
+    }
+}
diff --git a/database/factories/WebhookFactory.php b/database/factories/WebhookFactory.php
new file mode 100644 (file)
index 0000000..4d716fc
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+namespace Database\Factories;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+class WebhookFactory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array
+     */
+    public function definition()
+    {
+        return [
+            'name' => 'My webhook for ' . $this->faker->country(),
+            'endpoint' => $this->faker->url,
+        ];
+    }
+}
diff --git a/database/migrations/2021_12_07_111343_create_webhooks_table.php b/database/migrations/2021_12_07_111343_create_webhooks_table.php
new file mode 100644 (file)
index 0000000..7ccfe69
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateWebhooksTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('webhooks', function (Blueprint $table) {
+            $table->increments('id');
+            $table->string('name', 150);
+            $table->string('endpoint', 500);
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('webhooks');
+    }
+}
diff --git a/resources/icons/webhooks.svg b/resources/icons/webhooks.svg
new file mode 100644 (file)
index 0000000..fff0814
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10,15l5.88,0c0.27-0.31,0.67-0.5,1.12-0.5c0.83,0,1.5,0.67,1.5,1.5c0,0.83-0.67,1.5-1.5,1.5c-0.44,0-0.84-0.19-1.12-0.5 l-3.98,0c-0.46,2.28-2.48,4-4.9,4c-2.76,0-5-2.24-5-5c0-2.42,1.72-4.44,4-4.9l0,2.07C4.84,13.58,4,14.7,4,16c0,1.65,1.35,3,3,3 s3-1.35,3-3V15z M12.5,4c1.65,0,3,1.35,3,3h2c0-2.76-2.24-5-5-5l0,0c-2.76,0-5,2.24-5,5c0,1.43,0.6,2.71,1.55,3.62l-2.35,3.9 C6.02,14.66,5.5,15.27,5.5,16c0,0.83,0.67,1.5,1.5,1.5s1.5-0.67,1.5-1.5c0-0.16-0.02-0.31-0.07-0.45l3.38-5.63 C10.49,9.61,9.5,8.42,9.5,7C9.5,5.35,10.85,4,12.5,4z M17,13c-0.64,0-1.23,0.2-1.72,0.54l-3.05-5.07C11.53,8.35,11,7.74,11,7 c0-0.83,0.67-1.5,1.5-1.5S14,6.17,14,7c0,0.15-0.02,0.29-0.06,0.43l2.19,3.65C16.41,11.03,16.7,11,17,11l0,0c2.76,0,5,2.24,5,5 c0,2.76-2.24,5-5,5c-1.85,0-3.47-1.01-4.33-2.5l2.67,0C15.82,18.82,16.39,19,17,19c1.65,0,3-1.35,3-3S18.65,13,17,13z"/></svg>
\ No newline at end of file
index 688b0aad80b1c443739b22632096e1ce518b06ac..57cbe500e89c5170f698ac34d6705803f8cc3f64 100755 (executable)
@@ -233,6 +233,10 @@ return [
     'user_api_token_delete_confirm' => 'Are you sure you want to delete this API token?',
     'user_api_token_delete_success' => 'API token successfully deleted',
 
+    // Webhooks
+    'webhooks' => 'Webhooks',
+    'webhooks_create' => 'Create New Webhook',
+
     //! If editing translations files directly please ignore this in all
     //! languages apart from en. Content will be auto-copied from en.
     //!////////////////////////////////
index 84f180f3b41fbc43c07933aeab7a4b6910caa5d4..9261ed61b46618bccb5e3934bae85baee5dd1e34 100644 (file)
@@ -10,7 +10,7 @@
     </div>
 
     <div class="card content-wrap auto-height">
-        <h2 class="list-heading">{{ trans('settings.audit') }}</h2>
+        <h1 class="list-heading">{{ trans('settings.audit') }}</h1>
         <p class="text-muted">{{ trans('settings.audit_desc') }}</p>
 
         <div class="flex-container-row">
index 09af699a33b8fe8c778a49fe7dbf4bc6cabadd55..bec41146b6f1b43a80822ff47df42851897747bb 100644 (file)
@@ -6,10 +6,12 @@ $version - Version of bookstack to display
     <div class="py-m flex fit-content">
         @include('settings.parts.navbar', ['selected' => $selected])
     </div>
-    <div class="flex"></div>
-    <div class="text-right p-m flex fit-content">
-        <a target="_blank" rel="noopener noreferrer" href="https://github.com/BookStackApp/BookStack/releases">
-            BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
-        </a>
-    </div>
+</div>
+<div class="px-s">
+    <hr class="darker m-none">
+</div>
+<div class="py-l px-m flex fit-content">
+    <a target="_blank" rel="noopener noreferrer" href="https://github.com/BookStackApp/BookStack/releases">
+        BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
+    </a>
 </div>
\ No newline at end of file
index a472196c56e7bded70e893953f7383918257dca0..f2fad378c2f476ae2f3c4756088aa361eb8970cc 100644 (file)
@@ -13,4 +13,7 @@
     @if(userCan('user-roles-manage'))
         <a href="{{ url('/settings/roles') }}" @if($selected == 'roles') class="active" @endif>@icon('lock-open'){{ trans('settings.roles') }}</a>
     @endif
+    @if(userCan('settings-manage'))
+        <a href="{{ url('/settings/webhooks') }}" @if($selected == 'webhooks') class="active" @endif>@icon('webhooks'){{ trans('settings.webhooks') }}</a>
+    @endif
 </nav>
\ No newline at end of file
diff --git a/resources/views/settings/webhooks/index.blade.php b/resources/views/settings/webhooks/index.blade.php
new file mode 100644 (file)
index 0000000..ca93cfe
--- /dev/null
@@ -0,0 +1,25 @@
+@extends('layouts.simple')
+
+@section('body')
+
+    <div class="container small">
+
+        <div class="py-m">
+            @include('settings.parts.navbar', ['selected' => 'webhooks'])
+        </div>
+
+        <div class="card content-wrap auto-height">
+
+            <div class="grid half v-center">
+                <h1 class="list-heading">{{ trans('settings.webhooks') }}</h1>
+
+                <div class="text-right">
+                    <a href="{{ url("/settings/webhooks/new") }}" class="button outline">{{ trans('settings.webhooks_create') }}</a>
+                </div>
+            </div>
+
+
+        </div>
+    </div>
+
+@stop
index c924ed68c9ee93a2a3ef05665901b14d0aaed692..627ce6523971568c434e5c743d6b228214d10331 100644 (file)
@@ -29,7 +29,11 @@ use BookStack\Http\Controllers\UserApiTokenController;
 use BookStack\Http\Controllers\UserController;
 use BookStack\Http\Controllers\UserProfileController;
 use BookStack\Http\Controllers\UserSearchController;
+use BookStack\Http\Controllers\WebhookController;
+use BookStack\Http\Middleware\VerifyCsrfToken;
+use Illuminate\Session\Middleware\StartSession;
 use Illuminate\Support\Facades\Route;
+use Illuminate\View\Middleware\ShareErrorsFromSession;
 
 Route::get('/status', [StatusController::class, 'show']);
 Route::get('/robots.txt', [HomeController::class, 'robots']);
@@ -244,13 +248,16 @@ Route::middleware('auth')->group(function () {
     Route::delete('/settings/users/{userId}/api-tokens/{tokenId}', [UserApiTokenController::class, 'destroy']);
 
     // Roles
-    Route::get('/settings/roles', [RoleController::class, 'list']);
+    Route::get('/settings/roles', [RoleController::class, 'index']);
     Route::get('/settings/roles/new', [RoleController::class, 'create']);
     Route::post('/settings/roles/new', [RoleController::class, 'store']);
     Route::get('/settings/roles/delete/{id}', [RoleController::class, 'showDelete']);
     Route::delete('/settings/roles/delete/{id}', [RoleController::class, 'delete']);
     Route::get('/settings/roles/{id}', [RoleController::class, 'edit']);
     Route::put('/settings/roles/{id}', [RoleController::class, 'update']);
+
+    // Webhooks
+    Route::get('/settings/webhooks', [WebhookController::class, 'index']);
 });
 
 // MFA routes
@@ -291,9 +298,9 @@ Route::post('/saml2/logout', [Auth\Saml2Controller::class, 'logout']);
 Route::get('/saml2/metadata', [Auth\Saml2Controller::class, 'metadata']);
 Route::get('/saml2/sls', [Auth\Saml2Controller::class, 'sls']);
 Route::post('/saml2/acs', [Auth\Saml2Controller::class, 'startAcs'])->withoutMiddleware([
-    \Illuminate\Session\Middleware\StartSession::class,
-    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
-    \BookStack\Http\Middleware\VerifyCsrfToken::class,
+    StartSession::class,
+    ShareErrorsFromSession::class,
+    VerifyCsrfToken::class,
 ]);
 Route::get('/saml2/acs', [Auth\Saml2Controller::class, 'processAcs']);