diff --git a/api/user.py b/api/user.py index c023174..17e9492 100755 --- a/api/user.py +++ b/api/user.py @@ -3,6 +3,8 @@ from flask import request from web import app from db import User +from . import hexdecode +from user_manager import UserManager @app.route('/rest/getUser.view', methods = [ 'GET', 'POST' ]) def user_info(): @@ -10,26 +12,72 @@ def user_info(): if username is None: return request.error_formatter(10, 'Missing username') + if username != request.username and not request.user.admin: + return request.error_formatter(50, 'Admin restricted') + user = User.query.filter(User.name == username).first() if user is None: return request.error_formatter(0, 'Unknown user') - return request.formatter({ - 'user': { - 'username': user.name, - 'email': user.mail, - 'scrobblingEnabled': user.lastfm_session is not None and user.lastfm_status, - 'adminRole': user.admin, - 'settingsRole': user.admin, - 'downloadRole': True, - 'uploadRole': False, - 'playlistRole': False, - 'coverArtRole': False, - 'commentRole': False, - 'podcastRole': False, - 'streamRole': True, - 'jukeboxRole': False, - 'shareRole': False - } - }) + return request.formatter({ 'user': user.as_subsonic_user() }) + +@app.route('/rest/getUsers.view', methods = [ 'GET', 'POST' ]) +def users_info(): + if not request.user.admin: + return request.error_formatter(50, 'Admin restricted') + + return request.formatter({ 'users': { 'user': [ u.as_subsonic_user() for u in User.query.all() ] } }) + +@app.route('/rest/createUser.view', methods = [ 'GET', 'POST' ]) +def user_add(): + if not request.user.admin: + return request.error_formatter(50, 'Admin restricted') + + username, password, email, admin = map(request.args.get, [ 'username', 'password', 'email', 'adminRole' ]) + if not username or not password or not email: + return request.error_formatter(10, 'Missing parameter') + admin = True if admin in (True, 'True', 'true', 1, '1') else False + + if password.startswith('enc:'): + password = hexdecode(password[4:]) + + status = UserManager.add(username, password, email, admin) + if status == UserManager.NAME_EXISTS: + return request.error_formatter(0, 'There is already a user with that username') + + return request.formatter({}) + +@app.route('/rest/deleteUser.view', methods = [ 'GET', 'POST' ]) +def user_del(): + if not request.user.admin: + return request.error_formatter(50, 'Admin restricted') + + username = request.args.get('username') + user = User.query.filter(User.name == username).first() + if not user: + return request.error_formatter(70, 'Unknown user') + + status = UserManager.delete(user.id) + if status != UserManager.SUCCESS: + return request.error_formatter(0, UserManager.error_str(status)) + + return request.formatter({}) + +@app.route('/rest/changePassword.view', methods = [ 'GET', 'POST' ]) +def user_changepass(): + username, password = map(request.args.get, [ 'username', 'password' ]) + if not username or not password: + return request.error_formatter(10, 'Missing parameter') + + if username != request.username and not request.user.admin: + return request.error_formatter(50, 'Admin restricted') + + if password.startswith('enc:'): + password = hexdecode(password[4:]) + + status = UserManager.change_password2(username, password) + if status != UserManager.SUCCESS: + return request.error_formatter(0, UserManager.error_str(status)) + + return request.formatter({}) diff --git a/db.py b/db.py index 54e98d6..7c43ada 100755 --- a/db.py +++ b/db.py @@ -64,6 +64,24 @@ class User(Base): last_play = relationship('Track') last_play_date = Column(DateTime, nullable = True) + def as_subsonic_user(self): + return { + 'username': self.name, + 'email': self.mail, + 'scrobblingEnabled': self.lastfm_session is not None and self.lastfm_status, + 'adminRole': self.admin, + 'settingsRole': True, + 'downloadRole': True, + 'uploadRole': False, + 'playlistRole': False, + 'coverArtRole': False, + 'commentRole': False, + 'podcastRole': False, + 'streamRole': True, + 'jukeboxRole': False, + 'shareRole': False + } + class Folder(Base): __tablename__ = 'folder' diff --git a/user_manager.py b/user_manager.py index a3b5423..54fcf38 100755 --- a/user_manager.py +++ b/user_manager.py @@ -76,6 +76,16 @@ class UserManager: session.commit() return UserManager.SUCCESS + @staticmethod + def change_password2(name, new_pass): + user = User.query.filter(User.name == name).first() + if not user: + return UserManager.NO_SUCH_USER + + user.password = UserManager.__encrypt_password(new_pass, user.salt)[0] + session.commit() + return UserManager.SUCCESS + @staticmethod def error_str(err): if err == UserManager.SUCCESS: