migrating from basic to JWT auth #34
@ -5,7 +5,7 @@ from datetime import datetime
|
||||
|
||||
from google.cloud import tasks_v2
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, admin_required
|
||||
from music.api.decorators import login_or_jwt, admin_required
|
||||
|
||||
blueprint = Blueprint('admin-api', __name__)
|
||||
|
||||
@ -16,9 +16,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/tasks', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@admin_required
|
||||
def get_tasks(user=None):
|
||||
def get_tasks(auth=None, user=None):
|
||||
|
||||
tasks = list(tasker.list_tasks(task_path))
|
||||
|
||||
|
@ -7,7 +7,7 @@ import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from music.api.decorators import login_or_jwt, login_required, login_or_basic_auth, \
|
||||
from music.api.decorators import login_or_jwt, login_required, login_or_jwt, \
|
||||
admin_required, cloud_task, validate_json, validate_args, spotify_link_required
|
||||
from music.cloud import queue_run_user_playlist, offload_or_run_user_playlist
|
||||
from music.cloud.tasks import update_all_user_playlists, update_playlists
|
||||
@ -28,8 +28,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/playlists', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
def all_playlists_route(user=None):
|
||||
@login_or_jwt
|
||||
def all_playlists_route(auth=None, user=None):
|
||||
"""Retrieve all playlists for a given user
|
||||
|
||||
Args:
|
||||
@ -64,9 +64,9 @@ def playlist_get_delete_route(auth=None,user=None):
|
||||
|
||||
|
||||
@blueprint.route('/playlist', methods=['POST', 'PUT'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@validate_json(('name', str))
|
||||
def playlist_post_put_route(user=None):
|
||||
def playlist_post_put_route(auth=None, user=None):
|
||||
|
||||
request_json = request.get_json()
|
||||
|
||||
@ -161,8 +161,8 @@ def playlist_post_put_route(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/user', methods=['GET', 'POST'])
|
||||
@login_or_basic_auth
|
||||
def user_route(user=None):
|
||||
@login_or_jwt
|
||||
def user_route(auth=None, user=None):
|
||||
assert user is not None
|
||||
|
||||
if request.method == 'GET':
|
||||
@ -202,9 +202,9 @@ def user_route(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/users', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@admin_required
|
||||
def all_users_route(user=None):
|
||||
def all_users_route(auth=None, user=None):
|
||||
return jsonify({
|
||||
'accounts': [i.to_dict() for i in User.collection.fetch()]
|
||||
}), 200
|
||||
@ -234,9 +234,9 @@ def change_password(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/playlist/run', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@validate_args(('name', str))
|
||||
def run_playlist(user=None):
|
||||
def run_playlist(auth=None, user=None):
|
||||
|
||||
if os.environ.get('DEPLOY_DESTINATION', None) == 'PROD':
|
||||
queue_run_user_playlist(user.username, request.args['name']) # pass to either cloud tasks or functions
|
||||
@ -264,8 +264,8 @@ def run_playlist_task(): # receives cloud tasks request for update
|
||||
|
||||
|
||||
@blueprint.route('/playlist/run/user', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
def run_user(user=None):
|
||||
@login_or_jwt
|
||||
def run_user(auth=None, user=None):
|
||||
|
||||
if user.type == 'admin':
|
||||
user_name = request.args.get('username', user.username)
|
||||
@ -288,19 +288,19 @@ def run_user_task():
|
||||
|
||||
|
||||
@blueprint.route('/playlist/run/users', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@admin_required
|
||||
def run_users(user=None):
|
||||
def run_users(auth=None, user=None):
|
||||
|
||||
update_all_user_playlists()
|
||||
return jsonify({'message': 'executed all users', 'status': 'success'}), 200
|
||||
|
||||
|
||||
@blueprint.route('/playlist/image', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
@validate_args(('name', str))
|
||||
def image(user=None):
|
||||
def image(auth=None, user=None):
|
||||
|
||||
_playlist = user.get_playlist(request.args['name'], raise_error=False)
|
||||
if _playlist is None:
|
||||
|
@ -2,7 +2,7 @@ from flask import Blueprint, jsonify
|
||||
from datetime import date
|
||||
import logging
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, lastfm_username_required
|
||||
from music.api.decorators import login_or_jwt, lastfm_username_required
|
||||
|
||||
import music.db.database as database
|
||||
|
||||
@ -11,9 +11,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/today', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@lastfm_username_required
|
||||
def daily_scrobbles(user=None):
|
||||
def daily_scrobbles(auth=None, user=None):
|
||||
|
||||
net = database.get_authed_lastfm_network(user)
|
||||
|
||||
|
@ -2,7 +2,7 @@ from flask import Blueprint, request, jsonify
|
||||
|
||||
import logging
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, spotify_link_required, validate_json
|
||||
from music.api.decorators import login_or_jwt, spotify_link_required, validate_json
|
||||
import music.db.database as database
|
||||
|
||||
from spotframework.net.network import SpotifyNetworkException
|
||||
@ -16,9 +16,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/play', methods=['POST'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
def play(user=None):
|
||||
def play(auth=None, user=None):
|
||||
request_json = request.get_json()
|
||||
|
||||
if 'uri' in request_json:
|
||||
@ -78,9 +78,9 @@ def play(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/next', methods=['POST'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
def next_track(user=None):
|
||||
def next_track(auth=None, user=None):
|
||||
net = database.get_authed_spotify_network(user)
|
||||
player = Player(net)
|
||||
|
||||
@ -89,10 +89,10 @@ def next_track(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/shuffle', methods=['POST'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
@validate_json(('state', bool))
|
||||
def shuffle(user=None):
|
||||
def shuffle(auth=None, user=None):
|
||||
request_json = request.get_json()
|
||||
|
||||
net = database.get_authed_spotify_network(user)
|
||||
@ -103,10 +103,10 @@ def shuffle(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/volume', methods=['POST'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
@validate_json(('volume', int))
|
||||
def volume(user=None):
|
||||
def volume(auth=None, user=None):
|
||||
request_json = request.get_json()
|
||||
|
||||
if 0 <= request_json['volume'] <= 100:
|
||||
|
@ -3,7 +3,7 @@ import logging
|
||||
import json
|
||||
import os
|
||||
|
||||
from music.api.decorators import admin_required, login_or_basic_auth, lastfm_username_required, \
|
||||
from music.api.decorators import admin_required, login_or_jwt, lastfm_username_required, \
|
||||
spotify_link_required, cloud_task, validate_args
|
||||
import music.db.database as database
|
||||
from music.cloud.tasks import refresh_all_user_playlist_stats, refresh_user_playlist_stats, refresh_playlist_task
|
||||
@ -20,10 +20,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/count', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
@lastfm_username_required
|
||||
def count(user=None):
|
||||
def count(auth=None, user=None):
|
||||
|
||||
uri = request.args.get('uri', None)
|
||||
playlist_name = request.args.get('playlist_name', None)
|
||||
@ -69,11 +69,11 @@ def count(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/playlist/refresh', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
@lastfm_username_required
|
||||
@validate_args(('name', str))
|
||||
def playlist_refresh(user=None):
|
||||
def playlist_refresh(auth=None, user=None):
|
||||
|
||||
playlist_name = request.args['name']
|
||||
|
||||
@ -133,16 +133,16 @@ def run_playlist_artist_task():
|
||||
|
||||
|
||||
@blueprint.route('/playlist/refresh/users', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@admin_required
|
||||
def run_users(user=None):
|
||||
def run_users(auth=None, user=None):
|
||||
refresh_all_user_playlist_stats()
|
||||
return jsonify({'message': 'executed all users', 'status': 'success'}), 200
|
||||
|
||||
|
||||
@blueprint.route('/playlist/refresh/user', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
def run_user(user=None):
|
||||
@login_or_jwt
|
||||
def run_user(auth=None, user=None):
|
||||
|
||||
if user.type == 'admin':
|
||||
user_name = request.args.get('username', user.username)
|
||||
|
@ -1,7 +1,7 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
import logging
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, spotify_link_required
|
||||
from music.api.decorators import login_or_jwt, spotify_link_required
|
||||
import music.db.database as database
|
||||
|
||||
from spotframework.engine.playlistengine import PlaylistEngine
|
||||
@ -12,9 +12,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/sort', methods=['POST'])
|
||||
@login_or_basic_auth
|
||||
@login_or_jwt
|
||||
@spotify_link_required
|
||||
def sort(user=None):
|
||||
def sort(auth=None, user=None):
|
||||
request_json = request.get_json()
|
||||
|
||||
net = database.get_authed_spotify_network(user)
|
||||
|
@ -4,7 +4,7 @@ import logging
|
||||
import os
|
||||
import json
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, cloud_task
|
||||
from music.api.decorators import login_or_jwt, cloud_task
|
||||
from music.cloud.function import update_tag as serverless_update_tag
|
||||
from music.tasks.update_tag import update_tag
|
||||
|
||||
@ -15,8 +15,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/tag', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
def tags(user=None):
|
||||
@login_or_jwt
|
||||
def tags(auth=None, user=None):
|
||||
logger.info(f'retrieving tags for {user.username}')
|
||||
return jsonify({
|
||||
'tags': [i.to_dict() for i in Tag.collection.parent(user.key).fetch()]
|
||||
@ -24,8 +24,8 @@ def tags(user=None):
|
||||
|
||||
|
||||
@blueprint.route('/tag/<tag_id>', methods=['GET', 'PUT', 'POST', "DELETE"])
|
||||
@login_or_basic_auth
|
||||
def tag_route(tag_id, user=None):
|
||||
@login_or_jwt
|
||||
def tag_route(tag_id, auth=None, user=None):
|
||||
if request.method == 'GET':
|
||||
return get_tag(tag_id, user)
|
||||
elif request.method == 'PUT':
|
||||
@ -126,8 +126,8 @@ def delete_tag(tag_id, user):
|
||||
|
||||
|
||||
@blueprint.route('/tag/<tag_id>/update', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
def tag_refresh(tag_id, user=None):
|
||||
@login_or_jwt
|
||||
def tag_refresh(tag_id, auth=None, user=None):
|
||||
logger.info(f'updating {tag_id} tag for {user.username}')
|
||||
|
||||
if os.environ.get('DEPLOY_DESTINATION', None) == 'PROD':
|
||||
|
@ -6,6 +6,8 @@ from music.auth.jwt_keys import generate_key
|
||||
|
||||
from urllib.parse import urlencode, urlunparse
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from numbers import Number
|
||||
import logging
|
||||
from base64 import b64encode
|
||||
import requests
|
||||
@ -95,12 +97,19 @@ def jwt_token():
|
||||
logger.warning(f'locked account token attempt {username}')
|
||||
return jsonify({"message": 'user locked', "status": "error"}), 403
|
||||
|
||||
user.last_login = datetime.datetime.utcnow()
|
||||
user.last_keygen = datetime.datetime.utcnow()
|
||||
user.update()
|
||||
|
||||
logger.info(f'generating token for {username}')
|
||||
|
||||
token = generate_key(user)
|
||||
config = Config.collection.get("config/music-tools")
|
||||
|
||||
if isinstance(expiry := request_json.get('expiry', None), Number):
|
||||
expiry = min(expiry, config.jwt_max_length)
|
||||
else:
|
||||
expiry = config.jwt_default_length
|
||||
|
||||
token = generate_key(user, timeout=timedelta(seconds=expiry))
|
||||
|
||||
return jsonify({"token": token, "status": "success"}), 200
|
||||
else:
|
||||
|
@ -20,3 +20,5 @@ class Config(Model):
|
||||
"""
|
||||
secret_key = TextField()
|
||||
jwt_secret_key = TextField()
|
||||
jwt_max_length = NumberField()
|
||||
jwt_default_length = NumberField()
|
||||
|
@ -20,6 +20,7 @@ class User(Model):
|
||||
type = TextField(default="user")
|
||||
|
||||
last_login = DateTime()
|
||||
last_keygen = DateTime()
|
||||
last_refreshed = DateTime()
|
||||
locked = BooleanField(default=False, required=True)
|
||||
validated = BooleanField(default=True, required=True)
|
||||
|
Loading…
Reference in New Issue
Block a user