ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ILIAS\WOPI\Handler\RequestHandler Class Reference
+ Collaboration diagram for ILIAS\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'
 

Private Member Functions

 checkAuth ()
 

Private Attributes

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\WOPI\Handler\RequestHandler::__construct ( )

Definition at line 72 of file RequestHandler.php.

73 {
74 global $DIC;
75 $this->http = $DIC->http();
76 $this->data_signer = $DIC['file_delivery.data_signer'];
77 $this->irss = $DIC->resourceStorage();
78 $this->saving_interval = (int) $DIC->settings()->get('saving_interval');
79 }
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26

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

+ Here is the call graph for this function:

Member Function Documentation

◆ checkAuth()

ILIAS\WOPI\Handler\RequestHandler::checkAuth ( )
private

Definition at line 81 of file RequestHandler.php.

81 : void
82 {
83 $auth = $this->http->request()->getHeader(self::HEADER_AUTHORIZATION)[0] ?? '';
84 // spit and check bearer token
85 $bearer = explode(' ', $auth);
86 if ($auth !== '' && ($bearer[0] ?? '') !== self::HEADER_AUTHORIZATION_BEARER) {
87 throw new \InvalidArgumentException();
88 }
89 $bearer_token = $bearer[1] ?? '';
90 if ($auth === '' && $bearer_token === '') {
91 // we try to get the token from GET
92 $bearer_token = $this->http->request()->getQueryParams()['access_token'] ?? '';
93 }
94 if ($bearer_token === '') {
95 throw new \InvalidArgumentException('No access token provided');
96 }
97 if (($token_data = $this->data_signer->verify($bearer_token, 'wopi')) === null) {
98 throw new \InvalidArgumentException('Token verification failed');
99 }
100
101 $this->token_user_id = (int) ($token_data['user_id'] ?? 0);
102 $this->token_resource_id = (string) ($token_data['resource_id'] ?? '');
103 $this->editable = (bool) ($token_data['editable'] ?? '');
104 $stakeholder = $token_data['stakeholder'] ?? null;
105 if ($stakeholder !== null) {
106 try {
107 $this->stakeholder = new WOPIStakeholderWrapper();
108 $this->stakeholder->init($stakeholder, $this->token_user_id);
109 } catch (\Throwable) {
110 $this->stakeholder = new WOPIUnknownStakeholder($this->token_user_id);
111 }
112 }
113 }

References ILIAS\WOPI\Handler\RequestHandler\$stakeholder, ILIAS\FileDelivery\http(), and ILIAS\Repository\int().

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

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handleRequest()

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

Definition at line 118 of file RequestHandler.php.

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

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

+ Here is the call graph for this function:

Field Documentation

◆ $data_signer

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

Definition at line 65 of file RequestHandler.php.

◆ $editable

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

Definition at line 70 of file RequestHandler.php.

◆ $http

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

Definition at line 63 of file RequestHandler.php.

◆ $irss

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

Definition at line 64 of file RequestHandler.php.

◆ $saving_interval

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

Definition at line 69 of file RequestHandler.php.

◆ $stakeholder

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

Definition at line 68 of file RequestHandler.php.

Referenced by ILIAS\WOPI\Handler\RequestHandler\checkAuth().

◆ $token_resource_id

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

Definition at line 67 of file RequestHandler.php.

◆ $token_user_id

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

Definition at line 66 of file RequestHandler.php.

◆ HEADER_AUTHORIZATION

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

Definition at line 45 of file RequestHandler.php.

◆ HEADER_AUTHORIZATION_BEARER

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

Definition at line 49 of file RequestHandler.php.

◆ HEADER_X_WOPI_FILE_CONVERSION

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

Definition at line 61 of file RequestHandler.php.

◆ HEADER_X_WOPI_LOCK

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

Definition at line 57 of file RequestHandler.php.

◆ HEADER_X_WOPI_OVERRIDE

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

Definition at line 53 of file RequestHandler.php.

◆ NAMESPACE_FILES

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

◆ WOPI_BASE_URL

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

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