mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-11-03 02:13:16 +03:00 
			
		
		
		
	Added webhook_call_before theme event hook
This commit is contained in:
		@@ -4,8 +4,10 @@ namespace BookStack\Actions;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Entity;
 | 
					use BookStack\Entities\Models\Entity;
 | 
				
			||||||
 | 
					use BookStack\Facades\Theme;
 | 
				
			||||||
use BookStack\Interfaces\Loggable;
 | 
					use BookStack\Interfaces\Loggable;
 | 
				
			||||||
use BookStack\Model;
 | 
					use BookStack\Model;
 | 
				
			||||||
 | 
					use BookStack\Theming\ThemeEvents;
 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
@@ -68,10 +70,13 @@ class DispatchWebhookJob implements ShouldQueue
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function handle()
 | 
					    public function handle()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $themeResponse = Theme::dispatch(ThemeEvents::WEBHOOK_CALL_BEFORE, $this->event, $this->webhook, $this->detail);
 | 
				
			||||||
 | 
					        $webhookData = $themeResponse ?? $this->buildWebhookData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = Http::asJson()
 | 
					        $response = Http::asJson()
 | 
				
			||||||
            ->withOptions(['allow_redirects' => ['strict' => true]])
 | 
					            ->withOptions(['allow_redirects' => ['strict' => true]])
 | 
				
			||||||
            ->timeout(3)
 | 
					            ->timeout(3)
 | 
				
			||||||
            ->post($this->webhook->endpoint, $this->buildWebhookData());
 | 
					            ->post($this->webhook->endpoint, $webhookData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($response->failed()) {
 | 
					        if ($response->failed()) {
 | 
				
			||||||
            Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with status {$response->status()}");
 | 
					            Log::error("Webhook call to endpoint {$this->webhook->endpoint} failed with status {$response->status()}");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,4 +79,20 @@ class ThemeEvents
 | 
				
			|||||||
     * @returns \League\CommonMark\ConfigurableEnvironmentInterface|null
 | 
					     * @returns \League\CommonMark\ConfigurableEnvironmentInterface|null
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    const COMMONMARK_ENVIRONMENT_CONFIGURE = 'commonmark_environment_configure';
 | 
					    const COMMONMARK_ENVIRONMENT_CONFIGURE = 'commonmark_environment_configure';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Webhook call before event.
 | 
				
			||||||
 | 
					     * Runs before a webhook endpoint is called. Allows for customization
 | 
				
			||||||
 | 
					     * of the data format & content within the webhook POST request.
 | 
				
			||||||
 | 
					     * Provides the original event name as a string (see \BookStack\Actions\ActivityType)
 | 
				
			||||||
 | 
					     * along with the webhook instance along with the event detail which may be a
 | 
				
			||||||
 | 
					     * "Loggable" model type or a string.
 | 
				
			||||||
 | 
					     * If the listener returns a non-null value, that will be used as the POST data instead
 | 
				
			||||||
 | 
					     * of the system default.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string $event
 | 
				
			||||||
 | 
					     * @param \BookStack\Actions\Webhook $webhook
 | 
				
			||||||
 | 
					     * @param string|\BookStack\Interfaces\Loggable $detail
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    const WEBHOOK_CALL_BEFORE = 'webhook_call_before';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Tests;
 | 
					namespace Tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use BookStack\Actions\ActivityType;
 | 
				
			||||||
 | 
					use BookStack\Actions\DispatchWebhookJob;
 | 
				
			||||||
 | 
					use BookStack\Actions\Webhook;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use BookStack\Entities\Tools\PageContent;
 | 
					use BookStack\Entities\Tools\PageContent;
 | 
				
			||||||
use BookStack\Facades\Theme;
 | 
					use BookStack\Facades\Theme;
 | 
				
			||||||
use BookStack\Theming\ThemeEvents;
 | 
					use BookStack\Theming\ThemeEvents;
 | 
				
			||||||
use Illuminate\Console\Command;
 | 
					use Illuminate\Console\Command;
 | 
				
			||||||
 | 
					use Illuminate\Http\Client\Request as HttpClientRequest;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Illuminate\Http\Response;
 | 
					use Illuminate\Http\Response;
 | 
				
			||||||
use Illuminate\Support\Facades\Artisan;
 | 
					use Illuminate\Support\Facades\Artisan;
 | 
				
			||||||
use Illuminate\Support\Facades\File;
 | 
					use Illuminate\Support\Facades\File;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Http;
 | 
				
			||||||
use League\CommonMark\ConfigurableEnvironmentInterface;
 | 
					use League\CommonMark\ConfigurableEnvironmentInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ThemeTest extends TestCase
 | 
					class ThemeTest extends TestCase
 | 
				
			||||||
@@ -160,6 +165,36 @@ class ThemeTest extends TestCase
 | 
				
			|||||||
        $this->assertInstanceOf(User::class, $args[1]);
 | 
					        $this->assertInstanceOf(User::class, $args[1]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function test_event_webhook_call_before()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $args = [];
 | 
				
			||||||
 | 
					        $callback = function (...$eventArgs) use (&$args) {
 | 
				
			||||||
 | 
					            $args = $eventArgs;
 | 
				
			||||||
 | 
					            return ['test' => 'hello!'];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        Theme::listen(ThemeEvents::WEBHOOK_CALL_BEFORE, $callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Http::fake([
 | 
				
			||||||
 | 
					            '*' => Http::response('', 200),
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $webhook = new Webhook(['name' => 'Test webhook', 'endpoint' => 'https://example.com']);
 | 
				
			||||||
 | 
					        $webhook->save();
 | 
				
			||||||
 | 
					        $event = ActivityType::PAGE_UPDATE;
 | 
				
			||||||
 | 
					        $detail = Page::query()->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dispatch((new DispatchWebhookJob($webhook, $event, $detail)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertCount(3, $args);
 | 
				
			||||||
 | 
					        $this->assertEquals($event, $args[0]);
 | 
				
			||||||
 | 
					        $this->assertEquals($webhook->id, $args[1]->id);
 | 
				
			||||||
 | 
					        $this->assertEquals($detail->id, $args[2]->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Http::assertSent(function (HttpClientRequest $request) {
 | 
				
			||||||
 | 
					            return $request->isJson() && $request->data()['test'] === 'hello!';
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function test_add_social_driver()
 | 
					    public function test_add_social_driver()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Theme::addSocialDriver('catnet', [
 | 
					        Theme::addSocialDriver('catnet', [
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user