lots of changes to be compatible with Slim 4 which was introduced

This commit is contained in:
Uwe Steinmann 2025-01-02 17:10:52 +01:00
parent 9ba5882aa9
commit 6633e78ef8

View File

@ -110,6 +110,7 @@ class SeedDMS_ExtPaperless_Bootstrap { /* {{{ */
} /* }}} */ } /* }}} */
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
class SeedDMS_ExtPaperless_Process_Folder { /* {{{ */ class SeedDMS_ExtPaperless_Process_Folder { /* {{{ */
protected $list; protected $list;
@ -128,8 +129,27 @@ class SeedDMS_ExtPaperless_Process_Folder { /* {{{ */
} /* }}} */ } /* }}} */
} /* }}} */ } /* }}} */
final class SeedDMS_ExtPaperless_JsonRenderer { /* {{{ */
public function json(
ResponseInterface $response,
array $data = null
): ResponseInterface {
$response = $response->withHeader('Content-Type', 'application/json');
$response->getBody()->write(
(string)json_encode(
$data,
JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR
)
);
return $response;
}
} /* }}} */
class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
protected $container; protected $container;
protected $renderer;
static public function mb_word_count($string, $mode = MB_CASE_TITLE, $characters = null) { /* {{{ */ static public function mb_word_count($string, $mode = MB_CASE_TITLE, $characters = null) { /* {{{ */
$string = mb_convert_case($string, $mode, "UTF-8"); $string = mb_convert_case($string, $mode, "UTF-8");
@ -255,8 +275,9 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} /* }}} */ } /* }}} */
// constructor receives container instance // constructor receives container instance
public function __construct(ContainerInterface $container) { /* {{{ */ public function __construct(ContainerInterface $container, SeedDMS_ExtPaperless_JsonRenderer $renderer) { /* {{{ */
$this->container = $container; $this->container = $container;
$this->renderer = $renderer;
} /* }}} */ } /* }}} */
function api($request, $response) { /* {{{ */ function api($request, $response) { /* {{{ */
@ -273,7 +294,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
'mail_rule'=>$request->getUri().'mail_rule/', 'mail_rule'=>$request->getUri().'mail_rule/',
); );
return $response->withJson($data, 200); return $this->renderer->json($response, $data)->withStatus(200);
} /* }}} */ } /* }}} */
function token($request, $response) { /* {{{ */ function token($request, $response) { /* {{{ */
@ -289,7 +310,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if($data) { if($data) {
$userobj = $authenticator->authenticate($data['username'], $data['password']); $userobj = $authenticator->authenticate($data['username'], $data['password']);
if(!$userobj) if(!$userobj)
return $response->withJson(array('non_field_errors'=>['Unable to log in with provided credentials.']), 403); return $this->renderer->json($response, array('non_field_errors'=>['Unable to log in with provided credentials.']))->withStatus(403);
else { else {
if(!empty($settings->_extensions['paperless']['jwtsecret'])) { if(!empty($settings->_extensions['paperless']['jwtsecret'])) {
$token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']); $token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']);
@ -300,9 +321,9 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if(!$tokenstr = $token->jwtEncode($userobj->getId().':'.(time()+$days*84600))) { if(!$tokenstr = $token->jwtEncode($userobj->getId().':'.(time()+$days*84600))) {
return $response->withStatus(403); return $response->withStatus(403);
} }
return $response->withJson(array('token'=>$tokenstr), 200); return $this->renderer->json($response, array('token'=>$tokenstr))->withStatus(200);
} else { } else {
return $response->withJson(array('token'=>$settings->_apiKey), 200); return $this->renderer->json($response, array('token'=>$settings->_apiKey))->withStatus(200);
} }
} }
} }
@ -317,7 +338,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$logger = $this->container->get('logger'); $logger = $this->container->get('logger');
if(false === ($categories = $dms->getDocumentCategories())) { if(false === ($categories = $dms->getDocumentCategories())) {
return $response->withJson(array('results'=>null), 500); return $this->renderer->json($response, array('results'=>null))->withStatus(500);
} }
if(!empty($settings->_extensions['paperless']['usehomefolder'])) { if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
@ -347,7 +368,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$tmp['document_count'] = (int) $facets['category'][$category->getName()]; $tmp['document_count'] = (int) $facets['category'][$category->getName()];
$data[] = $tmp; $data[] = $tmp;
} }
return $response->withJson(array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data), 200); return $this->renderer->json($response, array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data))->withStatus(200);
} /* }}} */ } /* }}} */
function post_tag($request, $response) { /* {{{ */ function post_tag($request, $response) { /* {{{ */
@ -364,13 +385,13 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$data = $request->getParsedBody(); $data = $request->getParsedBody();
$oldcat = $dms->getDocumentCategoryByName($data['name']); $oldcat = $dms->getDocumentCategoryByName($data['name']);
if (is_object($oldcat)) { if (is_object($oldcat)) {
return $response->withJson(getMLText('paperless_tag_already_exists'), 400); return $this->renderer->json($response, getMLText('paperless_tag_already_exists'))->withStatus(400);
} }
$newCategory = $dms->addDocumentCategory($data['name']); $newCategory = $dms->addDocumentCategory($data['name']);
if (!$newCategory) if (!$newCategory)
return $response->withJson(getMLText('paperless_could_not_create_tag'), 400); return $this->renderer->json($response, getMLText('paperless_could_not_create_tag'))->withStatus(400);
return $response->withJson($this->__getCategoryData($newCategory, []), 201); return $this->renderer->json($response, $this->__getCategoryData($newCategory, []), 201);
} /* }}} */ } /* }}} */
function delete_tag($request, $response, $args) { /* {{{ */ function delete_tag($request, $response, $args) { /* {{{ */
@ -433,7 +454,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
); );
} }
} }
return $response->withJson(array('count'=>count($correspondents), 'next'=>null, 'previous'=>null, 'results'=>$correspondents), 200); return $this->renderer->json($response, array('count'=>count($correspondents), 'next'=>null, 'previous'=>null, 'results'=>$correspondents))->withStatus(200);
} /* }}} */ } /* }}} */
function document_types($request, $response) { /* {{{ */ function document_types($request, $response) { /* {{{ */
@ -459,7 +480,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
); );
} }
} }
return $response->withJson(array('count'=>count($types), 'next'=>null, 'previous'=>null, 'results'=>$types), 200); return $this->renderer->json($response, array('count'=>count($types), 'next'=>null, 'previous'=>null, 'results'=>$types))->withStatus(200);
} /* }}} */ } /* }}} */
function saved_views($request, $response) { /* {{{ */ function saved_views($request, $response) { /* {{{ */
@ -477,7 +498,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$tmp = $view->getView(); $tmp = $view->getView();
$data[] = $tmp; $data[] = $tmp;
} }
return $response->withJson(array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data), 200); return $this->renderer->json($response, array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data))->withStatus(200);
} /* }}} */ } /* }}} */
function post_saved_views($request, $response) { /* {{{ */ function post_saved_views($request, $response) { /* {{{ */
@ -497,9 +518,9 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$view->setDMS($dms); $view->setDMS($dms);
if($newview = $view->save()) { if($newview = $view->save()) {
// $logger->log(var_export($newview, true), PEAR_LOG_DEBUG); // $logger->log(var_export($newview, true), PEAR_LOG_DEBUG);
return $response->withJson($newview->getView(), 201); return $this->renderer->json($response, $newview->getView(), 201);
} else { } else {
return $response->withJson('', 501); return $response->withStatus(501);
} }
} /* }}} */ } /* }}} */
@ -547,7 +568,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$view->setView($data); $view->setView($data);
$view->save(); $view->save();
} }
return $response->withJson($view->getView(), 200); return $this->renderer->json($response, $view->getView(), 200);
} /* }}} */ } /* }}} */
function storage_paths($request, $response) { /* {{{ */ function storage_paths($request, $response) { /* {{{ */
@ -572,7 +593,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if($path[1] > 0) if($path[1] > 0)
$paths[] = array('id'=>(int)$fid, 'name'=>$path[0], 'slug'=>$path[0], 'path'=>$path[0], 'match'=>'', 'matching_algorithm'=>6, 'is_insensitive'=>true, 'document_count'=>$path[1]); $paths[] = array('id'=>(int)$fid, 'name'=>$path[0], 'slug'=>$path[0], 'path'=>$path[0], 'match'=>'', 'matching_algorithm'=>6, 'is_insensitive'=>true, 'document_count'=>$path[1]);
} }
return $response->withJson(array('count'=>count($paths), 'next'=>null, 'previous'=>null, 'results'=>$paths), 200); return $this->renderer->json($response, array('count'=>count($paths), 'next'=>null, 'previous'=>null, 'results'=>$paths))->withStatus(200);
} /* }}} */ } /* }}} */
function documents($request, $response) { /* {{{ */ function documents($request, $response) { /* {{{ */
@ -773,7 +794,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
$logger->log('Result is '.$allids, PEAR_LOG_DEBUG); $logger->log('Result is '.$allids, PEAR_LOG_DEBUG);
if($recs) if($recs)
return $response->withJson(array('count'=>$searchresult['count'], 'next'=>null, 'previous'=>null, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs), 200); return $this->renderer->json($response, array('count'=>$searchresult['count'], 'next'=>null, 'previous'=>null, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs))->withStatus(200);
else { else {
/* Still nothing found, so try a shorter query */ /* Still nothing found, so try a shorter query */
array_pop($newquery); array_pop($newquery);
@ -791,7 +812,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
} }
return $response->withJson(array('count'=>0, 'next'=>null, 'previous'=>null, 'offset'=>0, 'limit'=>$limit, 'results'=>[]), 200); return $this->renderer->json($response, array('count'=>0, 'next'=>null, 'previous'=>null, 'offset'=>0, 'limit'=>$limit, 'results'=>[]))->withStatus(200);
/* Get all documents in the same folder and subfolders /* Get all documents in the same folder and subfolders
$likeid = (int) $params['more_like_id']; $likeid = (int) $params['more_like_id'];
if($likeid && $likedoc = $dms->getDocument($likeid)) { if($likeid && $likedoc = $dms->getDocument($likeid)) {
@ -900,19 +921,19 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
if($offset + $limit < $searchresult['count']) { if($offset + $limit < $searchresult['count']) {
$params['page'] = $page+1; $params['page'] = $page+1;
$next = $request->getUri()->getBasePath().'/api/documents?'.http_build_query($params); $next = $request->getUri()->getPath().'?'.http_build_query($params);
} else } else
$next = null; $next = null;
if($offset > 0) { if($offset > 0) {
$params['page'] = $page-1; $params['page'] = $page-1;
$prev = $request->getUri()->getBasePath().'/api/documents?'.http_build_query($params); $prev = $request->getUri()->getPath().'?'.http_build_query($params);
} else } else
$prev = null; $prev = null;
return $response->withJson(array('count'=>$searchresult['count'], 'next'=>$next, 'previous'=>$prev, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs), 200); return $this->renderer->json($response, array('count'=>$searchresult['count'], 'next'=>$next, 'previous'=>$prev, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs))->withStatus(200);
} }
} }
} }
return $response->withJson('Error', 500); return $response->withStatus(500);
} /* }}} */ } /* }}} */
@ -931,12 +952,12 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if($document->getAccessMode($userobj) >= M_READ) { if($document->getAccessMode($userobj) >= M_READ) {
/* get untruncated content from file */ /* get untruncated content from file */
$rec = $this->__getDocumentData($document, true, true); $rec = $this->__getDocumentData($document, true, true);
return $response->withJson($rec, 200); return $this->renderer->json($response, $rec)->withStatus(200);
} else { } else {
return $response->withStatus(404); return $response->withStatus(404);
} }
} }
return $response->withJson('Error', 500); return $response->withStatus(500);
} /* }}} */ } /* }}} */
/** /**
@ -971,7 +992,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
return $response->withJson($list, 200); return $this->renderer->json($response, $list)->withStatus(200);
} /* }}} */ } /* }}} */
function ui_settings($request, $response) { /* {{{ */ function ui_settings($request, $response) { /* {{{ */
@ -1031,7 +1052,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
'settings'=>array('update_checking'=>array('backend_setting'=>'default')), 'settings'=>array('update_checking'=>array('backend_setting'=>'default')),
); );
*/ */
return $response->withJson($data, 200); return $this->renderer->json($response, $data)->withStatus(200);
} /* }}} */ } /* }}} */
function statstotal($request, $response) { /* {{{ */ function statstotal($request, $response) { /* {{{ */
@ -1042,7 +1063,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$logger = $this->container->get('logger'); $logger = $this->container->get('logger');
if(false === ($categories = $dms->getDocumentCategories())) { if(false === ($categories = $dms->getDocumentCategories())) {
return $response->withJson(array('results'=>null), 500); return $this->renderer->json($response, array('results'=>null))->withStatus(500);
} }
if(!empty($settings->_extensions['paperless']['usehomefolder'])) { if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
@ -1087,11 +1108,12 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
} }
return $response->withJson($data, 200); return $this->renderer->json($response, $data)->withStatus(200);
} /* }}} */ } /* }}} */
function fetch_thumb($request, $response, $args) { /* {{{ */ function fetch_thumb($request, $response, $args) { /* {{{ */
return $response->withRedirect($request->getUri()->getBasePath().'/api/documents/'.$args['id'].'/thumb/', 302); $p = strpos($request->getUri()->getPath(), '/fetch/thumb');
return $response->withHeader('Location', substr($request->getUri()->getPath(), 0, $p).'/api/documents/'.$args['id'].'/thumb/')->withStatus(302);
} /* }}} */ } /* }}} */
function documents_thumb($request, $response, $args) { /* {{{ */ function documents_thumb($request, $response, $args) { /* {{{ */
@ -1118,17 +1140,15 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$previewer->createPreview($object); $previewer->createPreview($object);
$file = $previewer->getFileName($object, $width).".png"; $file = $previewer->getFileName($object, $width).".png";
if(!($fh = @fopen($file, 'rb'))) { if(!file_exists($file))
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'', 'data'=>''))->withStatus(500);
}
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
$response->getBody()->write(file_get_contents($file));
return $response->withHeader('Content-Type', 'image/png') return $response->withHeader('Content-Type', 'image/png')
->withHeader('Content-Description', 'File Transfer') ->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary') ->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Content-Disposition', 'attachment; filename="preview-' . $document->getID() . "-" . $object->getVersion() . "-" . $width . ".png" . '"') ->withHeader('Content-Disposition', 'attachment; filename="preview-' . $document->getID() . "-" . $object->getVersion() . "-" . $width . ".png" . '"')
->withHeader('Content-Length', $previewer->getFilesize($object)) ->withHeader('Content-Length', $previewer->getFilesize($object));
->withBody($stream);
} }
} }
return $response->withStatus(403); return $response->withStatus(403);
@ -1137,7 +1157,8 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
function fetch_doc($request, $response, $args) { /* {{{ */ function fetch_doc($request, $response, $args) { /* {{{ */
$logger = $this->container->get('logger'); $logger = $this->container->get('logger');
$logger->log('Fetch doc '.$args['id'], PEAR_LOG_INFO); $logger->log('Fetch doc '.$args['id'], PEAR_LOG_INFO);
return $response->withRedirect($request->getUri()->getBasePath().'/api/documents/'.$args['id'].'/download/', 302); $p = strpos($request->getUri()->getPath(), '/fetch/doc');
return $response->withHeader('Location', substr($request->getUri()->getPath(), 0, $p).'/api/documents/'.$args['id'].'/download/')->withStatus(302);
} /* }}} */ } /* }}} */
/** /**
@ -1166,8 +1187,8 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
else else
$filename = $document->getName().$lc->getFileType(); $filename = $document->getName().$lc->getFileType();
$file = $dms->contentDir . $lc->getPath(); $file = $dms->contentDir . $lc->getPath();
if(!($fh = @fopen($file, 'rb'))) { if(!file_exists($file)) {
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'', 'data'=>''))->withStatus(500);
} }
$filesize = filesize($dms->contentDir . $lc->getPath()); $filesize = filesize($dms->contentDir . $lc->getPath());
} else { } else {
@ -1180,19 +1201,18 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$previewer->createPreview($lc); $previewer->createPreview($lc);
if(!$previewer->hasPreview($lc)) { if(!$previewer->hasPreview($lc)) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR); $logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'Creating pdf preview failed', 'data'=>''))->withStatus(500);
} else { } else {
$filename = $document->getName().".pdf"; $filename = $document->getName().".pdf";
$file = $previewer->getFileName($lc).".pdf"; $file = $previewer->getFileName($lc).".pdf";
$filesize = filesize($file); if(!file_exists($file)) {
if(!($fh = @fopen($file, 'rb'))) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR); $logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'Creating pdf preview failed', 'data'=>''))->withStatus(500);
}
$filesize = filesize($file);
} }
} }
} $response->getBody()->write(file_get_contents($file));
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', $lc->getMimeType()) return $response->withHeader('Content-Type', $lc->getMimeType())
->withHeader('Content-Description', 'File Transfer') ->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary') ->withHeader('Content-Transfer-Encoding', 'binary')
@ -1200,8 +1220,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
->withHeader('Content-Length', $filesize) ->withHeader('Content-Length', $filesize)
->withHeader('Expires', '0') ->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'no-cache') ->withHeader('Pragma', 'no-cache');
->withBody($stream);
} else { } else {
return $response->withStatus(403); return $response->withStatus(403);
} }
@ -1243,8 +1262,8 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$filename = $document->getName().$lc->getFileType(); $filename = $document->getName().$lc->getFileType();
$file = $dms->contentDir . $lc->getPath(); $file = $dms->contentDir . $lc->getPath();
if(!($fh = @fopen($file, 'rb'))) { if(!file_exists($file)) {
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'', 'data'=>''))->withStatus(500);
} }
$filesize = filesize($dms->contentDir . $lc->getPath()); $filesize = filesize($dms->contentDir . $lc->getPath());
} else { } else {
@ -1257,19 +1276,18 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$previewer->createPreview($lc); $previewer->createPreview($lc);
if(!$previewer->hasPreview($lc)) { if(!$previewer->hasPreview($lc)) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR); $logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'Creating pdf preview failed', 'data'=>''))->withStatus(500);
} else { } else {
$filename = $document->getName().".pdf"; $filename = $document->getName().".pdf";
$file = $previewer->getFileName($lc).".pdf"; $file = $previewer->getFileName($lc).".pdf";
$filesize = filesize($file); if(!file_exists($file)) {
if(!($fh = @fopen($file, 'rb'))) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR); $logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500); return $this->renderer->json($response, array('success'=>false, 'message'=>'Creating pdf preview failed', 'data'=>''))->withStatus(500);
}
$filesize = filesize($file);
} }
} }
} $response->getBody()->write(file_get_contents($file));
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', $lc->getMimeType()) return $response->withHeader('Content-Type', $lc->getMimeType())
->withHeader('Content-Description', 'File Transfer') ->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary') ->withHeader('Content-Transfer-Encoding', 'binary')
@ -1277,8 +1295,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
->withHeader('Content-Length', $filesize) ->withHeader('Content-Length', $filesize)
->withHeader('Expires', '0') ->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'no-cache') ->withHeader('Pragma', 'no-cache');
->withBody($stream);
} else { } else {
return $response->withStatus(403); return $response->withStatus(403);
} }
@ -1304,7 +1321,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if($document->getAccessMode($userobj) >= M_READ) { if($document->getAccessMode($userobj) >= M_READ) {
$lc = $document->getLatestContent(); $lc = $document->getLatestContent();
if($lc) { if($lc) {
return $response->withJson(array( return $this->renderer->json($response, array(
'original_checksum'=>$lc->getChecksum(), 'original_checksum'=>$lc->getChecksum(),
'original_size'=>(int) $lc->getFilesize(), 'original_size'=>(int) $lc->getFilesize(),
'original_mime_type'=>$lc->getMimeType(), 'original_mime_type'=>$lc->getMimeType(),
@ -1317,7 +1334,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
'lang'=>'en', 'lang'=>'en',
'archive_size'=>(int) $lc->getFilesize(), 'archive_size'=>(int) $lc->getFilesize(),
'archive_metadata'=>[], 'archive_metadata'=>[],
), 200); ))->withStatus(200);
} else { } else {
return $response->withStatus(403); return $response->withStatus(403);
} }
@ -1359,7 +1376,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$uploadedFiles = $request->getUploadedFiles(); $uploadedFiles = $request->getUploadedFiles();
if (count($uploadedFiles) == 0) { if (count($uploadedFiles) == 0) {
$logger->log('No files uploaded', PEAR_LOG_ERR); $logger->log('No files uploaded', PEAR_LOG_ERR);
return $response->withJson(getMLText("paperless_no_files_uploaded"), 400); return $this->renderer->json($response, getMLText("paperless_no_files_uploaded"))->withStatus(400);
} }
$file_info = array_pop($uploadedFiles); $file_info = array_pop($uploadedFiles);
@ -1367,7 +1384,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize); $maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize);
if ($maxuploadsize && $file_info->getSize() > $maxuploadsize) { if ($maxuploadsize && $file_info->getSize() > $maxuploadsize) {
$logger->log('File too large ('.$file_info->getSize().' > '.$maxuploadsize.')', PEAR_LOG_ERR); $logger->log('File too large ('.$file_info->getSize().' > '.$maxuploadsize.')', PEAR_LOG_ERR);
return $response->withJson(getMLText("paperless_upload_maxsize"), 400); return $this->renderer->json($response, getMLText("paperless_upload_maxsize"))->withStatus(400);
} }
$origfilename = null; $origfilename = null;
@ -1382,7 +1399,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
if(!$settings->_enableDuplicateDocNames) { if(!$settings->_enableDuplicateDocNames) {
if($mfolder->hasDocumentByName($docname)) { if($mfolder->hasDocumentByName($docname)) {
$logger->log('Duplicate document name '.$docname, PEAR_LOG_ERR); $logger->log('Duplicate document name '.$docname, PEAR_LOG_ERR);
return $response->withJson(getMLText("document_duplicate_name"), 409); return $this->renderer->json($response, getMLText("document_duplicate_name"))->withStatus(409);
} }
} }
/* If several tags are set, they will all be saved individually in /* If several tags are set, they will all be saved individually in
@ -1478,7 +1495,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
$errmsg = $err; $errmsg = $err;
} }
$logger->log('Upload failed: '.$errmsg, PEAR_LOG_ERR); $logger->log('Upload failed: '.$errmsg, PEAR_LOG_ERR);
return $response->withJson(getMLText('paperless_upload_failed'), 500); return $this->renderer->json($response, getMLText('paperless_upload_failed'))->withStatus(500);
} else { } else {
$logger->log('Upload succeeded', PEAR_LOG_INFO); $logger->log('Upload succeeded', PEAR_LOG_INFO);
/* Turn off for now, because file_info is not an array /* Turn off for now, because file_info is not an array
@ -1495,10 +1512,11 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
unlink($userfiletmp); unlink($userfiletmp);
} }
} }
return $response->withJson('OK', 200); $response->getBody()->write('OK');
return $response->withStatus(200);
} }
} }
return $response->withJson(getMLText('paperless_missing_target_folder'), 400); return $this->renderer->json($response, getMLText('paperless_missing_target_folder'))->withStatus(400);
} /* }}} */ } /* }}} */
function patch_documents($request, $response, $args) { /* {{{ */ function patch_documents($request, $response, $args) { /* {{{ */
@ -1601,7 +1619,7 @@ class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
} }
} }
} }
return $response->withJson($this->__getDocumentData($document), 200); return $this->renderer->json($response, $this->__getDocumentData($document), 200);
} /* }}} */ } /* }}} */
function delete_documents($request, $response, $args) { /* {{{ */ function delete_documents($request, $response, $args) { /* {{{ */
@ -1656,8 +1674,11 @@ class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
private $container; private $container;
public function __construct($container) { private $responsefactory;
public function __construct($container, $responsefactory) {
$this->container = $container; $this->container = $container;
$this->responsefactory = $responsefactory;
} }
/** /**
@ -1669,49 +1690,48 @@ class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
* *
* @return \Psr\Http\Message\ResponseInterface * @return \Psr\Http\Message\ResponseInterface
*/ */
public function __invoke($request, $response, $next) { /* {{{ */ public function __invoke($request, $handler) { /* {{{ */
// $this->container has the DI // $this->container has the DI
$dms = $this->container->get('dms'); $dms = $this->container->get('dms');
$settings = $this->container->get('config'); $settings = $this->container->get('config');
$logger = $this->container->get('logger'); $logger = $this->container->get('logger');
$logger->log("Invoke paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO);
/* Skip this middleware if the authentication was already successful */ /* Skip this middleware if the authentication was already successful */
$userobj = null; $userobj = null;
if($this->container->has('userobj')) if($this->container->has('userobj'))
$userobj = $this->container->get('userobj'); $userobj = $this->container->get('userobj');
if($userobj) { $environment = $request->getServerParams();
$response = $next($request, $response); $path = $environment['PATH_INFO'] ?? '';
return $response; if(!$userobj) {
} if(!in_array($path, array('/api/token/', '/api/'))) {
if(!empty($environment['HTTP_AUTHORIZATION'])) {
/* Pretent to be paperless ngx 1.10.0 with api version 2 */ $tmp = explode(' ', $environment['HTTP_AUTHORIZATION'], 2);
$response = $response->withHeader('x-api-version', '2')->withHeader('x-version', '1.13.0');
$logger->log("Invoke paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO);
if(!in_array($request->getUri()->getPath(), array('api/token/', 'api/'))) {
$userobj = null;
if(!empty($this->container->environment['HTTP_AUTHORIZATION'])) {
$tmp = explode(' ', $this->container->environment['HTTP_AUTHORIZATION'], 2);
switch($tmp[0]) { switch($tmp[0]) {
case 'Token': case 'Token':
$logger->log("Token authentication with ".$tmp[0]."=".$tmp[1], PEAR_LOG_INFO);
/* if jwtsecret is set, the token is expected to be a jwt */ /* if jwtsecret is set, the token is expected to be a jwt */
if(!empty($settings->_extensions['paperless']['jwtsecret'])) { if(!empty($settings->_extensions['paperless']['jwtsecret'])) {
$token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']); $token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']);
if(!$tokenstr = $token->jwtDecode($tmp[1])) { if(!$tokenstr = $token->jwtDecode($tmp[1])) {
$logger->log("Could not decode jwt", PEAR_LOG_ERR); $logger->log("Could not decode jwt", PEAR_LOG_ERR);
return $response->withJson("Invalid token", 403); $response = $this->responsefactory->createResponse();
return $this->renderer->json($response, array('success'=>false, 'message'=>'Could not decode token', 'data'=>''))->withStatus(403);
} }
$tmp = explode(':', json_decode($tokenstr, true)); $tmp = explode(':', json_decode($tokenstr, true));
if($tmp[1] < time()) { if($tmp[1] < time()) {
$logger->log("Jwt has expired at ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_ERR); $logger->log("Jwt has expired at ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_ERR);
return $response->withJson(getMLText('paperless_token_has_expired'), 403); $response = $this->responsefactory->createResponse();
return $this->renderer->json($response, getMLText('paperless_token_has_expired'))->withStatus(403);
} else { } else {
$logger->log("Token is valid till ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_DEBUG); $logger->log("Token is valid till ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_DEBUG);
} }
if(!($userobj = $dms->getUser((int) $tmp[0]))) { if(!($userobj = $dms->getUser((int) $tmp[0]))) {
$logger->log("No such user ".$tmp[0], PEAR_LOG_ERR); $logger->log("No such user ".$tmp[0], PEAR_LOG_ERR);
return $response->withJson("No such user", 403); $response = $this->responsefactory->createResponse();
return $this->renderer->json($response, array('success'=>false, 'message'=>'No such user', 'data'=>''))->withStatus(403);
} }
$dms->setUser($userobj); $dms->setUser($userobj);
if($this->container instanceof \Slim\Container) if($this->container instanceof \Slim\Container)
@ -1723,10 +1743,12 @@ class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
if(!empty($settings->_apiKey) && !empty($settings->_apiUserId)) { if(!empty($settings->_apiKey) && !empty($settings->_apiUserId)) {
if($settings->_apiKey == $tmp[1]) { if($settings->_apiKey == $tmp[1]) {
if(!($userobj = $dms->getUser($settings->_apiUserId))) { if(!($userobj = $dms->getUser($settings->_apiUserId))) {
$response = $this->responsefactory->createResponse();
return $response->withStatus(403); return $response->withStatus(403);
} }
} else { } else {
$logger->log("Login with apikey '".$tmp[1]."' failed", PEAR_LOG_ERR); $logger->log("Login with apikey '".$tmp[1]."' failed", PEAR_LOG_ERR);
$response = $this->responsefactory->createResponse();
return $response->withStatus(403); return $response->withStatus(403);
} }
$dms->setUser($userobj); $dms->setUser($userobj);
@ -1739,11 +1761,13 @@ class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
} }
break; break;
case 'Basic': case 'Basic':
$logger->log("Basic authentication with ".$tmp[0]."=".$tmp[1], PEAR_LOG_INFO);
$authenticator = $this->container->get('authenticator'); $authenticator = $this->container->get('authenticator');
$kk = explode(':', base64_decode($tmp[1])); $kk = explode(':', base64_decode($tmp[1]));
$userobj = $authenticator->authenticate($kk[0], $kk[1]); $userobj = $authenticator->authenticate($kk[0], $kk[1]);
if(!$userobj) { if(!$userobj) {
$logger->log("Login with basic authentication for '".$kk[0]."' failed", PEAR_LOG_ERR); $logger->log("Login with basic authentication for '".$kk[0]."' failed", PEAR_LOG_ERR);
$response = $this->responsefactory->createResponse();
return $response->withStatus(403); return $response->withStatus(403);
} }
$dms->setUser($userobj); $dms->setUser($userobj);
@ -1762,8 +1786,24 @@ class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
else else
$this->container->set('userobj', true); $this->container->set('userobj', true);
} }
}
if(!$userobj)
$logger->log("Not yet authenticated. Pass on to next middleware", PEAR_LOG_INFO);
else
$logger->log("Authenticated as ".(is_object($userobj) ? $userobj->getLogin() : "annon").". Pass on to next middleware", PEAR_LOG_INFO);
/* Always pass on to the next middleware. If that middleware does
* authentication, then it should first check if 'userobj' in the container
* is already set. The authentication shipped with seeddms restapi does that
* and skips its own authentication, if userobj already exists.
*/
$response = $handler->handle($request);
/* Pretent to be paperless ngx 1.13.0 with api version 2 */
$response = $response->withHeader('x-api-version', '2')->withHeader('x-version', '1.13.0');
$logger->log("End of paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO); $logger->log("End of paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO);
$response = $next($request, $response);
return $response; return $response;
} /* }}} */ } /* }}} */
} /* }}} */ } /* }}} */
@ -1785,7 +1825,7 @@ class SeedDMS_ExtPaperless_RestAPI { /* {{{ */
*/ */
public function addMiddleware($app) { /* {{{ */ public function addMiddleware($app) { /* {{{ */
$container = $app->getContainer(); $container = $app->getContainer();
$app->add(new SeedDMS_ExtPaperless_RestAPI_Auth($container)); $app->add(new SeedDMS_ExtPaperless_RestAPI_Auth($container, $app->getResponseFactory()));
} /* }}} */ } /* }}} */
/** /**