Skip to content

Commit

Permalink
API spec validation: more parameters, including suffixed
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Sep 12, 2024
1 parent d3a58cd commit 8459eb6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 16 deletions.
11 changes: 10 additions & 1 deletion batch/apispec.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ private function resolve_common_param($name) {
private function expand1($fn, $method, $j) {
$x = (object) [];
$params = $body_properties = $body_required = [];
$has_file = false;
if ($j->paper ?? false) {
$params[] = $this->resolve_common_param("p");
}
Expand All @@ -122,6 +123,10 @@ private function expand1($fn, $method, $j) {
$required = false;
} else if ($p[$i] === "=") {
$in = "body";
} else if ($p[$i] === "@") {
$in = "file";
} else if ($p[$i] === ":") {
// suffixed parameter
} else {
break;
}
Expand All @@ -134,6 +139,9 @@ private function expand1($fn, $method, $j) {
if ($required) {
$body_required[] = $name;
}
if ($in === "file") {
$has_file = true;
}
}
}
if (!empty($params)) {
Expand All @@ -147,9 +155,10 @@ private function expand1($fn, $method, $j) {
if (!empty($body_required)) {
$schema->required = $body_required;
}
$formtype = $has_file ? "multipart/form-data" : "application/x-www-form-urlencoded";
$x->requestBody = (object) [
"content" => (object) [
"application/x-www-form-urlencoded" => (object) [
$formtype => (object) [
"schema" => $schema
]
]
Expand Down
19 changes: 13 additions & 6 deletions etc/apifunctions.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
{
"name": "comment", "paper": true, "post": true,
"function": "Comment_API::run",
"parameters": ["c", "?override", "?=text", "?=response", "?=ready", "?=topic", "?=draft", "?=blind", "?=tags", "?=visibility"]
"parameters": ["c", "?override", "?=text", "?=response", "?=ready", "?=topic", "?=draft", "?=blind", "?=tags", "?=visibility", "?=:attachment", "?=by_author", "?=review_token"]
},
{
"name": "declinereview", "post": true, "redirect": true,
Expand All @@ -60,7 +60,7 @@
{
"name": "events", "get": true,
"function": "Events_API::run",
"parameters": ["?events_at"]
"parameters": ["?from"]
},
{
"name": "fieldtext", "get": true,
Expand All @@ -73,7 +73,8 @@
},
{
"name": "follow", "paper": true, "post": true, "xxx": true,
"function": "Follow_API::run"
"function": "Follow_API::run",
"parameters": ["?u", "=following"]
},
{
"name": "formatcheck", "get": true, "post": true,
Expand Down Expand Up @@ -168,8 +169,14 @@
"function": "Settings_API::reviewfieldlibrary"
},
{
"name": "reviewrating", "paper": true, "get": true, "post": true,
"function": "Review_API::reviewrating"
"name": "reviewrating", "paper": true, "get": true,
"function": "Review_API::reviewrating",
"parameters": ["r"]
},
{
"name": "reviewrating", "paper": true, "post": true,
"function": "Review_API::reviewrating",
"parameters": ["r", "=user_rating"]
},
{
"name": "reviewround", "paper": true, "post": true, "xxx": true,
Expand Down Expand Up @@ -278,7 +285,7 @@
{
"name": "upload", "post": true,
"function": "Upload_API::run",
"parameters": ["?p", "?dtype", "?start", "offset", "?finish", "?token", "?cancel", "?=size", "?=mimetype", "?=filename", "?!blob"]
"parameters": ["?p", "?dtype", "?start", "offset", "?finish", "?token", "?cancel", "?=size", "?=mimetype", "?=filename", "?@blob"]
},
{
"name": "user", "get": true,
Expand Down
8 changes: 5 additions & 3 deletions scripts/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -12252,9 +12252,11 @@ handle_ui.on("js-clickthrough", function () {

handle_ui.on("js-follow-change", function () {
var self = this;
$.post(hoturl("=api/follow",
{p: $(self).attr("data-pid") || siteinfo.paperid}),
{following: this.checked, reviewer: $(self).data("reviewer") || siteinfo.user.email},
$.post(hoturl("=api/follow", {
p: this.getAttribute("data-pid") || siteinfo.paperid,
u: this.getAttribute("data-reviewer") || siteinfo.user.email
}),
{following: this.checked},
function (rv) {
minifeedback(self, rv);
rv.ok && (self.checked = rv.following);
Expand Down
38 changes: 32 additions & 6 deletions src/api/api_specvalidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@ class SpecValidator_API {
const F_REQUIRED = 1;
const F_BODY = 2;
const F_FILE = 4;
const F_SUFFIX = 8;

static function run($uf, Qrequest $qreq) {
$known = [];
$has_suffix = false;
foreach ($uf->parameters ?? [] as $p) {
$flags = self::F_REQUIRED;
for ($i = 0; $i !== strlen($p); ++$i) {
if ($p[$i] === "?") {
$flags &= ~self::F_REQUIRED;
} else if ($p[$i] === "=") {
$flags |= self::F_BODY;
} else if ($p[$i] === "!") {
} else if ($p[$i] === "@") {
$flags |= self::F_FILE;
} else if ($p[$i] === ":") {
$flags |= self::F_SUFFIX;
$has_suffix = true;
} else {
break;
}
Expand All @@ -32,35 +37,56 @@ static function run($uf, Qrequest $qreq) {
}
$param = [];
foreach (array_keys($_GET) as $n) {
if (!isset($known[$n])) {
if (($t = self::lookup_param_type($n, $known, $has_suffix)) === null) {
if (!in_array($n, ["post", "base", "fn", "forceShow", "cap", "actas", "smsg", "_"])
&& ($n !== "p" || !($uf->paper ?? false))
&& !isset($known["*"])) {
self::error($qreq, "query param `{$n}` unknown");
}
} else if (($known[$n] & self::F_BODY) !== 0) {
} else if (($t & self::F_BODY) !== 0) {
self::error($qreq, "query param `{$n}` should be in body");
}
}
foreach (array_keys($_POST) as $n) {
if (!isset($known[$n])) {
if (($t = self::lookup_param_type($n, $known, $has_suffix)) === null) {
if (!isset($known["*"])) {
self::error($qreq, "post param `{$n}` unknown");
}
} else if (!isset($_GET[$n])
&& ($known[$n] & self::F_BODY) === 0) {
&& ($t & self::F_BODY) === 0) {
self::error($qreq, "post param `{$n}` should be in query");
}
}
foreach (array_keys($_FILES) as $n) {
if (!isset($known[$n])) {
if (($t = self::lookup_param_type($n, $known, $has_suffix)) === null
|| ($t & self::F_FILE) === 0) {
if (!isset($known["*"])) {
self::error($qreq, "file param `{$n}` unknown");
}
}
}
}

static function lookup_param_type($n, &$known, $has_suffix) {
if (isset($known[$n])) {
return $known[$n];
}
if (!$has_suffix
|| (($colon = strpos($n, ":")) === false
&& ($slash = strpos($n, "/")) === false)) {
return null;
}
if ($colon === false || ($slash !== false && $colon > $slash)) {
$colon = $slash;
}
$x = substr($n, $colon);
$t = $known[$x] ?? null;
if ($t !== null && ($t & self::F_SUFFIX) !== 0) {
return $t;
}
return null;
}

static function unparse_param_type($n, $flags) {
if (($flags & self::F_FILE) !== 0) {
return "file param";
Expand Down

0 comments on commit 8459eb6

Please sign in to comment.