<?php

define('DS', DIRECTORY_SEPARATOR);
define('APP_PATH_ROOT', dirname(__FILE__));
//define('APP_PATH_ROOT', '/Users/plabudda/se-dev-pl/SE');
define('APP_PATH_LIB', APP_PATH_ROOT . '/se-lib');
define('APP_PATH_WWW', APP_PATH_ROOT);
define('APP_PATH_CONFIG', APP_PATH_ROOT . DS . 'config');

//session_save_path("./tmp") ;
session_start();

date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions

error_reporting(0);
ini_set('error_reporting', 0);
ini_set('display_startup_errors','0'); 
//display_startup_errors(0);

#TEST $_SESSION['DEBUG'] = 3;// TODO: TEST
if (!isset($_SESSION['DEBUG'])) $_SESSION['DEBUG'] = 0;// set default value


if (file_exists(APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php")) {
	require APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php";
}

if (file_exists(APP_PATH_ROOT . "/.config.php")) include APP_PATH_ROOT . "/.config.php";

require_once APP_PATH_ROOT . "/superedit-SEF.php";

require_once APP_PATH_LIB . '/' . 'Lib.php';
Lib::loadClass('V');
Lib::loadClass('DB');
Lib::loadClass('User');
Lib::loadClass('SE_Layout');
Lib::loadClass('S');

if (User::logged() && V::get('testDigest', '', $_GET) == 1) {
	$realm = "Browse access /Library/Server/Web/Data/Sites/Default/PLIKI";

	if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
		header('HTTP/1.1 401 Unauthorized');
		header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
		die('Text to send if user hits Cancel button');
	}


	// analyze the PHP_AUTH_DIGEST variable
	if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) {
		die('Wrong Credentials!');
	}


	// generate the valid response
	$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
	$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
	$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

	if ($data['response'] != $valid_response) {
		die('Wrong Credentials!');
	}

	// ok, valid username & password
	echo 'You are logged in as: ' . $data['username'];

	// function to parse the http auth header
	function http_digest_parse($txt){
		// protect against missing data
		$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
		$data = array();
		$keys = implode('|', array_keys($needed_parts));

		preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

		foreach ($matches as $m) {
				$data[$m[1]] = $m[3] ? $m[3] : $m[4];
				unset($needed_parts[$m[1]]);
		}

		return $needed_parts ? false : $data;
	}

	die('Digest Login Test');
}

if (User::logged() && V::get('ajaxDigest', '', $_GET) == 1) {

	//header('Access-Control-Allow-Origin: *');

	SE_Layout::gora();
	Lib::loadClass('Crypt');
?>

<script>
/*
 * A JavaScript implementation of the Digest Authentication
 * Digest Authentication, as defined in RFC 2617.
 * Version 1.0 Copyright (C) Maricn Michalski (http://marcin-michalski.pl) 
 * Distributed under the BSD License
 * 
 * site: http://arrowgroup.eu
 */
 
DigestAuthentication = function() {
	return {
 MAX_ATTEMPTS : 1,
 AUTHORIZATION_HEADER : "Authorization",
 WWW_AUTHENTICATE_HEADER : 'WWW-Authenticate',
 NC : "00000001", //currently nc value is fixed it is not incremented
 HTTP_METHOD : "GET",
 /**
  * settings json:
  *  - onSuccess - on success callback
  *  - onFailure - on failure callback
  *  - username - user name
  *  - password - user password
  *  - cnonce - client nonce
  */
 init : function(settings) {
   this.settings = settings;
 },
 setCredentials: function(username, password){
   this.settings.username = username;
   this.settings.password = password;
 },
 call : function(uri){
   this.attempts = 0;
   this.invokeCall(uri);
 },
 invokeCall: function(uri,authorizationHeader){
   var digestAuth = this;
   $.ajax({
         url: uri,
         type: this.HTTP_METHOD,
         beforeSend: function(request){
          if(typeof authorizationHeader != 'undefined'){
          request.setRequestHeader(digestAuth.AUTHORIZATION_HEADER, authorizationHeader);           
          }
         },
         success: function(response) {
          digestAuth.settings.onSuccess(response);          
         },
         error: function(response) { 
          if(digestAuth.attempts == digestAuth.MAX_ATTEMPTS){
      digestAuth.settings.onFailure(response);
      return;
      }
          var paramParser = new HeaderParamsParser(response.getResponseHeader(digestAuth.WWW_AUTHENTICATE_HEADER));
          var nonce = paramParser.getParam("nonce");
          var realm = paramParser.getParam("realm");
          var qop = paramParser.getParam("qop");
          var response = digestAuth.calculateResponse(uri, nonce, realm, qop);
          var authorizationHeaderValue = digestAuth.generateAuthorizationHeader(paramParser.headerValue, response, uri); 
          digestAuth.attempts++;
          digestAuth.invokeCall(uri, authorizationHeaderValue);
         }             
     });
 },
 calculateResponse : function(uri, nonce, realm, qop){
   var a2 = this.HTTP_METHOD + ":" + uri;
   var a2Md5 = hex_md5(a2);
   var a1Md5 = hex_md5(this.settings.username + ":" + realm + ":" + this.settings.password);
   var digest = a1Md5 + ":" + nonce + ":" + this.NC + ":" + this.settings.cnonce + ":" + qop + ":" +a2Md5;
   return hex_md5(digest);
 },
 generateAuthorizationHeader : function(wwwAuthenticationHeader, response, uri){
   return wwwAuthenticationHeader+', username="'+this.settings.username+'", uri="'+
      uri+'", response="'+response+'", nc='+
      this.NC+', cnonce="'+this.settings.cnonce+'"';
   }
	}
};

HeaderParamsParser = function () {
	return {
		init : function(headerValue) {
		 this.headerValue = headerValue;
		 this.headerParams = this.headerValue.split(",");
		},
		getParam: function(paramName){
		 var paramVal = null;
		 $.each(this.headerParams, function(index, value){
			 if(value.indexOf(paramName)>0){
			 paramVal = value.split(paramName+"=")[1];
			 paramVal = paramVal.substring(1, paramVal.length-1);
			 }
		 });
		 return paramVal;
		}
	}
};

var ajaxDigest = new DigestAuthentication();
ajaxDigest.init({username: '<?php echo User::getLogin(); ?>', password:'<?php echo Crypt::decrypt($_SESSION['ADM_PASS_HASH']); ?>'});
//ajaxDigest.setCredentials('<?php echo User::getLogin(); ?>', '<?php echo Crypt::decrypt($_SESSION['ADM_PASS_HASH']); ?>');
ajaxDigest.call('<?php echo "http://{$_SERVER['SERVER_NAME']}/PLIKI/"; ?>');

</script>
<?php
	SE_Layout::dol();
	exit;
}

if (User::logged() && V::get('onlySrv', '', $_GET) == 1) {
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">SRV (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($_SERVER);echo'</pre>';
	exit;
}

if (User::logged()) {
	Lib::loadClass('Crypt');
	$login = User::getLogin();
	$pass = Crypt::decrypt($_SESSION['ADM_PASS_HASH']);

	$ch = curl_init();
	// set url
	curl_setopt($ch, CURLOPT_URL, "http://{$_SERVER['SERVER_NAME']}/PLIKI/");
	curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
	curl_setopt($ch, CURLOPT_USERPWD, "{$login}:{$pass}");

	// first authentication with a head request
	curl_setopt($ch, CURLINFO_HEADER_OUT, 1);

	curl_setopt($ch, CURLOPT_NOBODY, 1);
	curl_setopt($ch, CURLOPT_VERBOSE, 1);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$output = curl_exec($ch);
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">curl output 1 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($output);echo'</pre>';
	$info = curl_getinfo($ch);
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">curl info 1 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($info);echo'</pre>';

	// the get the real output
	curl_setopt($ch, CURLINFO_HEADER_OUT, 1);

	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_VERBOSE, 1);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, 1);
	curl_setopt($ch, CURLOPT_HTTPGET, 1);
	$output = curl_exec($ch);
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">curl output 2 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($output);echo'</pre>';
	$info = curl_getinfo($ch);
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">curl info 2 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($info);echo'</pre>';
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">curl (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($ch);echo'</pre>';
	curl_close($ch);

	// login by browser result in:
	// $_SERVER[PHP_AUTH_DIGEST] => username="plabudda", realm="Browse access /Library/Server/Web/Data/Sites/Default/PLIKI", nonce="03d338604c5e373eb15912fa3a9e75341381747501704512", uri="/SE/se-dev-pl/t.php", response="219a9c728b9f97317041c6f2cec672d5"

	// curl $info['request_header']
	// Authorization: Digest username="plabudda", realm="Browse access /Library/Server/Web/Data/Sites/Default/PLIKI", nonce="ab0433e0ddfd7c8875351f60ab0bfadf1381747561090631", uri="/PLIKI/", response="90758c48f0420635a45053902af41ab5"

	$info['request_header'] = explode("\n", $info['request_header']);
	foreach ($info['request_header'] as $vHeader) {
		if (substr($vHeader, 0, 22) == 'Authorization: Digest ') {
			$_SERVER['PHP_AUTH_DIGEST'] = substr($vHeader, 22);
		}
	}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$_SERVER[PHP_AUTH_DIGEST] (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($_SERVER['PHP_AUTH_DIGEST']);echo'</pre>';

} else {
	echo '<p>Log in to test digest</p>';
}


echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">db (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($SQL_DATABASE);echo'</pre>';

$tbls = array();
$db = DB::getDB();
$sql = "show tables;";
$res = $db->query($sql);
while ($r = $db->fetch($res)) {
	$tbls[] = $r;
}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">tbls (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($tbls);echo'</pre>';

?>
