PHP Classes

File: src/Discretion/Struct/User.php

Recommend this page to a friend!
  Packages of Scott Arciszewski   Discretion   src/Discretion/Struct/User.php   Download  
File: src/Discretion/Struct/User.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Discretion
Show contact forms and deliver encrypted mail
Author: By
Last change:
Date: 5 years ago
Size: 5,008 bytes
 

Contents

Class file image Download
<?php
declare(strict_types=1);
namespace ParagonIE\Discretion\Struct;

use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\Discretion\{
    Discretion,
    SimpleCrypto,
    Struct
};
use ParagonIE\Discretion\Data\HiddenString;
use ParagonIE\Discretion\Exception\RecordNotFound;
use ParagonIE\Discretion\Policies\Unique;

/**
 * Class User
 * @package ParagonIE\Discretion\Struct
 */
class User extends Struct implements Unique
{
    const BCRYPT_COST = 12;
    const TABLE_NAME = 'discretion_users';
    const PRIMARY_KEY = 'userid';
    const DB_FIELD_NAMES = [
        'userid' => 'id',
        'active' => 'active',
        'username' => 'username',
        'pwhash' => 'pwHash',
        'twofactor' => 'twoFactorSecret',
        'email' => 'email',
        'fullname' => 'fullName',
        'chronicle' => 'chronicle'
    ];
    const BOOLEAN_FIELDS = ['active'];

    /** @var bool $active */
    protected $active = false;

    /** @var string $chronicle */
    protected $chronicle = '';

    /** @var string $email */
    protected $email = '';

    /** @var string $fullName */
    protected $fullName = '';

    /** @var string $username */
    protected $username = '';

    /** @var string $pwHash */
    protected $pwHash = '';

    /** @var string $twoFactorSecret */
    protected $twoFactorSecret = '';

    /**
     * @param string $username
     * @return self
     * @throws RecordNotFound
     */
    public static function byUsername(string $username): self
    {
        /** @var int $userId */
        $userId = Discretion::getDatabase()->cell(
            "SELECT userid FROM discretion_users WHERE username = ?",
            $username
        );
        if (empty($userId)) {
            throw new RecordNotFound('No user with the username ' . $username);
        }
        return static::byId((int) $userId);
    }

    /**
     * @param HiddenString $password
     * @return bool
     */
    public function checkPassword(HiddenString $password): bool
    {
        $preHash = Base64UrlSafe::encode(
            \ParagonIE_Sodium_Compat::crypto_generichash(
                $password->getString(),
                '',
                54
            )
        );
        $stored = SimpleCrypto::decrypt(
            $this->pwHash,
            Discretion::getLocalEncryptionKey()
        );
        return \password_verify(
            $preHash,
            $stored->getString()
        );
    }

    /**
     * @return HiddenString
     */
    public function get2FASecret(): HiddenString
    {
        return SimpleCrypto::decrypt(
            $this->twoFactorSecret,
            Discretion::getLocalEncryptionKey()
        );
    }

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->active;
    }

    /**
     * Overwrite the 2FA secret.
     *
     * @param HiddenString $secret
     * @return self
     */
    public function set2FASecret(HiddenString $secret): self
    {
        $this->twoFactorSecret = SimpleCrypto::encrypt(
            $secret,
            Discretion::getLocalEncryptionKey()
        );
        return $this;
    }

    /**
     * @param bool $isActive
     * @return self
     */
    public function setActive(bool $isActive): self
    {
        $this->active = $isActive;
        return $this;
    }

    /**
     * @param string $email
     * @return self
     */
    public function setEmail(string $email): self
    {
        $this->email = $email;
        return $this;
    }

    /**
     * @param string $fullName
     * @return self
     */
    public function setFullName(string $fullName): self
    {
        $this->fullName = $fullName;
        return $this;
    }

    /**
     * @param HiddenString $password
     * @return self
     */
    public function setPassword(HiddenString $password): self
    {
        // Prehash it to prevent bcrypt truncation.
        $preHash = Base64UrlSafe::encode(
            \ParagonIE_Sodium_Compat::crypto_generichash(
                $password->getString(),
                '',
                54
            )
        );
        $this->pwHash = SimpleCrypto::encrypt(
            new HiddenString(
                \password_hash(
                    $preHash,
                    PASSWORD_DEFAULT,
                    ['cost' => static::BCRYPT_COST]
                )
            ),
            Discretion::getLocalEncryptionKey()
        );
        return $this;
    }

    /**
     * @param string $username
     * @return self
     */
    public function setUsername(string $username): self
    {
        $this->username = $username;
        return $this;
    }

    /**
     * @param string $username
     * @return bool
     */
    public static function usernameIsTaken(string $username): bool
    {
        /** @psalm-suppress InvalidArgument Trust me on this one, Psalm. */
        return Discretion::getDatabase()->exists(
            "SELECT count(*) FROM discretion_users WHERE username = ?",
            $username
        );
    }
}