import hashlib import random from collections import OrderedDict from szurubooru import config, db, errors from szurubooru.func import util RANK_MAP = OrderedDict([ (db.User.RANK_ANONYMOUS, 'anonymous'), (db.User.RANK_RESTRICTED, 'restricted'), (db.User.RANK_REGULAR, 'regular'), (db.User.RANK_POWER, 'power'), (db.User.RANK_MODERATOR, 'moderator'), (db.User.RANK_ADMINISTRATOR, 'administrator'), (db.User.RANK_NOBODY, 'nobody'), ]) def get_password_hash(salt, password): ''' Retrieve new-style password hash. ''' digest = hashlib.sha256() digest.update(config.config['secret'].encode('utf8')) digest.update(salt.encode('utf8')) digest.update(password.encode('utf8')) return digest.hexdigest() def get_legacy_password_hash(salt, password): ''' Retrieve old-style password hash. ''' digest = hashlib.sha1() digest.update(b'1A2/$_4xVa') digest.update(salt.encode('utf8')) digest.update(password.encode('utf8')) return digest.hexdigest() def create_password(): alphabet = { 'c': list('bcdfghijklmnpqrstvwxyz'), 'v': list('aeiou'), 'n': list('0123456789'), } pattern = 'cvcvnncvcv' return ''.join(random.choice(alphabet[l]) for l in list(pattern)) def is_valid_password(user, password): assert user salt, valid_hash = user.password_salt, user.password_hash possible_hashes = [ get_password_hash(salt, password), get_legacy_password_hash(salt, password) ] return valid_hash in possible_hashes def has_privilege(user, privilege_name): assert user all_ranks = list(RANK_MAP.keys()) assert privilege_name in config.config['privileges'] assert user.rank in all_ranks minimal_rank = util.flip(RANK_MAP)[ config.config['privileges'][privilege_name]] good_ranks = all_ranks[all_ranks.index(minimal_rank):] return user.rank in good_ranks def verify_privilege(user, privilege_name): assert user if not has_privilege(user, privilege_name): raise errors.AuthError('Insufficient privileges to do this.') def generate_authentication_token(user): ''' Generate nonguessable challenge (e.g. links in password reminder). ''' assert user digest = hashlib.md5() digest.update(config.config['secret'].encode('utf8')) digest.update(user.password_salt.encode('utf8')) return digest.hexdigest()