Upgrade auth and logging to new doreah

This commit is contained in:
krateng 2023-12-18 03:22:54 +01:00
parent febaff9722
commit 7ec5e88bc4
9 changed files with 50 additions and 59 deletions

View File

@ -32,8 +32,12 @@ minor_release_name: "Nicole"
- "[Bugfix] Fixed Spotify authentication thread blocking the process from terminating" - "[Bugfix] Fixed Spotify authentication thread blocking the process from terminating"
- "[Technical] Upgraded all third party modules to use requests module and send User Agent" - "[Technical] Upgraded all third party modules to use requests module and send User Agent"
3.2.2: 3.2.2:
commit: "febaff97228b37a192f2630aa331cac5e5c3e98e"
notes: notes:
- "[Security] Fixed XSS vulnerability in error page (Disclosed by https://github.com/NULLYUKI)" - "[Security] Fixed XSS vulnerability in error page (Disclosed by https://github.com/NULLYUKI)"
- "[Architecture] Reworked the default directory selection" - "[Architecture] Reworked the default directory selection"
- "[Feature] Added option to show scrobbles on tile charts" - "[Feature] Added option to show scrobbles on tile charts"
- "[Bugfix] Fixed Last.fm authentication" - "[Bugfix] Fixed Last.fm authentication"
3.2.3:
notes:
- "[Architecture] Upgraded doreah, significant rework of authentication"

View File

@ -7,7 +7,6 @@ from bottle import response, static_file, FormsDict
from inspect import signature from inspect import signature
from doreah.logging import log from doreah.logging import log
from doreah.auth import authenticated_function
# nimrodel API # nimrodel API
from nimrodel import EAPI as API from nimrodel import EAPI as API
@ -15,7 +14,7 @@ from nimrodel import Multi
from .. import database from .. import database
from ..pkg_global.conf import malojaconfig, data_dir from ..pkg_global.conf import malojaconfig, data_dir, auth
@ -567,7 +566,7 @@ def album_info_external(k_filter, k_limit, k_delimit, k_amount):
@api.post("newscrobble") @api.post("newscrobble")
@authenticated_function(alternate=api_key_correct,api=True,pass_auth_result_as='auth_result') @auth.authenticated_function(alternate=api_key_correct,api=True,pass_auth_result_as='auth_result')
@catch_exceptions @catch_exceptions
def post_scrobble( def post_scrobble(
artist:Multi=None, artist:Multi=None,
@ -647,7 +646,7 @@ def post_scrobble(
@api.post("addpicture") @api.post("addpicture")
@authenticated_function(alternate=api_key_correct,api=True) @auth.authenticated_function(alternate=api_key_correct,api=True)
@catch_exceptions @catch_exceptions
@convert_kwargs @convert_kwargs
def add_picture(k_filter, k_limit, k_delimit, k_amount, k_special): def add_picture(k_filter, k_limit, k_delimit, k_amount, k_special):
@ -670,7 +669,7 @@ def add_picture(k_filter, k_limit, k_delimit, k_amount, k_special):
@api.post("importrules") @api.post("importrules")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def import_rulemodule(**keys): def import_rulemodule(**keys):
"""Internal Use Only""" """Internal Use Only"""
@ -689,7 +688,7 @@ def import_rulemodule(**keys):
@api.post("rebuild") @api.post("rebuild")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def rebuild(**keys): def rebuild(**keys):
"""Internal Use Only""" """Internal Use Only"""
@ -765,7 +764,7 @@ def search(**keys):
@api.post("newrule") @api.post("newrule")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def newrule(**keys): def newrule(**keys):
"""Internal Use Only""" """Internal Use Only"""
@ -776,21 +775,21 @@ def newrule(**keys):
@api.post("settings") @api.post("settings")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def set_settings(**keys): def set_settings(**keys):
"""Internal Use Only""" """Internal Use Only"""
malojaconfig.update(keys) malojaconfig.update(keys)
@api.post("apikeys") @api.post("apikeys")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def set_apikeys(**keys): def set_apikeys(**keys):
"""Internal Use Only""" """Internal Use Only"""
apikeystore.update(keys) apikeystore.update(keys)
@api.post("import") @api.post("import")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def import_scrobbles(identifier): def import_scrobbles(identifier):
"""Internal Use Only""" """Internal Use Only"""
@ -798,7 +797,7 @@ def import_scrobbles(identifier):
import_scrobbles(identifier) import_scrobbles(identifier)
@api.get("backup") @api.get("backup")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def get_backup(**keys): def get_backup(**keys):
"""Internal Use Only""" """Internal Use Only"""
@ -811,7 +810,7 @@ def get_backup(**keys):
return static_file(os.path.basename(archivefile),root=tmpfolder) return static_file(os.path.basename(archivefile),root=tmpfolder)
@api.get("export") @api.get("export")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def get_export(**keys): def get_export(**keys):
"""Internal Use Only""" """Internal Use Only"""
@ -825,7 +824,7 @@ def get_export(**keys):
@api.post("delete_scrobble") @api.post("delete_scrobble")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def delete_scrobble(timestamp): def delete_scrobble(timestamp):
"""Internal Use Only""" """Internal Use Only"""
@ -837,7 +836,7 @@ def delete_scrobble(timestamp):
@api.post("edit_artist") @api.post("edit_artist")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def edit_artist(id,name): def edit_artist(id,name):
"""Internal Use Only""" """Internal Use Only"""
@ -847,7 +846,7 @@ def edit_artist(id,name):
} }
@api.post("edit_track") @api.post("edit_track")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def edit_track(id,title): def edit_track(id,title):
"""Internal Use Only""" """Internal Use Only"""
@ -857,7 +856,7 @@ def edit_track(id,title):
} }
@api.post("edit_album") @api.post("edit_album")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def edit_album(id,albumtitle): def edit_album(id,albumtitle):
"""Internal Use Only""" """Internal Use Only"""
@ -868,7 +867,7 @@ def edit_album(id,albumtitle):
@api.post("merge_tracks") @api.post("merge_tracks")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def merge_tracks(target_id,source_ids): def merge_tracks(target_id,source_ids):
"""Internal Use Only""" """Internal Use Only"""
@ -879,7 +878,7 @@ def merge_tracks(target_id,source_ids):
} }
@api.post("merge_artists") @api.post("merge_artists")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def merge_artists(target_id,source_ids): def merge_artists(target_id,source_ids):
"""Internal Use Only""" """Internal Use Only"""
@ -890,7 +889,7 @@ def merge_artists(target_id,source_ids):
} }
@api.post("merge_albums") @api.post("merge_albums")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def merge_artists(target_id,source_ids): def merge_artists(target_id,source_ids):
"""Internal Use Only""" """Internal Use Only"""
@ -901,7 +900,7 @@ def merge_artists(target_id,source_ids):
} }
@api.post("associate_albums_to_artist") @api.post("associate_albums_to_artist")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def associate_albums_to_artist(target_id,source_ids,remove=False): def associate_albums_to_artist(target_id,source_ids,remove=False):
result = database.associate_albums_to_artist(target_id,source_ids,remove=remove) result = database.associate_albums_to_artist(target_id,source_ids,remove=remove)
@ -913,7 +912,7 @@ def associate_albums_to_artist(target_id,source_ids,remove=False):
} }
@api.post("associate_tracks_to_artist") @api.post("associate_tracks_to_artist")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def associate_tracks_to_artist(target_id,source_ids,remove=False): def associate_tracks_to_artist(target_id,source_ids,remove=False):
result = database.associate_tracks_to_artist(target_id,source_ids,remove=remove) result = database.associate_tracks_to_artist(target_id,source_ids,remove=remove)
@ -925,7 +924,7 @@ def associate_tracks_to_artist(target_id,source_ids,remove=False):
} }
@api.post("associate_tracks_to_album") @api.post("associate_tracks_to_album")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def associate_tracks_to_album(target_id,source_ids): def associate_tracks_to_album(target_id,source_ids):
result = database.associate_tracks_to_album(target_id,source_ids) result = database.associate_tracks_to_album(target_id,source_ids)
@ -937,7 +936,7 @@ def associate_tracks_to_album(target_id,source_ids):
@api.post("reparse_scrobble") @api.post("reparse_scrobble")
@authenticated_function(api=True) @auth.authenticated_function(api=True)
@catch_exceptions @catch_exceptions
def reparse_scrobble(timestamp): def reparse_scrobble(timestamp):
"""Internal Use Only""" """Internal Use Only"""

View File

@ -27,7 +27,6 @@ from . import exceptions
# doreah toolkit # doreah toolkit
from doreah.logging import log from doreah.logging import log
from doreah.auth import authenticated_api, authenticated_api_with_alternate
import doreah import doreah

View File

@ -1,9 +1,9 @@
import os import os
import cProfile, pstats import cProfile, pstats
import time
from doreah.logging import log from doreah.logging import log
from doreah.timing import Clock
from ..pkg_global.conf import data_dir from ..pkg_global.conf import data_dir
@ -27,8 +27,7 @@ def profile(func):
def newfunc(*args,**kwargs): def newfunc(*args,**kwargs):
clock = Clock() starttime = time.time()
clock.start()
if FULL_PROFILE: if FULL_PROFILE:
benchmarkfolder = data_dir['logs']("benchmarks") benchmarkfolder = data_dir['logs']("benchmarks")
@ -44,7 +43,7 @@ def profile(func):
if FULL_PROFILE: if FULL_PROFILE:
localprofiler.disable() localprofiler.disable()
seconds = clock.stop() seconds = time.time() - starttime
if not SINGLE_CALLS: if not SINGLE_CALLS:
times.setdefault(realfunc,[]).append(seconds) times.setdefault(realfunc,[]).append(seconds)

View File

@ -1,4 +1,7 @@
import os import os
import doreah.auth
import doreah.logging
from doreah.configuration import Configuration from doreah.configuration import Configuration
from doreah.configuration import types as tp from doreah.configuration import types as tp
@ -331,26 +334,15 @@ data_dir = {
### DOREAH CONFIGURATION ### DOREAH OBJECTS
from doreah import config auth = doreah.auth.AuthManager(singleuser=True,cookieprefix='maloja',stylesheets=("/maloja.css",),dbfile=data_dir['auth']("auth.sqlite"))
config(
auth={
"multiuser":False,
"cookieprefix":"maloja",
"stylesheets":["/maloja.css"],
"dbfile":data_dir['auth']("auth.ddb")
},
logging={
"logfolder": data_dir['logs']() if malojaconfig["LOGGING"] else None
},
regular={
"offset": malojaconfig["TIMEZONE"]
}
)
#logger = doreah.logging.Logger(logfolder=data_dir['logs']() if malojaconfig["LOGGING"] else None)
#log = logger.log
# this is not how its supposed to be done, but lets ease the transition
doreah.logging.defaultlogger.logfolder = data_dir['logs']() if malojaconfig["LOGGING"] else None

View File

@ -12,14 +12,13 @@ from jinja2.exceptions import TemplateNotFound
# doreah toolkit # doreah toolkit
from doreah.logging import log from doreah.logging import log
from doreah import auth
# rest of the project # rest of the project
from . import database from . import database
from .database.jinjaview import JinjaDBConnection from .database.jinjaview import JinjaDBConnection
from .images import image_request from .images import image_request
from .malojauri import uri_to_internal, remove_identical from .malojauri import uri_to_internal, remove_identical
from .pkg_global.conf import malojaconfig, data_dir from .pkg_global.conf import malojaconfig, data_dir, auth
from .pkg_global import conf from .pkg_global import conf
from .jinjaenv.context import jinja_environment from .jinjaenv.context import jinja_environment
from .apis import init_apis, apikeystore from .apis import init_apis, apikeystore
@ -97,7 +96,7 @@ aliases = {
### API ### API
auth.authapi.mount(server=webserver) conf.auth.authapi.mount(server=webserver)
init_apis(webserver) init_apis(webserver)
# redirects for backwards compatibility # redirects for backwards compatibility
@ -197,7 +196,7 @@ def jinja_page(name):
if name in aliases: redirect(aliases[name]) if name in aliases: redirect(aliases[name])
keys = remove_identical(FormsDict.decode(request.query)) keys = remove_identical(FormsDict.decode(request.query))
adminmode = request.cookies.get("adminmode") == "true" and auth.check(request) adminmode = request.cookies.get("adminmode") == "true" and auth.check_request(request)
with JinjaDBConnection() as conn: with JinjaDBConnection() as conn:
@ -222,7 +221,7 @@ def jinja_page(name):
return res return res
@webserver.route("/<name:re:admin.*>") @webserver.route("/<name:re:admin.*>")
@auth.authenticated @auth.authenticated_function()
def jinja_page_private(name): def jinja_page_private(name):
return jinja_page(name) return jinja_page(name)

View File

@ -6,9 +6,8 @@ try:
except ImportError: except ImportError:
import distutils import distutils
from doreah.io import col, ask, prompt from doreah.io import col, ask, prompt
from doreah import auth
from .pkg_global.conf import data_dir, dir_settings, malojaconfig from .pkg_global.conf import data_dir, dir_settings, malojaconfig, auth
@ -67,10 +66,10 @@ def setup():
if forcepassword is not None: if forcepassword is not None:
# user has specified to force the pw, nothing else matters # user has specified to force the pw, nothing else matters
auth.defaultuser.setpw(forcepassword) auth.change_pw(password=forcepassword)
print("Password has been set.") print("Password has been set.")
elif auth.defaultuser.checkpw("admin"): elif auth.still_has_factory_default_user():
# if the actual pw is admin, it means we've never set this up properly (eg first start after update) # this means we've never set this up properly (eg first start after update)
while True: while True:
newpw = prompt("Please set a password for web backend access. Leave this empty to generate a random password.",skip=SKIP,secret=True) newpw = prompt("Please set a password for web backend access. Leave this empty to generate a random password.",skip=SKIP,secret=True)
if newpw is None: if newpw is None:
@ -81,7 +80,7 @@ def setup():
newpw_repeat = prompt("Please type again to confirm.",skip=SKIP,secret=True) newpw_repeat = prompt("Please type again to confirm.",skip=SKIP,secret=True)
if newpw != newpw_repeat: print("Passwords do not match!") if newpw != newpw_repeat: print("Passwords do not match!")
else: break else: break
auth.defaultuser.setpw(newpw) auth.change_pw(password=newpw)
except EOFError: except EOFError:
print("No user input possible. If you are running inside a container, set the environment variable",col['yellow']("MALOJA_SKIP_SETUP=yes")) print("No user input possible. If you are running inside a container, set the environment variable",col['yellow']("MALOJA_SKIP_SETUP=yes"))

View File

@ -21,7 +21,7 @@ classifiers = [
dependencies = [ dependencies = [
"bottle>=0.12.16", "bottle>=0.12.16",
"waitress>=2.1.0", "waitress>=2.1.0",
"doreah>=1.9.4, <2", "doreah>=2.0.0, <3",
"nimrodel>=0.8.0", "nimrodel>=0.8.0",
"setproctitle>=1.1.10", "setproctitle>=1.1.10",
#"pyvips>=2.1.16", #"pyvips>=2.1.16",

View File

@ -1,6 +1,6 @@
bottle>=0.12.16 bottle>=0.12.16
waitress>=2.1.0 waitress>=2.1.0
doreah>=1.9.4, <2 doreah>=2.0.0, <3
nimrodel>=0.8.0 nimrodel>=0.8.0
setproctitle>=1.1.10 setproctitle>=1.1.10
jinja2>=3.0.0 jinja2>=3.0.0