Skip to content

Commit 8c6da98

Browse files
authored
Merge pull request #226 from DigitalTimK/tests/hooks
Improving Hooks
2 parents af5436d + 7fd6175 commit 8c6da98

15 files changed

+355
-49
lines changed

.env

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Specify the Server Base URL of your BigBlueButton
1+
# Specify the URL and SECRET of your BigBlueButton-Server (check on your BBB-Server with command 'bbb-conf --secret')
22
BBB_SERVER_BASE_URL="https://test-install.blindsidenetworks.com/bigbluebutton/"
3+
BBB_SECRET="8cd8ef52e8e101574e400365b55e11a6"
34

4-
# Specify the value of your BigBlueButton secret
5-
BBB_SECRET="8cd8ef52e8e101574e400365b55e11a6"
5+
# SET THE HASHING ALGORITHM FOR HOOKS (BBB-SERVER < 3.0 MUST USE 'sha_1')
6+
HASH_ALGO_FOR_HOOKS="sha1"

src/BigBlueButton.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class BigBlueButton
8383
protected array $curlOpts = [];
8484
protected int $timeOut = 10;
8585
protected string $jSessionId;
86+
8687
private UrlBuilder $urlBuilder;
8788

8889
/**
@@ -611,7 +612,7 @@ private function sendRequest(string $url, string $payload = '', string $contentT
611612
*/
612613
private function processXmlResponse(string $url, string $payload = ''): \SimpleXMLElement
613614
{
614-
$response = $this->sendRequest($url, $payload, $contentType);
615+
$response = $this->sendRequest($url, $payload, 'application/xml');
615616

616617
return new \SimpleXMLElement($response);
617618
}

src/Parameters/HooksCreateParameters.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@
2222

2323
class HooksCreateParameters extends BaseParameters
2424
{
25-
private ?string $callbackUrl = null;
25+
private string $callbackUrl;
2626

2727
private ?string $meetingId = null;
2828

29+
private ?string $eventId = null;
30+
2931
private ?bool $getRaw = null;
3032

3133
public function __construct(string $callbackUrl)
3234
{
3335
$this->callbackUrl = $callbackUrl;
3436
}
3537

36-
public function getCallbackUrl(): ?string
38+
public function getCallbackUrl(): string
3739
{
3840
return $this->callbackUrl;
3941
}
@@ -57,6 +59,18 @@ public function setMeetingId(string $meetingId): self
5759
return $this;
5860
}
5961

62+
public function getEventId(): ?string
63+
{
64+
return $this->eventId;
65+
}
66+
67+
public function setEventId(string $eventId): self
68+
{
69+
$this->eventId = $eventId;
70+
71+
return $this;
72+
}
73+
6074
public function getRaw(): ?bool
6175
{
6276
return $this->getRaw;

src/Parameters/HooksDestroyParameters.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@
2222

2323
class HooksDestroyParameters extends BaseParameters
2424
{
25-
private ?string $hookId = null;
25+
private int $hookId;
2626

27-
public function __construct(string $hookId = null)
27+
public function __construct(int $hookId)
2828
{
2929
$this->hookId = $hookId;
3030
}
3131

32-
public function getHookId(): ?string
32+
public function getHookId(): int
3333
{
3434
return $this->hookId;
3535
}
3636

37-
public function setHookId(string $hookId): self
37+
public function setHookId(int $hookId): self
3838
{
3939
$this->hookId = $hookId;
4040

src/Responses/HooksCreateResponse.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,39 @@
2525
*/
2626
class HooksCreateResponse extends BaseResponse
2727
{
28-
public function getHookId(): int
28+
/**
29+
* According to documentation the hookId that needs to be used in the "destroy" command musst be of type number.
30+
* That is why the return here must be a number (= integer) too.
31+
*
32+
* But in the same time this property could be not part of the API-response in case the response failed. So it has
33+
* to return NULL as well.
34+
*
35+
* @see https://docs.bigbluebutton.org/development/webhooks/#hooksdestroy
36+
*/
37+
public function getHookId(): ?int
2938
{
39+
if (!$this->rawXml->hookID) {
40+
return null;
41+
}
42+
3043
return (int) $this->rawXml->hookID->__toString();
3144
}
3245

33-
public function isPermanentHook(): bool
46+
public function isPermanentHook(): ?bool
3447
{
48+
if (!$this->rawXml->permanentHook) {
49+
return null;
50+
}
51+
3552
return 'true' === $this->rawXml->permanentHook->__toString();
3653
}
3754

38-
public function hasRawData(): bool
55+
public function hasRawData(): ?bool
3956
{
57+
if (!$this->rawXml->rawData) {
58+
return null;
59+
}
60+
4061
return 'true' === $this->rawXml->rawData->__toString();
4162
}
4263
}

src/Responses/HooksDestroyResponse.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@
2525
*/
2626
class HooksDestroyResponse extends BaseResponse
2727
{
28-
public function removed(): bool
28+
public function removed(): ?bool
2929
{
30+
if (!$this->rawXml->removed) {
31+
return null;
32+
}
33+
3034
return 'true' === $this->rawXml->removed->__toString();
3135
}
3236
}

src/Util/UrlBuilder.php

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace BigBlueButton\Util;
2222

2323
use BigBlueButton\Core\ApiMethod;
24+
use BigBlueButton\Enum\HashingAlgorithm;
2425
use BigBlueButton\Parameters\CreateMeetingParameters;
2526
use BigBlueButton\Parameters\DeleteRecordingsParameters;
2627
use BigBlueButton\Parameters\EndMeetingParameters;
@@ -85,6 +86,7 @@ public function getHashingAlgorithm(): string
8586
}
8687

8788
// Basic functions
89+
8890
/**
8991
* Builds an API method URL that includes the url + params + its generated checksum.
9092
*/
@@ -169,18 +171,110 @@ public function getPutRecordingTextTrackUrl(PutRecordingTextTrackParameters $put
169171
return $this->buildUrl(ApiMethod::PUT_RECORDING_TEXT_TRACK, $putRecordingTextTrackParams->getHTTPQuery());
170172
}
171173

174+
/**
175+
* BBB-Server < 3.0 can only use SHA1 in the handling with hooks.
176+
* Please configure the HASH_ALGO_FOR_HOOKS environment variable in case SHA1 shall not be used.
177+
*
178+
* @see https://github.com/bigbluebutton/bbb-webhooks/issues/30
179+
*/
172180
public function getHooksCreateUrl(HooksCreateParameters $hookCreateParams): string
173181
{
174-
return $this->buildUrl(ApiMethod::HOOKS_CREATE, $hookCreateParams->getHTTPQuery());
182+
// store current hashing algorithm
183+
$hashingAlgorithm = $this->getHashingAlgorithm();
184+
185+
// change hashing algorithm for hooks
186+
$this->setHashingAlgorithm($this->getHashingAlgorithmForHooks());
187+
188+
// build URL
189+
$url = $this->buildUrl(ApiMethod::HOOKS_CREATE, $hookCreateParams->getHTTPQuery());
190+
191+
// reset to 'normal' hashing algorithm
192+
$this->setHashingAlgorithm($hashingAlgorithm);
193+
194+
return $url;
175195
}
176196

197+
/**
198+
* BBB-Server < 3.0 can only use SHA1 in the handling with hooks.
199+
* Please configure the HASH_ALGO_FOR_HOOKS environment variable in case SHA1 shall not be used.
200+
*
201+
* @see https://github.com/bigbluebutton/bbb-webhooks/issues/30
202+
*/
177203
public function getHooksListUrl(): string
178204
{
179-
return $this->buildUrl(ApiMethod::HOOKS_LIST);
205+
// store current hashing algorithm
206+
$hashingAlgorithm = $this->getHashingAlgorithm();
207+
208+
// change hashing algorithm for hooks
209+
$this->setHashingAlgorithm($this->getHashingAlgorithmForHooks());
210+
211+
// build URL
212+
$url = $this->buildUrl(ApiMethod::HOOKS_LIST);
213+
214+
// reset to 'normal' hashing algorithm
215+
$this->setHashingAlgorithm($hashingAlgorithm);
216+
217+
return $url;
180218
}
181219

220+
/**
221+
* BBB-Server < 3.0 can only use SHA1 in the handling with hooks.
222+
* Please configure the HASH_ALGO_FOR_HOOKS environment variable in case SHA1 shall not be used.
223+
*
224+
* @see https://github.com/bigbluebutton/bbb-webhooks/issues/30
225+
*/
182226
public function getHooksDestroyUrl(HooksDestroyParameters $hooksDestroyParams): string
183227
{
184-
return $this->buildUrl(ApiMethod::HOOKS_DESTROY, $hooksDestroyParams->getHTTPQuery());
228+
// store current hashing algorithm
229+
$hashingAlgorithm = $this->getHashingAlgorithm();
230+
231+
// change hashing algorithm for hooks
232+
$this->setHashingAlgorithm($this->getHashingAlgorithmForHooks());
233+
234+
// build URL
235+
$url = $this->buildUrl(ApiMethod::HOOKS_DESTROY, $hooksDestroyParams->getHTTPQuery());
236+
237+
// reset to 'normal' hashing algorithm
238+
$this->setHashingAlgorithm($hashingAlgorithm);
239+
240+
return $url;
241+
}
242+
243+
/**
244+
* This function defines the algorithm to be used for hooks.
245+
*
246+
* This function will evolve in phases:
247+
* - Phase 1: SHA1 as default (or superseded by environment-variable HASH_ALGO_FOR_HOOKS).
248+
* - Phase 2: same algo everywhere as default (or superseded by environment-variable HASH_ALGO_FOR_HOOKS and which will trigger in this case a deprecation-warning).
249+
* - Phase 3: removal of this function, adaptation of the other hook-functions in this class and remove the use of env-variable HASH_ALGO_FOR_HOOKS.
250+
*
251+
* Background:
252+
* BB-Server below 3.0 are using SHA1-algorithm for hooks only, but allow higher algorithms for
253+
* other APIs. This is creating issues since the algorithm of choice is used in the urlBuilder-class
254+
* for the hashing of the checksum. This is resulting in denied requests for hooks if the algorithm
255+
* of choice is not SHA1.
256+
* The current planning for BBB-Server 3.0 (and on) is to align the hashing algorithm for hooks with
257+
* the rest of the system. Having this in mind two situations need to be covered:
258+
* - BBB-Server < 3.0 ==> SHA1 is default for hooks (even rest is using other algorithm)
259+
* - BBB-Server >= 3.0 ==> same algorithm everywhere (according to planning).
260+
*
261+
* @deprecated This function will evolve in phases and will later disappear
262+
*/
263+
private function getHashingAlgorithmForHooks(): string
264+
{
265+
// ---------------------------------- phase 1 ----------------------------------
266+
// in case this env-variable is not set, SHA1 shall be used as default (phase 1)
267+
return getenv('HASH_ALGO_FOR_HOOKS') ?: HashingAlgorithm::SHA_1;
268+
// ---------------------------------- phase 1 ----------------------------------
269+
270+
/* ---------------------------------- phase 2 ----------------------------------
271+
* if (getenv('HASH_ALGO_FOR_HOOKS')) {
272+
* trigger_error('The environment variable HASH_ALGO_FOR_HOOKS will be removed soon. This will require you to run a BBB-Server 3.0 or higher!', E_USER_DEPRECATED);
273+
* }
274+
*
275+
* // in case this env-variable is not set, the 'normal' algorithm shall be used as default (phase 2)
276+
* return getenv('HASH_ALGO_FOR_HOOKS') ?: $this->getHashingAlgorithm();
277+
*
278+
* ---------------------------------- phase 2 ---------------------------------- */
185279
}
186280
}

tests/BigBlueButtonTest.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
use BigBlueButton\Parameters\EndMeetingParameters;
2727
use BigBlueButton\Parameters\GetMeetingInfoParameters;
2828
use BigBlueButton\Parameters\GetRecordingsParameters;
29+
use BigBlueButton\Parameters\HooksCreateParameters;
30+
use BigBlueButton\Parameters\HooksDestroyParameters;
2931
use BigBlueButton\Parameters\IsMeetingRunningParameters;
3032
use BigBlueButton\Parameters\PublishRecordingsParameters;
3133
use BigBlueButton\Util\ParamsIterator;
@@ -60,8 +62,9 @@ public function tearDown(): void
6062

6163
// close all existing meetings
6264
$meetingsResponse = $this->bbb->getMeetings();
63-
$meetings = $meetingsResponse->getMeetings();
65+
$this->assertTrue($meetingsResponse->success(), $meetingsResponse->getMessage());
6466

67+
$meetings = $meetingsResponse->getMeetings();
6568
foreach ($meetings as $meeting) {
6669
$endMeetingParameters = new EndMeetingParameters($meeting->getMeetingId(), $meeting->getModeratorPassword());
6770
$endMeetingResponse = $this->bbb->endMeeting($endMeetingParameters);
@@ -86,7 +89,7 @@ public function testApiVersion(): void
8689
// Create Meeting
8790

8891
/**
89-
* @deprecated Test will be removed together with the deprecated function from BigBlueButton::class
92+
* @deprecated test will be removed together with the deprecated function from BigBlueButton::class
9093
*
9194
* Test create meeting URL
9295
*/
@@ -176,7 +179,7 @@ public function testCreateMeetingWithMultiDocument(): void
176179
// Join Meeting
177180

178181
/**
179-
* @deprecated Test will be removed together with the deprecated function from BigBlueButton::class
182+
* @deprecated test will be removed together with the deprecated function from BigBlueButton::class
180183
*
181184
* Test create join meeting URL
182185
*/
@@ -230,7 +233,7 @@ public function testJoinMeeting(): void
230233
// End Meeting
231234

232235
/**
233-
* @deprecated Test will be removed together with the deprecated function from BigBlueButton::class
236+
* @deprecated test will be removed together with the deprecated function from BigBlueButton::class
234237
*
235238
* Test generate end meeting URL
236239
*/
@@ -400,6 +403,43 @@ public function testUpdateRecordings(): void
400403
$this->assertTrue($result->failed());
401404
}
402405

406+
// Hooks: create
407+
408+
public function testHooksCreate(): void
409+
{
410+
// create a hook
411+
$hooksCreateParameters = new HooksCreateParameters($this->faker->url);
412+
$hooksCreateResponse = $this->bbb->hooksCreate($hooksCreateParameters);
413+
$this->assertTrue($hooksCreateResponse->success(), $hooksCreateResponse->getMessage());
414+
}
415+
416+
public function testHooksList(): void
417+
{
418+
// create a hook
419+
$hooksListResponse = $this->bbb->hooksList();
420+
$this->assertTrue($hooksListResponse->success(), $hooksListResponse->getMessage());
421+
}
422+
423+
public function testHooksDestroy(): void
424+
{
425+
// create a hook
426+
$hooksCreateParameters = new HooksCreateParameters($this->faker->url);
427+
$hooksCreateResponse = $this->bbb->hooksCreate($hooksCreateParameters);
428+
$this->assertTrue($hooksCreateResponse->success(), $hooksCreateResponse->getMessage());
429+
$hookId = $hooksCreateResponse->getHookId();
430+
$this->assertNotNull($hookId);
431+
432+
// destroy existing hook
433+
$hooksDestroyParameters = new HooksDestroyParameters($hookId);
434+
$hooksCreateResponse = $this->bbb->hooksDestroy($hooksDestroyParameters);
435+
$this->assertTrue($hooksCreateResponse->success(), $hooksCreateResponse->getMessage());
436+
437+
// destroy non-existing hook
438+
$hooksDestroyParameters = new HooksDestroyParameters($this->faker->numberBetween(10000, 99999));
439+
$hooksCreateResponse = $this->bbb->hooksDestroy($hooksDestroyParameters);
440+
$this->assertFalse($hooksCreateResponse->success(), $hooksCreateResponse->getMessage());
441+
}
442+
403443
/**
404444
* @see https://github.com/vlucas/phpdotenv
405445
*/

tests/Parameters/HooksCreateParametersTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,23 @@ class HooksCreateParametersTest extends TestCase
3131
{
3232
public function testHooksCreateParameters(): void
3333
{
34+
// create string of eventIds
35+
$eventIds = [];
36+
for ($i = 0; $i < $this->faker->numberBetween(1, 5); ++$i) {
37+
$eventIds[] = $this->faker->uuid;
38+
}
39+
$eventIds = implode(',', $eventIds);
40+
3441
$hooksCreateParameters = new HooksCreateParameters($callBackUrl = $this->faker->url);
3542

3643
$this->assertEquals($callBackUrl, $hooksCreateParameters->getCallbackUrl());
3744

3845
// Test setters that are ignored by the constructor
3946
$hooksCreateParameters->setMeetingId($meetingId = $this->faker->uuid);
4047
$hooksCreateParameters->setGetRaw($getRaw = $this->faker->boolean);
48+
$hooksCreateParameters->setEventId($eventIds);
4149
$this->assertEquals($meetingId, $hooksCreateParameters->getMeetingId());
4250
$this->assertEquals($getRaw, $hooksCreateParameters->getRaw());
51+
$this->assertEquals($eventIds, $hooksCreateParameters->getEventId());
4352
}
4453
}

0 commit comments

Comments
 (0)