<commit_before><?php
namespace Firesphere\YubiAuth;

use Config;
use Controller;
use DateTime;
use Form;
use Member;
use MemberAuthenticator;
use ValidationResult;

/**
 * Class YubikeyAuthenticator
 *
 * Enable Yubikey Authentication.
 */
class YubikeyAuthenticator extends MemberAuthenticator
{
    /**
     * @var null|Form
     */
    protected static $form = null;

    /**
     * @inheritdoc
     *
     * @param array $data
     * @param Form|null $form
     *
     * @return null|Member
     */
    public static function authenticate($data, Form $form = null)
    {
        Config::inst()->update('Security', 'login_recording', false); // Disable login_recording for this auth.
        // First, let's see if we know the member
        $member = parent::authenticate($data, $form);
        Config::inst()->update('Security', 'login_recording', true);
        $validationError = ValidationResult::create(false,
            _t('YubikeyAuthenticator.ERRORYUBIKEY', 'Yubikey authentication error'));
        self::$form = $form;
        if ($member && $member instanceof Member) {
            // If we know the member, and it's YubiAuth enabled, continue.
            if ($member &&
                ($member->YubiAuthEnabled || $data['Yubikey'] !== '')
            ) {
                return self::authenticate_yubikey($data, $member, $validationError);
            } elseif (!$member->YubiAuthEnabled) { // We do not have to check the YubiAuth for now.
                return self::noYubiAuth($form, $member);
            }
        }
        if ($member) {
            $member->registerFailedLogin();
        }
        self::updateForm($validationError, $form);

        return null;
    }

    /**
     * @param Controller $controller
     *
     * @return Form
     */
    public static function get_login_form(Controller $controller)
    {
        return YubikeyLoginForm::create($controller, 'LoginForm');
    }

    public static function get_name()
    {
        return _t('YubikeyAuthenticator.TITLE', 'Yubikey login');
    }

    /**
     * Update the member to forcefully enable YubiAuth
     * Also, register the Yubikey to the member.
     * Documentation:
     * https://developers.yubico.com/yubikey-val/Getting_Started_Writing_Clients.html
     *
     * @param Member $member
     * @param string $yubiString
     */
    private static function updateMember($member, $yubiString)
    {
        if (!$member->YubiAuthEnabled) {
            $member->YubiAuthEnabled = true;
        }
        if (!$member->Yubikey) {
            $member->Yubikey = $yubiString;
        }
        $member->write();
    }

    /**
     * @param ValidationResult $validation
     * @param null|Form $form
     */
    private static function updateForm($validation, $form)
    {
        if ($form) {
            $form->sessionMessage($validation->message(), 'bad');
        }

    }

    /**
     * @param Form $form
     * @param $member
     * @return null
     */
    public static function noYubiAuth(Form $form, $member)
    {
        $member->NoYubikeyCount += 1;
        $member->write();
        $maxNoYubi = Config::inst()->get('YubikeyAuthenticator', 'MaxNoYubiLogin');
        if ($maxNoYubi > 0 && $maxNoYubi <= $member->NoYubikeyCount) {
            $validationError = ValidationResult::create(false,
                _t('YubikeyAuthenticator.ERRORMAXYUBIKEY', 'Maximum login without yubikey exceeded'));
            self::updateForm($validationError, $form);
            $member->registerFailedLogin();

            return null;
        }
        $date1 = new DateTime($member->Created);
        $date2 = new DateTime(date('Y-m-d'));

        $diff = $date2->diff($date1)->format("%a");
        $maxNoYubiDays = Config::inst()->get('YubikeyAuthenticator', 'MaxNoYubiLoginDays');

        if ($maxNoYubiDays > 0 && $diff >= $maxNoYubiDays) {
            $validationError = ValidationResult::create(false,
                _t('YubikeyAuthenticator.ERRORMAXYUBIKEYDAYS', 'Maximum days without yubikey exceeded'));
            self::updateForm($validationError, $form);
            $member->registerFailedLogin();

            return null;

        }

        return $member;
    }

    /**
     * @param $data
     * @param $member
     * @param $validationError
     * @return null
     */
    public static function authenticate_yubikey($data, $member, $validationError)
    {
        $form = self::$form;
        $data['Yubikey'] = strtolower($data['Yubikey']);
        $yubiCode = QwertyConvertor::convertString($data['Yubikey']);
        $yubiFingerprint = substr($yubiCode, 0, -32);
        // If the member has a yubikey ID set, compare it to the fingerprint.
        if ($member->Yubikey && strpos($yubiFingerprint, $member->Yubikey) !== 0) {
            self::updateForm($validationError, $form);

            return null; // Yubikey id doesn't match the member.
        }
        $clientID = YUBIAUTH_CLIENTID;
        $apiKey = YUBIAUTH_APIKEY;
        $service = new \Yubikey\Validate($apiKey, $clientID);
        if ($url = self::config()->get('AuthURL')) {
            $service->setHost($url);
        }
        $result = $service->check($yubiCode);

        if ($result->success() === true) {
            self::updateMember($member, $yubiFingerprint);
            if ($member) {
                $member->registerSuccessfulLogin();
                $member->NoYubikeyCount = 0;
                $member->write();
            }

            return $member;
        } else {
            self::updateForm($validationError, $form);

            return null;
        }
    }

}<commit_msg>Update docblocks<commit_after><?php
namespace Firesphere\YubiAuth;

use Config;
use Controller;
use DateTime;
use Form;
use Member;
use MemberAuthenticator;
use ValidationResult;

/**
 * Class YubikeyAuthenticator
 *
 * Enable Yubikey Authentication.
 */
class YubikeyAuthenticator extends MemberAuthenticator
{
    /**
     * @var null|Form
     */
    protected static $form = null;

    /**
     * @inheritdoc
     *
     * @param array $data
     * @param Form|null $form
     *
     * @return null|Member
     */
    public static function authenticate($data, Form $form = null)
    {
        Config::inst()->update('Security', 'login_recording', false); // Disable login_recording for this auth.
        // First, let's see if we know the member
        $member = parent::authenticate($data, $form);
        Config::inst()->update('Security', 'login_recording', true);
        $validationError = ValidationResult::create(false,
            _t('YubikeyAuthenticator.ERRORYUBIKEY', 'Yubikey authentication error'));
        self::$form = $form;
        if ($member && $member instanceof Member) {
            // If we know the member, and it's YubiAuth enabled, continue.
            if ($member &&
                ($member->YubiAuthEnabled || $data['Yubikey'] !== '')
            ) {
                return self::authenticate_yubikey($data, $member, $validationError);
            } elseif (!$member->YubiAuthEnabled) { // We do not have to check the YubiAuth for now.
                return self::noYubiAuth($form, $member);
            }
        }
        if ($member) {
            $member->registerFailedLogin();
        }
        self::updateForm($validationError, $form);

        return null;
    }

    /**
     * @param Controller $controller
     *
     * @return Form
     */
    public static function get_login_form(Controller $controller)
    {
        return YubikeyLoginForm::create($controller, 'LoginForm');
    }

    public static function get_name()
    {
        return _t('YubikeyAuthenticator.TITLE', 'Yubikey login');
    }

    /**
     * Update the member to forcefully enable YubiAuth
     * Also, register the Yubikey to the member.
     * Documentation:
     * https://developers.yubico.com/yubikey-val/Getting_Started_Writing_Clients.html
     *
     * @param Member $member
     * @param string $yubiString
     */
    private static function updateMember($member, $yubiString)
    {
        if (!$member->YubiAuthEnabled) {
            $member->YubiAuthEnabled = true;
        }
        if (!$member->Yubikey) {
            $member->Yubikey = $yubiString;
        }
        $member->write();
    }

    /**
     * @param ValidationResult $validation
     * @param null|Form $form
     */
    private static function updateForm($validation, $form)
    {
        if ($form) {
            $form->sessionMessage($validation->message(), 'bad');
        }

    }

    /**
     * @param Form $form
     * @param Member $member
     * @return null|Member
     */
    public static function noYubiAuth(Form $form, $member)
    {
        $member->NoYubikeyCount += 1;
        $member->write();
        $maxNoYubi = Config::inst()->get('YubikeyAuthenticator', 'MaxNoYubiLogin');
        if ($maxNoYubi > 0 && $maxNoYubi <= $member->NoYubikeyCount) {
            $validationError = ValidationResult::create(false,
                _t('YubikeyAuthenticator.ERRORMAXYUBIKEY', 'Maximum login without yubikey exceeded'));
            self::updateForm($validationError, $form);
            $member->registerFailedLogin();

            return null;
        }
        $date1 = new DateTime($member->Created);
        $date2 = new DateTime(date('Y-m-d'));

        $diff = $date2->diff($date1)->format("%a");
        $maxNoYubiDays = Config::inst()->get('YubikeyAuthenticator', 'MaxNoYubiLoginDays');

        if ($maxNoYubiDays > 0 && $diff >= $maxNoYubiDays) {
            $validationError = ValidationResult::create(false,
                _t('YubikeyAuthenticator.ERRORMAXYUBIKEYDAYS', 'Maximum days without yubikey exceeded'));
            self::updateForm($validationError, $form);
            $member->registerFailedLogin();

            return null;

        }

        return $member;
    }

    /**
     * @param array $data
     * @param Member $member
     * @param ValidationResult $validationError
     * @return null|Member
     */
    public static function authenticate_yubikey($data, $member, $validationError)
    {
        $form = self::$form;
        $data['Yubikey'] = strtolower($data['Yubikey']);
        $yubiCode = QwertyConvertor::convertString($data['Yubikey']);
        $yubiFingerprint = substr($yubiCode, 0, -32);
        // If the member has a yubikey ID set, compare it to the fingerprint.
        if ($member->Yubikey && strpos($yubiFingerprint, $member->Yubikey) !== 0) {
            self::updateForm($validationError, $form);

            return null; // Yubikey id doesn't match the member.
        }
        $clientID = YUBIAUTH_CLIENTID;
        $apiKey = YUBIAUTH_APIKEY;
        $service = new \Yubikey\Validate($apiKey, $clientID);
        if ($url = self::config()->get('AuthURL')) {
            $service->setHost($url);
        }
        $result = $service->check($yubiCode);

        if ($result->success() === true) {
            self::updateMember($member, $yubiFingerprint);
            if ($member) {
                $member->registerSuccessfulLogin();
                $member->NoYubikeyCount = 0;
                $member->write();
            }

            return $member;
        } else {
            self::updateForm($validationError, $form);

            return null;
        }
    }

}
{'fraction_non_alphanumeric': 0.13465979747734944, 'fraction_numerical': 0.0021318173743116006, 'mean_word_length': 2.274869109947644, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 71, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '123498', 'n_tokens_mistral': 3439, 'n_tokens_neox': 3334, 'n_words': 699}