-
Notifications
You must be signed in to change notification settings - Fork 4
/
api.php
126 lines (116 loc) · 4.41 KB
/
api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?php
// api.php -- HotCRP JSON API access page
// Copyright (c) 2006-2019 Eddie Kohler; see LICENSE.
require_once("src/initweb.php");
class APIRequest {
/** @var Conf */
public $conf;
/** @var Contact */
public $viewer;
/** @var Qrequest */
public $qreq;
function __construct(Contact $viewer, Qrequest $qreq) {
$this->conf = $viewer->conf;
$this->viewer = $viewer;
$this->qreq = $qreq;
if ($qreq->base !== null) {
$this->conf->set_site_path_relative($qreq->navigation(), $qreq->base);
}
if ($qreq->path_component(0)
&& substr($qreq->path_component(0), 0, 1) === "~") {
$qreq->u = substr(urldecode($qreq->shift_path_components(1)), 2);
}
if (($x = $qreq->shift_path_components(1))) {
$qreq->fn = urldecode(substr($x, 1));
}
if (($x = $qreq->shift_path_components(1))) {
if (!$qreq->pset) {
$qreq->pset = urldecode(substr($x, 1));
}
if (($x = $qreq->shift_path_components(1))) {
if (!$qreq->commit) {
$qreq->commit = urldecode(substr($x, 1));
}
}
}
}
function run() {
$api = new APIData($this->viewer);
// check user
if ($this->qreq->u) {
$user = $this->conf->user_by_whatever($this->qreq->u);
if (!$this->viewer->isPC
&& (!$user || $user->contactId !== $this->viewer->contactId)) {
return ["ok" => false, "error" => "Permission denied"];
} else if (!$user) {
return ["ok" => false, "error" => "User not found"];
} else {
$user->set_anonymous(substr($this->qreq->u, 0, 5) === "[anon");
$api->user = $user;
}
}
// check pset
if ($this->qreq->pset
&& !($api->pset = $this->conf->pset_by_key($this->qreq->pset))) {
return ["ok" => false, "error" => "Pset not found"];
}
if ($api->pset && $api->pset->disabled && !$this->viewer->privChair) {
if ($this->viewer->isPC) {
return ["ok" => false, "error" => "Pset disabled"];
} else {
return ["ok" => false, "error" => "Pset not found"];
}
} else if ($api->pset && !$api->pset->visible && !$this->viewer->isPC) {
return ["ok" => false, "error" => "Pset not found"];
}
// check commit
if ($api->pset && !$api->pset->gitless && !$this->viewer->is_empty()) {
$api->repo = $api->user->repo($api->pset);
$api->branch = $api->user->branch($api->pset);
}
if ($api->repo && $this->qreq->commit) {
$api->hash = $this->qreq->commit;
}
// call api
$uf = $this->conf->api($this->qreq->fn);
if (!$uf
&& $api->pset) {
$uf = $api->pset->api[$this->qreq->fn] ?? null;
}
if (!$uf
&& is_object($this->conf->config->_api ?? null)) {
$uf = $this->conf->config->_api->{$this->qreq->fn} ?? null;
}
if ($uf
&& $api->pset
&& $api->pset->disabled
&& !($uf->anypset ?? false)) {
return ["ok" => false, "error" => "Pset disabled"];
}
if ($uf
&& ($uf->redirect ?? false)
&& $this->qreq->redirect
&& preg_match('/\A(?![a-z]+:|\/).+/', $this->qreq->redirect)) {
try {
JsonResultException::$capturing = true;
$j = $this->conf->call_api($uf, $this->viewer, $this->qreq, $api);
} catch (JsonResultException $ex) {
$j = $ex->result;
}
if (is_object($j) && $j instanceof JsonResult) {
$j = $j->content;
}
if (!($j->ok ?? false) && !($j->error ?? false)) {
Conf::msg_error("Internal error");
} else if (($x = $j->error ?? false)) {
Conf::msg_error(htmlspecialchars($x));
} else if (($x = $j->error_html ?? false)) {
Conf::msg_error($x);
}
$this->conf->redirect($this->conf->make_absolute_site($this->qreq->redirect));
} else {
return $this->conf->call_api($uf, $this->viewer, $this->qreq, $api);
}
}
}
json_exit((new APIRequest($Me, $Qreq))->run());