ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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.

References $GLOBALS.

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

Member Function Documentation

◆ createProxyRequest()

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

Definition at line 296 of file XapiProxyRequest.php.

References $auth, and XapiProxy\$req.

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

◆ 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  }
handleProxy($request, $fakePostBody=null)

◆ 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  }
handleProxy($request, $fakePostBody=null)

◆ 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  }
handleProxy($request, $fakePostBody=null)

◆ 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  }
handleProxy($request, $fakePostBody=null)

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

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

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  }
static getInstance(ilObjCmiXapi $object)
$_GET["client_id"]
static getCMI5RegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
static getInstance($a_id=0, $a_reference=true)
handleProxy($request, $fakePostBody=null)
static getRegistrationFromAuthToken(ilCmiXapiAuthToken $authToken)
+ Here is the call graph for this function:

◆ handlePostPutStatementsRequest()

XapiProxy\XapiProxyRequest::handlePostPutStatementsRequest (   $request)
private

Definition at line 131 of file XapiProxyRequest.php.

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

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  }
handleProxy($request, $fakePostBody=null)

◆ handleProxy()

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

Definition at line 199 of file XapiProxyRequest.php.

References Vendor\Package\$e.

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)

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