Skip to content

Commit 63369c6

Browse files
committed
feat(editor): add signed callback state storage for external save handlers
1 parent 5098f73 commit 63369c6

3 files changed

Lines changed: 389 additions & 10 deletions

File tree

php/connector.minimal.php-dist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ elFinder::$netDrivers['ftp'] = 'FTP';
110110
// // Zoho Office Editor APIKey
111111
// // https://www.zoho.com/docs/help/office-apis.html
112112
// define('ELFINDER_ZOHO_OFFICE_APIKEY', '');
113+
// Zoho Office save callback state TTL in seconds
114+
// Default: 3600 (1 hour), Max: 86400 (24 hours)
115+
// define('ELFINDER_ZOHO_OFFICE_CALLBACK_TTL', 3600);
113116
// ===============================================
114117

115118
// // Online converter (online-convert.com) APIKey

php/editors/ZohoOffice/editor.php

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public function enabled()
8080

8181
public function init()
8282
{
83+
$this->gcCallbackStates();
84+
8385
if (!defined('ELFINDER_ZOHO_OFFICE_APIKEY') || !function_exists('curl_init')) {
8486
return array('error', array(elFinder::ERROR_CONF, '`ELFINDER_ZOHO_OFFICE_APIKEY` or curl extension'));
8587
}
@@ -143,7 +145,7 @@ public function init()
143145
'callback_settings' => array(
144146
'save_format' => $format,
145147
'save_url_params' => array(
146-
'hash' => $hash
148+
'content' => 'content'
147149
)
148150
),
149151
'editor_settings' => $this->editor_settings[$srvsName],
@@ -152,6 +154,26 @@ public function init()
152154
)
153155
);
154156
$data['editor_settings']['language'] = $lang;
157+
if ($save) {
158+
$ttl = defined('ELFINDER_ZOHO_OFFICE_CALLBACK_TTL')
159+
? (int)ELFINDER_ZOHO_OFFICE_CALLBACK_TTL
160+
: 3600;
161+
162+
if ($ttl <= 0) {
163+
$ttl = 3600;
164+
} else if ($ttl > 86400) {
165+
$ttl = 86400;
166+
}
167+
$saveParams = $this->createCallbackState('save', $hash, $this->getCallbackStateSecret(), array(), $ttl);
168+
if ($saveParams === false) {
169+
$save = false;
170+
} else {
171+
$data['callback_settings']['save_url_params'] = array_merge(
172+
$data['callback_settings']['save_url_params'],
173+
$saveParams
174+
);
175+
}
176+
}
155177
if ($save) {
156178
$conUrl = elFinder::getConnectorUrl();
157179
$data['callback_settings']['save_url'] = $conUrl . (strpos($conUrl, '?') !== false? '&' : '?') . 'cmd=editor&name=' . $this->myName . '&method=save' . $cdata;
@@ -204,17 +226,33 @@ public function init()
204226

205227
public function save()
206228
{
207-
if (!empty($_POST) && !empty($_POST['hash']) && !empty($_FILES) && !empty($_FILES['content'])) {
208-
$hash = $_POST['hash'];
209-
/** @var elFinderVolumeDriver $volume */
210-
if ($volume = $this->elfinder->getVolume($hash)) {
211-
if ($content = file_get_contents($_FILES['content']['tmp_name'])) {
212-
if ($volume->putContents($hash, $content)) {
213-
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 200 OK');
214-
}
215-
}
229+
$state = $this->verifyCallbackRequest('save', $_POST, $this->getCallbackStateSecret());
230+
if ($state === false) {
231+
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 403 Forbidden');
232+
}
233+
234+
if (empty($_FILES['content']) || (isset($_FILES['content']['error']) && (int)$_FILES['content']['error'] !== 0)) {
235+
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
236+
}
237+
238+
$tmpName = isset($_FILES['content']['tmp_name']) ? $_FILES['content']['tmp_name'] : '';
239+
if (!$tmpName || !is_uploaded_file($tmpName) && !is_file($tmpName)) {
240+
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
241+
}
242+
243+
$content = file_get_contents($tmpName);
244+
if ($content === false) {
245+
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
246+
}
247+
248+
$hash = $state['hash'];
249+
/** @var elFinderVolumeDriver $volume */
250+
if ($volume = $this->elfinder->getVolume($hash)) {
251+
if ($volume->putContents($hash, $content)) {
252+
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 200 OK');
216253
}
217254
}
255+
218256
return array('raw' => true, 'error' => '', 'header' => 'HTTP/1.1 500 Internal Server Error');
219257
}
220258

@@ -230,4 +268,13 @@ public function chk()
230268
}
231269
return array('cansave' => $res);
232270
}
271+
272+
protected function getCallbackStateSecret()
273+
{
274+
return hash('sha256', implode('|', array(
275+
__CLASS__,
276+
__FILE__,
277+
ELFINDER_ZOHO_OFFICE_APIKEY
278+
)));
279+
}
233280
}

0 commit comments

Comments
 (0)