<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package clearFusionCMS
 * @copyright Copyright (c) 2012 - 2017 clearFusionCMS. All rights reserved.
 * @link http://clearfusioncms.com
 */

/**
 * cfBackendLoginAction Class
 *
 * Class to implement the login action.
 *
 * @package clearFusionCMS
 */
class cfBackendLoginAction extends cfBackendControllerAction {
	/**
	 * Process the action.
	 */
	function process() {
		$this->tpl->setPlaceholder('pwdreseturi', $this->assemble('', 'forgotpwd'));

		$form = new flForm($this->request, 'loginform', $this->assemble('', 'login'), true);

		$username = new flFormElementText($form, 'username');
		$username->setLabel(__('Username', 'cfBackend'))
			->setAutocomplete('username')
			->setRequired()
			->addValidator(new flFormValidatorRequired())
			->addValidator(new flFormValidatorMaxLength(100));

		$password = new flFormElementPassword($form, 'password');
		$password->setLabel(__('Password', 'cfBackend'))
			->setAutocomplete('current-password')
			->setRequired()
			->addValidator(new flFormValidatorRequired());

		$cfg = new flConfigDb('cfSystemSecurity', $this->db);
		if($cfg->get('twoFactor', false)) {
			$twoFactor = new flFormElementText($form, 'twoFactor');
			$twoFactor->setLabel(__('Google Authenticator Code', 'cfBackend'))
				->setDescription(__('If you have two factor authentication enabled on your account then complete this field, otherwise leave it blank.', 'cfBackend'));
		}

		$remember = new flFormElementCheckbox($form, 'rememberme', 0);
		$remember->setLabel(__('Remember Me', 'cfBackend'));

		$submit = new flFormElementSubmit($form, 'login');
		$submit->setCaption(__('Login', 'cfBackend'))
			->setCSS('primary');

		$form->focusElement($username);

		if($form->isSubmitted() && $form->isValid()) {
			if($this->user->authenticate($username->getValue(), $password->getValue(), $remember->getValue())) {
				if(!is_string($editPerm = $this->db->fetchOne('SELECT editperm FROM cf_sites WHERE domain=?', $this->request->getServerName())))
					$editPerm = $this->db->fetchOne('SELECT editperm FROM cf_sites WHERE shortname=?', 'default_site');

				// If not manager access then don't permit user to login
				if($this->user->hasPermission('core.accessmgr', $editPerm)) {
					// If two factor authentication enabled test it
					$secret = $this->user->getAuthKey();
					if(isset($twoFactor) && !empty($secret) && !flAuthTOTP::verifyCode($secret, $twoFactor->getValue())) {
						cfUserAudit::loginFailed($username->getValue());
						$username->forceError(__('You do not have permission to access this system.', 'cfBackend'));
						$this->response->setCookie(clearFusionCMS::getConfig()->get('authCookieMgrName', '__managerauth'), 0, -3600, clearFusionCMS::getConfig()->get('authCookieDomain', ''), clearFusionCMS::getConfig()->get('authCookiePath', '/'), clearFusionCMS::usingSecureCookies(), true);
						$this->user->logout();
					}
					else {
						cfUserAudit::login($this->user->getId(), $this->user->getUsername());
						if ($this->session !== null)
							$this->session->destorySession();
						$this->response->setCookie(clearFusionCMS::getConfig()->get('authCookieMgrName', '__managerauth'), hash_hmac('md5', $this->user->getId() . ($remember->getValue() ? '1' : '0'), $this->user->getSecret()), $remember->getValue() ? flUser::getRememberMeTime() : 0, clearFusionCMS::getConfig()->get('authCookieDomain', ''), clearFusionCMS::getConfig()->get('authCookiePath', '/'), clearFusionCMS::usingSecureCookies(), true);
						$this->response->redirectTo($this->assemble('', 'dashboard', array(), true));
					}
				}
				else {
					cfUserAudit::loginFailed($username->getValue());
					$this->user->logout();
					$username->forceError(__('You do not have permission to access this system.', 'cfBackend'));
				}
			}
			else {
				$state = $this->user->getState();
				if(!in_array($state, [ flUser::AUTH_UNKNOWN, flUser::AUTH_IP_BLOCKED])) {
					cfUserAudit::loginFailed($username->getValue());
				}
				$username->forceError(__('Incorrect username or password.', 'cfBackend'));
			}
		}

		$this->response->setBody($this->tpl->parseDocument('managerLoginPage', 'backend_' . $this->request->getSelf(),
			array(
				'page_title' => __('CMS Login', 'cfBackend'),
				'page_desc' => __('Please enter your login details below.', 'cfBackend'),
				'forgotten' => __('Forgotten your password?', 'cfBackend'),
				'content' => $form->render($this->tpl->getCodeBuffer()),
				'mgr_lang' => fusionLib::getLocale(true)
			)))
			->sendResponse();
	}
}
