3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 01:09:22 +01:00

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.
This commit is contained in:
James Lu 2016-11-19 17:00:18 -08:00
parent 69066029f1
commit b1e4b34b79
3 changed files with 39 additions and 25 deletions

View File

@ -41,6 +41,7 @@ First, make sure the following dependencies are met:
* Setuptools (`pip3 install setuptools`)
* PyYAML (`pip3 install pyyaml`)
* [ircmatch](https://github.com/mammon-ircd/ircmatch) (`pip3 install ircmatch`)
* passlib (`pip3 install passlib`)
* *For the servprotect plugin*: [expiringdict](https://github.com/mailgun/expiringdict) (install this from source; installation is broken in pip due to [mailgun/expiringdict#13](https://github.com/mailgun/expiringdict/issues/13))
1) Clone the repository: `git clone https://github.com/GLolol/PyLink && cd PyLink`

View File

@ -9,7 +9,7 @@ import gc
import sys
import importlib
from . import control
from . import control, login
from pylinkirc import utils, world, conf
from pylinkirc.log import log
@ -43,27 +43,18 @@ def identify(irc, source, args):
irc.reply('Error: Not enough arguments.')
return
username = username.lower()
# Process new-style accounts.
if login.checkLogin(username, password):
_login(irc, source, username)
return
# Process new-style accounts. Note: usernames are case-insensitive, passwords are NOT.
for account, block in conf.conf['login'].get('accounts', {}).items():
if account.lower() == username:
# Username matched config.
if password and password == block.get('password'):
# Password exists and matched config. TODO: hash user passwords in config.
_login(irc, source, account)
break
else:
_loginfail(irc, source, account)
break
# Process legacy logins (login:user).
if username.lower() == conf.conf['login'].get('user', '').lower() and password == conf.conf['login'].get('password'):
realuser = conf.conf['login']['user']
_login(irc, source, realuser)
else:
# Process legacy logins (login:user).
if username.lower() == conf.conf['login'].get('user', '').lower() and password == conf.conf['login'].get('password'):
realuser = conf.conf['login']['user']
_login(irc, source, realuser)
else:
# Username not found.
_loginfail(irc, source, username)
# Username not found.
_loginfail(irc, source, username)
@utils.add_cmd

View File

@ -1,5 +1,5 @@
"""
login.py - Implement core login abstraction
login.py - Implement core login abstraction.
"""
from pylinkirc import conf, utils, world
@ -8,12 +8,33 @@ 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."""
try:
passhash = conf.conf['login']['accounts'][user].get('password')
except KeyError: # Invalid combination
accounts = conf.conf['login'].get('accounts')
if not accounts:
# No accounts specified, return.
return False
return verifyHash(password, passhash)
# 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."""
@ -38,6 +59,7 @@ def mkpasswd(irc, source, args):
return
if not password:
irc.error("Password cannot be empty.")
return
hashed_pass = pwd_context.encrypt(password)
irc.reply(hashed_pass, private=True)