ILIAS  trunk Revision v11.0_alpha-1744-gb0451eebef4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
XapiProxy\XapiProxyRequest Class Reference
+ Collaboration diagram for XapiProxy\XapiProxyRequest:

Public Member Functions

 __construct (XapiProxy $xapiproxy)
 
 handle ()
 

Private Member Functions

 msg (string $msg)
 
 handleStatementsRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleGetStatementsRequest (\Psr\Http\Message\RequestInterface $request)
 
 handlePostPutStatementsRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleActivitiesRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleActivitiesProfileRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleActivitiesStateRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleAgentsRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleAgentsProfileRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleAboutRequest (\Psr\Http\Message\RequestInterface $request)
 
 handleProxy (\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)
 
 createProxyRequest (\Psr\Http\Message\RequestInterface $request, \GuzzleHttp\Psr7\Uri $uri, string $auth, string $body)
 

Private Attributes

Container $dic
 
XapiProxy $xapiproxy
 
XapiProxyResponse $xapiProxyResponse
 
string $cmdPart2plus = ""
 
bool $checkGetStatements = true
 

Detailed Description

Definition at line 30 of file XapiProxyRequest.php.

Constructor & Destructor Documentation

◆ __construct()

XapiProxy\XapiProxyRequest::__construct ( XapiProxy  $xapiproxy)

Definition at line 41 of file XapiProxyRequest.php.

References $GLOBALS, and XapiProxy\$xapiproxy.

42  {
43  $this->dic = $GLOBALS['DIC'];
44  $this->xapiproxy = $xapiproxy;
45  $this->cmdPart2plus = "";
46  }
$GLOBALS["DIC"]
Definition: wac.php:53

Member Function Documentation

◆ createProxyRequest()

XapiProxy\XapiProxyRequest::createProxyRequest ( \Psr\Http\Message\RequestInterface  $request,
\GuzzleHttp\Psr7\Uri  $uri,
string  $auth,
string  $body 
)
private

Definition at line 338 of file XapiProxyRequest.php.

References XapiProxy\$req.

338  : \GuzzleHttp\Psr7\Request
339  {
340  $headers = array(
341  'Cache-Control' => 'no-cache, no-store, must-revalidate',
342  'Authorization' => $auth
343  );
344 
345  if ($request->hasHeader('X-Experience-API-Version')) {
346  $headers['X-Experience-API-Version'] = $request->getHeader('X-Experience-API-Version');
347  }
348 
349  if ($request->hasHeader('Referrer')) {
350  $headers['Referrer'] = $request->getHeader('Referrer');
351  }
352 
353  if ($request->hasHeader('Content-Type')) {
354  $headers['Content-Type'] = $request->getHeader('Content-Type');
355  }
356 
357  if ($request->hasHeader('Origin')) {
358  $headers['Origin'] = $request->getHeader('Origin');
359  }
360 
361  if ($request->hasHeader('Content-Length')) {
362  $contentLength = $request->getHeader('Content-Length');
363  if (is_array($contentLength) && $contentLength[0] === '') {
364  $contentLength = array(0);
365  } elseif ($contentLength === '') {
366  $contentLength = array(0);
367  }
368  $headers['Content-Length'] = $contentLength;
369  }
370 
371  if ($request->hasHeader('Connection')) {
372  $headers['Connection'] = $request->getHeader('Connection');
373  }
374 
375  //$this->xapiproxy->log()->debug($this->msg($body));
376 
377  $req = new Request(strtoupper($request->getMethod()), $uri, $headers, $body);
378 
379  return $req;
380  }
catch(\Exception $e) $req
Definition: xapiproxy.php:91

◆ handle()

XapiProxy\XapiProxyRequest::handle ( )

Definition at line 48 of file XapiProxyRequest.php.

48  : void
49  {
50  $this->xapiProxyResponse = $this->xapiproxy->getXapiProxyResponse();
51  $request = $this->dic->http()->request();
52  $cmdParts = $this->xapiproxy->cmdParts();
53  $this->xapiproxy->log()->debug($this->msg(var_export($cmdParts, true)));
54  if (count($cmdParts) === 5) {
55  $cmd = $cmdParts[3];
56  if ($cmd === "statements") {
57  $this->handleStatementsRequest($request);
58  } elseif ($cmd === "activities") {
59  $this->handleActivitiesRequest($request);
60  } elseif ($cmd === "activities/profile") {
61  $this->handleActivitiesProfileRequest($request);
62  } elseif ($cmd === "activities/state") {
63  $this->handleActivitiesStateRequest($request);
64  } elseif ($cmd === "agents") {
65  $this->handleAgentsRequest($request);
66  } elseif ($cmd === "agents/profile") {
67  $this->handleAgentsProfileRequest($request);
68  } elseif ($cmd === "about") {
69  $this->handleAboutRequest($request);
70  } else {
71  $this->xapiproxy->log()->debug($this->msg("Wrong xApi Query: " . $request->getUri()));
72  $this->xapiProxyResponse->exitBadRequest();
73  }
74  } else {
75  $this->xapiproxy->log()->error($this->msg("Wrong xApi Query: " . $request->getUri()));
76  $this->xapiProxyResponse->exitBadRequest();
77  }
78  }
handleStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handleAboutRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesProfileRequest(\Psr\Http\Message\RequestInterface $request)
handleAgentsRequest(\Psr\Http\Message\RequestInterface $request)
handleAgentsProfileRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesStateRequest(\Psr\Http\Message\RequestInterface $request)

◆ handleAboutRequest()

XapiProxy\XapiProxyRequest::handleAboutRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 224 of file XapiProxyRequest.php.

224  : void
225  {
226  $this->xapiproxy->log()->debug($this->msg("handleAboutRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
227  $this->handleProxy($request);
228  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)

◆ handleActivitiesProfileRequest()

XapiProxy\XapiProxyRequest::handleActivitiesProfileRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 200 of file XapiProxyRequest.php.

200  : void
201  {
202  $this->xapiproxy->log()->debug($this->msg("handleActivitiesProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
203  $this->handleProxy($request);
204  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)

◆ handleActivitiesRequest()

XapiProxy\XapiProxyRequest::handleActivitiesRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 192 of file XapiProxyRequest.php.

192  : void
193  {
194  // $this->xapiproxy->log()->debug($this->msg("blocked handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
195  // $this->xapiProxyResponse->exitBadRequest();
196  $this->xapiproxy->log()->debug($this->msg("handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
197  $this->handleProxy($request);
198  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)

◆ handleActivitiesStateRequest()

XapiProxy\XapiProxyRequest::handleActivitiesStateRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 206 of file XapiProxyRequest.php.

206  : void
207  {
208  $this->xapiproxy->log()->debug($this->msg("handleActivitiesStateRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
209  $this->handleProxy($request);
210  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)

◆ handleAgentsProfileRequest()

XapiProxy\XapiProxyRequest::handleAgentsProfileRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 218 of file XapiProxyRequest.php.

218  : void
219  {
220  $this->xapiproxy->log()->debug($this->msg("handleAgentsProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
221  $this->handleProxy($request);
222  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)

◆ handleAgentsRequest()

XapiProxy\XapiProxyRequest::handleAgentsRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 212 of file XapiProxyRequest.php.

212  : void
213  {
214  $this->xapiproxy->log()->debug($this->msg("blocked handleAgentsRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
215  $this->xapiProxyResponse->exitBadRequest();
216  }

◆ handleGetStatementsRequest()

XapiProxy\XapiProxyRequest::handleGetStatementsRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 98 of file XapiProxyRequest.php.

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

98  : void
99  {
100  if ($this->xapiproxy->cmdParts()[4] == "") {
101  $this->xapiproxy->log()->warning($this->msg("unfiltered get statements requests are not allowed for security reasons"));
102  $this->xapiProxyResponse->exitBadRequest();
103  }
104  $this->xapiproxy->log()->debug($this->msg("handleGetStatementsRequest: " . $request->getUri()));
105 
106  try {
107  $badRequest = false;
108  if ($this->checkGetStatements) {
109  $authToken = \ilCmiXapiAuthToken::getInstanceByToken($this->xapiproxy->token());
110  $obj = \ilObjCmiXapi::getInstance($authToken->getRefId(), true);
111  $access = \ilCmiXapiAccess::getInstance($obj);
112  $params = $this->dic->http()->wrapper()->query();
113  if ($params->has('statementId')) {
114  $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)"));
115  // single statementId can not be handled. it is not allowed to append a registration on single statement requests (tested in LL7)
116  $this->handleProxy($request);
117  } else {
118  if ($params->has('activity')) {
119  // ToDo: how this can be verified? the object only knows the top activityId
120  $this->handleProxy($request);
121  } else {
122  $this->xapiproxy->log()->debug($this->msg("add activity: " . $obj->getActivityId()));
123  $this->cmdPart2plus .= "&activity=" . $obj->getActivityId() . "&related_activities=true";
124  }
125  if (!$access->hasOutcomesAccess($authToken->getUsrId())) {
126  // ToCheck
127  /*
128  if (!$access->hasStatementsAccess()) {
129  $this->xapiproxy->log()->warning($this->msg("statements access is not enabled"));
130  $this->xapiProxyResponse->exitBadRequest();
131  }
132  */
133  if ($obj->getContentType() == \ilObjCmiXapi::CONT_TYPE_CMI5) {
134  $regUserObject = \ilCmiXapiUser::getCMI5RegistrationFromAuthToken($authToken);
135  } else {
136  $regUserObject = \ilCmiXapiUser::getRegistrationFromAuthToken($authToken);
137  }
138  if ($params->has('registration')) {
139  $regParam = $params->retrieve('registration', $this->dic->refinery()->kindlyTo()->string());
140  if ($regParam != $regUserObject) {
141  $this->xapiproxy->log()->debug($this->msg("wrong registration: " . $regParam . " != " . $regUserObject));
142  $badRequest = true;
143  }
144  } else { // add registration
145  $this->xapiproxy->log()->debug($this->msg("add registration: " . $regUserObject));
146  $this->cmdPart2plus .= "&registration=" . $regUserObject;
147  }
148  }
149  }
150  }
151  if ($badRequest) {
152  $this->xapiProxyResponse->exitBadRequest();
153  } else {
154  $this->handleProxy($request);
155  }
156  } catch (\Exception $e) {
157  $this->xapiproxy->log()->error($this->msg($e->getMessage()));
158  }
159  }
static getInstance(ilObjCmiXapi $object)
static getInstanceByToken(string $token)
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:31
static getInstance(int $a_id=0, bool $a_reference=true)
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)
static getCMI5RegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getRegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
+ Here is the call graph for this function:

◆ handlePostPutStatementsRequest()

XapiProxy\XapiProxyRequest::handlePostPutStatementsRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 161 of file XapiProxyRequest.php.

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

161  : void
162  {
163  $this->xapiproxy->log()->debug($this->msg("handlePostPutStatementsRequest: " . $request->getUri()));
164  $body = $request->getBody()->getContents();
165  $fakePostBody = null;
166  if (empty($body)) {
167  $this->xapiproxy->log()->warning($this->msg("empty body in handlePostPutRequest"));
168  $this->handleProxy($request);
169  } else {
170  try {
171  $this->xapiproxy->log()->debug($this->msg("process statements"));
172  $retArr = $this->xapiproxy->processStatements($request, $body);
173  if (is_array($retArr)) {
174  $body = json_encode($retArr[0]); // new body with allowed statements
175  $fakePostBody = $retArr[1]; // fake post php array of ALL statments as if all statements were processed
176  }
177  } catch (\Exception $e) {
178  $this->xapiproxy->log()->error($this->msg($e->getMessage()));
179  $this->xapiProxyResponse->exitProxyError();
180  }
181  try {
182  $body = $this->xapiproxy->modifyBody($body);
183  $req = new Request($request->getMethod(), $request->getUri(), $request->getHeaders(), $body);
184  $this->handleProxy($req, $fakePostBody);
185  } catch (\Exception $e) {
186  $this->xapiproxy->log()->error($this->msg($e->getMessage()));
187  $this->handleProxy($request, $fakePostBody);
188  }
189  }
190  }
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)
catch(\Exception $e) $req
Definition: xapiproxy.php:91
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null

◆ handleProxy()

XapiProxy\XapiProxyRequest::handleProxy ( \Psr\Http\Message\RequestInterface  $request,
  $fakePostBody = null 
)
private

Definition at line 230 of file XapiProxyRequest.php.

References Vendor\Package\$e.

230  : void
231  {
232  $endpointDefault = $this->xapiproxy->getDefaultLrsEndpoint();
233  $endpointFallback = $this->xapiproxy->getFallbackLrsEndpoint();
234 
235  $this->xapiproxy->log()->debug($this->msg("endpointDefault: " . $endpointDefault));
236  $this->xapiproxy->log()->debug($this->msg("endpointFallback: " . $endpointFallback));
237 
238  $keyDefault = $this->xapiproxy->getDefaultLrsKey();
239  $secretDefault = $this->xapiproxy->getDefaultLrsSecret();
240  $authDefault = 'Basic ' . base64_encode($keyDefault . ':' . $secretDefault);
241 
242  $hasFallback = ($endpointFallback === "") ? false : true;
243 
244  if ($hasFallback) {
245  $keyFallback = $this->xapiproxy->getFallbackLrsKey();
246  $secretFallback = $this->xapiproxy->getFallbackLrsSecret();
247  $authFallback = 'Basic ' . base64_encode($keyFallback . ':' . $secretFallback);
248  }
249 
250  $req_opts = array(
251  RequestOptions::VERIFY => true,
252  RequestOptions::CONNECT_TIMEOUT => 10,
253  RequestOptions::HTTP_ERRORS => false
254  );
255  $cmd = $this->xapiproxy->cmdParts()[2] . $this->cmdPart2plus;
256  $upstreamDefault = $endpointDefault . $cmd;
257  $uriDefault = new Uri($upstreamDefault);
258  $body = $request->getBody()->getContents();
259  $reqDefault = $this->createProxyRequest($request, $uriDefault, $authDefault, $body);
260 
261  if ($hasFallback) {
262  $upstreamFallback = $endpointFallback . $cmd;
263  $uriFallback = new Uri($upstreamFallback);
264  $reqFallback = $this->createProxyRequest($request, $uriFallback, $authFallback, $body);
265  }
266 
267  $httpclient = new Client();
268  if ($hasFallback) {
269  $promises = [
270  'default' => $httpclient->sendAsync($reqDefault, $req_opts),
271  'fallback' => $httpclient->sendAsync($reqFallback, $req_opts)
272  ];
273 
274  // this would throw first ConnectionException
275  // $responses = Promise\unwrap($promises);
276  try {
277  $responses = Promise\Utils::settle($promises)->wait();
278  } catch (\Exception $e) {
279  $this->xapiproxy->log()->error($this->msg($e->getMessage()));
280  }
281 
282  $defaultOk = $this->xapiProxyResponse->checkResponse($responses['default'], $endpointDefault);
283  $fallbackOk = $this->xapiProxyResponse->checkResponse($responses['fallback'], $endpointFallback);
284 
285  if ($defaultOk) {
286  try {
287  $this->xapiProxyResponse->handleResponse(
288  $reqDefault,
289  $responses['default']['value'],
290  $fakePostBody
291  );
292  } catch (\Exception $e) {
293  // $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
294  $this->xapiProxyResponse->exitProxyError();
295  }
296  } elseif ($fallbackOk) {
297  try {
298  $this->xapiProxyResponse->handleResponse(
299  $reqFallback,
300  $responses['fallback']['value'],
301  $fakePostBody
302  );
303  } catch (\Exception $e) {
304  // $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
305  $this->xapiProxyResponse->exitProxyError();
306  }
307  } else {
308  $this->xapiProxyResponse->exitResponseError();
309  }
310  } else {
311  $promises = [
312  'default' => $httpclient->sendAsync($reqDefault, $req_opts)
313  ];
314  // this would throw first ConnectionException
315  // $responses = Promise\unwrap($promises);
316  try {
317  $responses = Promise\Utils::settle($promises)->wait();
318  } catch (\Exception $e) {
319  $this->xapiproxy->log()->error($this->msg($e->getMessage()));
320  }
321  if ($this->xapiProxyResponse->checkResponse($responses['default'], $endpointDefault)) {
322  try {
323  $this->xapiProxyResponse->handleResponse(
324  $reqDefault,
325  $responses['default']['value'],
326  $fakePostBody
327  );
328  } catch (\Exception $e) {
329  // $this->xapiproxy->error($this->msg("XAPI exception from Default LRS: " . $endpointDefault . " (sent HTTP 500 to client): " . $e->getMessage()));
330  $this->xapiProxyResponse->exitProxyError();
331  }
332  } else {
333  $this->xapiProxyResponse->exitResponseError();
334  }
335  }
336  }
createProxyRequest(\Psr\Http\Message\RequestInterface $request, \GuzzleHttp\Psr7\Uri $uri, string $auth, string $body)

◆ handleStatementsRequest()

XapiProxy\XapiProxyRequest::handleStatementsRequest ( \Psr\Http\Message\RequestInterface  $request)
private

Definition at line 85 of file XapiProxyRequest.php.

85  : void
86  {
87  $this->xapiproxy->log()->debug($this->msg("handleStatementsRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
88  $method = $this->xapiproxy->method();
89  if ($method === "post" || $method === "put") {
90  $this->handlePostPutStatementsRequest($request);
91  } elseif ($method === "get") {
92  $this->handleGetStatementsRequest($request);
93  } else {
94  $this->xapiProxyResponse->exitBadRequest();
95  }
96  }
handleGetStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handlePostPutStatementsRequest(\Psr\Http\Message\RequestInterface $request)

◆ msg()

XapiProxy\XapiProxyRequest::msg ( string  $msg)
private

Definition at line 80 of file XapiProxyRequest.php.

80  : string
81  {
82  return $this->xapiproxy->msg($msg);
83  }

Field Documentation

◆ $checkGetStatements

bool XapiProxy\XapiProxyRequest::$checkGetStatements = true
private

Definition at line 39 of file XapiProxyRequest.php.

◆ $cmdPart2plus

string XapiProxy\XapiProxyRequest::$cmdPart2plus = ""
private

Definition at line 38 of file XapiProxyRequest.php.

◆ $dic

Container XapiProxy\XapiProxyRequest::$dic
private

Definition at line 32 of file XapiProxyRequest.php.

◆ $xapiproxy

XapiProxy XapiProxy\XapiProxyRequest::$xapiproxy
private

Definition at line 34 of file XapiProxyRequest.php.

◆ $xapiProxyResponse

XapiProxyResponse XapiProxy\XapiProxyRequest::$xapiProxyResponse
private

Definition at line 36 of file XapiProxyRequest.php.


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