<?php
 namespace Shared;

 class Authentication
 {
    private $authenticated= false;
    private $loggedUser=null;
    private $headers;
    private $supressNTLM=false;

     public static function Authenticate()
     {
        $authentication = new Authentication();
        $authentication->headers=apache_request_headers();
        $authentication->supressNTLM=@$_POST["supressNTLM"] || @$_GET["supressNTLM"];
        session_start();
       
        $authentication->requestAuthentication();

        if(self::IsAuthenticated())    
            return $authentication;
        return false;
     }
     public static function Logout()
     {
        @session_start();
        @session_destroy();   
        @session_unset();   
        unset($_SESSION);
        return true;
     }

     public static function IsAuthenticated()
     {
        @session_start();
        if(isset($_SESSION["loggedUser"]))
            return true;
        return false;
     }

     public static function IfNotAuthenticated401()
     {
        
        if(self::IsAuthenticated())
            return true;
        http_response_code(401);
        die();
     }

     public static function IfNotAdmin401()
     {

        if(!self::IsAuthenticated())
        {
            http_response_code(401);
            die();
        }
        if(self::GetLoggedUser()["admin"]!=true)
        {
            http_response_code(401);
            die(); 
        }
       
     }
     public static function GetLoggedUser()
     {
        @session_start();
         return @$_SESSION["loggedUser"];
     }

     private function requestAuthentication()
     {
        if (isset($this->headers['Authorization']))
        {
            if(!$this->supressNTLM && $this->hashNTLMAuthHeader())
                if(!$this->validateNTLMToken())
                    $this->requestBasicAuthentication();
            
            if($this->hasBasicAuthHeader())
                if(!$this->validateBasicToken())
                    $this->requestBasicAuthentication();        
        }
        else
        {
            if($this->supressNTLM || \Shared\Settings::$NTLMDisabled==true)
                $this->requestBasicAuthentication();    
            else
                $this->requestNTLMAuthentication();  
        }
            
    }

    //ověření basic autentizace
     private function validateBasicToken()
     {
        $tokenUsername=$_SERVER['PHP_AUTH_USER'];
        $tokenPassword=$_SERVER['PHP_AUTH_PW'];
        $dbUser= DBUser::GetActiveUserByUsernameFromDB($tokenUsername);

        if(($dbUser[DBUser::$colUserName]==$tokenUsername) && 
            password_verify($tokenPassword,$dbUser[DBUser::$colPasswordHash]) && 
             $dbUser[DBUser::$colActive]==1)
             {
                $this->authenticated=true;
                unset($dbUser[DBUser::$colPasswordHash]);//hash je citlivy udaj, nikam ho neukladam krome DB.
                $_SESSION["loggedUser"]=$dbUser;
                $this->loggedUser=$_SESSION["loggedUser"];
                
                return true;
            }
        $this->authenticated=false;
        return false;
     }

     private function validateNTLMToken()
     {
        //if(!isset($_SERVER['HTTP_AUTHORIZATION'])) 
         //   return false;
        $auth = $_SERVER['HTTP_AUTHORIZATION'];

    
        $msg = base64_decode(substr($auth, 5));
        if (substr($msg, 0, 8) != "NTLMSSP\x00")
            die('error header not recognised');

        if ($msg[8] == "\x01") 
        {
            $msg2 = "NTLMSSP\x00\x02\x00\x00\x00".
                "\x00\x00\x00\x00". // target name len/alloc
                "\x00\x00\x00\x00". // target name offsest
                "\x01\x02\x81\x00". // flags
                "\x00\x00\x00\x00\x00\x00\x00\x00". // challenge
                "\x00\x00\x00\x00\x00\x00\x00\x00". // context
                "\x00\x00\x00\x00\x00\x00\x00\x00"; // target info len/alloc/offset
                
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate: NTLM '.trim(base64_encode($msg2)));
            exit;
        }
        else if ($msg[8] == "\x03") 
        {
            function get_msg_str($msg, $start, $unicode = true) 
            {
                $len = (ord($msg[$start+1]) * 256) + ord($msg[$start]);
                $off = (ord($msg[$start+5]) * 256) + ord($msg[$start+4]);
                if ($unicode)
                    return str_replace("\0", '', substr($msg, $off, $len));
                else
                    return substr($msg, $off, $len);
            }

            $ntlm_user = get_msg_str($msg, 36);
            $ntlm_domain = get_msg_str($msg, 28);
            $ntlm_workstation = get_msg_str($msg, 44);
        }

        $user= DBUser::GetActiveUserByUsernameAndDomainFromDB($ntlm_user,$ntlm_domain);
        if( $user!=null)
        {
            $this->authenticated=true;
            $_SESSION["loggedUser"]=$user;
            $this->loggedUser=$_SESSION["loggedUser"];
            return true;
        }
        $this->authenticated=false;
        return false;
     }

     private function hasBasicAuthHeader()
     {
        return contains("Basic ",$this->headers['Authorization']); 
     }

     private function hashNTLMAuthHeader()
     {
        return contains("NTLM ",$this->headers['Authorization']);
     }

     private function requestBasicAuthentication()
     {
        header('HTTP/1.0 401 Unauthorized');
        header('WWW-Authenticate: Basic realm="UTBFileShare"');
        session_destroy();   
        session_unset();   
        unset($_SESSION);
        die();
     }

     private function requestNTLMAuthentication()
     {
        header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate: NTLM');
        session_destroy();   
        session_unset();   
        unset($_SESSION);
        die();
     }

}