a58e8166c8f057249334291d64d046a0802c9353
[WebKit-https.git] / Websites / perf.webkit.org / public / include / json-header.php
1 <?php
2
3 require_once('db.php');
4 require_once('test-path-resolver.php');
5
6 header('Content-type: application/json');
7
8 function exit_with_error($status, $details = array()) {
9     $details['status'] = $status;
10     merge_additional_details($details);
11
12     echo json_encode($details);
13     exit(1);
14 }
15
16 function success_json($details = array()) {
17     $details['status'] = 'OK';
18     merge_additional_details($details);
19
20     return json_encode($details);
21 }
22
23 function exit_with_success($details = array()) {
24     echo success_json($details);
25     exit(0);
26 }
27
28 $additional_exit_details = array();
29
30 function set_exit_detail($name, $value) {
31     global $additional_exit_details;
32     $additional_exit_details[$name] = $value;
33 }
34
35 function merge_additional_details(&$details) {
36     global $additional_exit_details;
37     foreach ($additional_exit_details as $name => $value) {
38         if (!array_key_exists($name, $details))
39             $details[$name] = $value;
40     }
41 }
42
43 function connect() {
44     $db = new Database;
45     if (!$db->connect())
46         exit_with_error('DatabaseConnectionError');
47     return $db;
48 }
49
50 function camel_case_words_separated_by_underscore($name) {
51     return implode('', array_map('ucfirst', explode('_', $name)));
52 }
53
54 function require_format($name, $value, $pattern) {
55     if (!preg_match($pattern, $value))
56         exit_with_error('Invalid' . $name, array('value' => $value));
57 }
58
59 function require_match_one_of_values($name, $value, $valid_values) {
60     if (!in_array($value, $valid_values))
61         exit_with_error('Invalid' . $name, array('value' => $value));
62 }
63
64 function require_existence_of($array, $list_of_arguments, $prefix = '') {
65     if ($prefix)
66         $prefix .= '_';
67     foreach ($list_of_arguments as $key => $pattern) {
68         $name = camel_case_words_separated_by_underscore($prefix . $key);
69         if (!array_key_exists($key, $array))
70             exit_with_error($name . 'NotSpecified');
71         require_format($name, $array[$key], $pattern);
72     }
73 }
74
75 function ensure_privileged_api_data() {
76     global $HTTP_RAW_POST_DATA;
77
78     if ($_SERVER['REQUEST_METHOD'] != 'POST')
79         exit_with_error('InvalidRequestMethod');
80
81     if (!isset($HTTP_RAW_POST_DATA))
82         exit_with_error('InvalidRequestContent');
83
84     $data = json_decode($HTTP_RAW_POST_DATA, true);
85
86     if ($data === NULL)
87         exit_with_error('InvalidRequestContent');
88
89     return $data;
90 }
91
92 function ensure_privileged_api_data_and_token() {
93     $data = ensure_privileged_api_data();
94     if (!verify_token(array_get($data, 'token')))
95         exit_with_error('InvalidToken');
96     return $data;
97 }
98
99 function remote_user_name() {
100     return array_get($_SERVER, 'REMOTE_USER');
101 }
102
103 function compute_token() {
104     if (!array_key_exists('CSRFSalt', $_COOKIE) || !array_key_exists('CSRFExpiration', $_COOKIE))
105         return NULL;
106     $user = remote_user_name();
107     $salt = $_COOKIE['CSRFSalt'];
108     $expiration = $_COOKIE['CSRFExpiration'];
109     return hash('sha256', "$salt|$user|$expiration");
110 }
111
112 function verify_token($token) {
113     $expected_token = compute_token();
114     return $expected_token && $token == $expected_token && $_COOKIE['CSRFExpiration'] > time();
115 }
116
117 function verify_slave($db, $params) {
118     array_key_exists('slaveName', $params) or exit_with_error('MissingSlaveName');
119     array_key_exists('slavePassword', $params) or exit_with_error('MissingSlavePassword');
120
121     $slave_info = array(
122         'name' => $params['slaveName'],
123         'password_hash' => hash('sha256', $params['slavePassword'])
124     );
125
126     $matched_slave = $db->select_first_row('build_slaves', 'slave', $slave_info);
127     if (!$matched_slave)
128         exit_with_error('SlaveNotFound', array('name' => $slave_info['name']));
129 }
130
131 function find_triggerable_for_task($db, $task_id) {
132     $task_id = intval($task_id);
133
134     $test_rows = $db->query_and_fetch_all('SELECT metric_test AS "test", task_platform as "platform"
135         FROM analysis_tasks JOIN test_metrics ON task_metric = metric_id WHERE task_id = $1', array($task_id));
136     if (!$test_rows)
137         return NULL;
138     $target_test_id = $test_rows[0]['test'];
139     $platform_id = $test_rows[0]['platform'];
140
141     $path_resolver = new TestPathResolver($db);
142     $test_ids = $path_resolver->ancestors_for_test($target_test_id);
143
144     $results = $db->query_and_fetch_all('SELECT trigconfig_triggerable AS "triggerable", trigconfig_test AS "test"
145         FROM triggerable_configurations WHERE trigconfig_platform = $1 AND trigconfig_test = ANY($2)',
146         array($platform_id, '{' . implode(', ', $test_ids) . '}'));
147     if (!$results)
148         return NULL;
149
150     $test_to_triggerable = array();
151     foreach ($results as $row)
152         $test_to_triggerable[$row['test']] = $row['triggerable'];
153
154     foreach ($test_ids as $test_id) {
155         $triggerable = array_get($test_to_triggerable, $test_id);
156         if ($triggerable)
157             return array('id' => $triggerable, 'test' => $test_id, 'platform' => $platform_id);
158     }
159
160     return NULL;
161 }
162
163 ?>