<?php

/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */



define('ISKUFERTOOLS', true);

if (!defined('BASEDIR')) {
  include_once '..' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'constants.php';
}

session_start();


CodingOperations::encodeEingaben();
CodingOperations::setObStartIfInternalAndExternalEncodingAreDiffrent();
CodingOperations::setEncodingResponseHeader();

SecurityOperations::PurgeInput(true);

$reminder = new Reminder();
$reminder->handle();

class Reminder
{
  const SUCCESS_PASSWORT_GEAENDERT = 'passwortGeaendert';
  const SUCCESS_DBLOPTIN_EMAIL_VERSANDT = 'dblOptinEMailVersandt';
  const ERROR_OPTIN_NICHT_GEFUNDEN = 'optinNichtGefunden';
  const ERROR_KEIN_LOGIN_ANGEGEBEN = 'keinLoginAngegeben';
  const ERROR_KEIN_PASSWORT_ANGEGEBEN = 'keinPasswortAngegeben';
  const ERROR_PASSWORT_NICHT_WIEDERHOLT = 'PasswortNichtWiederholt';
  const ERROR_PASSWORT_PASST_NICHT_ZU_WIEDERHOLUNG = 'PasswortPasstNichtZurWiederholung';
  const ERROR_CAPTCHA_LEER_ODER_FALSCH = 'CaptchaLeerOderFalsch';
  const ERROR_PASSWORT_ZU_KURZ = 'PasswortZuKurz';
  const ERROR_PASSWORT_KEIN_SONDERZEICHEN = 'PasswortKeinSonderzeichen';
  const ERROR_PASSWORT_KEINE_ZIFFER = 'PasswortKeineZiffer';
  const ERROR_LOGIN_NICHT_GEFUNDEN = 'LoginExistiertNicht';
  const ERROR_LOGIN_OHNE_EMAIL = 'LoginHatKeineEMail';
  const ERROR_FEHLER_BEIM_DBLOPTIN_EMAIL_VERSAND = 'dblOptinEMailNichtVersandt';
  const ERROR_XSRF_NOT_OK = 'XsrfNotOk';

  private $status = array();

  public function handle()
  {
    if (GetOperations::isDefined('key')) {
      $this->handleDoubleOptInKey();
    } elseif (PostOperations::isDefined('post_id')) {
      $this->handlePasswordAnfordern();
    }
    $this->showFormular();
  }

  private function handleDoubleOptInKey()
  {
    $optinCode = GetOperations::getVarValue('key');
    $dbwDoubleOptin = new DBWorkDblOptinToolPasswortAnfordern(1, true);
    $optin = $dbwDoubleOptin->getDblOptinByOptin($optinCode);
    if ($optin) {
      $this->aenderePasswort($optin);
      $this->status[] = self::SUCCESS_PASSWORT_GEAENDERT;
    } else {
      $this->status[] = self::ERROR_OPTIN_NICHT_GEFUNDEN;
    }
  }

  private function aenderePasswort($pOptin)
  {
    $login = $pOptin->name;
    $passwordHash = $pOptin->passwort;
    if (StringOperations::strlen($pOptin->passworttext) > 0) {
      $passwordHash = $pOptin->passworttext;
    }
    $hashversion = $pOptin->hashversion;
    $dbwUser = new DBWorkUser(1, true);
    $dbwUser->setHashedPassWD($login, $passwordHash, $hashversion);
    $dbwDoubleOptin = new DBWorkDblOptinToolPasswortAnfordern(1, true);
    $dbwDoubleOptin->deleteByOptin($pOptin->optin);
  }

  private function handlePasswordAnfordern()
  {
    $filter = FilterFactory::getFilterClass();

    $login = $filter->filterLogin(PostOperations::getVarValue('login'));
    $password = trim(PostOperations::getVarValue('password'));
    $passwordRepeat = trim(PostOperations::getVarValue('password_repeat'));

    $validateEingaben = new HandlePasswortAnfordernEingaben($login, $password, $passwordRepeat);

    $xsrf = Xsrf::checkAndUseXsrfFromGet('wt_pw_reminder');
    if ($xsrf != Xsrf::KEY_OK) {
      $this->status = array(self::ERROR_XSRF_NOT_OK);
    } else {
      $statusEingaben = $validateEingaben->validateEingaben();
      $this->status = array_merge($this->status, $statusEingaben);
    }

    if (empty($this->status)) {
      if ($validateEingaben->existiertLogin()) {
        $this->handleSendOptInMail($login, $password);
      }
      $this->status = array(self::SUCCESS_DBLOPTIN_EMAIL_VERSANDT);
    }
  }

  private function showFormular()
  {
    $pwd = new password();
    $pwd->createHTML($this->status);

    CodingOperations::encodeAnzeige();
  }

  private function handleSendOptInMail($pLogin, $pPassword)
  {
    $pw = \PasswordFactory::getLatest();
    $passwordHashed = $pw->getHash($pPassword);
    $hashversion = $pw::getHashversion();
    $dblOptin = $this->getDblOption($pLogin, $passwordHashed, $hashversion);
    $dbwDoubleOptin = new DBWorkDblOptinToolPasswortAnfordern(1, true);
    $dblOptin->optin = $dbwDoubleOptin->saveDblOptin($dblOptin);

    $dbwUser = new DBWorkUser(1, true);
    $user = $dbwUser->getUserbyLogin(StringOperations::strtoupper($pLogin));
    $result = $this->sendOptInMail($dblOptin, $user);

    if (!$result) {
      $dbwDoubleOptin->deleteByOptin($dblOptin->optin);
    }
  }

  private function getDblOption($pLogin, $pPasswordHashed, $pHashversion)
  {
    $dtop = new DateTimeOperations();

    $optin = new WebDblOptin();
    
    $optin->bearbdatum = $dtop->getDateTimeNow();
    $optin->name = $pLogin;
    $optin->passwort = $pPasswordHashed;
    $optin->passworttext = $pPasswordHashed;
    $optin->hashversion = $pHashversion;

    return $optin;
  }

  private function getLinkZuSkript()
  {
    $settingsTool0 = ToolSettingsAPI::getToolSettings(0);
    if ($settingsTool0->SSLAnmeldung || $settingsTool0->SSLLogin) {
      if ($settingsTool0->SSLAnmeldung) {
        return ConstantOperations::getHTTPSPath4Url('') . 'reminder.php';
      } else {
        return ConstantOperations::getHTTPSPath4Url(LOGIN) . 'reminder.php';
      }
    } else {
      return 'http://' . StringOperations::getCompleteUrlToSkript();
    }
  }

  private function sendOptInMail($pDbloptin, $pUser)
  {
    if (!$pDbloptin->isEmpty()) {
      $subject = $this->getPasswortMailBetreff();
      $mailText = $this->getPasswortMailBody($pDbloptin, $pUser);

      $email = new smtpMail();
      $email->SetVar2Value('to', $pUser->email);
      $email->SetVar2Value('subject', $subject);
      $email->SetVar2Value('contenttype', SMTP_CONTENTTYPE_HTML);
      $email->SetVar2Value('body', $mailText);
      $retour = $email->sendMail();
      if (!$retour) {
        Logger::logg('Tools Passwort DoubleOptin: Fehler beim Versenden der eMail an ' . $pUser->email, 50);
      } else {
        Logger::logg('Tools Passwort DoubleOptin: dbloptin mail sent', 1);
      }

      return $retour;
    } else {
      return false;
    }
  }

  private function getPasswortMailBetreff()
  {
    $objsettings = ToolSettingsAPI::getToolSettings(0);
    if (isset($objsettings->vorlagePasswortEMailBetreff) && trim($objsettings->vorlagePasswortEMailBetreff) !== '') {
      return $objsettings->vorlagePasswortEMailBetreff;
    } else {
      return MenuEinstellAllg::getDefaultPasswortMailBetreff();
    }
  }

  private function getPasswortMailBody($pDbloptin, $pUser)
  {
    $objsettings = ToolSettingsAPI::getToolSettings(0);
    $allgeinstell = AllgSettingsAPI::getAllgSettings();

    if (isset($objsettings->vorlagePasswortEMailInhalt) && trim($objsettings->vorlagePasswortEMailInhalt) !== '') {
      $mailText = $objsettings->vorlagePasswortEMailInhalt;
    } else {
      $mailText = MenuEinstellAllg::getDefaultPasswortMailBody();
    }
    $linkZuSkript = $this->getLinkZuSkript();
    $linkDblOptIn = $linkZuSkript . '?key=' . $pDbloptin->optin;
    $newtoolsmessage = '';
    $mailText = nl2br($mailText);
    $mailText = str_replace('{%ansprache%}', $pUser->getVarValue('ansprache_default'), $mailText);
    $mailText = str_replace('{%aktivierungslink%}', '<a href="' . $linkDblOptIn . '">' . $linkDblOptIn . '</a>', $mailText);
    $mailText = str_replace('{%linkhref%}', $linkDblOptIn, $mailText);
    $mailText = str_replace('{%newtoolsmessage%}', $newtoolsmessage, $mailText);
    $mailText = str_replace('{%linkzumformular%}', '<a href="' . $linkZuSkript . '">' . $linkZuSkript . '</a>', $mailText);

    return str_replace('{%einrichtungsname%}', $allgeinstell->vhsname, $mailText);
  }
}

class HandlePasswortAnfordernEingaben
{
  private $status = array();
  private $login;
  private $password;
  private $passwordRepeat;

  public function __construct($pLogin, $pPassword, $pPasswordRepeat)
  {
    $this->login = $pLogin;
    $this->password = $pPassword;
    $this->passwordRepeat = $pPasswordRepeat;
  }

  public function validateEingaben()
  {
    $this->validateLogin();
    $this->validatePasswoerterGefuellt();
    $this->validateCaptcha();

    if ($this->password !== '') {
      $this->validatePasswortErfuelltVoraussetzungen();
    }

    return $this->status;
  }

  private function validateLogin()
  {
    if (trim($this->login) === '') {
      $this->status[] = Reminder::ERROR_KEIN_LOGIN_ANGEGEBEN;
    }
  }

  public function existiertLogin()
  {
    $dbwUser = new DBWorkUser(1, true);
    $user = $dbwUser->getUserbyLogin(StringOperations::strtoupper($this->login));
    if ($user->isEmpty()) {
      Logger::logg('KuferTools Passwort anfordern: Login nicht gefunden', 50);

      return false;
    } elseif ($user->email == '') {
      Logger::logg('KuferTools Passwort anfordern: Login hat keine E-Mail', 50);

      return false;
    }

    return true;
  }

  private function validateCaptcha()
  {
    $captcha = new \Kufer\Web\Classes\Captchas\SimpleCaptcha();
    if (!$captcha->isValid(null, true, 'tedit', true)) {
      $this->status[] = Reminder::ERROR_CAPTCHA_LEER_ODER_FALSCH;
    }
  }

  private function validatePasswoerterGefuellt()
  {
    if ($this->password === '') {
      $this->status[] = Reminder::ERROR_KEIN_PASSWORT_ANGEGEBEN;
    } elseif ($this->passwordRepeat === '') {
      $this->status[] = Reminder::ERROR_PASSWORT_NICHT_WIEDERHOLT;
    } elseif ($this->password !== $this->passwordRepeat) {
      $this->status[] = Reminder::ERROR_PASSWORT_PASST_NICHT_ZU_WIEDERHOLUNG;
    }
  }

  private function validatePasswortErfuelltVoraussetzungen()
  {
    $pwOp = new PasswordOperations();
    if (!$pwOp->validSize($this->password)) {
      $this->status[] = Reminder::ERROR_PASSWORT_ZU_KURZ;
    }
    if (!$pwOp->validSpecialChars($this->password)) {
      $this->status[] = Reminder::ERROR_PASSWORT_KEIN_SONDERZEICHEN;
    }
    if (!$pwOp->validNumbers($this->password)) {
      $this->status[] = Reminder::ERROR_PASSWORT_KEINE_ZIFFER;
    }
  }
}