Support auth

This commit is contained in:
dave 2017-08-15 20:26:03 -07:00
parent 7c13750b4a
commit f17d53296e
2 changed files with 41 additions and 1 deletions

View File

@ -14,6 +14,9 @@ def main():
parser.add_argument('-p', '--port', default=8080, type=int, help="tcp port to listen on") parser.add_argument('-p', '--port', default=8080, type=int, help="tcp port to listen on")
parser.add_argument('-d', '--dirs', required=True, nargs='+', help="new music dirs to share") parser.add_argument('-d', '--dirs', required=True, nargs='+', help="new music dirs to share")
parser.add_argument('-u', '--user', nargs='+', type=lambda x: x.split(":"), default=[],
help="user:password pairs for auth")
parser.add_argument('--disable-auth', action="store_true", help="disable authentication")
parser.add_argument('-s', '--database-path', default="./db.sqlite", help="path to persistent sqlite database") parser.add_argument('-s', '--database-path', default="./db.sqlite", help="path to persistent sqlite database")
parser.add_argument('--debug', action="store_true", help="enable development options") parser.add_argument('--debug', action="store_true", help="enable development options")
@ -35,11 +38,22 @@ def main():
pass pass
library.update() library.update()
for username, password in args.user:
db.add_user(username, password)
logging.warning("Libraries: {}".format([i["name"] for i in library.get_libraries()])) logging.warning("Libraries: {}".format([i["name"] for i in library.get_libraries()]))
logging.warning("Artists: {}".format([i["name"] for i in library.get_artists()])) logging.warning("Artists: {}".format([i["name"] for i in library.get_artists()]))
logging.warning("Albums: {}".format(len(library.get_albums()))) logging.warning("Albums: {}".format(len(library.get_albums())))
cherrypy.tree.mount(PysonicApi(db, library, args), '/rest/', {'/': {}}) api_config = {}
if args.disable_auth:
logging.warning("starting up with auth disabled")
else:
api_config.update({'tools.auth_basic.on': True,
'tools.auth_basic.realm': 'pysonic',
'tools.auth_basic.checkpassword': db.validate_password})
cherrypy.tree.mount(PysonicApi(db, library, args), '/rest/', {'/': api_config})
cherrypy.config.update({ cherrypy.config.update({
'sessionFilter.on': True, 'sessionFilter.on': True,
'tools.sessions.on': True, 'tools.sessions.on': True,

View File

@ -2,6 +2,7 @@ import os
import json import json
import sqlite3 import sqlite3
import logging import logging
from hashlib import sha512
from itertools import chain from itertools import chain
from contextlib import closing from contextlib import closing
@ -58,6 +59,17 @@ class PysonicDatabase(object):
else: else:
# Migrate if old db exists # Migrate if old db exists
version = int(cursor.execute("SELECT * FROM meta WHERE key='db_version';").fetchone()['value']) version = int(cursor.execute("SELECT * FROM meta WHERE key='db_version';").fetchone()['value'])
if version < 1:
logging.warning("migrating database to v1 from %s", version)
users_table = """CREATE TABLE 'users' (
'id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
'username' TEXT UNIQUE NOT NULL,
'password' TEXT NOT NULL,
'admin' BOOLEAN DEFAULT 0,
'email' TEXT)"""
cursor.execute(users_table)
version = 1
cursor.execute("""UPDATE meta SET value=? WHERE key="db_version";""", (str(version), ))
logging.warning("db schema is version {}".format(version)) logging.warning("db schema is version {}".format(version))
# Virtual file tree # Virtual file tree
@ -115,3 +127,17 @@ class PysonicDatabase(object):
if metadata: if metadata:
return json.loads(metadata) return json.loads(metadata)
return {} return {}
def hashit(self, unicode_string):
return sha512(unicode_string.encode('UTF-8')).hexdigest()
def validate_password(self, realm, username, password):
with closing(self.db.cursor()) as cursor:
users = cursor.execute("SELECT * FROM users WHERE username=? AND password=?;",
(username, self.hashit(password))).fetchall()
return bool(users)
def add_user(self, username, password, is_admin=False):
with closing(self.db.cursor()) as cursor:
cursor.execute("REPLACE INTO users (username, password, admin) VALUES (?, ?, ?)",
(username, self.hashit(password), is_admin)).fetchall()