3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 09:19:23 +01:00
PyLink/coremods/login.py
James Lu b1e4b34b79 Switch 'identify' to use the new login backend, add passlib to README dependencies
This new backend supports optional encryption (sha256_crypt / sha512_crypt via passlib). Closes #322.
2016-11-19 17:21:45 -08:00

66 lines
2.0 KiB
Python

"""
login.py - Implement core login abstraction.
"""
from pylinkirc import conf, utils, world
from pylinkirc.log import log
from passlib.apps import custom_app_context as pwd_context
def checkLogin(user, password):
"""Checks whether the given user and password is a valid combination."""
accounts = conf.conf['login'].get('accounts')
if not accounts:
# No accounts specified, return.
return False
# Lowercase account names to make them case insensitive. TODO: check for
# duplicates.
user = user.lower()
accounts = {k.lower(): v for k, v in accounts.items()}
try:
account = accounts[user]
except KeyError: # Invalid combination
return False
else:
passhash = account.get('password')
if not passhash:
# No password given, return. XXX: we should allow plugins to override
# this in the future.
return False
# Encryption in account passwords is optional (to not break backwards
# compatibility).
if account.get('encrypted', False):
return verifyHash(password, passhash)
else:
return password == passhash
def verifyHash(password, passhash):
"""Checks whether the password given matches the hash."""
if password:
# ... good we have a password inputted
# XXX: the greatest thing here is that the hash
# is just a string either way, not a object with
# a method to output the hash
return pwd_context.verify(password, passhash)
return False
@utils.add_cmd
def mkpasswd(irc, source, args):
"""<password>
Hashes a password for use in the configuration file."""
# TODO: restrict to only certain users?
try:
password = args[0]
except IndexError:
irc.error("Not enough arguments. (Needs 1, password)")
return
if not password:
irc.error("Password cannot be empty.")
return
hashed_pass = pwd_context.encrypt(password)
irc.reply(hashed_pass, private=True)