19 declare(strict_types=1);
38 private string $cmdPart2plus =
"";
39 private bool $checkGetStatements =
true;
45 $this->cmdPart2plus =
"";
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) {
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);
71 $this->xapiproxy->log()->debug($this->msg(
"Wrong xApi Query: " . $request->getUri()));
72 $this->xapiProxyResponse->exitBadRequest();
75 $this->xapiproxy->log()->error($this->msg(
"Wrong xApi Query: " . $request->getUri()));
76 $this->xapiProxyResponse->exitBadRequest();
80 private function msg(
string $msg): string
82 return $this->xapiproxy->msg($msg);
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);
94 $this->xapiProxyResponse->exitBadRequest();
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();
104 $this->xapiproxy->log()->debug($this->msg(
"handleGetStatementsRequest: " . $request->getUri()));
108 if ($this->checkGetStatements) {
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)"));
116 $this->handleProxy($request);
118 if (
$params->has(
'activity')) {
120 $this->handleProxy($request);
122 $this->xapiproxy->log()->debug($this->msg(
"add activity: " . $obj->getActivityId()));
123 $this->cmdPart2plus .=
"&activity=" . $obj->getActivityId() .
"&related_activities=true";
125 if (!$access->hasOutcomesAccess($authToken->getUsrId())) {
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));
145 $this->xapiproxy->log()->debug($this->msg(
"add registration: " . $regUserObject));
146 $this->cmdPart2plus .=
"®istration=" . $regUserObject;
152 $this->xapiProxyResponse->exitBadRequest();
154 $this->handleProxy($request);
157 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
163 $this->xapiproxy->log()->debug($this->msg(
"handlePostPutStatementsRequest: " . $request->getUri()));
164 $body = $request->getBody()->getContents();
165 $fakePostBody =
null;
167 $this->xapiproxy->log()->warning($this->msg(
"empty body in handlePostPutRequest"));
168 $this->handleProxy($request);
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]);
175 $fakePostBody = $retArr[1];
178 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
179 $this->xapiProxyResponse->exitProxyError();
182 $body = $this->xapiproxy->modifyBody($body);
183 $req =
new Request($request->getMethod(), $request->getUri(), $request->getHeaders(), $body);
184 $this->handleProxy(
$req, $fakePostBody);
186 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
187 $this->handleProxy($request, $fakePostBody);
196 $this->xapiproxy->log()->debug($this->msg(
"handleActivitiesRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
197 $this->handleProxy($request);
202 $this->xapiproxy->log()->debug($this->msg(
"handleActivitiesProfileRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
203 $this->handleProxy($request);
208 $this->xapiproxy->log()->debug($this->msg(
"handleActivitiesStateRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
209 $this->handleProxy($request);
214 $this->xapiproxy->log()->debug($this->msg(
"blocked handleAgentsRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
215 $this->xapiProxyResponse->exitBadRequest();
220 $this->xapiproxy->log()->debug($this->msg(
"handleAgentsProfileRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
221 $this->handleProxy($request);
226 $this->xapiproxy->log()->debug($this->msg(
"handleAboutRequest (" . $this->xapiproxy->method() .
"): " . $request->getUri()));
227 $this->handleProxy($request);
232 $endpointDefault = $this->xapiproxy->getDefaultLrsEndpoint();
233 $endpointFallback = $this->xapiproxy->getFallbackLrsEndpoint();
235 $this->xapiproxy->log()->debug($this->msg(
"endpointDefault: " . $endpointDefault));
236 $this->xapiproxy->log()->debug($this->msg(
"endpointFallback: " . $endpointFallback));
238 $keyDefault = $this->xapiproxy->getDefaultLrsKey();
239 $secretDefault = $this->xapiproxy->getDefaultLrsSecret();
240 $authDefault =
'Basic ' . base64_encode($keyDefault .
':' . $secretDefault);
242 $hasFallback = ($endpointFallback ===
"") ?
false :
true;
245 $keyFallback = $this->xapiproxy->getFallbackLrsKey();
246 $secretFallback = $this->xapiproxy->getFallbackLrsSecret();
247 $authFallback =
'Basic ' . base64_encode($keyFallback .
':' . $secretFallback);
251 RequestOptions::VERIFY =>
true,
252 RequestOptions::CONNECT_TIMEOUT => 10,
253 RequestOptions::HTTP_ERRORS =>
false 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);
262 $upstreamFallback = $endpointFallback . $cmd;
263 $uriFallback =
new Uri($upstreamFallback);
264 $reqFallback = $this->createProxyRequest($request, $uriFallback, $authFallback, $body);
267 $httpclient =
new Client();
270 'default' => $httpclient->sendAsync($reqDefault, $req_opts),
271 'fallback' => $httpclient->sendAsync($reqFallback, $req_opts)
277 $responses = Promise\Utils::settle($promises)->wait();
279 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
282 $defaultOk = $this->xapiProxyResponse->checkResponse($responses[
'default'], $endpointDefault);
283 $fallbackOk = $this->xapiProxyResponse->checkResponse($responses[
'fallback'], $endpointFallback);
287 $this->xapiProxyResponse->handleResponse(
289 $responses[
'default'][
'value'],
294 $this->xapiProxyResponse->exitProxyError();
296 } elseif ($fallbackOk) {
298 $this->xapiProxyResponse->handleResponse(
300 $responses[
'fallback'][
'value'],
305 $this->xapiProxyResponse->exitProxyError();
308 $this->xapiProxyResponse->exitResponseError();
312 'default' => $httpclient->sendAsync($reqDefault, $req_opts)
317 $responses = Promise\Utils::settle($promises)->wait();
319 $this->xapiproxy->log()->error($this->msg($e->getMessage()));
321 if ($this->xapiProxyResponse->checkResponse($responses[
'default'], $endpointDefault)) {
323 $this->xapiProxyResponse->handleResponse(
325 $responses[
'default'][
'value'],
330 $this->xapiProxyResponse->exitProxyError();
333 $this->xapiProxyResponse->exitResponseError();
341 'Cache-Control' =>
'no-cache, no-store, must-revalidate',
342 'Authorization' => $auth
345 if ($request->hasHeader(
'X-Experience-API-Version')) {
346 $headers[
'X-Experience-API-Version'] = $request->getHeader(
'X-Experience-API-Version');
349 if ($request->hasHeader(
'Referrer')) {
350 $headers[
'Referrer'] = $request->getHeader(
'Referrer');
353 if ($request->hasHeader(
'Content-Type')) {
354 $headers[
'Content-Type'] = $request->getHeader(
'Content-Type');
357 if ($request->hasHeader(
'Origin')) {
358 $headers[
'Origin'] = $request->getHeader(
'Origin');
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);
368 $headers[
'Content-Length'] = $contentLength;
371 if ($request->hasHeader(
'Connection')) {
372 $headers[
'Connection'] = $request->getHeader(
'Connection');
377 $req =
new Request(strtoupper($request->getMethod()), $uri, $headers, $body);
handleStatementsRequest(\Psr\Http\Message\RequestInterface $request)
static getInstance(ilObjCmiXapi $object)
static getInstanceByToken(string $token)
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
handleAboutRequest(\Psr\Http\Message\RequestInterface $request)
XapiProxyResponse $xapiProxyResponse
createProxyRequest(\Psr\Http\Message\RequestInterface $request, \GuzzleHttp\Psr7\Uri $uri, string $auth, string $body)
handleActivitiesProfileRequest(\Psr\Http\Message\RequestInterface $request)
static getInstance(int $a_id=0, bool $a_reference=true)
handleAgentsRequest(\Psr\Http\Message\RequestInterface $request)
handleGetStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handleProxy(\Psr\Http\Message\RequestInterface $request, $fakePostBody=null)
Customizing of pimple-DIC for ILIAS.
catch(\Exception $e) $req
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static getCMI5RegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
handleAgentsProfileRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesRequest(\Psr\Http\Message\RequestInterface $request)
static getRegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
__construct(XapiProxy $xapiproxy)
handlePostPutStatementsRequest(\Psr\Http\Message\RequestInterface $request)
handleActivitiesStateRequest(\Psr\Http\Message\RequestInterface $request)