Subversion Repositories oidplus

Rev

Rev 147 | Rev 155 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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 {
  27.         OIDplus::db()->transaction_begin();
  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.  
  56.         // === jsTree ===
  57.  
  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");
  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.                         }
  74.                 }
  75.  
  76.                 if (!$found) {
  77.                         echo json_encode(array());
  78.                 }
  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.  
  103.                 $ra_logged_in = OIDplus::authUtils()->isRaLoggedIn($email);
  104.  
  105.                 if (!OIDplus::authUtils()->isAdminLoggedIn() && !$ra_logged_in) {
  106.                         throw new Exception('Authentification error. Please log in.');
  107.                 }
  108.  
  109.                 if ($ra_logged_in) OIDplus::authUtils()->raLogout($email);
  110.  
  111.                 $ra = new OIDplusRA($email);
  112.                 $ra->delete();
  113.  
  114.                 OIDplus::logger()->log("RA($email)?/A?", "RA '$email' deleted");
  115.  
  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);
  130.  
  131.                 // Prüfen ob zugelassen
  132.                 if (!$obj->userHasParentalWriteRights()) throw new Exception('Authentification error. Please log in as the superior RA to delete this OID.');
  133.  
  134.                 OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "Object '$id' (recursively) deleted");
  135.                 OIDplus::logger()->log("OIDRA($id)!", "Lost ownership of object '$id' because it was deleted");
  136.  
  137.                 // Delete object
  138.                 OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
  139.  
  140.                 // Delete orphan stuff
  141.                 foreach (OIDplus::getRegisteredObjectTypes() as $ot) {
  142.                         do {
  143.                                 $res = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where parent <> ? and parent like ? and parent not in (select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id like ?)", array($ot::root(), $ot::root().'%', $ot::root().'%'));
  144.  
  145.                                 while ($row = OIDplus::db()->fetch_array($res)) {
  146.                                         $id_to_delete = $row['id'];
  147.                                         OIDplus::logger()->log("OIDRA($id_to_delete)!", "Lost ownership of object '$id_to_delete' because one of the superior objects ('$id') was recursively deleted");
  148.                                         if (!OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id_to_delete))) {
  149.                                                 throw new Exception(OIDplus::db()->error());
  150.                                         }
  151.                                 }
  152.                         } while (OIDplus::db()->num_rows($res) > 0);
  153.                 }
  154.                 OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."asn1id where well_known <> 1 and oid not in (select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id like 'oid:%');");
  155.                 OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."iri    where well_known <> 1 and oid not in (select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id like 'oid:%');");
  156.  
  157.                 echo json_encode(array("status" => 0));
  158.         }
  159.  
  160.         // Action:     Update
  161.         // Method:     POST
  162.         // Parameters: id, ra_email, iris, asn1ids, confidential
  163.         // Outputs:    Text
  164.         if (isset($_POST["action"]) && ($_POST["action"] == "Update")) {
  165.                 $handled = true;
  166.  
  167.                 $id = $_POST['id'];
  168.                 $obj = OIDplusObject::parse($id);
  169.  
  170.                 // Prüfen ob zugelassen
  171.                 if (!$obj->userHasParentalWriteRights()) throw new Exception('Authentification error. Please log in as the superior RA to update this OID.');
  172.  
  173.                 // Validate RA email address
  174.                 $new_ra = $_POST['ra_email'];
  175.                 if (!empty($new_ra) && !oidplus_valid_email($new_ra)) {
  176.                         throw new Exception('Invalid RA email address');
  177.                 }
  178.  
  179.                 // First, do a simulation for ASN.1 IDs and IRIs to check if there are any problems (then an Exception will be thrown)
  180.                 if ($obj::ns() == 'oid') {
  181.                         $oid = $obj;
  182.  
  183.                         $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
  184.                         $ids = array_map('trim',$ids);
  185.                         $oid->replaceIris($ids, true);
  186.  
  187.                         $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
  188.                         $ids = array_map('trim',$ids);
  189.                         $oid->replaceAsn1Ids($ids, true);
  190.                 }
  191.  
  192.                 // Change RA recursively
  193.                 $res = OIDplus::db()->query("select ra_email from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
  194.                 $row = OIDplus::db()->fetch_array($res);
  195.                 $current_ra = $row['ra_email'];
  196.                 if ($new_ra != $current_ra) {
  197.                         OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "RA of object '$id' changed from '$current_ra' to '$new_ra'");
  198.                         OIDplus::logger()->log("RA($current_ra)!",           "Lost ownership of object '$id' due to RA transfer of superior RA / admin.");
  199.                         OIDplus::logger()->log("RA($new_ra)!",               "Gained ownership of object '$id' due to RA transfer of superior RA / admin.");
  200.                         _ra_change_rec($id, $current_ra, $new_ra); // Inherited RAs rekursiv mitändern
  201.                 }
  202.  
  203.                 OIDplus::logger()->log("OID($id)+SUPOIDRA($id)?/A?", "Identifiers/Confidential flag of object '$id' updated"); // TODO: Check if they were ACTUALLY updated!
  204.  
  205.                 // Replace ASN.1 IDs und IRIs
  206.                 if ($obj::ns() == 'oid') {
  207.                         $oid = $obj;
  208.  
  209.                         $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
  210.                         $ids = array_map('trim',$ids);
  211.                         $oid->replaceIris($ids, false);
  212.  
  213.                         $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
  214.                         $ids = array_map('trim',$ids);
  215.                         $oid->replaceAsn1Ids($ids, false);
  216.                 }
  217.  
  218.                 $confidential = $_POST['confidential'] == 'true';
  219.                 if (!OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET confidential = ?, updated = now() WHERE id = ?", array($confidential, $id))) {
  220.                         throw new Exception('Error at setting confidential flag:' . OIDplus::db()->error());
  221.                 }
  222.  
  223.                 $status = 0;
  224.  
  225.                 if (!empty($new_ra)) {
  226.                         $res = OIDplus::db()->query("select ra_name from ".OIDPLUS_TABLENAME_PREFIX."ra where email = ?", array($new_ra));
  227.                         if (OIDplus::db()->num_rows($res) == 0) $status = 1;
  228.                 }
  229.  
  230.                 echo json_encode(array("status" => $status));
  231.         }
  232.  
  233.         // Action:     Update2
  234.         // Method:     POST
  235.         // Parameters: id, title, description
  236.         // Outputs:    Text
  237.         if (isset($_POST["action"]) && ($_POST["action"] == "Update2")) {
  238.                 $handled = true;
  239.  
  240.                 $id = $_POST['id'];
  241.                 $obj = OIDplusObject::parse($id);
  242.  
  243.                 // Check if allowed
  244.                 if (!$obj->userHasWriteRights()) throw new Exception('Authentification error. Please log in as the RA to update this OID.');
  245.  
  246.                 OIDplus::logger()->log("OID($id)+OIDRA($id)?/A?", "Title/Description of object '$id' updated");
  247.  
  248.                 if (!OIDplus::db()->query("UPDATE ".OIDPLUS_TABLENAME_PREFIX."objects SET title = ?, description = ?, updated = now() WHERE id = ?", array($_POST['title'], $_POST['description'], $id))) {
  249.                         throw new Exception(OIDplus::db()->error());
  250.                 }
  251.  
  252.                 echo json_encode(array("status" => 0));
  253.         }
  254.  
  255.         // Action:     Insert
  256.         // Method:     POST
  257.         // Parameters: parent, id, ra_email, confidential, iris, asn1ids
  258.         // Outputs:    Text
  259.         if (isset($_POST["action"]) && ($_POST["action"] == "Insert")) {
  260.                 $handled = true;
  261.  
  262.                 // Validated are: ID, ra email, asn1 ids, iri ids
  263.  
  264.                 // Check if you have write rights on the parent (to create a new object)
  265.                 $objParent = OIDplusObject::parse($_POST['parent']);
  266.                 if (!$objParent->userHasWriteRights()) throw new Exception('Authentification error. Please log in as the correct RA to insert an OID at this arc.');
  267.  
  268.                 // Check if the ID is valid
  269.                 if ($_POST['id'] == '') throw new Exception('ID may not be empty');
  270.  
  271.                 // Absoluten OID namen bestimmen
  272.                 // Note: At addString() and parse(), the syntax of the ID will be checked
  273.                 $id = $objParent->addString($_POST['id']);
  274.  
  275.                 // Check, if the OID exists
  276.                 $test = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where id = ?", array($id));
  277.                 if (OIDplus::db()->num_rows($test) >= 1) {
  278.                         throw new Exception("Object $id already exists!");
  279.                 }
  280.  
  281.                 $obj = OIDplusObject::parse($id);
  282.  
  283.                 // First simulate if there are any problems of ASN.1 IDs und IRIs
  284.                 if ($obj::ns() == 'oid') {
  285.                         $oid = $obj;
  286.  
  287.                         $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
  288.                         $ids = array_map('trim',$ids);
  289.                         $oid->replaceIris($ids, true);
  290.  
  291.                         $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
  292.                         $ids = array_map('trim',$ids);
  293.                         $oid->replaceAsn1Ids($ids, true);
  294.                 }
  295.  
  296.                 // Superior RA Änderung durchführen
  297.                 $parent = $_POST['parent'];
  298.                 $ra_email = $_POST['ra_email'];
  299.                 if (!empty($ra_email) && !oidplus_valid_email($ra_email)) {
  300.                         throw new Exception('Invalid RA email address');
  301.                 }
  302.                 $confidential = $_POST['confidential'] == 'true';
  303.  
  304.                 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'";
  305.                 if (!empty($ra_email)) {
  306.                         OIDplus::logger()->log("RA($ra_email)!", "Gained ownership of newly created object '$id'");
  307.                 }
  308.  
  309.                 if (!OIDplus::db()->query("INSERT INTO ".OIDPLUS_TABLENAME_PREFIX."objects (id, parent, ra_email, confidential, created) VALUES (?, ?, ?, ?, now())", array($id, $parent, $ra_email, $confidential))) {
  310.                         throw new Exception(OIDplus::db()->error());
  311.                 }
  312.  
  313.                 // Set ASN.1 IDs und IRIs
  314.                 if ($obj::ns() == 'oid') {
  315.                         $oid = $obj;
  316.  
  317.                         $ids = ($_POST['iris'] == '') ? array() : explode(',',$_POST['iris']);
  318.                         $ids = array_map('trim',$ids);
  319.                         $oid->replaceIris($ids, false);
  320.  
  321.                         $ids = ($_POST['asn1ids'] == '') ? array() : explode(',',$_POST['asn1ids']);
  322.                         $ids = array_map('trim',$ids);
  323.                         $oid->replaceAsn1Ids($ids, false);
  324.                 }
  325.  
  326.                 $status = 0;
  327.  
  328.                 if (!empty($ra_email)) {
  329.                         // Do we need to notify that the RA does not exist?
  330.                         $res = OIDplus::db()->query("select ra_name from ".OIDPLUS_TABLENAME_PREFIX."ra where email = ?", array($ra_email));
  331.                         if (OIDplus::db()->num_rows($res) == 0) $status = 1;
  332.                 }
  333.  
  334.                 echo json_encode(array("status" => $status));
  335.         }
  336.  
  337.         if (!$handled) {
  338.                 throw new Exception('Invalid action ID');
  339.         }
  340.  
  341.         OIDplus::db()->transaction_commit();
  342. } catch (Exception $e) {
  343.         OIDplus::db()->transaction_rollback();
  344.         $ary = array();
  345.         $ary['error'] = $e->getMessage();
  346.         echo json_encode($ary);
  347. }
  348.  
  349. # ---
  350.  
  351. function _ra_change_rec($id, $old_ra, $new_ra) {
  352.         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));
  353.  
  354.         $res = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where parent = ? and ifnull(ra_email,'') = ?", array($id, $old_ra));
  355.         while ($row = OIDplus::db()->fetch_array($res)) {
  356.                 _ra_change_rec($row['id'], $old_ra, $new_ra);
  357.         }
  358. }
  359.