]> dev.renevier.net Git - syp.git/blob - api.php
web interface to add co-administrators
[syp.git] / api.php
1 <?php
2 /* Copyright (c) 2009 Arnaud Renevier, Inc, published under the modified BSD
3    license. */
4
5 function exit_document ($body) {
6     exit ("<html><head></head><body>$body</body></html>");
7 }
8
9 function success ($reason) {
10     exit_document ("<success request=\"$reason\"></success>");
11 }
12
13 function success_newuser ($username) {
14     $res = "<success request=\"newuser\"><user>" .
15             htmlspecialchars ($user) .
16             "</user></success>";
17     exit_document ($res);
18 }
19
20 function success_auth ($user) {
21     $res = "<success request=\"$reason\"><user>" . 
22             htmlspecialchars ($user) .
23             "</user></success>";
24     exit_document ($res);
25 }
26
27 function success_feature ($feature, $request) {
28     $res = "<success request=\"$request\"><feature>";
29     $res .= "<id>" .  $feature->id .  "</id>";
30
31     $res .= "<imgurl>" .
32              ($feature->imgpath ? 
33                     image_url_from_imgpath ($feature->imgpath)
34                     : "") .
35              "</imgurl>";
36
37     $res .= "<description>" .
38                  htmlspecialchars ($feature->description) .
39                  "</description>";
40
41     // XXX: we do not use <title> because that would be interpreted and
42     // altered by browers html parser
43     $res .= "<heading>" . 
44             htmlspecialchars ($feature->title) .
45             "</heading>";
46
47     $res .= "<lon>" . $feature->lon . "</lon>";
48     $res .= "<lat>" . $feature->lat . "</lat>";
49     $res .= "</feature></success>";
50     exit_document ($res);
51 }
52
53 function success_delete_feature ($feature) {
54     $res = "<success request=\"del\"><feature>";
55     $res .= "<id>" .  $feature->id .  "</id>";
56     $res .= "</feature></success>";
57     exit_document ($res);
58 }
59
60 function error ($reason) {
61     exit_document ("<error reason=\"$reason\"></error>");
62 }
63
64 function error_newuser_exists () {
65     error ("newuser_exists");
66 }
67
68 function error_feature ($id, $reason) {
69     $res = "<error reason=\"$reason\"><feature>";
70     $res .= "<id>" .  $id .  "</id>";
71     $res .= "</feature></error>";
72     exit_document ($res);
73 }
74
75 function error_nochange ($id) {
76     error_feature ($id, "nochange");
77 }
78 function error_unreferenced ($id) {
79     error_feature ($id, "unreferenced");
80 }
81
82 function error_server () {
83     error ("server");
84 }
85
86 function error_unauthorized () {
87     error ("unauthorized");
88 }
89
90 function error_request () {
91     error ("request");
92 }
93
94 function error_file_too_big () {
95     error ("toobig");
96 }
97
98 function error_notanimage () {
99     error ("notimage");
100 }
101
102 function save_uploaded_file ($file, $con) {
103     $dest = "";
104     if (isset ($file) && ($file ["error"] != UPLOAD_ERR_NO_FILE)) {
105         img_check_upload ($file);
106         $dest = unique_file (UPLOADDIR, $file ["name"], $con);
107         if (!isset ($dest) || 
108                 (!move_uploaded_file ($file ["tmp_name"], $dest))) {
109             error_server ();
110         }
111         $mini_dest = getthumbsdir () . "/mini_" . basename_safe ($dest);
112
113         if (!create_thumbnail_or_copy ($dest, $mini_dest)) {
114             error_server ();
115         }
116     }
117     return basename_safe ($dest);
118 }
119
120 function img_check_upload ($file) {
121     if (!is_uploaded_file ($file ["tmp_name"])) {
122         if ($file ["error"] ==  UPLOAD_ERR_INI_SIZE) {
123             error_file_too_big ();
124         } else {
125             error_server ();
126         }
127     }
128     if (!getimagesize ($file ["tmp_name"])) {
129         error_notanimage ();
130     }
131 }
132
133 function delete_image_if_unused ($imgpath, $con) {
134     if (!isset ($imgpath) || (strlen ($imgpath) == 0)) {
135         return;
136     }
137     if ($con->imgpath_exists ($imgpath)) {
138         return;
139     }
140
141     $path = UPLOADDIR . "/" . $imgpath;
142     if (file_exists ($path)) {
143         unlink ($path);
144     }
145
146     $thumb_path = getthumbsdir () . "/mini_" . $imgpath;
147     if (file_exists ($thumb_path)) {
148         unlink ($thumb_path);
149     }
150 }
151
152 function unique_file ($dirname, $relpath, $con) {
153    $relpath = str_replace ('/', '', $relpath); // strip slashes from path
154    $relpath = str_replace ('\\', '', $relpath); // strip antislashes from path
155    $filename = $dirname . '/' . $relpath;
156    $counter = 1;
157
158    $dotpos = strrpos ($relpath, '.');
159    if ($dotpos) {
160        $base = substr ($relpath, 0, $dotpos);
161        $ext = substr ($relpath, $dotpos + 1);
162    } else {
163        $base = $relpath;
164        $ext = "";
165    }
166
167    while ($counter < 1000) {
168        if (!file_exists ($filename) && 
169            !($con->imgpath_exists (basename_safe ($filename)))) {
170            return $filename;
171        } else {
172             $counter++;
173             $filename = $dirname . '/' . $base . '_' . $counter . '.' . $ext;
174        }
175    }
176    // we tried to find an unused filename 1000 times. Give up now.
177    return null;
178 }
179
180 function check_auth ($con, $user, $pwd, $auth_only) {
181     $authentificated = false;
182
183     if (isset ($pwd)) {
184         if ($con->checkpwdmd5 ($user, md5 ($pwd))) {
185             // cookie will be valid for 2 weeks. I've chosen that value
186             // arbitrarily, and it may change in the future.
187             $time = time () + 14 * 60 * 24 * 60;
188             setcookie (sprintf ("%sauth", DBPREFIX), md5 ($pwd), $time, "" , "", false, true);
189             setcookie (sprintf ("%suser", DBPREFIX), $user, $time, "" , "", false, true);
190             $authentificated = true;
191             if ($auth_only) {
192                 success_auth ($user);
193             }
194         } else {
195             error_unauthorized ();
196         }
197     }
198
199     if (!$authentificated && !($con->checkpwdmd5 (
200                              $_COOKIE [sprintf ("%suser",  DBPREFIX)],
201                              $_COOKIE [sprintf ("%sauth",  DBPREFIX)]))) {
202         error_unauthorized ();
203     }
204 }
205
206 function main ($con) {
207     if (!isset ($_POST ["request"])) {
208         error_request ();
209     }
210
211     $pwd = unquote ($_POST ["password"]);
212     $user = unquote ($_POST ["user"]);
213     // does user only want authentication or does he want to do other things
214     $auth_only = ($_POST ["request"] == "auth");
215     check_auth ($con, $user, $pwd, $auth_only);
216     if (!$user) {
217         $user = $_COOKIE [sprintf ("%suser",  DBPREFIX)];
218     }
219
220     switch ($_POST ["request"]) {
221         case "update":
222             $id = $_POST ["fid"];
223             $feature = $con->getfeature ($id);
224             if (!isset ($feature)) {
225                 error_unreferenced ($id);
226             }
227             if ($feature->user != $user) {
228                 error_unauthorized ();
229             }
230
231             // no file uploaded, but editor currently has an image: it means
232             // image was not changed
233             if ($_POST ["keep_img"] == "yes") {
234                 $imgpath = $feature->imgpath;
235             } else {
236                 $imgpath = save_uploaded_file ($_FILES ["image_file"], $con);
237             }
238
239             $lon = $_POST ["lon"];
240             $lat = $_POST ["lat"];
241             $title = unquote ($_POST ["title"]);
242             $description = unquote ($_POST ["description"]);
243
244             try {
245                 $new_feature = new feature ($id, $lon, $lat, $imgpath, $title, $description, 0, $user);
246             } catch (Exception $e) {
247                 error_request ();
248             }
249
250             if (($new_feature->lon == $feature->lon) &&
251                 ($new_feature->lat == $feature->lat) &&
252                 ($new_feature->title == $feature->title) &&
253                 ($new_feature->imgpath == $feature->imgpath) &&
254                 ($new_feature->description == $feature->description)) {
255                 error_nochange ($feature->id);
256             }
257
258             $old_imgpath = "";
259             if ($feature->imgpath && ($feature->imgpath != $new_feature->imgpath)) {
260                 $old_imgpath = $feature->imgpath;
261             }
262
263             try {
264                 $con->save_feature ($new_feature);
265             } catch (Exception $e) {
266                 error_server ();
267             }
268             if ($old_imgpath) {
269                 try {
270                     delete_image_if_unused ($old_imgpath, $con); 
271                 } catch (Exception $e) {}
272             }
273             success_feature ($new_feature, "update");
274         break;
275         case "add":
276             $imgpath = save_uploaded_file ($_FILES ["image_file"], $con);
277
278             $lon = $_POST ["lon"];
279             $lat = $_POST ["lat"];
280             $title = unquote ($_POST ["title"]);
281             $description = unquote ($_POST ["description"]);
282             try {
283                 $feature = new feature (null, $lon, $lat, $imgpath, $title, $description, 0, $user);
284             } catch (Exception $e) {
285                 error_request ();
286             }
287             try {
288                 $feature = $con->save_feature ($feature);
289             } catch (Exception $e) {
290                 error_server ();
291             }
292             success_feature ($feature, "add");
293         break;
294         case "del":
295             $id = $_POST ["fid"];
296             $feature = $con->getfeature ($id);
297             if (!isset ($feature)) {
298                 error_unreferenced ($id);
299             }
300             if ($feature->user != $user) {
301                 error_unauthorized ();
302             }
303             $imgpath = $feature->imgpath;
304
305             try {
306                 $con->delete_feature ($feature);
307             } catch (Exception $e) {
308                 error_server ();
309             }
310
311             try {
312                 delete_image_if_unused ($imgpath, $con);
313             } catch (Exception $e) {}
314
315             success_delete_feature ($feature);
316         case "newuser":
317             if ($user != "admin") {
318                 error_unauthorized ();
319             }
320             $newuser_name = unquote ($_POST ["newuser_name"]);
321             if (!$newuser_name) {
322                 error_request ();
323             }
324             $newuser_password = unquote ($_POST ["newuser_password"]);
325             try {
326                 $con->setpwd ($newuser_name, $newuser_password, false);
327             } catch (Exception $e) {
328                 if ($e->getMessage () == anydbConnection::err_query) {
329                     error_newuser_exists ();
330                 } else {
331                     error_server ();
332                 }
333             }
334             success_newuser ($newuser_name);
335         break;
336         default:
337             error_request();
338         break;
339     }
340
341     error_server ();
342 }
343
344 if (!@include_once ("./inc/settings.php")) {
345     error_server ();
346 }
347 require_once ("./inc/db/mysql.php");
348 require_once ("./inc/utils.php");
349
350 try {
351     $connection->connect (DBHOST, DBUSER, DBPWD, DBNAME, DBPREFIX);
352 } catch (Exception $e) {
353     error_server ();
354 }
355
356 main ($connection);
357 ?>