1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-04-23 11:52:59 +02:00
joplin/src/AppBundle/Controller/ApiController.php

187 lines
5.7 KiB
PHP
Raw Normal View History

2016-10-19 16:54:41 +01:00
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use AppBundle\Model\BaseModel;
use AppBundle\Model\Session;
use AppBundle\Model\User;
use AppBundle\Exception\ForbiddenException;
use AppBundle\Exception\UnauthorizedException;
use Illuminate\Database\Eloquent\Collection;
use AppBundle\Exception\BaseException;
abstract class ApiController extends Controller {
protected $db = null;
protected $session = null;
protected $user = null;
private $useTestUserAndSession = true;
private $testClientNum = 1;
public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null) {
parent::setContainer($container);
set_exception_handler(function($e) {
if ($e instanceof BaseException) {
$r = $e->toJsonResponse();
$r->send();
echo "\n";
} else {
$msg = array();
$msg[] = 'Exception: ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine();
$msg[] = '';
$msg[] = $e->getTraceAsString();
echo implode("\n", $msg);
echo "\n";
}
});
// 1. client 1 : bla bla bla
// 2. client 2 : bla bla bla fromclient2
// 3. client 1 : client1bla bla bla
// RESULT: client1bla bla bla
// Because diff for 3 is done between 2 and 3
// Need to introduce revID so that Change class knows between which versions the diff should be made
// HACK: get connection once here so that it's initialized and can
// be accessed from models.
$this->db = $this->get('app.eloquent')->connection();
$s = $this->session();
// TODO: to keep it simple, only respond to logged in users, but in theory some data
// could be public.
if (!$s || !$this->user()) throw new UnauthorizedException('A session and user are required');
BaseModel::setClientId($s ? $s->client_id : 0);
}
protected function session() {
if ($this->useTestUserAndSession) {
$session = Session::find(Session::unhex('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'));
if ($session) $session->delete();
$session = new Session();
$session->id = Session::unhex('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB');
$session->owner_id = Session::unhex('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
$session->client_id = Session::unhex($this->testClientNum == 1 ? 'C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1' : 'C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2');
$session->save();
return $session;
}
if ($this->session) return $this->session;
$request = $this->container->get('request_stack')->getCurrentRequest();
$this->session = Session::find(BaseModel::unhex($request->query->get('session')));
return $this->session;
}
protected function user() {
if ($this->useTestUserAndSession) {
$user = User::find(User::unhex('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'));
if (!$user) {
$user = new User();
$user->id = User::unhex('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
$user->owner_id = $user->id;
$user->email = 'test@example.com';
$user->password = Session::hashPassword('12345678');
$user->save();
}
return $user;
}
if ($this->user) return $this->user;
$s = $this->session();
$this->user = $s ? $s->owner() : null;
return $this->user;
}
2016-12-23 18:47:38 +01:00
protected function userId() {
$u = $this->user();
return $u ? $u->id : 0;
}
2016-10-19 16:54:41 +01:00
protected function aclCheck($resource) {
if (!is_array($resource)) $resource = array($resource);
$user = $this->user();
if (!$user) throw new ForbiddenException();
foreach ($resource as $r) {
if (!isset($r->owner_id)) continue;
if ($r->owner_id != $user->id) throw new ForbiddenException();
}
}
static protected function successResponse($data = null) {
2016-10-26 16:03:26 +01:00
$output = BaseModel::anythingToPublicArray($data);
2016-10-19 16:54:41 +01:00
return new JsonResponse($output);
}
static protected function errorResponse($message, $errorCode = 0, $httpCode = 400) {
$o = array('error' => $message, 'code' => $errorCode);
$response = new JsonResponse($o);
$response->setStatusCode($httpCode);
return $response;
}
protected function multipleValues($v) {
if ($v === null || $v === false) return array();
if (strpos((string)$v, ';') === false) return array($v);
return explode(';', $v);
}
// PHP doesn't parse PATCH and PUT requests automatically, so it needs
// to be done manually.
// http://stackoverflow.com/a/5488449/561309
protected function patchParameters() {
$output = array();
$input = file_get_contents('php://input');
preg_match('/boundary=(.*)$/', $_SERVER['CONTENT_TYPE'], $matches);
$boundary = $matches[1];
$blocks = preg_split("/-+$boundary/", $input);
array_pop($blocks);
foreach ($blocks as $id => $block) {
if (empty($block)) continue;
// you'll have to var_dump $block to understand this and maybe replace \n or \r with a visibile char
// parse uploaded files
if (strpos($block, 'application/octet-stream') !== FALSE) {
// match "name", then everything after "stream" (optional) except for prepending newlines
preg_match("/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s", $block, $matches);
} else {
// match "name" and optional value in between newline sequences
preg_match('/name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?\r$/s', $block, $matches);
}
if (!isset($matches[2])) {
// Regex above will not find anything if the parameter has not value. For example
// "parent_id" below:
// Content-Disposition: form-data; name="parent_id"
//
//
// Content-Disposition: form-data; name="id"
//
// 54ad197be333c98778c7d6f49506efcb
$output[$matches[1]] = '';
} else {
$output[$matches[1]] = $matches[2];
}
}
return $output;
}
protected function putParameters() {
return $this->patchParameters();
}
}