Subversion Repositories oidplus

Rev

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