Date: Fri, 29 Mar 2024 05:56:57 +0100 (CET) Message-ID: <2082307900.47343.1711688217641@docs.flashphoner.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_47342_657447706.1711688217641" ------=_Part_47342_657447706.1711688217641 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Let's suppose that there is task to limit user access to server content = on domain basis, e.g. allow users to watch a video from specified domain on= ly. This task can be resolved with REST hooks.
In REST query of type 1 "connect" to the backend server, WCS sends the "origi= n" field that contains WCS server domain name by which user accessed to it,= for example
{ "nodeId" : "5tWOFn5ZoMQs22KrEls2Ulhee57hQO9D", "appKey" : "defaultApp", "sessionId" : "/5.44.168.45:53438/abcdef0123456789", "useWsTunnel" : false, "useWsTunnelPacketization2" : false, "useBase64BinaryEncoding" : false, "mediaProviders" : [ "WebRTC", "MSE", "WSPlayer" ], "clientVersion" : "0.5.28", "clientOSVersion" : "5.0 (Windows)", "clientBrowserVersion" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60= .0) Gecko/20100101 Firefox/60.0", "keepAlive" : false, "origin" : "https://test2.flashphoner.com:8888" }=20
So, REST hook of type 1 "connect" should be implemented to authorize use= r by domain.
1. REST hook of type 1 s= hould be availabale on your web host as
http://yourhost/r= est-hooks/connect=20
2. REST hook should allow POST application/json HTTP requests.=
span>
3. REST hook should return exactly the same body as received (mir=
roring), except restClientConfig configuration.
4. WCS server should be set up to work with =
REST hook as:
ssh -p 2001 admin= @localhost >update app -l http://yourhost/rest-hooks defaultApp=20
REST hook using can be traced in WCS server logs
tail -f /usr/loca= l/FlashphonerWebCallServer/logs/server_logs/flashphoner.log=20
The first lines of the script define the method and decode the request b= ody.. Here the domain for authorization is set:
<?php $api_method =3D array_pop(explode("/", $_SERVER['REQUEST_URI'])); $incoming_data =3D json_decode(file_get_contents('php://input'), true); $domain =3D "yourdomain.com";=20
"connect" method handling begins. Here "origin" field value is defined a= nd "re= stClientConfig" field for answer is filled:
switch($api_method= ) { case"connect":=09 =09 =09$origin =3D $incoming_data['origin'];=09 =09 =09//logs =09error_log("sessionId: " . $incoming_data['sessionId']); =09error_log("origin: " . $origin);=09 =09 =09 =09$rest_client_config =3D json_decode(file_get_contents('rest_client_confi= g.json'), true);=09 =09$incoming_data['restClientConfig'] =3D $rest_client_config;=20
Domain checking. If domain is not found, the ubnormalResponse() function= is called to form negative response 403:
=09$found =3D strp= os($origin, $domain); =09if ($found !=3D=3D false){ =09 error_log("User authorized by domain " . $domain); =09}else{ =09 error_log("User not authorized by domain: " . $domain . " Connection= failed with 403 status."); =09 ubnormalResponse(403); =09} =09break; }=20
Successful response is returned
header('Content-Ty= pe: application/json'); echo json_encode($incoming_data);=20
ubnormalResponse() function completes the script:
function ubnormalR= esponse($code) { if ($code =3D=3D 403) { =09header('HTTP/1.1 403 Forbidden', true, $code); } else { =09header(':', true, $code); } die(); } ?>=20
&l= t;?php $api_method =3D array_pop(explode("/", $_SERVER['REQUEST_URI'])); $incoming_data =3D json_decode(file_get_contents('php://input'), true); $domain =3D "yourdomain.com"; switch($api_method) { case"connect":=09 =09 =09$origin =3D $incoming_data['origin'];=09 =09 =09//logs =09error_log("sessionId: " . $incoming_data['sessionId']); =09error_log("origin: " . $origin);=09 =09 =09 =09$rest_client_config =3D json_decode(file_get_contents('rest_client_confi= g.json'), true);=09 =09$incoming_data['restClientConfig'] =3D $rest_client_config; =09$found =3D strpos($origin, $domain); =09if ($found !=3D=3D false){ =09 error_log("User authorized by domain " . $domain); =09}else{ =09 error_log("User not authorized by domain: " . $domain . " Connection= failed with 403 status."); =09 ubnormalResponse(403); =09} =09break; } header('Content-Type: application/json'); echo json_encode($incoming_data); function ubnormalResponse($code) { if ($code =3D=3D 403) { =09header('HTTP/1.1 403 Forbidden', true, $code); } else { =09header(':', true, $code); } die(); } ?>=20
{ "ConnectionStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "RegistrationStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "sendXcapRequest" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "XcapStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "sendDtmf" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "call" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "OnCallEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "answer" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "hangup" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "hold" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "unhold" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "transfer" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "OnTransferEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "FAIL", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "TransferStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "CallStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "sendMessage" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "FAIL", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "OnMessageEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "MessageStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "publishStream" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "unPublishStream" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "playStream" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "stopStream" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "StreamStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "subscribe" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "SubscriptionStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "OnDataEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "DataStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "submitBugReport" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "BugReportStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "pushLogs" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "RecordingStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "ErrorStatusEvent" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" }, "disconnect" : { "clientExclude" : "", "restExclude" : "", "restOnError" : "LOG", "restPolicy" : "NOTIFY", "restOverwrite" : "" } }=20