diff --git a/cps/kobo.py b/cps/kobo.py index 85337fb3..d58be3c5 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -43,6 +43,7 @@ import requests from . import config, logger, kobo_auth, db, helper from .services import SyncToken as SyncToken from .web import download_required +from .kobo_auth import requires_kobo_auth KOBO_FORMATS = {"KEPUB": ["KEPUB"], "EPUB": ["EPUB3", "EPUB"]} KOBO_STOREAPI_URL = "https://storeapi.kobo.com" @@ -72,8 +73,8 @@ CONNECTION_SPECIFIC_HEADERS = [ def get_kobo_activated(): return config.config_kobo_sync -def redirect_or_proxy_request(): - if config.config_kobo_proxy: +def redirect_or_proxy_request(proxy=False): + if config.config_kobo_proxy or proxy == True: if request.method == "GET": return redirect(get_store_url_for_current_request(), 307) if request.method == "DELETE": @@ -102,7 +103,7 @@ def redirect_or_proxy_request(): return make_response(jsonify({})) @kobo.route("/v1/library/sync") -@login_required +@requires_kobo_auth @download_required def HandleSyncRequest(): sync_token = SyncToken.SyncToken.from_headers(request.headers) @@ -193,7 +194,7 @@ def generate_sync_response(request, sync_token, entitlements): @kobo.route("/v1/library//metadata") -@login_required +@requires_kobo_auth @download_required def HandleMetadataRequest(book_uuid): if not current_app.wsgi_app.is_proxied: @@ -347,7 +348,7 @@ def reading_state(book): @kobo.route("//image.jpg") -@login_required +@requires_kobo_auth def HandleCoverImageRequest(book_uuid): log.debug("Cover request received for book %s" % book_uuid) book_cover = helper.get_book_cover_with_uuid( @@ -393,9 +394,13 @@ def handle_404(err): log.debug("Unknown Request received: %s", request.base_url) return redirect_or_proxy_request() +@kobo.route("/v1/auth/device", methods=["POST"]) +def login_auth_token(): + log.info('Auth') + return redirect_or_proxy_request(proxy=True) @kobo.route("/v1/initialization") -@login_required +@requires_kobo_auth def HandleInitRequest(): if not current_app.wsgi_app.is_proxied: log.debug('Kobo: Received unproxied request, changed request port to server port') diff --git a/cps/kobo_auth.py b/cps/kobo_auth.py index cd2524e7..5178da69 100644 --- a/cps/kobo_auth.py +++ b/cps/kobo_auth.py @@ -61,13 +61,19 @@ from binascii import hexlify from datetime import datetime from os import urandom -from flask import g, Blueprint, url_for +from flask import g, Blueprint, url_for, abort from flask_login import login_user, login_required from flask_babel import gettext as _ from . import logger, ub, lm from .web import render_title_template +try: + from functools import wraps +except ImportError: + pass # We're not using Python 3 + + log = logger.create() @@ -88,21 +94,24 @@ def get_auth_token(): return None -@lm.request_loader -def load_user_from_kobo_request(request): - auth_token = get_auth_token() - if auth_token is not None: - user = ( - ub.session.query(ub.User) - .join(ub.RemoteAuthToken) - .filter(ub.RemoteAuthToken.auth_token == auth_token).filter(ub.RemoteAuthToken.token_type==1) - .first() - ) - if user is not None: - login_user(user) - return user - log.debug("Received Kobo request without a recognizable auth token.") - return +def requires_kobo_auth(f): + @wraps(f) + def inner(*args, **kwargs): + auth_token = get_auth_token() + if auth_token is not None: + user = ( + ub.session.query(ub.User) + .join(ub.RemoteAuthToken) + .filter(ub.RemoteAuthToken.auth_token == auth_token).filter(ub.RemoteAuthToken.token_type==1) + .first() + ) + if user is not None: + login_user(user) + return f(*args, **kwargs) + log.debug("Received Kobo request without a recognizable auth token.") + return abort(401) + return inner + kobo_auth = Blueprint("kobo_auth", __name__, url_prefix="/kobo_auth") diff --git a/cps/templates/generate_kobo_auth_url.html b/cps/templates/generate_kobo_auth_url.html index 307b26bd..79f6c46d 100644 --- a/cps/templates/generate_kobo_auth_url.html +++ b/cps/templates/generate_kobo_auth_url.html @@ -8,7 +8,7 @@ {{_('api_endpoint=')}}{{kobo_auth_url}}

- {{_('Please note that every visit to this current page invalidates any previously generated Authentication url for this user.')}}. + {{_('Please note that every visit to this current page invalidates any previously generated Authentication url for this user.')}}

{% endblock %}