ILIAS  trunk Revision v11.0_alpha-1831-g8615d53dadb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ILIAS\components\WOPI\Handler\RequestHandler Class Reference
+ Collaboration diagram for ILIAS\components\WOPI\Handler\RequestHandler:

Public Member Functions

 __construct ()
 
 handleRequest ()
 

Data Fields

const WOPI_BASE_URL = '/wopi/index.php/'
 
const NAMESPACE_FILES = 'files'
 
const HEADER_X_WOPI_OVERRIDE = 'X-WOPI-Override'
 
const HEADER_X_WOPI_LOCK = 'X-WOPI-Lock'
 
const HEADER_X_WOPI_FILE_CONVERSION = 'X-WOPI-FileConversion'
 

Protected Member Functions

 checkAuth ()
 

Private Attributes

const HEADER_X_REQUEST_ID = 'X-Request-ID'
 
const HEADER_AUTHORIZATION = 'Authorization'
 
const HEADER_AUTHORIZATION_BEARER = 'Bearer'
 
Services $http
 
ILIAS ResourceStorage Services $irss
 
DataSigner $data_signer
 
int $token_user_id = null
 
string $token_resource_id = null
 
ResourceStakeholder $stakeholder
 
int $saving_interval = 0
 
bool $editable = false
 

Detailed Description

Author
Fabian Schmid fabia.nosp@m.n@sr.nosp@m..solu.nosp@m.tion.nosp@m.s

Definition at line 32 of file RequestHandler.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\components\WOPI\Handler\RequestHandler::__construct ( )

Definition at line 78 of file RequestHandler.php.

References $DIC, ILIAS\FileDelivery\http(), and ILIAS\Repository\int().

79  {
80  global $DIC;
81  $this->http = $DIC->http();
82  $this->data_signer = $DIC['file_delivery.data_signer'];
83  $this->irss = $DIC->resourceStorage();
84  $this->saving_interval = (int) $DIC->settings()->get('saving_interval');
85  }
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:22
+ Here is the call graph for this function:

Member Function Documentation

◆ checkAuth()

ILIAS\components\WOPI\Handler\RequestHandler::checkAuth ( )
protected

Definition at line 87 of file RequestHandler.php.

References ILIAS\FileDelivery\http(), ILIAS\Repository\int(), and null.

Referenced by ILIAS\components\WOPI\Handler\RequestHandler\handleRequest().

87  : void
88  {
89  $auth = $this->http->request()->getHeader(self::HEADER_AUTHORIZATION)[0] ?? '';
90  // spit and check bearer token
91  $bearer = explode(' ', $auth);
92  if ($auth !== '' && ($bearer[0] ?? '') !== self::HEADER_AUTHORIZATION_BEARER) {
93  throw new \InvalidArgumentException();
94  }
95  $bearer_token = $bearer[1] ?? '';
96  if ($auth === '' && $bearer_token === '') {
97  // we try to get the token from GET
98  $bearer_token = $this->http->request()->getQueryParams()['access_token'] ?? '';
99  }
100  if ($bearer_token === '') {
101  throw new \InvalidArgumentException();
102  }
103  if (($token_data = $this->data_signer->verify($bearer_token, 'wopi')) === null) {
104  throw new \InvalidArgumentException();
105  }
106 
107  $this->token_user_id = (int) ($token_data['user_id'] ?? 0);
108  $this->token_resource_id = (string) ($token_data['resource_id'] ?? '');
109  $this->editable = (bool) ($token_data['editable'] ?? '');
110  $stakeholder = $token_data['stakeholder'] ?? null;
111  if ($stakeholder !== null) {
112  try {
113  $this->stakeholder = new WOPIStakeholderWrapper();
114  $this->stakeholder->init($stakeholder, $this->token_user_id);
115  } catch (\Throwable) {
116  $this->stakeholder = new WOPIUnknownStakeholder($this->token_user_id);
117  }
118  }
119  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static http()
Fetches the global http state from ILIAS.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handleRequest()

ILIAS\components\WOPI\Handler\RequestHandler::handleRequest ( )
Returns
never

Definition at line 124 of file RequestHandler.php.

References $message, $response, ILIAS\components\WOPI\Handler\RequestHandler\checkAuth(), ILIAS\FileDelivery\http(), null, and ILIAS\Filesystem\Stream\Streams\ofString().

124  : void
125  {
126  try {
127  $this->checkAuth();
128 
129  $uri = $this->http->request()->getUri()->getPath();
130  $request = substr($uri, strpos($uri, self::WOPI_BASE_URL) + strlen(self::WOPI_BASE_URL));
131  $request = explode('/', $request);
132  $method = $this->http->request()->getMethod();
133 
134  $resource_id = $request[1];
135  $action = $request[2] ?? '';
136 
137  // check resource_id
138  if ($this->token_resource_id !== $resource_id) {
139  $this->http->close();
140  }
141 
142  $resource_id = $this->irss->manage()->find($resource_id);
143  if (!$resource_id instanceof ResourceIdentification) {
144  $this->http->close();
145  }
146  $resource = $this->irss->manage()->getResource($resource_id);
147  $current_revision = $this->editable ? $resource->getCurrentRevisionIncludingDraft() : $resource->getCurrentRevision();
148 
149  $method_override = $this->http->request()->getHeader(self::HEADER_X_WOPI_OVERRIDE)[0] ?? null;
150  $is_file_convertion = (bool) ($this->http->request()->getHeader(
151  self::HEADER_X_WOPI_FILE_CONVERSION
152  )[0] ?? false);
153 
154  // GET
155  switch ($method_override ?? $method) {
156  case 'GET':
157  switch ($action) {
158  case '':
159  // CheckFileInfo
160  $response = new GetFileInfoResponse(
161  $current_revision,
162  $this->token_user_id,
163  $this->editable
164  );
165  $this->http->saveResponse(
166  $this->http->response()->withBody(
167  Streams::ofString(json_encode($response, JSON_THROW_ON_ERROR))
168  )
169  );
170 
171  break;
172  case 'contents':
173  // GetFile
174  $stream = $this->irss->consume()->stream($resource_id)->setRevisionNumber(
175  $current_revision->getVersionNumber()
176  )->getStream();
177  $this->http->saveResponse(
178  $this->http->response()->withBody($stream)
179  );
180 
181  break;
182  }
183  break;
184  case 'PUT_RELATIVE':
185  if (!$is_file_convertion) {
186  throw new \InvalidArgumentException();
187  }
188  // no break
189  case 'PUT':
190  switch ($action) {
191  case 'contents':
192  // PutFile
193  $body_stream = $this->http->request()->getBody();
194  $body = $body_stream->getContents();
195  $file_stream = Streams::ofString($body);
196 
197  $draft = true;
198 
199  if ($this->saving_interval > 0) {
200  $latest_revision = $resource->getCurrentRevision();
201  $creation_time = $latest_revision->getInformation()->getCreationDate()->getTimestamp();
202  $current_time = time();
203  $time_diff = $current_time - $creation_time;
204  if ($time_diff > $this->saving_interval) {
205  $this->irss->manage()->publish($resource_id);
206  }
207  }
208 
209  $new_revision = $this->irss->manage()->appendNewRevisionFromStream(
210  $resource_id,
211  $file_stream,
212  $this->stakeholder,
213  $current_revision->getTitle(),
214  $draft
215  );
216 
217  // CheckFileInfo
218  $response = new GetFileInfoResponse(
219  $new_revision,
220  $this->token_user_id
221  );
222  $this->http->saveResponse(
223  $this->http->response()->withBody(
224  Streams::ofString(json_encode($response, JSON_THROW_ON_ERROR))
225  )
226  );
227 
228  break;
229  case '': // if we want to create new files in the future, this will be a separate case
230  break;
231  }
232  break;
233  case 'POST':
234  switch ($action) {
235  case 'contents':
236  $this->http->saveResponse(
237  $this->http->response()->withBody(
239  )
240  );
241 
242  break;
243  case '':
244  // Lock
245  $lock = $this->http->request()->getHeader(self::HEADER_X_WOPI_LOCK)[0] ?? null;
246  $this->http->saveResponse(
247  $this->http->response()->withBody(
249  )
250  );
251  }
252  break;
253  }
254  } catch (\Throwable $t) {
255  $message = $t->getMessage();
256  // append simple stacktrace
257  $trace = array_map(
258  static fn(array $trace): string => $trace['file'] . ':' . $trace['line'],
259  $t->getTrace()
260  );
261 
262  $message .= "\n" . implode("\n", $trace);
263 
264  $this->http->saveResponse(
265  $this->http->response()
266  ->withBody(Streams::ofString($message))
267  ->withStatus(500)
268  ->withHeader('X-WOPI-ServerError', $t->getMessage())
269  );
270  }
271  $this->http->sendResponse();
272  $this->http->close();
273  }
$response
Definition: xapitoken.php:93
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static http()
Fetches the global http state from ILIAS.
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
$message
Definition: xapiexit.php:31
+ Here is the call graph for this function:

Field Documentation

◆ $data_signer

DataSigner ILIAS\components\WOPI\Handler\RequestHandler::$data_signer
private

Definition at line 71 of file RequestHandler.php.

◆ $editable

bool ILIAS\components\WOPI\Handler\RequestHandler::$editable = false
private

Definition at line 76 of file RequestHandler.php.

◆ $http

Services ILIAS\components\WOPI\Handler\RequestHandler::$http
private

Definition at line 69 of file RequestHandler.php.

◆ $irss

ILIAS ResourceStorage Services ILIAS\components\WOPI\Handler\RequestHandler::$irss
private

Definition at line 70 of file RequestHandler.php.

◆ $saving_interval

int ILIAS\components\WOPI\Handler\RequestHandler::$saving_interval = 0
private

Definition at line 75 of file RequestHandler.php.

◆ $stakeholder

ResourceStakeholder ILIAS\components\WOPI\Handler\RequestHandler::$stakeholder
private

Definition at line 74 of file RequestHandler.php.

◆ $token_resource_id

string ILIAS\components\WOPI\Handler\RequestHandler::$token_resource_id = null
private

Definition at line 73 of file RequestHandler.php.

◆ $token_user_id

int ILIAS\components\WOPI\Handler\RequestHandler::$token_user_id = null
private

Definition at line 72 of file RequestHandler.php.

◆ HEADER_AUTHORIZATION

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_AUTHORIZATION = 'Authorization'
private

Definition at line 51 of file RequestHandler.php.

◆ HEADER_AUTHORIZATION_BEARER

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_AUTHORIZATION_BEARER = 'Bearer'
private

Definition at line 55 of file RequestHandler.php.

◆ HEADER_X_REQUEST_ID

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_X_REQUEST_ID = 'X-Request-ID'
private

Definition at line 47 of file RequestHandler.php.

◆ HEADER_X_WOPI_FILE_CONVERSION

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_X_WOPI_FILE_CONVERSION = 'X-WOPI-FileConversion'

Definition at line 67 of file RequestHandler.php.

◆ HEADER_X_WOPI_LOCK

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_X_WOPI_LOCK = 'X-WOPI-Lock'

Definition at line 63 of file RequestHandler.php.

◆ HEADER_X_WOPI_OVERRIDE

const ILIAS\components\WOPI\Handler\RequestHandler::HEADER_X_WOPI_OVERRIDE = 'X-WOPI-Override'

Definition at line 59 of file RequestHandler.php.

◆ NAMESPACE_FILES

const ILIAS\components\WOPI\Handler\RequestHandler::NAMESPACE_FILES = 'files'

◆ WOPI_BASE_URL

const ILIAS\components\WOPI\Handler\RequestHandler::WOPI_BASE_URL = '/wopi/index.php/'

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