<commit_before><?php
/**
* Functions that are needed for all CalDAV Requests
*
*  - Ascertaining the paths
*  - Ascertaining the current user's permission to those paths.
*  - Utility functions which we can use to decide whether this
*    is a permitted activity for this user.
*
* @package   rscds
* @subpackage   CalDAVRequest
* @author    <NAME> <<EMAIL>>
* @copyright <NAME>
* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2
*/

/**
* A class for collecting things to do with this request.
*
* @package   rscds
*/
class CalDAVRequest
{

  /**
  * Create a new CalDAVRequest object.
  */
  function CalDAVRequest( ) {
    global $session, $c, $debugging;

    $this->raw_post = file_get_contents ( 'php://input');

    if ( isset($debugging) && isset($_GET['method']) ) {
      $_SERVER['REQUEST_METHOD'] = $_GET['method'];
    }
    $this->method = $_SERVER['REQUEST_METHOD'];

    /**
    * A variety of requests may set the "Depth" header to control recursion
    */
    $this->depth = ( isset($_SERVER['HTTP_DEPTH']) ? $_SERVER['HTTP_DEPTH'] : 0 );
    if ( $this->depth == 'infinity' ) $this->depth = 99;
    $this->depth = intval($this->depth);

    /**
    * Our path is /<script name>/<user name>/<user controlled> if it ends in
    * a trailing '/' then it is referring to a DAV 'collection' but otherwise
    * it is referring to a DAV data item.
    *
    * Permissions are controlled as follows:
    *  1. if there is no <user name> component, the request has read privileges
    *  2. if the requester is an admin, the request has read/write priviliges
    *  3. if there is a <user name> component which matches the logged on user
    *     then the request has read/write privileges
    *  4. otherwise we query the defined relationships between users and use
    *     the minimum privileges returned from that analysis.
    */
    $this->path = $_SERVER['PATH_INFO'];
    $bad_chars_regex = '/[\\^\\[\\(\\\\]/';
    if ( preg_match( $bad_chars_regex, $this->path ) ) {
      $this->DoResponse( 400, translate("The calendar path contains illegal characters.") );
    }

    $path_split = preg_split('#/+#', $this->path );
    $this->permissions = array();
    if ( !isset($path_split[1]) || $path_split[1] == '' ) {
      dbg_error_log( "caldav", "No useful path split possible" );
      unset($this->user_no);
      unset($this->username);
      $this->permissions = array("read" => 'read' );
      dbg_error_log( "caldav", "Read permissions for user accessing /" );
    }
    else {
      $this->username = $path_split[1];
      @dbg_error_log( "caldav", "Path split into at least /// %s /// %s /// %s", $path_split[1], $path_split[2], $path_split[3] );
      $qry = new PgQuery( "SELECT * FROM usr WHERE username = ?;", $this->username );
      if ( $qry->Exec("caldav") && $user = $qry->Fetch() ) {
        $this->user_no = $user->user_no;
      }
      if ( $session->AllowedTo("Admin") ) {
        $this->permissions = array('all' => 'all' );
        dbg_error_log( "caldav", "Full permissions for a systems administrator" );
      }
      else if ( $session->user_no == $this->user_no ) {
        $this->permissions = array('all' => 'all' );
        dbg_error_log( "caldav", "Full permissions for user accessing their own hierarchy" );
      }
      else if ( isset($this->user_no) ) {
        /**
        * We need to query the database for permissions
        */
        $qry = new PgQuery( "SELECT get_permissions( ?, ? ) AS perm;", $session->user_no, $this->user_no);
        if ( $qry->Exec("caldav") && $permission_result = $qry->Fetch() ) {
          $permission_result = "!".$permission_result->perm; // We prepend something to ensure we get a non-zero position.
          $this->permissions = array();
          if ( strpos($permission_result,"A") )
            $this->permissions['all'] = 'all';
          else {
            if ( strpos($permission_result,"R") )       $this->permissions['read'] = 'read';
            if ( strpos($permission_result,"W") )
              $this->permissions['write'] = 'write';
            else {
              if ( strpos($permission_result,"C") )       $this->permissions['bind'] = 'bind';      // PUT of new content (i.e. Create)
              if ( strpos($permission_result,"D") )       $this->permissions['unbind'] = 'unbind';  // DELETE
              if ( strpos($permission_result,"M") )       $this->permissions['write-content'] = 'write-content';  // DELETE
            }
          }
        }
        dbg_error_log( "caldav", "Restricted permissions for user accessing someone elses hierarchy: %s", implode( ", ", $this->permissions ) );
      }
    }

    /**
    * If the content we are receiving is XML then we parse it here.
    */
    $xml_parser = xml_parser_create_ns('UTF-8');
    $this->xml_tags = array();<commit_msg>Take more notice of the headers we receive, especially ones that apply to LOCK, UNLOCK.<commit_after><?php
/**
* Functions that are needed for all CalDAV Requests
*
*  - Ascertaining the paths
*  - Ascertaining the current user's permission to those paths.
*  - Utility functions which we can use to decide whether this
*    is a permitted activity for this user.
*
* @package   rscds
* @subpackage   CalDAVRequest
* @author    <NAME> <<EMAIL>>
* @copyright <NAME>
* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2
*/

/**
* A class for collecting things to do with this request.
*
* @package   rscds
*/
class CalDAVRequest
{

  /**
  * Create a new CalDAVRequest object.
  */
  function CalDAVRequest( ) {
    global $session, $c, $debugging;

    $this->raw_post = file_get_contents ( 'php://input');

    if ( isset($debugging) && isset($_GET['method']) ) {
      $_SERVER['REQUEST_METHOD'] = $_GET['method'];
    }
    $this->method = $_SERVER['REQUEST_METHOD'];

    /**
    * A variety of requests may set the "Depth" header to control recursion
    */
    $this->depth = ( isset($_SERVER['HTTP_DEPTH']) ? $_SERVER['HTTP_DEPTH'] : 0 );
    if ( $this->depth == 'infinity' ) $this->depth = 99;
    $this->depth = intval($this->depth);

    /**
    * MOVE/COPY use a "Destination" header and (optionally) an "Overwrite" one.
    */
    if ( isset($_SERVER['HTTP_DESTINATION']) ) $this->destination = $_SERVER['HTTP_DESTINATION'];
    $this->overwrite = ( isset($_SERVER['HTTP_OVERWRITE']) ? $_SERVER['HTTP_OVERWRITE'] : 'T' ); // RFC2518, 9.6 says default True.

    /**
    * LOCK things use an "If" header to hold the lock in some cases, and "Lock-token" in others
    */
    if ( isset($_SERVER['HTTP_IF']) ) $this->if_clause = $_SERVER['HTTP_IF'];
    if ( isset($_SERVER['HTTP_LOCK-TOKEN']) ) $this->lock_token = $_SERVER['HTTP_LOCK-TOKEN'];

    /**
    * Our path is /<script name>/<user name>/<user controlled> if it ends in
    * a trailing '/' then it is referring to a DAV 'collection' but otherwise
    * it is referring to a DAV data item.
    *
    * Permissions are controlled as follows:
    *  1. if there is no <user name> component, the request has read privileges
    *  2. if the requester is an admin, the request has read/write priviliges
    *  3. if there is a <user name> component which matches the logged on user
    *     then the request has read/write privileges
    *  4. otherwise we query the defined relationships between users and use
    *     the minimum privileges returned from that analysis.
    */
    $this->path = $_SERVER['PATH_INFO'];
    $bad_chars_regex = '/[\\^\\[\\(\\\\]/';
    if ( preg_match( $bad_chars_regex, $this->path ) ) {
      $this->DoResponse( 400, translate("The calendar path contains illegal characters.") );
    }

    $path_split = preg_split('#/+#', $this->path );
    $this->permissions = array();
    if ( !isset($path_split[1]) || $path_split[1] == '' ) {
      dbg_error_log( "caldav", "No useful path split possible" );
      unset($this->user_no);
      unset($this->username);
      $this->permissions = array("read" => 'read' );
      dbg_error_log( "caldav", "Read permissions for user accessing /" );
    }
    else {
      $this->username = $path_split[1];
      @dbg_error_log( "caldav", "Path split into at least /// %s /// %s /// %s", $path_split[1], $path_split[2], $path_split[3] );
      $qry = new PgQuery( "SELECT * FROM usr WHERE username = ?;", $this->username );
      if ( $qry->Exec("caldav") && $user = $qry->Fetch() ) {
        $this->user_no = $user->user_no;
      }
      if ( $session->AllowedTo("Admin") ) {
        $this->permissions = array('all' => 'all' );
        dbg_error_log( "caldav", "Full permissions for a systems administrator" );
      }
      else if ( $session->user_no == $this->user_no ) {
        $this->permissions = array('all' => 'all' );
        dbg_error_log( "caldav", "Full permissions for user accessing their own hierarchy" );
      }
      else if ( isset($this->user_no) ) {
        /**
        * We need to query the database for permissions
        */
        $qry = new PgQuery( "SELECT get_permissions( ?, ? ) AS perm;", $session->user_no, $this->user_no);
        if ( $qry->Exec("caldav") && $permission_result = $qry->Fetch() ) {
          $permission_result = "!".$permission_result->perm; // We prepend something to ensure we get a non-zero position.
          $this->permissions = array();
          if ( strpos($permission_result,"A") )
            $this->permissions['all'] = 'all';
          else {
            if ( strpos($permission_result,"R") )       $this->permissions['read'] = 'read';
            if ( strpos($permission_result,"W") )
              $this->permissions['write'] = 'write';
            else {
              if ( strpos($permission_result,"C") )       $this->permissions['bind'] = 'bind';      // PUT of new content (i.e. Create)
              if ( strpos($permission_result,"D") )       $this->permissions['unbind'] = 'unbind';  // DELETE
              if ( strpos($permission_result,"M") )       $this->permissions['write-content'] = 'write-content';  // PUT Modify
            }
          }
        }
        dbg_error_log( "caldav", "Restricted permissions for user accessing someone elses hierarchy: %s", implode( ", ", $this->permissions ) );
      }
    }

    /**
    * If the content we are receiving is XML then we parse it here.
    */
    $xml_parser = xml_parser_create_ns('UTF-8');
    $this->xml_tags = array();
{'fraction_non_alphanumeric': 0.15885947046843177, 'fraction_numerical': 0.004073319755600814, 'mean_word_length': 2.7133597407274035, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '771376', 'n_tokens_mistral': 3261, 'n_tokens_neox': 3178, 'n_words': 888}