Ejemplo n.º 1
0
class SecurePassword(object):
    """Adds hashing (with salting) and verification capabilities to a clear text password."""

    _password_context = context.CryptContext(schemes=["bcrypt"],
                                             deprecated="auto")

    def hash_and_salt_password(self, password: str) -> str:
        """Hash and salt a clear text password using bcrypt.

        Args:
            password (str): Plain text password

        Returns:
            str: Password hash
        """

        return self._password_context.hash(password)

    def verify_password(self, password: str, password_hash: str) -> bool:
        """Verify password.

        Args:
            password (str): Clear text password.
            password_hash (str): Salted and hashed password.

        Returns:
            bool: True if the plain text password is correct.
        """

        return self._password_context.verify(secret=password,
                                             hash=password_hash)
Ejemplo n.º 2
0
    def get_password_context():
        if User._ctx:
            return User._ctx

        schemes = registry.list_crypt_handlers()
        # scrypt throws a warning if the native wheels aren't found
        schemes.remove('scrypt')
        # we can't leave plaintext schemes as they will be misidentified
        for scheme in schemes:
            if scheme.endswith('plaintext'):
                schemes.remove(scheme)
        User._ctx = context.CryptContext(
            schemes=schemes,
            default='bcrypt_sha256',
            bcrypt_sha256__rounds=app.config['CREDENTIAL_ROUNDS'],
            deprecated='auto')
        return User._ctx
Ejemplo n.º 3
0
 def get_password_context(self):
     return context.CryptContext(
         schemes=self.scheme_dict.values(),
         default=self.scheme_dict[app.config['PASSWORD_SCHEME']],
     )
Ejemplo n.º 4
0
class User(Base, Email):
    """ A user is an email address that has a password to access a mailbox.
    """
    __tablename__ = "user"

    domain = db.relationship(Domain,
                             backref=db.backref('users',
                                                cascade='all, delete-orphan'))
    password = db.Column(db.String(255), nullable=False)
    quota_bytes = db.Column(db.Integer(), nullable=False, default=10**9)
    global_admin = db.Column(db.Boolean(), nullable=False, default=False)

    # Features
    enable_imap = db.Column(db.Boolean(), nullable=False, default=True)
    enable_pop = db.Column(db.Boolean(), nullable=False, default=True)

    # Filters
    forward_enabled = db.Column(db.Boolean(), nullable=False, default=False)
    forward_destination = db.Column(db.String(255),
                                    nullable=True,
                                    default=None)
    reply_enabled = db.Column(db.Boolean(), nullable=False, default=False)
    reply_subject = db.Column(db.String(255), nullable=True, default=None)
    reply_body = db.Column(db.Text(), nullable=True, default=None)

    # Settings
    displayed_name = db.Column(db.String(160), nullable=False, default="")
    spam_enabled = db.Column(db.Boolean(), nullable=False, default=True)
    spam_threshold = db.Column(db.Numeric(), nullable=False, default=80.0)

    # Flask-login attributes
    is_authenticated = True
    is_active = True
    is_anonymous = False

    def get_id(self):
        return self.email

    pw_context = context.CryptContext(
        ["sha512_crypt", "sha256_crypt", "md5_crypt"])

    def check_password(self, password):
        reference = re.match('({[^}]+})?(.*)', self.password).group(2)
        return User.pw_context.verify(password, reference)

    def set_password(self, password):
        self.password = '******' + User.pw_context.encrypt(password)

    def get_managed_domains(self):
        if self.global_admin:
            return Domain.query.all()
        else:
            return self.manager_of

    def get_managed_emails(self, include_aliases=True):
        emails = []
        for domain in self.get_managed_domains():
            emails.extend(domain.users)
            if include_aliases:
                emails.extend(domain.aliases)
        return emails

    @classmethod
    def login(cls, email, password):
        user = cls.query.get(email)
        return user if (user and user.check_password(password)) else None
Ejemplo n.º 5
0
class User(Base, Email):
    """ A user is an email address that has a password to access a mailbox.
    """
    __tablename__ = "user"

    domain = db.relationship(Domain,
                             backref=db.backref('users',
                                                cascade='all, delete-orphan'))
    password = db.Column(db.String(255), nullable=False)
    quota_bytes = db.Column(db.Integer(), nullable=False, default=10**9)
    global_admin = db.Column(db.Boolean(), nullable=False, default=False)
    enabled = db.Column(db.Boolean(), nullable=False, default=True)

    # Features
    enable_imap = db.Column(db.Boolean(), nullable=False, default=True)
    enable_pop = db.Column(db.Boolean(), nullable=False, default=True)

    # Filters
    forward_enabled = db.Column(db.Boolean(), nullable=False, default=False)
    forward_destination = db.Column(db.String(255),
                                    nullable=True,
                                    default=None)
    forward_keep = db.Column(db.Boolean(), nullable=False, default=True)
    reply_enabled = db.Column(db.Boolean(), nullable=False, default=False)
    reply_subject = db.Column(db.String(255), nullable=True, default=None)
    reply_body = db.Column(db.Text(), nullable=True, default=None)
    reply_enddate = db.Column(db.Date,
                              nullable=False,
                              default=date(2999, 12, 31))

    # Settings
    displayed_name = db.Column(db.String(160), nullable=False, default="")
    spam_enabled = db.Column(db.Boolean(), nullable=False, default=True)
    spam_threshold = db.Column(db.Integer(), nullable=False, default=80.0)

    # Flask-login attributes
    is_authenticated = True
    is_active = True
    is_anonymous = False

    def get_id(self):
        return self.email

    scheme_dict = {
        'SHA512-CRYPT': "sha512_crypt",
        'SHA256-CRYPT': "sha256_crypt",
        'MD5-CRYPT': "md5_crypt",
        'CRYPT': "des_crypt"
    }
    pw_context = context.CryptContext(
        schemes=scheme_dict.values(),
        default=scheme_dict[app.config['PASSWORD_SCHEME']],
    )

    def check_password(self, password):
        reference = re.match('({[^}]+})?(.*)', self.password).group(2)
        return User.pw_context.verify(password, reference)

    def set_password(self,
                     password,
                     hash_scheme=app.config['PASSWORD_SCHEME'],
                     raw=False):
        """Set password for user with specified encryption scheme
           @password: plain text password to encrypt (if raw == True the hash itself)
        """
        # for the list of hash schemes see https://wiki2.dovecot.org/Authentication/PasswordSchemes
        if raw:
            self.password = '******' + hash_scheme + '}' + password
        else:
            self.password = '******' + hash_scheme + '}' + User.pw_context.encrypt(
                password, self.scheme_dict[hash_scheme])

    def get_managed_domains(self):
        if self.global_admin:
            return Domain.query.all()
        else:
            return self.manager_of

    def get_managed_emails(self, include_aliases=True):
        emails = []
        for domain in self.get_managed_domains():
            emails.extend(domain.users)
            if include_aliases:
                emails.extend(domain.aliases)
        return emails

    def send_welcome(self):
        if app.config["WELCOME"].lower() == "true":
            self.sendmail(app.config["WELCOME_SUBJECT"],
                          app.config["WELCOME_BODY"])

    @classmethod
    def login(cls, email, password):
        user = cls.query.get(email)
        return user if (user and user.enabled
                        and user.check_password(password)) else None
Ejemplo n.º 6
0
import passlib.context as context

_CONTEXT = context.CryptContext(schemes=['argon2'], deprecated='auto')


def hash(password):
    """Hash the given password and return the hash as string."""
    return _CONTEXT.hash(password)


def verify(password, password_hash):
    """Return true if the password results in the hash, else False."""
    return _CONTEXT.verify(password, password_hash)
 def __init__(self) -> None:
     self._context = passlib_context.CryptContext(schemes=["bcrypt"],
                                                  deprecated="auto")