<?php
/*
 * PiAnoS (Picture Annotation System), A fingerprint examiner training tool
 * Copyright (C) 2011-2021 University of Lausanne, Switzerland
 * https://ips-labs.unil.ch/pianos
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */
require_once ( "unil/Application.php" );
class ChangePassword extends Node
{
    function ChangePassword( $errors )
    {
        $this->errors = $errors;
    }
    public function render( &$rs )
    {
        // Theme-related CSS
        $rs->getPage()->addStyleSheet( Application::get( 'csslib_jquery_ui' ) );
        $rs->setJQueryStyleSheet( Application::get( 'jqueryui_theme' ), 'theme-backend.css' );
        // Theme agnostic CSS
        $rs->getPage()->addStyleSheet( 'css/backend.css' );
        
        $rs->getPage()->addScript( Application::get( 'jslib_md5' ) );
        
        $rs->getPage()->setNoScript( '<div class="ui-widget ui-widget-content ui-corner-bottom ui-state-error" style="font-size:1.1em;text-align:center;padding:0.5em;">You must enable Javascript for this application to function !</div>' );
        
        $this->domStart( 'div', NULL, array (), 'style="text-align:center;width:100%;padding-top:2em"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget', 
                'login_panel' 
        ) );
        $this->domStart( 'div', NULL, array (
                'ui-widget-header', 
                'ui-corner-top' 
        ), 'style="text-align:center;margin-bottom:0;"' );
        echo _( "Password renewal required" );
        $this->domClose();
        $this->domStart( 'div', NULL, array (
                'ui-widget-content', 
                'ui-corner-bottom' 
        ) );
        echo '<p style="margin:1em;text-align:center">Your current password is expired, please choose a new password. Please make it strong enough !</p>';
        $this->domStart( 'form', 'login_form', NULL, 'action="?" method="post"' );
        $this->domStart( 'fieldset', NULL, array (
                'data_panel_section' 
        ), 'style="border:none;"' );
        $this->domStart( 'div' );
        $this->domElement( 'label', _H( _( "Username" ) ), NULL, NULL, ' for="username"' );
        $this->domElement( 'input', NULL, 'username', NULL, 'type="text" name="username" value="' . _H( $_SESSION[ 'user' ][ 'username' ] ) . '" disabled="disabled"' );
        $this->domClose();
        $this->domStart( 'div' );
        $this->domElement( 'label', _H( _( "Old password" ) ), NULL, NULL, ' for="old_password"' );
        $this->domElement( 'input', NULL, 'old_password', NULL, 'type="password" name="old_password" value="" disabled="disabled"' );
        $this->domClose();
        $this->domStart( 'div' );
        $this->domElement( 'label', _H( _( "New password" ) ), NULL, NULL, ' for="new_password"' );
        $this->domElement( 'input', NULL, 'new_password', NULL, 'type="password" name="new_password" value="" disabled="disabled"' );
        $this->domClose();
        $this->domStart( 'div' );
        $this->domElement( 'label', _H( _( "Re-type new password" ) ), NULL, NULL, ' for="new_password_2"' );
        $this->domElement( 'input', NULL, 'new_password_2', NULL, 'type="password" name="new_password_2" value="" disabled="disabled"' );
        $this->domClose();
        $this->domStart( 'div', NULL, array (), 'style="text-align:center;margin-top:1.5em;clear:both;"' );
        $this->domElement( 'input', NULL, 'submit', NULL, 'type="submit" value="' . _H( _( "Set new password" ) ) . '" disabled="disabled"' );
        $this->domElement( 'a', 'Leave', NULL, array (), 'href="?action=logout"' );
        $this->domClose();
        $this->domClose();
        $this->domClose();
        if( count( $this->errors ) )
        {
            $this->domStart( 'div' );
            foreach( $this->errors as $err )
                $this->domElement( 'p', _H( $err ), NULL, array (
                        'ui-state-error', 
                        'ui-corner-all' 
                ), 'style="margin:0.5em; padding: 0 0.5em;"' );
            $this->domClose();
        }
        $this->domClose();
        $this->domClose();
        $this->domClose();
        
        $this->domStartJS();
        echo "
			$(document).ready(function() {
				$('a').button();
				$('#old_password, #new_password, #new_password_2').prop('disabled', false);
				$('input[type=submit]').prop('disabled',false).button();
			});
		";
        $this->domClose();
    }
    private $errors = array ();
}
class IntroDriver extends ContentDriver
{
    public function accept()
    {
        if( ! isset( $_SESSION[ 'security' ] ) )
            throw new Exception( "Access denied" );
        if( isset( $_SESSION[ 'security' ][ 'must_change_pwd' ] ) )
            return true;
        return false;
    }
    protected function doHandleRequest()
    {
        if( isset( $_SESSION[ 'security' ][ 'must_change_pwd' ] ) )
        {
            $errors = array ();
            
            if( isset( $_POST[ 'old_password' ] ) && isset( $_POST[ 'new_password' ] ) && isset( $_POST[ 'new_password_2' ] ) )
            {
                if( strlen( $_POST[ 'old_password' ] ) == 0 )
                    $errors[] = 'The old password must be entered';
                if( strlen( $_POST[ 'new_password' ] ) == 0 )
                    $errors[] = 'The new password must be entered';
                if( strlen( $_POST[ 'new_password_2' ] ) == 0 )
                    $errors[] = 'The confirmation of the new password must be entered';
                
                if( count( $errors ) == 0 && $_POST[ 'new_password' ] !== $_POST[ 'new_password_2' ] )
                    $errors[] = 'The password and the confirmation do not match';
                
                if( count( $errors ) == 0 )
                {
                    $db = Application::instance()->getDB();
                    
                    $uname = pg_escape_string( $_SESSION[ 'user' ][ 'username' ] );
                    $old = pg_escape_string( $_POST[ 'old_password' ] );
                    $new = pg_escape_string( $_POST[ 'new_password' ] );
                    $res = $db->query( "SELECT md5(E'" . $uname . "' || ':' || E'" . $old . "') = (SELECT password FROM person WHERE id = " . ( int ) $_SESSION[ 'user' ][ 'id' ] . ") AS checked;" );
                    if( $res[ 0 ][ 'checked' ] === 't' )
                    {
                        $db->query( "UPDATE person SET password = md5(E'" . $uname . "' || ':' || E'" . $new . "'), must_change_pwd = false WHERE id = " . ( int ) $_SESSION[ 'user' ][ 'id' ] . ";" );
                        unset( $_SESSION[ 'security' ][ 'must_change_pwd' ] );
                        return false;
                    } else
                        $errors[] = 'The old password does not match';
                }
            }
            
            $node = new ChangePassword( $errors );
            $this->printHtml( $node );
        } else
        {
            throw new Exception( "Access denied" );
        }
    }
}
