ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
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)
 
 sendCurlRequest (string $url, string $authHeader, string $method, string $body='')
 
 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 27 of file XapiProxyRequest.php.

Constructor & Destructor Documentation

◆ __construct()

XapiProxy\XapiProxyRequest::__construct ( XapiProxy  $xapiproxy)

Definition at line 38 of file XapiProxyRequest.php.

39 {
40 $this->dic = $GLOBALS['DIC'];
41 $this->xapiproxy = $xapiproxy;
42 $this->cmdPart2plus = "";
43 }
$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 320 of file XapiProxyRequest.php.

320 : \GuzzleHttp\Psr7\Request
321 {
322 $headers = array(
323 'Cache-Control' => 'no-cache, no-store, must-revalidate',
324 'Authorization' => $auth
325 );
326
327 if ($request->hasHeader('X-Experience-API-Version')) {
328 $headers['X-Experience-API-Version'] = $request->getHeader('X-Experience-API-Version');
329 }
330
331 if ($request->hasHeader('Referrer')) {
332 $headers['Referrer'] = $request->getHeader('Referrer');
333 }
334
335 if ($request->hasHeader('Content-Type')) {
336 $headers['Content-Type'] = $request->getHeader('Content-Type');
337 }
338
339 if ($request->hasHeader('Origin')) {
340 $headers['Origin'] = $request->getHeader('Origin');
341 }
342
343 if ($request->hasHeader('Content-Length')) {
344 $contentLength = $request->getHeader('Content-Length');
345 if (is_array($contentLength) && $contentLength[0] === '') {
346 $contentLength = array(0);
347 } elseif ($contentLength === '') {
348 $contentLength = array(0);
349 }
350 $headers['Content-Length'] = $contentLength;
351 }
352
353 if ($request->hasHeader('Connection')) {
354 $headers['Connection'] = $request->getHeader('Connection');
355 }
356
357 //$this->xapiproxy->log()->debug($this->msg($body));
358
359 $req = new Request(strtoupper($request->getMethod()), $uri, $headers, $body);
360
361 return $req;
362 }
catch(\Exception $e) $req
Definition: xapiproxy.php:78

References XapiProxy\$req.

◆ handle()

XapiProxy\XapiProxyRequest::handle ( )

Definition at line 45 of file XapiProxyRequest.php.

45 : void
46 {
47 $this->xapiProxyResponse = $this->xapiproxy->getXapiProxyResponse();
48 $request = $this->dic->http()->request();
49 $cmdParts = $this->xapiproxy->cmdParts();
50 $this->xapiproxy->log()->debug($this->msg(var_export($cmdParts, true)));
51 if (count($cmdParts) === 5) {
52 $cmd = $cmdParts[3];
53 if ($cmd === "statements") {
54 $this->handleStatementsRequest($request);
55 } elseif ($cmd === "activities") {
56 $this->handleActivitiesRequest($request);
57 } elseif ($cmd === "activities/profile") {
58 $this->handleActivitiesProfileRequest($request);
59 } elseif ($cmd === "activities/state") {
60 $this->handleActivitiesStateRequest($request);
61 } elseif ($cmd === "agents") {
62 $this->handleAgentsRequest($request);
63 } elseif ($cmd === "agents/profile") {
64 $this->handleAgentsProfileRequest($request);
65 } elseif ($cmd === "about") {
66 $this->handleAboutRequest($request);
67 } else {
68 $this->xapiproxy->log()->debug($this->msg("Wrong xApi Query: " . $request->getUri()));
69 $this->xapiProxyResponse->exitBadRequest();
70 }
71 } else {
72 $this->xapiproxy->log()->error($this->msg("Wrong xApi Query: " . $request->getUri()));
73 $this->xapiProxyResponse->exitBadRequest();
74 }
75 }
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 221 of file XapiProxyRequest.php.

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

◆ handleActivitiesProfileRequest()

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

Definition at line 197 of file XapiProxyRequest.php.

197 : void
198 {
199 $this->xapiproxy->log()->debug($this->msg("handleActivitiesProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
200 $this->handleProxy($request);
201 }

◆ handleActivitiesRequest()

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

Definition at line 189 of file XapiProxyRequest.php.

189 : void
190 {
191 // $this->xapiproxy->log()->debug($this->msg("blocked handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
192 // $this->xapiProxyResponse->exitBadRequest();
193 $this->xapiproxy->log()->debug($this->msg("handleActivitiesRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
194 $this->handleProxy($request);
195 }

◆ handleActivitiesStateRequest()

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

Definition at line 203 of file XapiProxyRequest.php.

203 : void
204 {
205 $this->xapiproxy->log()->debug($this->msg("handleActivitiesStateRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
206 $this->handleProxy($request);
207 }

◆ handleAgentsProfileRequest()

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

Definition at line 215 of file XapiProxyRequest.php.

215 : void
216 {
217 $this->xapiproxy->log()->debug($this->msg("handleAgentsProfileRequest (" . $this->xapiproxy->method() . "): " . $request->getUri()));
218 $this->handleProxy($request);
219 }

◆ handleAgentsRequest()

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

Definition at line 209 of file XapiProxyRequest.php.

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

◆ handleGetStatementsRequest()

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

Definition at line 95 of file XapiProxyRequest.php.

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

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

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

◆ handleProxy()

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

Definition at line 228 of file XapiProxyRequest.php.

228 : void
229 {
230 $endpointDefault = $this->xapiproxy->getDefaultLrsEndpoint();
231 $endpointFallback = $this->xapiproxy->getFallbackLrsEndpoint();
232
233 $this->xapiproxy->log()->debug($this->msg("endpointDefault: " . $endpointDefault));
234 $this->xapiproxy->log()->debug($this->msg("endpointFallback: " . $endpointFallback));
235
236 $keyDefault = $this->xapiproxy->getDefaultLrsKey();
237 $secretDefault = $this->xapiproxy->getDefaultLrsSecret();
238 $authDefault = 'Basic ' . base64_encode($keyDefault . ':' . $secretDefault);
239
240 $hasFallback = ($endpointFallback !== "");
241
242 if ($hasFallback) {
243 $keyFallback = $this->xapiproxy->getFallbackLrsKey();
244 $secretFallback = $this->xapiproxy->getFallbackLrsSecret();
245 $authFallback = 'Basic ' . base64_encode($keyFallback . ':' . $secretFallback);
246 }
247
248 $cmd = $this->xapiproxy->cmdParts()[2] . $this->cmdPart2plus;
249 $upstreamDefault = $endpointDefault . $cmd;
250 $body = $request->getBody()->getContents();
251
252 // Default request ausführen
253 $responseDefault = $this->sendCurlRequest($upstreamDefault, $authDefault, $request->getMethod(), $body);
254
255 // Falls Fallback definiert, zweites Ziel testen
256 $responseFallback = null;
257 if ($hasFallback) {
258 $upstreamFallback = $endpointFallback . $cmd;
259 $responseFallback = $this->sendCurlRequest($upstreamFallback, $authFallback, $request->getMethod(), $body);
260 }
261
262 // Reaktionen auswerten
263 $defaultOk = $this->xapiProxyResponse->checkResponse($responseDefault, $endpointDefault);
264 $fallbackOk = $hasFallback ? $this->xapiProxyResponse->checkResponse($responseFallback, $endpointFallback) : false;
265
266 if ($defaultOk) {
267 try {
268 $this->xapiProxyResponse->handleResponse($request, $responseDefault, $fakePostBody);
269 } catch (\Exception $e) {
270 $this->xapiProxyResponse->exitProxyError();
271 }
272 } elseif ($fallbackOk) {
273 try {
274 $this->xapiProxyResponse->handleResponse($request, $responseFallback, $fakePostBody);
275 } catch (\Exception $e) {
276 $this->xapiProxyResponse->exitProxyError();
277 }
278 } else {
279 $this->xapiProxyResponse->exitResponseError();
280 }
281 }
sendCurlRequest(string $url, string $authHeader, string $method, string $body='')

References Vendor\Package\$e.

◆ handleStatementsRequest()

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

Definition at line 82 of file XapiProxyRequest.php.

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

◆ msg()

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

Definition at line 77 of file XapiProxyRequest.php.

77 : string
78 {
79 return $this->xapiproxy->msg($msg);
80 }

◆ sendCurlRequest()

XapiProxy\XapiProxyRequest::sendCurlRequest ( string  $url,
string  $authHeader,
string  $method,
string  $body = '' 
)
private

Definition at line 283 of file XapiProxyRequest.php.

283 : \GuzzleHttp\Psr7\Response
284 {
285 $ch = curl_init($url);
286 $headers = [
287 "Authorization: $authHeader",
288 "X-Experience-API-Version: 1.0.3",
289 "Accept: application/json",
290 "Content-Type: application/json"
291 ];
292
293 curl_setopt_array($ch, [
294 CURLOPT_RETURNTRANSFER => true,
295 CURLOPT_FOLLOWLOCATION => true,
296 CURLOPT_CONNECTTIMEOUT => 10,
297 CURLOPT_TIMEOUT => 30,
298 CURLOPT_SSL_VERIFYPEER => true,
299 CURLOPT_HTTPHEADER => $headers,
300 CURLOPT_CUSTOMREQUEST => strtoupper($method),
301 ]);
302
303 if (in_array(strtoupper($method), ['POST', 'PUT', 'PATCH'])) {
304 curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
305 }
306
307 $rawBody = curl_exec($ch);
308 $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
309 $curlError = curl_error($ch);
310 curl_close($ch);
311
312 if ($curlError) {
313 $this->xapiproxy->log()->error("cURL error for $url: $curlError");
314 $rawBody = '';
315 }
316
317 return new \GuzzleHttp\Psr7\Response($statusCode, [], $rawBody);
318 }
$url
Definition: shib_logout.php:68

References $url.

Field Documentation

◆ $checkGetStatements

bool XapiProxy\XapiProxyRequest::$checkGetStatements = true
private

Definition at line 36 of file XapiProxyRequest.php.

◆ $cmdPart2plus

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

Definition at line 35 of file XapiProxyRequest.php.

◆ $dic

Container XapiProxy\XapiProxyRequest::$dic
private

Definition at line 29 of file XapiProxyRequest.php.

◆ $xapiproxy

XapiProxy XapiProxy\XapiProxyRequest::$xapiproxy
private

Definition at line 31 of file XapiProxyRequest.php.

◆ $xapiProxyResponse

XapiProxyResponse XapiProxy\XapiProxyRequest::$xapiProxyResponse
private

Definition at line 33 of file XapiProxyRequest.php.


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