Subversion Repositories oidplus

Rev

Rev 237 | Rev 243 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
107 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
require_once __DIR__ . '/includes/oidplus.inc.php';
21
 
22
OIDplus::init(false);
23
 
24
header('Content-Type:application/json; charset=utf-8');
25
 
26
try {
150 daniel-mar 27
        OIDplus::db()->transaction_begin();
107 daniel-mar 28
        $handled = false;
29
 
30
        // Action:     (actions defined by plugins)
31
        // Method:     GET / POST
32
        // Parameters: ...
33
        // Outputs:    ...
34
        foreach (OIDplus::getPagePlugins('*') as $plugin) {
35
                $plugin->action($handled);
36
        }
37
 
38
        // Action:     get_description
39
        // Method:     GET / POST
40
        // Parameters: id
41
        // Outputs:    JSON
42
        if (isset($_REQUEST["action"]) && ($_REQUEST['action'] == 'get_description')) {
43
                $handled = true;
44
                if (!isset($_REQUEST['id'])) throw new Exception("Invalid args");
45
                try {
46
                        $out = OIDplus::gui()::generateContentPage($_REQUEST['id']);
47
                } catch(Exception $e) {
48
                        $out = array();
49
                        $out['title'] = 'Error';
50
                        $out['icon'] = 'img/error_big.png';
51
                        $out['text'] = $e->getMessage();
52
                }
53
                echo json_encode($out);
54
        }
55
 
108 daniel-mar 56
        // === jsTree ===
57
 
107 daniel-mar 58
        // Action:     tree_search
59
        // Method:     GET / POST
60
        // Parameters: search
61
        // Outputs:    JSON
62
        if (isset($_REQUEST["action"]) && ($_REQUEST['action'] == 'tree_search')) {
63
                $handled = true;
64
                if (!isset($_REQUEST['search'])) throw new Exception("Invalid args");
108 daniel-mar 65
 
66
                $found = false;
67
                foreach (OIDplus::getPagePlugins('*') as $plugin) {
68
                        $res = $plugin->tree_search($_REQUEST['search']);
69
                        if ($res) {
70
                                echo json_encode($res);
71
                                $found = true;
72
                                break;
73
                        }
107 daniel-mar 74
                }
108 daniel-mar 75
 
76
                if (!$found) {
77
                        echo json_encode(array());
78
                }
107 daniel-mar 79
        }
80
 
81
        // Action:     tree_load
82
        // Method:     GET / POST
83
        // Parameters: id; goto (optional)
84
        // Outputs:    JSON
85
        if (isset($_REQUEST["action"]) && ($_REQUEST['action'] == 'tree_load')) {
86
                $handled = true;
87
                if (!isset($_REQUEST['id'])) throw new Exception("Invalid args");
88
                $json = OIDplusTree::json_tree($_REQUEST['id'], isset($_REQUEST['goto']) ? $_REQUEST['goto'] : '');
89
                echo $json;
90
        }
91
 
92
        // === Admin / RA actions ===
93
 
94
        // Action:     delete_ra
95
        // Method:     POST
96
        // Parameters: email
97
        // Outputs:    Text
98
        if (isset($_POST["action"]) && ($_POST["action"] == "delete_ra")) {
99
                $handled = true;
100
 
101
                $email = $_POST['email'];
102
 
115 daniel-mar 103
                $ra_logged_in = OIDplus::authUtils()->isRaLoggedIn($email);
107 daniel-mar 104
 
115 daniel-mar 105
                if (!OIDplus::authUtils()->isAdminLoggedIn() && !$ra_logged_in) {
106
                        throw new Exception('Authentification error. Please log in.');
107 daniel-mar 107
                }
108
 
115 daniel-mar 109
                if ($ra_logged_in) OIDplus::authUtils()->raLogout($email);
107 daniel-mar 110
 
111
                $ra = new OIDplusRA($email);
112
                $ra->delete();
113
 
115 daniel-mar 114
                OIDplus::logger()->log("RA($email)?/A?", "RA '$email' deleted");
115
 
107 daniel-mar 116
                echo json_encode(array("status" => 0));
117
        }
118
 
119
        // === OID CRUD ===
120
 
121
        // Action:     Delete
122
        // Method:     POST
123
        // Parameters: id
124
        // Outputs:    Text
125
        if (isset($_POST["action"]) && ($_POST["action"] == "Delete")) {
126
                $handled = true;
127
 
128
                $id = $_POST['id'];
129
                $obj = OIDplusObject::parse($id);
179 daniel-mar 130
                if ($obj === null) throw new Exception("DELETE action failed because object '$id' cannot be parsed!");
107 daniel-mar 131
 
184 daniel-mar 132
                // Check if permitted
107 daniel-mar 133
                if (!$obj->userHasParentalWriteRights()) throw new Exception('Authentification error. Please log in as the superior RA to delete this OID.');
150 daniel-mar 134
 
115 daniel-mar 135
                OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "Object '$id' (recursively) deleted");
119 daniel-mar 136
                OIDplus::logger()->log("OIDRA($id)!", "Lost ownership of object '$id' because it was deleted");
227 daniel-mar 137
 
209 daniel-mar 138
                if ($parentObj = $obj->getParent()) {
139
                        OIDplus::logger()->log("OID(".$parentObj->nodeId().")", "Object '$id' (recursively) deleted");
140
                }
227 daniel-mar 141
 
107 daniel-mar 142
                // Delete object
150 daniel-mar 143
                OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
107 daniel-mar 144
 
145
                // Delete orphan stuff
227 daniel-mar 146
                foreach (OIDplus::getEnabledObjectTypes() as $ot) {
107 daniel-mar 147
                        do {
239 daniel-mar 148
                                $res = OIDplus::db()->query("select tchild.id from ".OIDPLUS_TABLENAME_PREFIX."objects tchild " .
149
                                                            "left join ".OIDPLUS_TABLENAME_PREFIX."objects tparent on tparent.id = tchild.parent " .
150
                                                            "where tchild.parent <> ? and tchild.id like ? and tparent.id is null;", array($ot::root(), $ot::root().'%'));
151
                                if ($res->num_rows() == 0) break; // we need to call num_rows() before fetch_array()   [Problem with ODBC/MsSQL]
150 daniel-mar 152
 
236 daniel-mar 153
                                while ($row = $res->fetch_array()) {
119 daniel-mar 154
                                        $id_to_delete = $row['id'];
155
                                        OIDplus::logger()->log("OIDRA($id_to_delete)!", "Lost ownership of object '$id_to_delete' because one of the superior objects ('$id') was recursively deleted");
237 daniel-mar 156
                                        OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id_to_delete));
107 daniel-mar 157
                                }
239 daniel-mar 158
                        } while (true);
107 daniel-mar 159
                }
239 daniel-mar 160
                OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."asn1id where well_known = '0' and oid not in (select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id like 'oid:%');");
161
                OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."iri    where well_known = '0' and oid not in (select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id like 'oid:%');");
107 daniel-mar 162
 
163
                echo json_encode(array("status" => 0));
164
        }
165
 
166
        // Action:     Update
167
        // Method:     POST
204 daniel-mar 168
        // Parameters: id, ra_email, comment, iris, asn1ids, confidential
107 daniel-mar 169
        // Outputs:    Text
170
        if (isset($_POST["action"]) && ($_POST["action"] == "Update")) {
171
                $handled = true;
172
 
173
                $id = $_POST['id'];
174
                $obj = OIDplusObject::parse($id);
179 daniel-mar 175
                if ($obj === null) throw new Exception("UPDATE action failed because object '$id' cannot be parsed!");
107 daniel-mar 176
 
184 daniel-mar 177
                // Check if permitted
115 daniel-mar 178
                if (!$obj->userHasParentalWriteRights()) throw new Exception('Authentification error. Please log in as the superior RA to update this OID.');
179
 
107 daniel-mar 180
                // Validate RA email address
181
                $new_ra = $_POST['ra_email'];
182
                if (!empty($new_ra) && !oidplus_valid_email($new_ra)) {
183
                        throw new Exception('Invalid RA email address');
184
                }
147 daniel-mar 185
 
186
                // First, do a simulation for ASN.1 IDs and IRIs to check if there are any problems (then an Exception will be thrown)
187
                if ($obj::ns() == 'oid') {
188
                        $oid = $obj;
189
 
190
                        $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
191
                        $ids = array_map('trim',$ids);
192
                        $oid->replaceIris($ids, true);
193
 
194
                        $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
195
                        $ids = array_map('trim',$ids);
196
                        $oid->replaceAsn1Ids($ids, true);
197
                }
150 daniel-mar 198
 
147 daniel-mar 199
                // Change RA recursively
150 daniel-mar 200
                $res = OIDplus::db()->query("select ra_email from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
236 daniel-mar 201
                $row = $res->fetch_array();
107 daniel-mar 202
                $current_ra = $row['ra_email'];
115 daniel-mar 203
                if ($new_ra != $current_ra) {
204
                        OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "RA of object '$id' changed from '$current_ra' to '$new_ra'");
119 daniel-mar 205
                        OIDplus::logger()->log("RA($current_ra)!",           "Lost ownership of object '$id' due to RA transfer of superior RA / admin.");
206
                        OIDplus::logger()->log("RA($new_ra)!",               "Gained ownership of object '$id' due to RA transfer of superior RA / admin.");
209 daniel-mar 207
                        if ($parentObj = $obj->getParent()) {
208
                                OIDplus::logger()->log("OID(".$parentObj->nodeId().")", "RA of object '$id' changed from '$current_ra' to '$new_ra'");
209
                        }
115 daniel-mar 210
                        _ra_change_rec($id, $current_ra, $new_ra); // Inherited RAs rekursiv mitändern
211
                }
107 daniel-mar 212
 
209 daniel-mar 213
                // Log if confidentially flag was changed
115 daniel-mar 214
                OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "Identifiers/Confidential flag of object '$id' updated"); // TODO: Check if they were ACTUALLY updated!
209 daniel-mar 215
                if ($parentObj = $obj->getParent()) {
216
                        OIDplus::logger()->log("OID(".$parentObj->nodeId().")", "Identifiers/Confidential flag of object '$id' updated"); // TODO: Check if they were ACTUALLY updated!
217
                }
115 daniel-mar 218
 
147 daniel-mar 219
                // Replace ASN.1 IDs und IRIs
107 daniel-mar 220
                if ($obj::ns() == 'oid') {
221
                        $oid = $obj;
222
 
223
                        $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
224
                        $ids = array_map('trim',$ids);
147 daniel-mar 225
                        $oid->replaceIris($ids, false);
107 daniel-mar 226
 
227
                        $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
228
                        $ids = array_map('trim',$ids);
147 daniel-mar 229
                        $oid->replaceAsn1Ids($ids, false);
227 daniel-mar 230
 
209 daniel-mar 231
                        // TODO: Check if any identifiers have been actually changed,
232
                        // and log it to OID($id), OID($parent), ... (see above)
107 daniel-mar 233
                }
234
 
150 daniel-mar 235
                $confidential = $_POST['confidential'] == 'true';
204 daniel-mar 236
                $comment = $_POST['comment'];
239 daniel-mar 237
                if (OIDplus::db()->slang() == 'mssql') {
238
                        OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET confidential = ?, comment = ?, updated = getdate() WHERE id = ?", array($confidential, $comment, $id));
239
                } else {
240
                        // MySQL + PgSQL
241
                        OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET confidential = ?, comment = ?, updated = now() WHERE id = ?", array($confidential, $comment, $id));
242
                }
107 daniel-mar 243
 
244
                $status = 0;
245
 
246
                if (!empty($new_ra)) {
150 daniel-mar 247
                        $res = OIDplus::db()->query("select ra_name from ".OIDPLUS_TABLENAME_PREFIX."ra where email = ?", array($new_ra));
236 daniel-mar 248
                        if ($res->num_rows() == 0) $status = OIDplus::config()->getValue('ra_invitation_enabled') ? 1 : 2;
107 daniel-mar 249
                }
250
 
251
                echo json_encode(array("status" => $status));
252
        }
253
 
254
        // Action:     Update2
255
        // Method:     POST
256
        // Parameters: id, title, description
257
        // Outputs:    Text
258
        if (isset($_POST["action"]) && ($_POST["action"] == "Update2")) {
259
                $handled = true;
260
 
261
                $id = $_POST['id'];
262
                $obj = OIDplusObject::parse($id);
179 daniel-mar 263
                if ($obj === null) throw new Exception("UPDATE2 action failed because object '$id' cannot be parsed!");
107 daniel-mar 264
 
150 daniel-mar 265
                // Check if allowed
107 daniel-mar 266
                if (!$obj->userHasWriteRights()) throw new Exception('Authentification error. Please log in as the RA to update this OID.');
150 daniel-mar 267
 
119 daniel-mar 268
                OIDplus::logger()->log("OID($id)+OIDRA($id)?/A?", "Title/Description of object '$id' updated");
107 daniel-mar 269
 
239 daniel-mar 270
                if (OIDplus::db()->slang() == 'mssql') {
271
                        OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET title = ?, description = ?, updated = getdate() WHERE id = ?", array($_POST['title'], $_POST['description'], $id));
272
                } else {
273
                        // MySQL + PgSQL
274
                        OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET title = ?, description = ?, updated = now() WHERE id = ?", array($_POST['title'], $_POST['description'], $id));
275
                }
107 daniel-mar 276
 
277
                echo json_encode(array("status" => 0));
278
        }
279
 
280
        // Action:     Insert
281
        // Method:     POST
282
        // Parameters: parent, id, ra_email, confidential, iris, asn1ids
283
        // Outputs:    Text
284
        if (isset($_POST["action"]) && ($_POST["action"] == "Insert")) {
285
                $handled = true;
286
 
150 daniel-mar 287
                // Validated are: ID, ra email, asn1 ids, iri ids
107 daniel-mar 288
 
289
                // Check if you have write rights on the parent (to create a new object)
290
                $objParent = OIDplusObject::parse($_POST['parent']);
187 daniel-mar 291
                if ($objParent === null) throw new Exception("INSERT action failed because parent object '".$_POST['parent']."' cannot be parsed!");
107 daniel-mar 292
                if (!$objParent->userHasWriteRights()) throw new Exception('Authentification error. Please log in as the correct RA to insert an OID at this arc.');
293
 
294
                // Check if the ID is valid
295
                if ($_POST['id'] == '') throw new Exception('ID may not be empty');
150 daniel-mar 296
 
204 daniel-mar 297
                // Determine absolute OID name
107 daniel-mar 298
                // Note: At addString() and parse(), the syntax of the ID will be checked
299
                $id = $objParent->addString($_POST['id']);
147 daniel-mar 300
 
301
                // Check, if the OID exists
150 daniel-mar 302
                $test = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
236 daniel-mar 303
                if ($test->num_rows() >= 1) {
147 daniel-mar 304
                        throw new Exception("Object $id already exists!");
305
                }
306
 
107 daniel-mar 307
                $obj = OIDplusObject::parse($id);
179 daniel-mar 308
                if ($obj === null) throw new Exception("INSERT action failed because object '$id' cannot be parsed!");
107 daniel-mar 309
 
147 daniel-mar 310
                // First simulate if there are any problems of ASN.1 IDs und IRIs
311
                if ($obj::ns() == 'oid') {
312
                        $oid = $obj;
313
 
314
                        $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
315
                        $ids = array_map('trim',$ids);
316
                        $oid->replaceIris($ids, true);
317
 
318
                        $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
319
                        $ids = array_map('trim',$ids);
320
                        $oid->replaceAsn1Ids($ids, true);
321
                }
322
 
204 daniel-mar 323
                // Apply superior RA change
107 daniel-mar 324
                $parent = $_POST['parent'];
325
                $ra_email = $_POST['ra_email'];
326
                if (!empty($ra_email) && !oidplus_valid_email($ra_email)) {
327
                        throw new Exception('Invalid RA email address');
328
                }
115 daniel-mar 329
 
119 daniel-mar 330
                OIDplus::logger()->log("OID($parent)+OID($id)+OIDRA($parent)?/A?", "Object '$id' created, ".(empty($ra_email) ? "without defined RA" : "given to RA '$ra_email'")).", superior object is '$parent'";
331
                if (!empty($ra_email)) {
332
                        OIDplus::logger()->log("RA($ra_email)!", "Gained ownership of newly created object '$id'");
333
                }
115 daniel-mar 334
 
239 daniel-mar 335
                $confidential = $_POST['confidential'] == 'true';
204 daniel-mar 336
                $comment = $_POST['comment'];
239 daniel-mar 337
                $title = '';
338
                $description = '';
339
 
340
                if (OIDplus::db()->slang() == 'mssql') {
341
                        OIDplus::db()->query("INSERT INTO ".OIDPLUS_TABLENAME_PREFIX."objects (id, parent, ra_email, confidential, comment, created, title, description) VALUES (?, ?, ?, ?, ?, getdate(), ?, ?)", array($id, $parent, $ra_email, $confidential, $comment, $title, $description));
342
                } else {
343
                        // MySQL + PgSQL
344
                        OIDplus::db()->query("INSERT INTO ".OIDPLUS_TABLENAME_PREFIX."objects (id, parent, ra_email, confidential, comment, created, title, description) VALUES (?, ?, ?, ?, ?, now(), ?, ?)", array($id, $parent, $ra_email, $confidential, $comment, $title, $description));
345
                }
107 daniel-mar 346
 
147 daniel-mar 347
                // Set ASN.1 IDs und IRIs
107 daniel-mar 348
                if ($obj::ns() == 'oid') {
349
                        $oid = $obj;
350
 
351
                        $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
352
                        $ids = array_map('trim',$ids);
147 daniel-mar 353
                        $oid->replaceIris($ids, false);
107 daniel-mar 354
 
355
                        $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
356
                        $ids = array_map('trim',$ids);
147 daniel-mar 357
                        $oid->replaceAsn1Ids($ids, false);
107 daniel-mar 358
                }
359
 
360
                $status = 0;
176 daniel-mar 361
 
107 daniel-mar 362
                if (!empty($ra_email)) {
115 daniel-mar 363
                        // Do we need to notify that the RA does not exist?
150 daniel-mar 364
                        $res = OIDplus::db()->query("select ra_name from ".OIDPLUS_TABLENAME_PREFIX."ra where email = ?", array($ra_email));
236 daniel-mar 365
                        if ($res->num_rows() == 0) $status = OIDplus::config()->getValue('ra_invitation_enabled') ? 1 : 2;
107 daniel-mar 366
                }
367
 
368
                echo json_encode(array("status" => $status));
369
        }
370
 
371
        if (!$handled) {
372
                throw new Exception('Invalid action ID');
373
        }
150 daniel-mar 374
 
375
        OIDplus::db()->transaction_commit();
107 daniel-mar 376
} catch (Exception $e) {
239 daniel-mar 377
        try {
378
                OIDplus::db()->transaction_rollback();
379
        } catch (Exception $e1) {
380
        }
381
 
107 daniel-mar 382
        $ary = array();
383
        $ary['error'] = $e->getMessage();
239 daniel-mar 384
        $out = json_encode($ary);
385
 
386
        if ($out === false) {
387
                // Some modules (like ODBC) might output non-UTF8 data
388
                $ary['error'] = utf8_encode($e->getMessage());
389
                $out = json_encode($ary);
390
        }
391
 
392
        die($out);
107 daniel-mar 393
}
394
 
395
# ---
396
 
397
function _ra_change_rec($id, $old_ra, $new_ra) {
239 daniel-mar 398
        if (OIDplus::db()->slang() == 'mssql') {
399
                OIDplus::db()->query("update ".OIDPLUS_TABLENAME_PREFIX."objects set ra_email = ?, updated = getdate() where id = ? and ifnull(ra_email,'') = ?", array($new_ra, $id, $old_ra));
400
        } else {
401
                // MySQL + PgSQL
402
                OIDplus::db()->query("update ".OIDPLUS_TABLENAME_PREFIX."objects set ra_email = ?, updated = now() where id = ? and ifnull(ra_email,'') = ?", array($new_ra, $id, $old_ra));
403
        }
107 daniel-mar 404
 
150 daniel-mar 405
        $res = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where parent = ? and ifnull(ra_email,'') = ?", array($id, $old_ra));
236 daniel-mar 406
        while ($row = $res->fetch_array()) {
107 daniel-mar 407
                _ra_change_rec($row['id'], $old_ra, $new_ra);
408
        }
409
}