From 033a86381b245a59836c5c67a77b5a3684ff83f8 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 28 Oct 2017 12:41:34 +0200 Subject: [PATCH] Removed password decoding from UserManager Decode only when passwords are coming from API query parameters --- supysonic/api/__init__.py | 11 +++++++++++ supysonic/api/user.py | 3 +++ supysonic/managers/user.py | 16 ---------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/supysonic/api/__init__.py b/supysonic/api/__init__.py index ca96ae5..21ca9c0 100644 --- a/supysonic/api/__init__.py +++ b/supysonic/api/__init__.py @@ -23,6 +23,7 @@ from xml.etree import ElementTree from xml.dom import minidom import simplejson import uuid +import binascii from supysonic.web import app, store from supysonic.managers.user import UserManager @@ -51,6 +52,15 @@ def set_formatter(): request.error_formatter = lambda code, msg: request.formatter({ 'error': { 'code': code, 'message': msg } }, error = True) +def decode_password(password): + if not password.startswith('enc:'): + return password + + try: + return binascii.unhexlify(password[4:]).decode('utf-8') + except: + return password + @app.before_request def authorize(): if not request.path.startswith('/rest/'): @@ -69,6 +79,7 @@ def authorize(): if not username or not password: return error + password = decode_password(password) status, user = UserManager.try_auth(store, username, password) if status != UserManager.SUCCESS: return error diff --git a/supysonic/api/user.py b/supysonic/api/user.py index 1303e88..2d26616 100644 --- a/supysonic/api/user.py +++ b/supysonic/api/user.py @@ -22,6 +22,7 @@ from flask import request from supysonic.web import app, store from supysonic.db import User from supysonic.managers.user import UserManager +from . import decode_password @app.route('/rest/getUser.view', methods = [ 'GET', 'POST' ]) def user_info(): @@ -55,6 +56,7 @@ def user_add(): return request.error_formatter(10, 'Missing parameter') admin = True if admin in (True, 'True', 'true', 1, '1') else False + password = decode_password(password) status = UserManager.add(store, username, password, email, admin) if status == UserManager.NAME_EXISTS: return request.error_formatter(0, 'There is already a user with that username') @@ -86,6 +88,7 @@ def user_changepass(): if username != request.username and not request.user.admin: return request.error_formatter(50, 'Admin restricted') + password = decode_password(password) status = UserManager.change_password2(store, username, password) if status != UserManager.SUCCESS: return request.error_formatter(0, UserManager.error_str(status)) diff --git a/supysonic/managers/user.py b/supysonic/managers/user.py index d4704b5..8643d2e 100644 --- a/supysonic/managers/user.py +++ b/supysonic/managers/user.py @@ -9,7 +9,6 @@ # # Distributed under terms of the GNU AGPLv3 license. -import binascii import string import random import hashlib @@ -49,7 +48,6 @@ class UserManager: if store.find(User, User.name == name).one(): return UserManager.NAME_EXISTS - password = UserManager.__decode_password(password) crypt, salt = UserManager.__encrypt_password(password) user = User() @@ -88,7 +86,6 @@ class UserManager: @staticmethod def try_auth(store, name, password): - password = UserManager.__decode_password(password) user = store.find(User, User.name == name).one() if not user: return UserManager.NO_SUCH_USER, None @@ -103,9 +100,6 @@ class UserManager: if status != UserManager.SUCCESS: return status - old_pass = UserManager.__decode_password(old_pass) - new_pass = UserManager.__decode_password(new_pass) - if UserManager.__encrypt_password(old_pass, user.salt)[0] != user.password: return UserManager.WRONG_PASS @@ -119,7 +113,6 @@ class UserManager: if not user: return UserManager.NO_SUCH_USER - new_pass = UserManager.__decode_password(new_pass) user.password = UserManager.__encrypt_password(new_pass, user.salt)[0] store.commit() return UserManager.SUCCESS @@ -145,12 +138,3 @@ class UserManager: salt = ''.join(random.choice(string.printable.strip()) for i in xrange(6)) return hashlib.sha1(salt.encode('utf-8') + password.encode('utf-8')).hexdigest(), salt - @staticmethod - def __decode_password(password): - if not password.startswith('enc:'): - return password - - try: - return binascii.unhexlify(password[4:]).decode('utf-8') - except: - return password