ILIAS  release_7 Revision v7.30-3-g800a261c036
XapiProxy\XapiProxyRequest Class Reference
+ Collaboration diagram for XapiProxy\XapiProxyRequest:

Public Member Functions

 __construct ()
 
 handle ()
 

Private Member Functions

 handleStatementsRequest ($request)
 
 handleGetStatementsRequest ($request)
 
 handlePostPutStatementsRequest ($request)
 
 handleActivitiesRequest ($request)
 
 handleActivitiesProfileRequest ($request)
 
 handleActivitiesStateRequest ($request)
 
 handleAgentsRequest ($request)
 
 handleAgentsProfileRequest ($request)
 
 handleAboutRequest ($request)
 
 handleProxy ($request, $fakePostBody=null)
 
 createProxyRequest ($request, $uri, $auth, $body)
 
 msg ($msg)
 

Private Attributes

 $dic
 
 $xapiproxy
 
 $request
 
 $xapiProxyResponse
 
 $cmdPart2plus = ""
 
 $checkGetStatements = true
 

Detailed Description

Definition at line 10 of file XapiProxyRequest.php.

Constructor & Destructor Documentation

◆ __construct()

XapiProxy\XapiProxyRequest::__construct ( )

Definition at line 19 of file XapiProxyRequest.php.

20 {
21 $this->dic = $GLOBALS['DIC'];
22 $this->xapiproxy = $this->dic['xapiproxy'];
23 $this->request = $this->dic->http()->request();
24 }
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64

References $GLOBALS.

Member Function Documentation

◆ createProxyRequest()

XapiProxy\XapiProxyRequest::createProxyRequest (   $request,
  $uri,
  $auth,
  $body 
)
private

Definition at line 296 of file XapiProxyRequest.php.

297 {
298 $headers = array(
299 'Cache-Control' => 'no-cache, no-store, must-revalidate',
300 'Authorization' => $auth
301 );
302
303 if ($request->hasHeader('X-Experience-API-Version')) {
304 $headers['X-Experience-API-Version'] = $request->getHeader('X-Experience-API-Version');
305 }
306
307 if ($request->hasHeader('Referrer')) {
308 $headers['Referrer'] = $request->getHeader('Referrer');
309 }
310
311 if ($request->hasHeader('Content-Type')) {
312 $headers['Content-Type'] = $request->getHeader('Content-Type');
313 }
314
315 if ($request->hasHeader('Origin')) {
316 $headers['Origin'] = $request->getHeader('Origin');
317 }
318
319 if ($request->hasHeader('Content-Length')) {
320 $contentLength = $request->getHeader('Content-Length');
321 if (is_array($contentLength) && $contentLength[0] === '') {
322 $contentLength = array(0);
323 } elseif ($contentLength === '') {
324 $contentLength = array(0);
325 }
326 $headers['Content-Length'] = $contentLength;
327 }
328
329 if ($request->hasHeader('Connection')) {
330 $headers['Connection'] = $request->getHeader('Connection');
331 }
332
333 //$this->xapiproxy->log()->debug($this->msg($body));
334
335 $req = new Request(strtoupper($request->getMethod()), $uri, $headers, $body);
336
337 return $req;
338 }
$auth
Definition: metadata.php:59

References $auth, and XapiProxy\$req.

◆ handle()

XapiProxy\XapiProxyRequest::handle ( )

Definition at line 26 of file XapiProxyRequest.php.

27 {
28 $this->xapiProxyResponse = $this->xapiproxy->getXapiProxyResponse();
29 $request = $this->dic->http()->request();
30 $cmdParts = $this->xapiproxy->cmdParts();
31 $this->xapiproxy->log()->debug($this->msg(var_export($cmdParts, true)));
32 if (count($cmdParts) === 5) {
33 $cmd = $cmdParts[3];
34 if ($cmd === "statements") {
36 } elseif ($cmd === "activities") {
38 } elseif ($cmd === "activities/profile") {
40 } elseif ($cmd === "activities/state") {
42 } elseif ($cmd === "agents") {
44 } elseif ($cmd === "agents/profile") {
46 } elseif ($cmd === "about") {
48 } else {
49 $this->xapiproxy->log()->debug($this->msg("Wrong xApi Query: " . $request->getUri()));
50 $this->xapiProxyResponse->exitBadRequest();
51 }
52 } else {
53 $this->xapiproxy->log()->error($this->msg("Wrong xApi Query: " . $request->getUri()));
54 $this->xapiProxyResponse->exitBadRequest();
55 }
56 }

◆ handleAboutRequest()

XapiProxy\XapiProxyRequest::handleAboutRequest (   $request)
private

Definition at line 193 of file XapiProxyRequest.php.

194 {
195 $this->xapiproxy->log()->debug($this->msg("handleAboutRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
196 $this->handleProxy($request);
197 }
handleProxy($request, $fakePostBody=null)

◆ handleActivitiesProfileRequest()

XapiProxy\XapiProxyRequest::handleActivitiesProfileRequest (   $request)
private

Definition at line 169 of file XapiProxyRequest.php.

170 {
171 $this->xapiproxy->log()->debug($this->msg("handleActivitiesProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
172 $this->handleProxy($request);
173 }

◆ handleActivitiesRequest()

XapiProxy\XapiProxyRequest::handleActivitiesRequest (   $request)
private

Definition at line 161 of file XapiProxyRequest.php.

162 {
163// $this->xapiproxy->log()->debug($this->msg("blocked handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
164// $this->xapiProxyResponse->exitBadRequest();
165 $this->xapiproxy->log()->debug($this->msg("handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
166 $this->handleProxy($request);
167 }

◆ handleActivitiesStateRequest()

XapiProxy\XapiProxyRequest::handleActivitiesStateRequest (   $request)
private

Definition at line 175 of file XapiProxyRequest.php.

176 {
177 $this->xapiproxy->log()->debug($this->msg("handleActivitiesStateRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
178 $this->handleProxy($request);
179 }

◆ handleAgentsProfileRequest()

XapiProxy\XapiProxyRequest::handleAgentsProfileRequest (   $request)
private

Definition at line 187 of file XapiProxyRequest.php.

188 {
189 $this->xapiproxy->log()->debug($this->msg("handleAgentsProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
190 $this->handleProxy($request);
191 }

◆ handleAgentsRequest()

XapiProxy\XapiProxyRequest::handleAgentsRequest (   $request)
private

Definition at line 181 of file XapiProxyRequest.php.

182 {
183 $this->xapiproxy->log()->debug($this->msg("blocked handleAgentsRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
184 $this->xapiProxyResponse->exitBadRequest();
185 }

◆ handleGetStatementsRequest()

XapiProxy\XapiProxyRequest::handleGetStatementsRequest (   $request)
private

Definition at line 71 of file XapiProxyRequest.php.

72 {
73 if ($this->xapiproxy->cmdParts()[4] == "") {
74 $this->xapiproxy->log()->warning($this->msg("unfiltered get statements requests are not allowed for security reasons"));
75 $this->xapiProxyResponse->exitBadRequest();
76 }
77 $this->xapiproxy->log()->debug($this->msg("handleGetStatementsRequest: " . $request->getUri()));
78
79 try {
80 $badRequest = false;
81 if ($this->checkGetStatements) {
82 $authToken = \ilCmiXapiAuthToken::getInstanceByToken($this->xapiproxy->token());
83 $obj = \ilObjCmiXapi::getInstance($authToken->getRefId(), true);
84 $access = \ilCmiXapiAccess::getInstance($obj);
85 if (isset($_GET['statementId'])) {
86 $this->xapiproxy->log()->debug($this->msg("single statementId requests can not be secured. It is not allowed to append any additional parameter like registration or activity (tested in LL7)"));
87 // single statementId can not be handled. it is not allowed to append a registration on single statement requests (tested in LL7)
88 } else {
89 if (isset($_GET['activity'])) {
90 // ToDo: how this can be verified? the object only knows the top activityId
91 } else {
92 $this->xapiproxy->log()->debug($this->msg("add activity: " . $obj->getActivityId()));
93 $this->cmdPart2plus .= "&activity=" . $obj->getActivityId() . "&related_activities=true";
94 }
95 if (!$access->hasOutcomesAccess($authToken->getUsrId())) {
96 // ToCheck
97 /*
98 if (!$access->hasStatementsAccess()) {
99 $this->xapiproxy->log()->warning($this->msg("statements access is not enabled"));
100 $this->xapiProxyResponse->exitBadRequest();
101 }
102 */
103 if ($obj->getContentType() == \ilObjCmiXapi::CONT_TYPE_CMI5) {
104 $regUserObject = \ilCmiXapiUser::getCMI5RegistrationFromAuthToken($authToken);
105 } else {
106 $regUserObject = \ilCmiXapiUser::getRegistrationFromAuthToken($authToken);
107 }
108 if (isset($_GET['registration'])) {
109 $regParam = $_GET['registration'];
110 if ($regParam != $regUserObject) {
111 $this->xapiproxy->log()->debug($this->msg("wrong registration: " . $regParam . " != " . $regUserObject));
112 $badRequest = true;
113 }
114 } else { // add registration
115 $this->xapiproxy->log()->debug($this->msg("add registration: " . $regUserObject));
116 $this->cmdPart2plus .= "&registration=" . $regUserObject;
117 }
118 }
119 }
120 }
121 if ($badRequest) {
122 $this->xapiProxyResponse->exitBadRequest();
123 } else {
124 $this->handleProxy($request);
125 }
126 } catch (\Exception $e) {
127 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
128 }
129 }
$_GET["client_id"]
static getInstance(ilObjCmiXapi $object)
static getCMI5RegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getRegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getInstance($a_id=0, $a_reference=true)

References $_GET, Vendor\Package\$e, ilObjCmiXapi\CONT_TYPE_CMI5, ilCmiXapiUser\getCMI5RegistrationFromAuthToken(), ilObjCmiXapi\getInstance(), ilCmiXapiAccess\getInstance(), ilCmiXapiAuthToken\getInstanceByToken(), and ilCmiXapiUser\getRegistrationFromAuthToken().

+ Here is the call graph for this function:

◆ handlePostPutStatementsRequest()

XapiProxy\XapiProxyRequest::handlePostPutStatementsRequest (   $request)
private

Definition at line 131 of file XapiProxyRequest.php.

132 {
133 $this->xapiproxy->log()->debug($this->msg("handlePostPutStatementsRequest: " . $request->getUri()));
134 $body = $request->getBody()->getContents();
135 if (empty($body)) {
136 $this->xapiproxy->log()->warning($this->msg("empty body in handlePostPutRequest"));
137 $this->handleProxy($request);
138 } else {
139 try {
140 $this->xapiproxy->log()->debug($this->msg("process statements"));
141 $retArr = $this->xapiproxy->processStatements($request, $body);
142 if (is_array($retArr)) {
143 $body = json_encode($retArr[0]); // new body with allowed statements
144 $fakePostBody = $retArr[1]; // fake post php array of ALL statments as if all statements were processed
145 }
146 } catch (\Exception $e) {
147 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
148 $this->xapiProxyResponse->exitProxyError();
149 }
150 try {
151 $body = $this->xapiproxy->modifyBody($body);
152 $req = new Request($request->getMethod(), $request->getUri(), $request->getHeaders(), $body);
153 $this->handleProxy($req, $fakePostBody);
154 } catch (\Exception $e) {
155 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
156 $this->handleProxy($request, $fakePostBody);
157 }
158 }
159 }

References Vendor\Package\$e, and XapiProxy\$req.

◆ handleProxy()

XapiProxy\XapiProxyRequest::handleProxy (   $request,
  $fakePostBody = null 
)
private

Definition at line 199 of file XapiProxyRequest.php.

200 {
201 $endpointDefault = $this->xapiproxy->getDefaultLrsEndpoint();
202 $endpointFallback = $this->xapiproxy->getFallbackLrsEndpoint();
203
204 $this->xapiproxy->log()->debug($this->msg("endpointDefault: " . $endpointDefault));
205 $this->xapiproxy->log()->debug($this->msg("endpointFallback: " . $endpointFallback));
206
207 $keyDefault = $this->xapiproxy->getDefaultLrsKey();
208 $secretDefault = $this->xapiproxy->getDefaultLrsSecret();
209 $authDefault = 'Basic ' . base64_encode($keyDefault . ':' . $secretDefault);
210
211 $hasFallback = ($endpointFallback === "") ? false : true;
212
213 if ($hasFallback) {
214 $keyFallback = $this->xapiproxy->getFallbackLrsKey();
215 $secretFallback = $this->xapiproxy->getFallbackLrsSecret();
216 $authFallback = 'Basic ' . base64_encode($keyFallback . ':' . $secretFallback);
217 }
218
219 $req_opts = array(
220 RequestOptions::VERIFY => true,
221 RequestOptions::CONNECT_TIMEOUT => 10,
222 RequestOptions::HTTP_ERRORS => false
223 );
224 $cmd = $this->xapiproxy->cmdParts()[2] . $this->cmdPart2plus;
225 $upstreamDefault = $endpointDefault . $cmd;
226 $uriDefault = new Uri($upstreamDefault);
227 $body = $request->getBody()->getContents();
228 $reqDefault = $this->createProxyRequest($request, $uriDefault, $authDefault, $body);
229
230 if ($hasFallback) {
231 $upstreamFallback = $endpointFallback . $cmd;
232 $uriFallback = new Uri($upstreamFallback);
233 $reqFallback = $this->createProxyRequest($request, $uriFallback, $authFallback, $body);
234 }
235
236 $httpclient = new Client();
237 if ($hasFallback) {
238 $promises = [
239 'default' => $httpclient->sendAsync($reqDefault, $req_opts),
240 'fallback' => $httpclient->sendAsync($reqFallback, $req_opts)
241 ];
242
243 // this would throw first ConnectionException
244 // $responses = Promise\unwrap($promises);
245 try {
246 $responses = Promise\Utils::settle($promises)->wait();
247 } catch (\Exception $e) {
248 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
249 }
250
251 $defaultOk = $this->xapiProxyResponse->checkResponse($responses['default'], $endpointDefault);
252 $fallbackOk = $this->xapiProxyResponse->checkResponse($responses['fallback'], $endpointFallback);
253
254 if ($defaultOk) {
255 try {
256 $this->xapiProxyResponse->handleResponse($reqDefault, $responses['default']['value'], $fakePostBody);
257 } catch (\Exception $e) {
258 $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
259 $this->xapiProxyResponse->exitProxyError();
260 }
261 } elseif ($fallbackOk) {
262 try {
263 $this->xapiProxyResponse->handleResponse($reqFallback, $responses['fallback']['value'], $fakePostBody);
264 } catch (\Exception $e) {
265 $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
266 $this->xapiProxyResponse->exitProxyError();
267 }
268 } else {
269 $this->xapiProxyResponse->exitResponseError();
270 }
271 } else {
272 $promises = [
273 'default' => $httpclient->sendAsync($reqDefault, $req_opts)
274 ];
275 // this would throw first ConnectionException
276 // $responses = Promise\unwrap($promises);
277 try {
278 $responses = Promise\Utils::settle($promises)->wait();
279 } catch (\Exception $e) {
280 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
281 }
282 if ($this->xapiProxyResponse->checkResponse($responses['default'], $endpointDefault)) {
283 try {
284 $this->xapiProxyResponse->handleResponse($reqDefault, $responses['default']['value'], $fakePostBody);
285 } catch (\Exception $e) {
286 $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
287 $this->xapiProxyResponse->exitProxyError();
288 }
289 } else {
290 $this->xapiProxyResponse->exitResponseError();
291 }
292 }
293 }
createProxyRequest($request, $uri, $auth, $body)

References Vendor\Package\$e.

◆ handleStatementsRequest()

XapiProxy\XapiProxyRequest::handleStatementsRequest (   $request)
private

Definition at line 58 of file XapiProxyRequest.php.

59 {
60 $this->xapiproxy->log()->debug($this->msg("handleStatementsRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
61 $method = $this->xapiproxy->method();
62 if ($method === "post" || $method === "put") {
64 } elseif ($method === "get") {
66 } else {
67 $this->xapiProxyResponse->exitBadRequest();
68 }
69 }

◆ msg()

XapiProxy\XapiProxyRequest::msg (   $msg)
private

Definition at line 340 of file XapiProxyRequest.php.

341 {
342 return $this->xapiproxy->msg($msg);
343 }

Field Documentation

◆ $checkGetStatements

XapiProxy\XapiProxyRequest::$checkGetStatements = true
private

Definition at line 17 of file XapiProxyRequest.php.

◆ $cmdPart2plus

XapiProxy\XapiProxyRequest::$cmdPart2plus = ""
private

Definition at line 16 of file XapiProxyRequest.php.

◆ $dic

XapiProxy\XapiProxyRequest::$dic
private

Definition at line 12 of file XapiProxyRequest.php.

◆ $request

XapiProxy\XapiProxyRequest::$request
private

Definition at line 14 of file XapiProxyRequest.php.

◆ $xapiproxy

XapiProxy\XapiProxyRequest::$xapiproxy
private

Definition at line 13 of file XapiProxyRequest.php.

◆ $xapiProxyResponse

XapiProxy\XapiProxyRequest::$xapiProxyResponse
private

Definition at line 15 of file XapiProxyRequest.php.


The documentation for this class was generated from the following file: