seek_quarry
[ class tree: seek_quarry ] [ index: seek_quarry ] [ all elements ]

Source for file admin_controller.php

Documentation is available at admin_controller.php

  1. <?php
  2. /**
  3.  * SeekQuarry/Yioop --
  4.  * Open Source Pure PHP Search Engine, Crawler, and Indexer
  5.  *
  6.  * Copyright (C) 2009 - 2014  Chris Pollett chris@pollett.org
  7.  *
  8.  * LICENSE:
  9.  *
  10.  * This program is free software: you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation, either version 3 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22.  *
  23.  * END LICENSE
  24.  *
  25.  * @author Chris Pollett chris@pollett.org
  26.  * @package seek_quarry
  27.  * @subpackage controller
  28.  * @license http://www.gnu.org/licenses/ GPL3
  29.  * @link http://www.seekquarry.com/
  30.  * @copyright 2009 - 2014
  31.  * @filesource
  32.  */
  33. if(!defined('BASE_DIR')) {echo "BAD REQUEST"exit();}
  34. /** Load base controller class if needed */
  35. require_once BASE_DIR."/controllers/controller.php";
  36. /** Loads common constants for web crawling */
  37. require_once BASE_DIR."/lib/crawl_constants.php";
  38. /** Need get host for search filter admin */
  39. require_once BASE_DIR."/lib/url_parser.php";
  40. /** Used in rule parser test in page options */
  41. require_once BASE_DIR."/lib/page_rule_parser.php";
  42. /** Used to create, update, and delete user-trained classifiers. */
  43. require_once BASE_DIR."/lib/classifiers/classifier.php";
  44. /** Loads crawl_daemon to manage news_updater */
  45. require_once BASE_DIR."/lib/crawl_daemon.php";
  46. /**
  47.  * Controller used to handle admin functionalities such as
  48.  * modify login and password, CREATE, UPDATE,DELETE operations
  49.  * for users, roles, locale, and crawls
  50.  *
  51.  * @author Chris Pollett
  52.  * @package seek_quarry
  53.  * @subpackage controller
  54.  */
  55. class AdminController extends Controller implements CrawlConstants
  56. {
  57.     /**
  58.      * Says which activities (roughly methods invoke from the web) this
  59.      * controller will respond to (note: more activities will be loaded from
  60.      * components)
  61.      * @var array 
  62.      */
  63.     var $activities = array("crawlStatus""machineStatus");
  64.     /**
  65.      * An array of activities which are periodically updated within other
  66.      * activities that they live. For example, within manage crawl,
  67.      * the current crawl status is updated every 20 or so seconds.
  68.      * @var array 
  69.      */
  70.     var $status_activities = array("crawlStatus""machineStatus");
  71.     /**
  72.      * This is the main entry point for handling requests to administer the
  73.      * Yioop/SeekQuarry site
  74.      *
  75.      * ProcessRequest determines the type of request (signin , manageAccount,
  76.      * etc) is being made.  It then calls the appropriate method to handle the
  77.      * given activity. Finally, it draws the relevant admin screen
  78.      */
  79.     function processRequest()
  80.     {
  81.         $data array();
  82.         if(!PROFILE{
  83.             return $this->configureRequest();
  84.         }
  85.         $view "signin";
  86.         if(isset($_SESSION['USER_ID'])) {
  87.             $user $_SESSION['USER_ID'];
  88.         else {
  89.             $user $_SERVER['REMOTE_ADDR'];
  90.         }
  91.         $data['SCRIPT'"";
  92.         $data[CSRF_TOKEN$this->generateCSRFToken($user);
  93.         $token_okay $this->checkCSRFToken(CSRF_TOKEN$user);
  94.         if($token_okay{
  95.             if(isset($_SESSION['USER_ID']&& !isset($_REQUEST['u'])) {
  96.                 $data array_merge($data$this->processSession());
  97.                 if(!isset($data['REFRESH'])) {
  98.                     $view "admin";
  99.                 else {
  100.                     $view $data['REFRESH'];
  101.                 }
  102.             else if (!isset($_SESSION['REMOTE_ADDR'])) {
  103.                 $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  104.                     tl('admin_controller_need_cookies')."</h1>');";
  105.                 unset($_SESSION['USER_ID']);
  106.             else if ($this->checkSignin()) {
  107.                 if (!isset($_SESSION['AUTH_COUNT']||
  108.                     isset($_REQUEST['round_num']&&
  109.                     $_REQUEST['round_num'$_SESSION['AUTH_COUNT']{
  110.                     $_SESSION['AUTH_COUNT'0;
  111.                 }
  112.                 if(AUTHENTICATION_MODE == ZKP_AUTHENTICATION{
  113.                     $_SESSION['AUTH_COUNT']++;
  114.                     if($_SESSION['AUTH_COUNT'!= FIAT_SHAMIR_ITERATIONS{
  115.                         $_SESSION['SALT_VALUE'rand(01);
  116.                         $salt_value $_SESSION['SALT_VALUE'];
  117.                         if($_SESSION['AUTH_COUNT'== FIAT_SHAMIR_ITERATIONS-1){
  118.                             $salt_value "done".$salt_value;
  119.                         }
  120.                         e($salt_value);
  121.                         exit();
  122.                     }
  123.                 else {
  124.                     /*
  125.                         if not doing Fiat Shamir pretend have gone through all
  126.                         needed iterations
  127.                      */
  128.                     $_SESSION['AUTH_COUNT'FIAT_SHAMIR_ITERATIONS;
  129.                 }
  130.                 $_SESSION['USER_NAME'$_REQUEST['u'];
  131.                 if ($_SESSION['AUTH_COUNT'== FIAT_SHAMIR_ITERATIONS{
  132.                     $_SESSION['AUTH_COUNT'0;
  133.                     $user_id $this->model("signin")->getUserId(
  134.                         $this->clean($_REQUEST['u']"string"));
  135.                     $session $this->model("user")->getUserSession($user_id);
  136.                     if(is_array($session)) {
  137.                         $_SESSION $session;
  138.                     }
  139.                     $_SESSION['USER_ID'$user_id;
  140.                     $data[CSRF_TOKEN$this->generateCSRFToken(
  141.                         $_SESSION['USER_ID']);
  142.                     // now don't want to use remote address anymore
  143.                     $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  144.                         tl('admin_controller_login_successful')."</h1>')";
  145.                     $data array_merge($data$this->processSession());
  146.                     $view "admin";
  147.                     if(isset($data['INACTIVE'])) {
  148.                         $data['CURRENT_ACTIVITY'"signin";
  149.                         $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  150.                             tl('admin_controller_account_not_active')."</h1>');";
  151.                         $view "signin";
  152.                         unset($_SESSION['USER_ID']);
  153.                     }
  154.                 }
  155.             else {
  156.                 $alt_message false;
  157.                 if(AUTHENTICATION_MODE == ZKP_AUTHENTICATION
  158.                     && !isset($_SESSION['AUTH_FAILED'])) {
  159.                     if(isset($_REQUEST['round_num'])) {
  160.                         $_SESSION['SALT_VALUE'1;
  161.                         $_SESSION['AUTH_FAILED'= -1;
  162.                         e($_SESSION['AUTH_FAILED']);
  163.                         exit();
  164.                     else {
  165.                         $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  166.                             tl('admin_controller_no_back_button')."</h1>');";
  167.                         $alt_message true;
  168.                     }
  169.                 }
  170.                 $_SESSION['AUTH_COUNT'0;
  171.                 if(!$alt_message{
  172.                     $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  173.                         tl('admin_controller_login_failed')."</h1>');";
  174.                 }
  175.                 unset($_SESSION['USER_ID']);
  176.                 unset($_SESSION['AUTH_FAILED']);
  177.             }
  178.         else if($this->checkCSRFToken(CSRF_TOKEN"config")) {
  179.             $data['SCRIPT'"doMessage('<h1 class=\"red\" >".
  180.                 tl('admin_controller_login_to_config')."</h1>')";
  181.         else if(isset($_REQUEST['a']&&
  182.             in_array($_REQUEST['a']$this->status_activities)) {
  183.             e("<p class='red'>".
  184.                 tl('admin_controller_status_updates_stopped')."</p>");
  185.             exit();
  186.         }
  187.         if($token_okay && isset($_SESSION["USER_ID"])) {
  188.             $data["ADMIN"true;
  189.         else {
  190.             $data["ADMIN"false;
  191.         }
  192.         if($view == 'signin'{
  193.             if(AUTHENTICATION_MODE == ZKP_AUTHENTICATION{
  194.                 $data['AUTH_ITERATION'FIAT_SHAMIR_ITERATIONS;
  195.                 $data['FIAT_SHAMIR_MODULUS'FIAT_SHAMIR_MODULUS;
  196.                 $_SESSION['SALT_VALUE'rand(01);
  197.                 $data['INCLUDE_SCRIPTS'array("zkp""big_int""sha1");
  198.             else {
  199.                  unset($_SESSION['SALT_VALUE']);
  200.             }
  201.             unset($_SESSION['USER_ID']);
  202.             $data[CSRF_TOKEN$this->generateCSRFToken(
  203.                 $_SERVER['REMOTE_ADDR']);
  204.             $data['SCRIPT'.= "var u; if ((u = elt('username')) && u.focus) ".
  205.                "u.focus();";
  206.         }
  207.         $_SESSION['REMOTE_ADDR'$_SERVER['REMOTE_ADDR'];
  208.         $this->displayView($view$data);
  209.     }
  210.     /**
  211.      * If there is no profile/work directory set up then this method
  212.      * get called to by pass any login and go to the configure screen.
  213.      * The configure screen is only displayed if the user is connected
  214.      * from localhost in this case
  215.      */
  216.     function configureRequest()
  217.     {
  218.         $data $this->processSession();
  219.         $data[CSRF_TOKEN$this->generateCSRFToken("config");
  220.         $this->displayView("admin"$data);
  221.     }
  222.     /**
  223.      * Checks whether the user name and password sent presumably by the signin
  224.      * form match a user in the database
  225.      *
  226.      * @return bool whether they do or not
  227.      */
  228.     function checkSignin()
  229.     {
  230.         if(AUTHENTICATION_MODE == NORMAL_AUTHENTICATION{
  231.             $result $this->model("signin")->checkValidSignin(
  232.                 $this->clean($_REQUEST['u']"string"),
  233.                 $this->clean($_REQUEST['p']"string") );
  234.         else {
  235.             if(!isset($_REQUEST['u']|| !isset($_REQUEST['x']||
  236.                 !isset($_REQUEST['y']|| !isset($_SESSION['SALT_VALUE']||
  237.                 isset($_SESSION['AUTH_FAILED'])) {
  238.                 $result false;
  239.             else {
  240.                 $result $this->model("signin")->checkValidSigninForZKP(
  241.                     $this->clean($_REQUEST['u']"string"),
  242.                     $this->clean($_REQUEST['x']"string"),
  243.                     $this->clean($_REQUEST['y']"string"),
  244.                     $_SESSION['SALT_VALUE']FIAT_SHAMIR_MODULUS);
  245.             }
  246.             if(!$result{
  247.                 $_SESSION['AUTH_COUNT'0;
  248.             }
  249.         }
  250.         return $result;
  251.     }
  252.     /**
  253.      * Determines the user's current allowed activities and current activity,
  254.      * then calls the method for the latter.
  255.      *
  256.      * This is called from {@link processRequest()} once a user is logged in.
  257.      *
  258.      * @return array $data the results of doing the activity for display in the
  259.      *      view
  260.      */
  261.     function processSession()
  262.     {
  263.         if(!PROFILE || (defined("FIX_NAME_SERVER"&& FIX_NAME_SERVER)) {
  264.             $activity "configure";
  265.         else if(isset($_REQUEST['a']&&
  266.             in_array($_REQUEST['a']$this->activities)) {
  267.             $activity $_REQUEST['a'];
  268.         else {
  269.             $activity "manageAccount";
  270.         }
  271.         $allowed true;
  272.         $activity_model $this->model("activity");
  273.         if(!PROFILE{
  274.             $allowed_activities arrayarray(
  275.                 "ACTIVITY_NAME" =>
  276.                 $activity_model->getActivityNameFromMethodName($activity),
  277.                 'METHOD_NAME' => $activity));
  278.             $allowed true;
  279.         else {
  280.             $allowed_activities =
  281.                  $this->model("user")->getUserActivities($_SESSION['USER_ID']);
  282.         }
  283.         if($allowed_activities == array()) {
  284.             $data['INACTIVE'true;
  285.             return $data;
  286.         }
  287.         foreach($allowed_activities as $allowed_activity{
  288.             if($activity == $allowed_activity['METHOD_NAME']{
  289.                  $allowed true;
  290.             }
  291.             if($allowed_activity['METHOD_NAME'== "manageCrawls" &&
  292.                 $activity == "crawlStatus"{
  293.                 $allowed true;
  294.             }
  295.             if($allowed_activity['METHOD_NAME'== "manageMachines" &&
  296.                 $activity == "machineStatus"{
  297.                 $allowed true;
  298.             }
  299.         }
  300.         //for now we allow anyone to get crawlStatus
  301.         if($allowed{
  302.             $data $this->call($activity);
  303.             $data['ACTIVITY_METHOD'$activity//for settings controller
  304.             if(!is_array($data)) {
  305.                 $data array();
  306.             }
  307.             $data['ACTIVITIES'$allowed_activities;
  308.         }
  309.         if(!in_array($activity$this->status_activities)) {
  310.             $name_activity $activity;
  311.             if($activity == "wiki"{
  312.                 $name_activity "groupFeeds";
  313.             }
  314.             $data['CURRENT_ACTIVITY'=
  315.                 $activity_model->getActivityNameFromMethodName($name_activity);
  316.         }
  317.  
  318.         $data['COMPONENT_ACTIVITIES'array();
  319.         $component_translations array(
  320.             "accountaccess" => tl('admin_controller_account_access'),
  321.             "social" => tl('admin_controller_social'),
  322.             "crawl" => tl('admin_controller_crawl_settings'),
  323.             "system" => tl('admin_controller_system_settings')
  324.         );
  325.         if(isset($data["ACTIVITIES"])) {
  326.             foreach($this->component_activities as $component => $activities{
  327.                 foreach($data["ACTIVITIES"as $activity{
  328.                     if(in_array($activity['METHOD_NAME']$activities)) {
  329.                         $data['COMPONENT_ACTIVITIES'][
  330.                             $component_translations[$component]][=
  331.                             $activity;
  332.                     }
  333.                 }
  334.             }
  335.         }
  336.         return $data;
  337.     }
  338.     /**
  339.      * Used to handle crawlStatus REST activities requesting the status of the
  340.      * current web crawl
  341.      *
  342.      * @return array $data contains crawl status of current crawl as well as
  343.      *      info about prior crawls and which crawl is being used for default
  344.      *      search results
  345.      */
  346.     function crawlStatus()
  347.     {
  348.         $data array();
  349.         $data['REFRESH'"crawlstatus";
  350.         $crawl_model $this->model("crawl");
  351.         $crawl_time $crawl_model->getCurrentIndexDatabaseName();
  352.         if(isset($crawl_time) ) {
  353.             $data['CURRENT_INDEX'= (int)$crawl_time;
  354.         else {
  355.             $data['CURRENT_INDEX'= -1;
  356.         }
  357.         $machine_urls $this->model("machine")->getQueueServerUrls();
  358.         list($stalled$status$data['RECENT_CRAWLS']=
  359.             $crawl_model->combinedCrawlInfo($machine_urls);
  360.  
  361.         if($stalled{
  362.             $crawl_model->sendStopCrawlMessage($machine_urls);
  363.         }
  364.         $data array_merge($data$status);
  365.         $data["CRAWL_RUNNING"false;
  366.         if(isset($data['CRAWL_TIME']&& $data["CRAWL_TIME"!= 0{
  367.             //erase from previous crawl list any active crawl
  368.             $num_crawls count($data['RECENT_CRAWLS']);
  369.             for($i 0$i $num_crawls$i++{
  370.                 if($data['RECENT_CRAWLS'][$i]['CRAWL_TIME'==
  371.                     $data['CRAWL_TIME']{
  372.                     $data['RECENT_CRAWLS'][$ifalse;
  373.                 }
  374.             }
  375.             $data["CRAWL_RUNNING"true;
  376.             $data['RECENT_CRAWLS']array_filter($data['RECENT_CRAWLS']);
  377.         }
  378.         if(isset($data['RECENT_CRAWLS'][0])) {
  379.             rorderCallback($data['RECENT_CRAWLS'][0]$data['RECENT_CRAWLS'][0],
  380.                 'CRAWL_TIME');
  381.             usort($data['RECENT_CRAWLS']"rorderCallback");
  382.         }
  383.         $this->pagingLogic($data'RECENT_CRAWLS''RECENT_CRAWLS',
  384.             DEFAULT_ADMIN_PAGING_NUM);
  385.         return $data;
  386.     }
  387.     /**
  388.      * Gets data from the machine model concerning the on/off states
  389.      * of the machines managed by this Yioop instance and then passes
  390.      * this data the the machinestatus view.
  391.      * @return array $data MACHINES field has information about each
  392.      *      machine managed by this Yioop instance as well the on off
  393.      *      status of its queue_servers and fetchers.
  394.      *      The REFRESH field is used to tell the controller that the
  395.      *      view shouldn't have its own sidemenu.
  396.      */
  397.     function machineStatus()
  398.     {
  399.         $data array();
  400.         $data['REFRESH'"machinestatus";
  401.         $this->pagingLogic($data$this->model("machine")'MACHINES',
  402.             DEFAULT_ADMIN_PAGING_NUM);
  403.         $profile =  $this->model("profile")->getProfile(WORK_DIRECTORY);
  404.         $data['NEWS_MODE'= isset($profile['NEWS_MODE']?
  405.             $profile['NEWS_MODE']"";
  406.         if($data['NEWS_MODE'== "news_process" &&
  407.             $data['MACHINES']['NAME_SERVER']["news_updater"== 0{
  408.             // try to restart news server if dead
  409.             CrawlDaemon::start("news_updater"'none'""-1);
  410.         }
  411.         return $data;
  412.     }
  413.     /**
  414.      * Used to update the yioop installation profile based on $_REQUEST data
  415.      *
  416.      * @param array& $data field data to be sent to the view
  417.      * @param array& $profile used to contain the current and updated profile
  418.      *      field values
  419.      * @param array $check_box_fields fields whose data comes from a html
  420.      *      checkbox
  421.      */
  422.     function updateProfileFields(&$data&$profile$check_box_fields array())
  423.     {
  424.         foreach($this->model("profile")->profile_fields as $field{
  425.             if(isset($_REQUEST[$field])) {
  426.                 if($field != "ROBOT_DESCRIPTION" &&
  427.                     $field != "MEMCACHE_SERVERS" &&
  428.                     $field != "PROXY_SERVERS"{
  429.                     $clean_field =
  430.                         $this->clean($_REQUEST[$field]"string");
  431.                 else {
  432.                     $clean_field $_REQUEST[$field];
  433.                 }
  434.                 if($field == "NAME_SERVER" &&
  435.                     $clean_field[strlen($clean_field-1!= "/"{
  436.                     $clean_field .= "/";
  437.                 }
  438.                 $data[$field$clean_field;
  439.                 $profile[$field$data[$field];
  440.                 if($field == "MEMCACHE_SERVERS" || $field == "PROXY_SERVERS"{
  441.                     $mem_array preg_split("/(\s)+/"$clean_field);
  442.                     $profile[$field=
  443.                         $this->convertArrayLines(
  444.                             $mem_array"|Z|"true);
  445.                 }
  446.             }
  447.             if(!isset($data[$field])) {
  448.                 $data[$field"";
  449.                 if(in_array($field$check_box_fields)) {
  450.                     $profile[$fieldfalse;
  451.                 }
  452.             }
  453.         }
  454.     }
  455.     /**
  456.      * Used to set up view data for table search form (might make use of
  457.      * $_REQUEST if form was submitted, results gotten, and we want to preserve
  458.      * form drop down). Table search forms
  459.      * are used by manageUsers, manageRoles, manageGroups, to do advanced
  460.      * search of the entity they are responsible for.
  461.      *
  462.      * @param array& $data modified to contain the field data needed for
  463.      *      the view to draw the search form
  464.      * @param array $comparison_fields those fields of the entity
  465.      *      in question ( for example, users) which we can search both with
  466.      *      string comparison operators and equality operators
  467.      * @param array $equal_comparison_fields those fields of the entity in
  468.      *      question which can only be search by equality/inequality operators
  469.      * @param string $field_postfix suffix to append onto field names in
  470.      *      case there are multiple forms on the same page
  471.      */
  472.     function tableSearchRequestHandler(&$data$comparison_fields array(),
  473.         $equal_comparison_fields array()$field_postfix "")
  474.     {
  475.         $data['FORM_TYPE'"search";
  476.         $data['COMPARISON_TYPES'array(
  477.             "=" => tl('admin_controller_equal'),
  478.             "!=" => tl('admin_controller_not_equal'),
  479.             "CONTAINS" => tl('admin_controller_contains'),
  480.             "BEGINS WITH" => tl('admin_controller_begins_with'),
  481.             "ENDS WITH" => tl('admin_controller_ends_with'),
  482.         );
  483.         $data['EQUAL_COMPARISON_TYPES'array(
  484.             "=" => tl('admin_controller_equal'),
  485.             "!=" => tl('admin_controller_not_equal'),
  486.         );
  487.         $data['SORT_TYPES'array(
  488.             "NONE" => tl('admin_controller_no_sort'),
  489.             "ASC" => tl('admin_controller_sort_ascending'),
  490.             "DESC" => tl('admin_controller_sort_descending'),
  491.         );
  492.         $paging "";
  493.         foreach($comparison_fields as $comparison_start{
  494.             $comparison $comparison_start."_comparison";
  495.             $comparison_types (in_array($comparison_start$data[
  496.                 'EQUAL_COMPARISON_TYPES']))
  497.                 ? 'EQUAL_COMPARISON_TYPES' 'COMPARISON_TYPES';
  498.             $data[$comparison(isset($_REQUEST[$comparison]&&
  499.                 isset($data[$comparison_types][
  500.                 $_REQUEST[$comparison]])) $_REQUEST[$comparison:
  501.                 "=";
  502.             $paging .= "&amp;$comparison=".
  503.                 urlencode($data[$comparison]);
  504.         }
  505.         foreach($comparison_fields as $sort_start{
  506.             $sort $sort_start."_sort";
  507.             $data[$sort(isset($_REQUEST[$sort]&&
  508.                 isset($data['SORT_TYPES'][
  509.                 $_REQUEST[$sort]])) ?$_REQUEST[$sort:
  510.                 "NONE";
  511.             $paging .= "&amp;$sort=".urlencode($data[$sort]);
  512.         }
  513.         $search_array array();
  514.         foreach($comparison_fields as $field{
  515.             $field_name $field.$field_postfix;
  516.             $field_comparison $field."_comparison";
  517.             $field_sort $field."_sort";
  518.             $data[$field_name(isset($_REQUEST[$field_name])) ?
  519.                 $this->clean($_REQUEST[$field_name]"string":
  520.                 "";
  521.             if($field_name=='access' && $data[$field_name>=10{
  522.                 $search_array[array("status",
  523.                     $data[$field_comparison]$data[$field_name]/10,
  524.                     $data[$field_sort]);
  525.             else {
  526.                 $search_array[array($field,
  527.                     $data[$field_comparison]$data[$field_name],
  528.                     $data[$field_sort]);
  529.             }
  530.             $paging .= "&amp;$field_name=".
  531.                 urlencode($data[$field_name]);
  532.         }
  533.         $data['PAGING'$paging;
  534.         return $search_array;
  535.     }
  536. }
  537. ?>

Documentation generated by phpDocumentor 1.4.3