Completed
Push — master ( 99caf6...b741c4 )
by Ghazi
01:40
created

BigBlueButton::getJSessionId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * BigBlueButton open source conferencing system - https://www.bigbluebutton.org/.
4
 *
5
 * Copyright (c) 2016-2018 BigBlueButton Inc. and by respective authors (see below).
6
 *
7
 * This program is free software; you can redistribute it and/or modify it under the
8
 * terms of the GNU Lesser General Public License as published by the Free Software
9
 * Foundation; either version 3.0 of the License, or (at your option) any later
10
 * version.
11
 *
12
 * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14
 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License along
17
 * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
namespace BigBlueButton;
20
21
use BigBlueButton\Core\ApiMethod;
22
use BigBlueButton\Parameters\CreateMeetingParameters;
23
use BigBlueButton\Parameters\DeleteRecordingsParameters;
24
use BigBlueButton\Parameters\EndMeetingParameters;
25
use BigBlueButton\Parameters\GetMeetingInfoParameters;
26
use BigBlueButton\Parameters\GetRecordingsParameters;
27
use BigBlueButton\Parameters\IsMeetingRunningParameters;
28
use BigBlueButton\Parameters\JoinMeetingParameters;
29
use BigBlueButton\Parameters\PublishRecordingsParameters;
30
use BigBlueButton\Parameters\UpdateRecordingsParameters;
31
use BigBlueButton\Responses\ApiVersionResponse;
32
use BigBlueButton\Responses\CreateMeetingResponse;
33
use BigBlueButton\Responses\DeleteRecordingsResponse;
34
use BigBlueButton\Responses\EndMeetingResponse;
35
use BigBlueButton\Responses\GetDefaultConfigXMLResponse;
36
use BigBlueButton\Responses\GetMeetingInfoResponse;
37
use BigBlueButton\Responses\GetMeetingsResponse;
38
use BigBlueButton\Responses\GetRecordingsResponse;
39
use BigBlueButton\Responses\IsMeetingRunningResponse;
40
use BigBlueButton\Responses\JoinMeetingResponse;
41
use BigBlueButton\Responses\PublishRecordingsResponse;
42
use BigBlueButton\Responses\SetConfigXMLResponse;
43
use BigBlueButton\Responses\UpdateRecordingsResponse;
44
use BigBlueButton\Util\UrlBuilder;
45
use SimpleXMLElement;
46
47
/**
48
 * Class BigBlueButton
49
 * @package BigBlueButton
50
 */
51
class BigBlueButton
52
{
53
    protected $securitySecret;
54
    protected $bbbServerBaseUrl;
55
    protected $urlBuilder;
56
    protected $jSessionId;
57
58
    public function __construct()
59
    {
60
        // Keeping backward compatibility with older deployed versions
61
        $this->securitySecret   = (getenv('BBB_SECURITY_SALT') === false) ? getenv('BBB_SECRET') : $this->securitySecret = getenv('BBB_SECURITY_SALT');
62
        $this->bbbServerBaseUrl = getenv('BBB_SERVER_BASE_URL');
63
        $this->urlBuilder       = new UrlBuilder($this->securitySecret, $this->bbbServerBaseUrl);
64
    }
65
66
    /**
67
     * @return ApiVersionResponse
68
     *
69
     * @throws \RuntimeException
70
     */
71
    public function getApiVersion()
72
    {
73
        $xml = $this->processXmlResponse($this->urlBuilder->buildUrl());
74
75
        return new ApiVersionResponse($xml);
76
    }
77
78
    /* __________________ BBB ADMINISTRATION METHODS _________________ */
79
    /* The methods in the following section support the following categories of the BBB API:
80
    -- create
81
    -- getDefaultConfigXML
82
    -- setConfigXML
83
    -- join
84
    -- end
85
    */
86
87
    /**
88
     * @param  CreateMeetingParameters $createMeetingParams
89
     * @return string
90
     */
91
    public function getCreateMeetingUrl($createMeetingParams)
92
    {
93
        return $this->urlBuilder->buildUrl(ApiMethod::CREATE, $createMeetingParams->getHTTPQuery());
94
    }
95
96
    /**
97
     * @param  CreateMeetingParameters $createMeetingParams
98
     * @return CreateMeetingResponse
99
     * @throws \RuntimeException
100
     */
101
    public function createMeeting($createMeetingParams)
102
    {
103
        $xml = $this->processXmlResponse($this->getCreateMeetingUrl($createMeetingParams), $createMeetingParams->getPresentationsAsXML());
0 ignored issues
show
Security Bug introduced by
It seems like $createMeetingParams->getPresentationsAsXML() targeting BigBlueButton\Parameters...getPresentationsAsXML() can also be of type false; however, BigBlueButton\BigBlueButton::processXmlResponse() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
104
105
        return new CreateMeetingResponse($xml);
106
    }
107
108
    /**
109
     * @return string
110
     */
111
    public function getDefaultConfigXMLUrl()
112
    {
113
        return $this->urlBuilder->buildUrl(ApiMethod::GET_DEFAULT_CONFIG_XML);
114
    }
115
116
    /**
117
     * @return GetDefaultConfigXMLResponse
118
     * @throws \RuntimeException
119
     */
120
    public function getDefaultConfigXML()
121
    {
122
        $xml = $this->processXmlResponse($this->getDefaultConfigXMLUrl());
123
124
        return new GetDefaultConfigXMLResponse($xml);
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function setConfigXMLUrl()
131
    {
132
        return $this->urlBuilder->buildUrl(ApiMethod::SET_CONFIG_XML, '', false);
133
    }
134
135
    /**
136
     * @param  $setConfigXMLParams
137
     * @return SetConfigXMLResponse
138
     * @throws \RuntimeException
139
     */
140
    public function setConfigXML($setConfigXMLParams)
141
    {
142
        $setConfigXMLPayload = $this->urlBuilder->buildQs(ApiMethod::SET_CONFIG_XML, $setConfigXMLParams->getHTTPQuery());
143
144
        $xml = $this->processXmlResponse($this->setConfigXMLUrl(), $setConfigXMLPayload, 'application/x-www-form-urlencoded');
145
146
        return new SetConfigXMLResponse($xml);
147
    }
148
149
    /**
150
     * @param $joinMeetingParams JoinMeetingParameters
151
     *
152
     * @return string
153
     */
154
    public function getJoinMeetingURL($joinMeetingParams)
155
    {
156
        return $this->urlBuilder->buildUrl(ApiMethod::JOIN, $joinMeetingParams->getHTTPQuery());
157
    }
158
159
    /**
160
     * @param $joinMeetingParams JoinMeetingParameters
161
     *
162
     * @return JoinMeetingResponse
163
     * @throws \RuntimeException
164
     */
165
    public function joinMeeting($joinMeetingParams)
166
    {
167
        $xml = $this->processXmlResponse($this->getJoinMeetingURL($joinMeetingParams));
168
169
        return new JoinMeetingResponse($xml);
170
    }
171
172
    /**
173
     * @param $endParams EndMeetingParameters
174
     *
175
     * @return string
176
     */
177
    public function getEndMeetingURL($endParams)
178
    {
179
        return $this->urlBuilder->buildUrl(ApiMethod::END, $endParams->getHTTPQuery());
180
    }
181
182
    /**
183
     * @param $endParams EndMeetingParameters
184
     *
185
     * @return EndMeetingResponse
186
     * @throws \RuntimeException
187
     * */
188
    public function endMeeting($endParams)
189
    {
190
        $xml = $this->processXmlResponse($this->getEndMeetingURL($endParams));
191
192
        return new EndMeetingResponse($xml);
193
    }
194
195
    /* __________________ BBB MONITORING METHODS _________________ */
196
    /* The methods in the following section support the following categories of the BBB API:
197
    -- isMeetingRunning
198
    -- getMeetings
199
    -- getMeetingInfo
200
    */
201
202
    /**
203
     * @param $meetingParams IsMeetingRunningParameters
204
     * @return string
205
     */
206
    public function getIsMeetingRunningUrl($meetingParams)
207
    {
208
        return $this->urlBuilder->buildUrl(ApiMethod::IS_MEETING_RUNNING, $meetingParams->getHTTPQuery());
209
    }
210
211
    /**
212
     * @param $meetingParams
213
     * @return IsMeetingRunningResponse
214
     * @throws \RuntimeException
215
     */
216
    public function isMeetingRunning($meetingParams)
217
    {
218
        $xml = $this->processXmlResponse($this->getIsMeetingRunningUrl($meetingParams));
219
220
        return new IsMeetingRunningResponse($xml);
221
    }
222
223
    /**
224
     * @return string
225
     */
226
    public function getMeetingsUrl()
227
    {
228
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETINGS);
229
    }
230
231
    /**
232
     * @return GetMeetingsResponse
233
     * @throws \RuntimeException
234
     */
235
    public function getMeetings()
236
    {
237
        $xml = $this->processXmlResponse($this->getMeetingsUrl());
238
239
        return new GetMeetingsResponse($xml);
240
    }
241
242
    /**
243
     * @param $meetingParams GetMeetingInfoParameters
244
     * @return string
245
     */
246
    public function getMeetingInfoUrl($meetingParams)
247
    {
248
        return $this->urlBuilder->buildUrl(ApiMethod::GET_MEETING_INFO, $meetingParams->getHTTPQuery());
249
    }
250
251
    /**
252
     * @param $meetingParams GetMeetingInfoParameters
253
     * @return GetMeetingInfoResponse
254
     * @throws \RuntimeException
255
     */
256
    public function getMeetingInfo($meetingParams)
257
    {
258
        $xml = $this->processXmlResponse($this->getMeetingInfoUrl($meetingParams));
259
260
        return new GetMeetingInfoResponse($xml);
261
    }
262
263
    /* __________________ BBB RECORDING METHODS _________________ */
264
    /* The methods in the following section support the following categories of the BBB API:
265
    -- getRecordings
266
    -- publishRecordings
267
    -- deleteRecordings
268
    */
269
270
    /**
271
     * @param $recordingsParams GetRecordingsParameters
272
     * @return string
273
     */
274
    public function getRecordingsUrl($recordingsParams)
275
    {
276
        return $this->urlBuilder->buildUrl(ApiMethod::GET_RECORDINGS, $recordingsParams->getHTTPQuery());
277
    }
278
279
    /**
280
     * @param $recordingParams
281
     * @return GetRecordingsResponse
282
     * @throws \RuntimeException
283
     */
284
    public function getRecordings($recordingParams)
285
    {
286
        $xml = $this->processXmlResponse($this->getRecordingsUrl($recordingParams));
287
288
        return new GetRecordingsResponse($xml);
289
    }
290
291
    /**
292
     * @param $recordingParams PublishRecordingsParameters
293
     * @return string
294
     */
295
    public function getPublishRecordingsUrl($recordingParams)
296
    {
297
        return $this->urlBuilder->buildUrl(ApiMethod::PUBLISH_RECORDINGS, $recordingParams->getHTTPQuery());
298
    }
299
300
    /**
301
     * @param $recordingParams PublishRecordingsParameters
302
     * @return PublishRecordingsResponse
303
     * @throws \RuntimeException
304
     */
305
    public function publishRecordings($recordingParams)
306
    {
307
        $xml = $this->processXmlResponse($this->getPublishRecordingsUrl($recordingParams));
308
309
        return new PublishRecordingsResponse($xml);
310
    }
311
312
    /**
313
     * @param $recordingParams DeleteRecordingsParameters
314
     * @return string
315
     */
316
    public function getDeleteRecordingsUrl($recordingParams)
317
    {
318
        return $this->urlBuilder->buildUrl(ApiMethod::DELETE_RECORDINGS, $recordingParams->getHTTPQuery());
319
    }
320
321
    /**
322
     * @param $recordingParams DeleteRecordingsParameters
323
     * @return DeleteRecordingsResponse
324
     * @throws \RuntimeException
325
     */
326
    public function deleteRecordings($recordingParams)
327
    {
328
        $xml = $this->processXmlResponse($this->getDeleteRecordingsUrl($recordingParams));
329
330
        return new DeleteRecordingsResponse($xml);
331
    }
332
333
    /**
334
     * @param $recordingParams UpdateRecordingsParameters
335
     * @return string
336
     */
337
    public function getUpdateRecordingsUrl($recordingParams)
338
    {
339
        return $this->urlBuilder->buildUrl(ApiMethod::UPDATE_RECORDINGS, $recordingParams->getHTTPQuery());
340
    }
341
342
    /**
343
     * @param $recordingParams UpdateRecordingsParameters
344
     * @return UpdateRecordingsResponse
345
     * @throws \RuntimeException
346
     */
347
    public function updateRecordings($recordingParams)
348
    {
349
        $xml = $this->processXmlResponse($this->getUpdateRecordingsUrl($recordingParams));
350
351
        return new UpdateRecordingsResponse($xml);
352
    }
353
354
    /* ____________________ SPECIAL METHODS ___________________ */
355
    /**
356
     * @return string
357
     */
358
    public function getJSessionId()
359
    {
360
        return $this->jSessionId;
361
    }
362
363
    /**
364
     * @param string $jSessionId
365
     */
366
    public function setJSessionId($jSessionId)
367
    {
368
        $this->jSessionId = $jSessionId;
369
    }
370
371
    /* ____________________ INTERNAL CLASS METHODS ___________________ */
372
373
    /**
374
     * A private utility method used by other public methods to process XML responses.
375
     *
376
     * @param  string            $url
377
     * @param  string            $payload
378
     * @param  string            $contentType
379
     * @return SimpleXMLElement
380
     * @throws \RuntimeException
381
     */
382
    private function processXmlResponse($url, $payload = '', $contentType = 'application/xml')
383
    {
384
        if (extension_loaded('curl')) {
385
            $ch = curl_init();
386
            if (!$ch) {
387
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
388
            }
389
            $timeout = 10;
390
391
            // Needed to store the JSESSIONID
392
            $cookiefile     = tmpfile();
393
            $cookiefilepath = stream_get_meta_data($cookiefile)['uri'];
394
395
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
396
            curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
397
            curl_setopt($ch, CURLOPT_URL, $url);
398
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
399
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
400
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefilepath);
401
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefilepath);
402
            if (!empty($payload)) {
403
                curl_setopt($ch, CURLOPT_HEADER, 0);
404
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
405
                curl_setopt($ch, CURLOPT_POST, 1);
406
                curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
407
                curl_setopt($ch, CURLOPT_HTTPHEADER, [
408
                    'Content-type: ' . $contentType,
409
                    'Content-length: ' . mb_strlen($payload),
410
                ]);
411
            }
412
            $data = curl_exec($ch);
413
            if ($data === false) {
414
                throw new \RuntimeException('Unhandled curl error: ' . curl_error($ch));
415
            }
416
            curl_close($ch);
417
418
            $cookies = file_get_contents($cookiefilepath);
419
            if (strpos($cookies, 'JSESSIONID') !== false) {
420
                preg_match('/(?:JSESSIONID\s*)(?<JSESSIONID>.*)/', $cookies, $output_array);
421
                $this->setJSessionId($output_array['JSESSIONID']);
422
            }
423
424
            return new SimpleXMLElement($data);
425
        } else {
426
            throw new \RuntimeException('Post XML data set but curl PHP module is not installed or not enabled.');
427
        }
428
    }
429
}
430