ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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.

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

References $GLOBALS, and XapiProxy\$xapiproxy.

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.

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

References XapiProxy\$req.

◆ 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 }
handleActivitiesStateRequest(\Psr\Http\Message\RequestInterface $request)
handleAboutRequest(\Psr\Http\Message\RequestInterface $request)
handleStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesProfileRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesRequest(\Psr\Http\Message\RequestInterface $request)
handleAgentsRequest(\Psr\Http\Message\RequestInterface $request)
handleAgentsProfileRequest(\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 }

◆ 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 }

◆ 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 }

◆ 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 }

◆ 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.

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)
static getCMI5RegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getRegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getInstance(int $a_id=0, bool $a_reference=true)
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:31

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

+ 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.

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 }

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

◆ handleProxy()

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

Definition at line 230 of file XapiProxyRequest.php.

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)

References Vendor\Package\$e.

◆ 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 }
handlePostPutStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handleGetStatementsRequest(\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: