1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 01:16:18 +00:00

Web UI user section: factoring some usual validation with a decorator

This commit is contained in:
spl0k 2017-11-22 23:11:58 +01:00
parent b7e9914246
commit 0353a8a1bc
2 changed files with 50 additions and 84 deletions

View File

@ -18,53 +18,67 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid, csv
from flask import request, session, flash, render_template, redirect, url_for, make_response from flask import request, session, flash, render_template, redirect, url_for, make_response
from functools import wraps
from supysonic.web import app, store from supysonic.web import app, store
from supysonic.managers.user import UserManager from supysonic.managers.user import UserManager
from supysonic.db import User, ClientPrefs from supysonic.db import User, ClientPrefs
import uuid, csv
from supysonic import config from supysonic import config
from supysonic.lastfm import LastFm from supysonic.lastfm import LastFm
from . import admin_only from . import admin_only
def me_or_uuid(f, arg = 'uid'):
@wraps(f)
def decorated_func(*args, **kwargs):
if kwargs:
uid = kwargs[arg]
else:
uid = args[0]
if uid == 'me':
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
flash(UserManager.error_str(code))
return redirect(url_for('index'))
if kwargs:
kwargs['user'] = user
else:
args = (uid, user)
return f(*args, **kwargs)
return decorated_func
@app.route('/user') @app.route('/user')
@admin_only @admin_only
def user_index(): def user_index():
return render_template('users.html', users = store.find(User)) return render_template('users.html', users = store.find(User))
@app.route('/user/<uid>') @app.route('/user/<uid>')
def user_profile(uid): @me_or_uuid
if uid == 'me': def user_profile(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
flash(UserManager.error_str(code))
return redirect(url_for('index'))
prefs = store.find(ClientPrefs, ClientPrefs.user_id == user.id) prefs = store.find(ClientPrefs, ClientPrefs.user_id == user.id)
return render_template('profile.html', user = user, has_lastfm = config.get('lastfm', 'api_key') != None, clients = prefs) return render_template('profile.html', user = user, has_lastfm = config.get('lastfm', 'api_key') != None, clients = prefs)
@app.route('/user/<uid>', methods = [ 'POST' ]) @app.route('/user/<uid>', methods = [ 'POST' ])
def update_clients(uid): @me_or_uuid
def update_clients(uid, user):
clients_opts = {} clients_opts = {}
for client in set(map(lambda k: k.rsplit('_', 1)[0], request.form.keys())): for client in set(map(lambda k: k.rsplit('_', 1)[0], request.form.keys())):
clients_opts[client] = { k.rsplit('_', 1)[1]: v for k, v in filter(lambda (k, v): k.startswith(client), request.form.iteritems()) } clients_opts[client] = { k.rsplit('_', 1)[1]: v for k, v in filter(lambda (k, v): k.startswith(client), request.form.iteritems()) }
app.logger.debug(clients_opts) app.logger.debug(clients_opts)
if uid == 'me':
userid = request.user.id
else:
if not request.user.admin or not UserManager.get(store, uid)[0] is UserManager.SUCCESS:
return redirect(url_for('index'))
userid = uuid.UUID(uid)
for client, opts in clients_opts.iteritems(): for client, opts in clients_opts.iteritems():
prefs = store.get(ClientPrefs, (userid, client)) prefs = store.get(ClientPrefs, (user.id, client))
if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]: if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
store.remove(prefs) store.remove(prefs)
continue continue
@ -74,7 +88,7 @@ def update_clients(uid):
store.commit() store.commit()
flash('Clients preferences updated.') flash('Clients preferences updated.')
return user_profile(uid) return user_profile(uid, user)
@app.route('/user/<uid>/changeusername') @app.route('/user/<uid>/changeusername')
@admin_only @admin_only
@ -112,29 +126,13 @@ def change_username_post(uid):
return redirect(url_for('user_profile', uid = uid)) return redirect(url_for('user_profile', uid = uid))
@app.route('/user/<uid>/changemail') @app.route('/user/<uid>/changemail')
def change_mail_form(uid): @me_or_uuid
if uid == 'me': def change_mail_form(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
return render_template('change_mail.html', user = user) return render_template('change_mail.html', user = user)
@app.route('/user/<uid>/changemail', methods = [ 'POST' ]) @app.route('/user/<uid>/changemail', methods = [ 'POST' ])
def change_mail_post(uid): @me_or_uuid
if uid == 'me': def change_mail_post(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
mail = request.form.get('mail') mail = request.form.get('mail')
# No validation, lol. # No validation, lol.
user.mail = mail user.mail = mail
@ -142,29 +140,13 @@ def change_mail_post(uid):
return redirect(url_for('user_profile', uid = uid)) return redirect(url_for('user_profile', uid = uid))
@app.route('/user/<uid>/changepass') @app.route('/user/<uid>/changepass')
def change_password_form(uid): @me_or_uuid
if uid == 'me': def change_password_form(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
return render_template('change_pass.html', user = user) return render_template('change_pass.html', user = user)
@app.route('/user/<uid>/changepass', methods = [ 'POST' ]) @app.route('/user/<uid>/changepass', methods = [ 'POST' ])
def change_password_post(uid): @me_or_uuid
if uid == 'me': def change_password_post(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
error = False error = False
if user.id == request.user.id: if user.id == request.user.id:
current = request.form.get('current') current = request.form.get('current')
@ -193,7 +175,7 @@ def change_password_post(uid):
flash('Password changed') flash('Password changed')
return redirect(url_for('user_profile', uid = uid)) return redirect(url_for('user_profile', uid = uid))
return change_password_form(uid) return change_password_form(uid, user)
@app.route('/user/add') @app.route('/user/add')
@admin_only @admin_only
@ -288,21 +270,13 @@ def do_user_import():
return redirect(url_for('user_index')) return redirect(url_for('user_index'))
@app.route('/user/<uid>/lastfm/link') @app.route('/user/<uid>/lastfm/link')
def lastfm_reg(uid): @me_or_uuid
def lastfm_reg(uid, user):
token = request.args.get('token') token = request.args.get('token')
if token in ('', None): if token in ('', None):
flash('Missing LastFM auth token') flash('Missing LastFM auth token')
return redirect(url_for('user_profile', uid = uid)) return redirect(url_for('user_profile', uid = uid))
if uid == 'me':
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
lfm = LastFm(user, app.logger) lfm = LastFm(user, app.logger)
status, error = lfm.link_account(token) status, error = lfm.link_account(token)
store.commit() store.commit()
@ -311,16 +285,8 @@ def lastfm_reg(uid):
return redirect(url_for('user_profile', uid = uid)) return redirect(url_for('user_profile', uid = uid))
@app.route('/user/<uid>/lastfm/unlink') @app.route('/user/<uid>/lastfm/unlink')
def lastfm_unreg(uid): @me_or_uuid
if uid == 'me': def lastfm_unreg(uid, user):
user = request.user
elif not request.user.admin:
return redirect(url_for('index'))
else:
code, user = UserManager.get(store, uid)
if code != UserManager.SUCCESS:
return redirect(url_for('index'))
lfm = LastFm(user, app.logger) lfm = LastFm(user, app.logger)
lfm.unlink_account() lfm.unlink_account()
store.commit() store.commit()

View File

@ -25,7 +25,7 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div class="page-header first-header"> <div class="page-header first-header">
<h2>{{ user }}</h2> <h2>{{ user.name }}</h2>
</div> </div>
<form method="post"> <form method="post">
{% if request.user.id == user.id %} {% if request.user.id == user.id %}