mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 17:06:17 +00:00
New feature: Now admins can edit users profiles
This commit is contained in:
parent
3c2f1651a3
commit
97fb5232e5
@ -39,20 +39,33 @@ def check_admin():
|
||||
def user_index():
|
||||
return render_template('users.html', users = store.find(User), admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/me')
|
||||
def user_profile():
|
||||
prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid')))
|
||||
return render_template('profile.html', user = UserManager.get(store, session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
@app.route('/user/<uid>')
|
||||
def user_profile(uid):
|
||||
if uid == 'me':
|
||||
prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(session.get('userid')))
|
||||
return render_template('profile.html', user = UserManager.get(store, session.get('userid'))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
prefs = store.find(ClientPrefs, ClientPrefs.user_id == uuid.UUID(uid))
|
||||
return render_template('profile.html', user = UserManager.get(store, uuid.UUID(uid))[1], api_key = config.get('lastfm', 'api_key'), clients = prefs, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/me', methods = [ 'POST' ])
|
||||
def update_clients():
|
||||
@app.route('/user/<uid>', methods = [ 'POST' ])
|
||||
def update_clients(uid):
|
||||
clients_opts = {}
|
||||
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()) }
|
||||
app.logger.debug(clients_opts)
|
||||
|
||||
if uid == 'me':
|
||||
userid = uuid.UUID(session.get('userid'))
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
userid = uuid.UUID(uid)
|
||||
|
||||
for client, opts in clients_opts.iteritems():
|
||||
prefs = store.get(ClientPrefs, (uuid.UUID(session.get('userid')), client))
|
||||
prefs = store.get(ClientPrefs, (userid, client))
|
||||
if 'delete' in opts and opts['delete'] in [ 'on', 'true', 'checked', 'selected', '1' ]:
|
||||
store.remove(prefs)
|
||||
continue
|
||||
@ -62,22 +75,60 @@ def update_clients():
|
||||
|
||||
store.commit()
|
||||
flash('Clients preferences updated.')
|
||||
return user_profile()
|
||||
return user_profile(uid)
|
||||
|
||||
@app.route('/user/changemail', methods = [ 'GET', 'POST' ])
|
||||
def change_mail():
|
||||
user = UserManager.get(store, session.get('userid'))[1]
|
||||
@app.route('/user/<uid>/changeusername', methods = [ 'GET', 'POST' ])
|
||||
def change_username(uid):
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
user = UserManager.get(store, uuid.UUID(uid))[1]
|
||||
if request.method == 'POST':
|
||||
username = request.form.get('user')
|
||||
if username in ('', None):
|
||||
flash('The username is required')
|
||||
return render_template('change_username.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
if request.form.get('admin') is None:
|
||||
admin = False
|
||||
else:
|
||||
admin = True
|
||||
changed = False
|
||||
if user.name != username or user.admin != admin:
|
||||
user.name = username
|
||||
user.admin = admin
|
||||
store.commit()
|
||||
flash("User '%s' updated." % username)
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
else:
|
||||
flash("No changes for '%s'." % username)
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
return render_template('change_username.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/<uid>/changemail', methods = [ 'GET', 'POST' ])
|
||||
def change_mail(uid):
|
||||
if uid == 'me':
|
||||
user = UserManager.get(store, session.get('userid'))[1]
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
user = UserManager.get(store, uuid.UUID(uid))[1]
|
||||
if request.method == 'POST':
|
||||
mail = request.form.get('mail')
|
||||
# No validation, lol.
|
||||
user.mail = mail
|
||||
store.commit()
|
||||
return redirect(url_for('user_profile'))
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
return render_template('change_mail.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/changepass', methods = [ 'GET', 'POST' ])
|
||||
def change_password():
|
||||
@app.route('/user/<uid>/changepass', methods = [ 'GET', 'POST' ])
|
||||
def change_password(uid):
|
||||
if uid == 'me':
|
||||
user = UserManager.get(store, session.get('userid'))[1].name
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
user = UserManager.get(store, uuid.UUID(uid))[1].name
|
||||
if request.method == 'POST':
|
||||
current, new, confirm = map(request.form.get, [ 'current', 'new', 'confirm' ])
|
||||
error = False
|
||||
@ -92,14 +143,17 @@ def change_password():
|
||||
error = True
|
||||
|
||||
if not error:
|
||||
status = UserManager.change_password(store, session.get('userid'), current, new)
|
||||
if uid == 'me':
|
||||
status = UserManager.change_password(store, session.get('userid'), current, new)
|
||||
else:
|
||||
status = UserManager.change_password(store, uuid.UUID(uid), current, new)
|
||||
if status != UserManager.SUCCESS:
|
||||
flash(UserManager.error_str(status))
|
||||
else:
|
||||
flash('Password changed')
|
||||
return redirect(url_for('user_profile'))
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
return render_template('change_pass.html', user = UserManager.get(store, session.get('userid'))[1].name, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
return render_template('change_pass.html', user = user, admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/add', methods = [ 'GET', 'POST' ])
|
||||
def add_user():
|
||||
@ -131,8 +185,7 @@ def add_user():
|
||||
else:
|
||||
flash(UserManager.error_str(status))
|
||||
|
||||
return render_template('adduser.html')
|
||||
|
||||
return render_template('adduser.html', admin = UserManager.get(store, session.get('userid'))[1].admin)
|
||||
|
||||
@app.route('/user/del/<uid>')
|
||||
def del_user(uid):
|
||||
@ -187,27 +240,37 @@ def do_user_import():
|
||||
|
||||
return redirect(url_for('user_index'))
|
||||
|
||||
@app.route('/user/lastfm/link')
|
||||
def lastfm_reg():
|
||||
@app.route('/user/<uid>/lastfm/link')
|
||||
def lastfm_reg(uid):
|
||||
token = request.args.get('token')
|
||||
if token in ('', None):
|
||||
flash('Missing LastFM auth token')
|
||||
return redirect(url_for('user_profile'))
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||
if uid == 'me':
|
||||
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
lfm = LastFm(UserManager.get(store, uuid.UUID(uid))[1], app.logger)
|
||||
status, error = lfm.link_account(token)
|
||||
store.commit()
|
||||
flash(error if not status else 'Successfully linked LastFM account')
|
||||
|
||||
return redirect(url_for('user_profile'))
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
@app.route('/user/lastfm/unlink')
|
||||
def lastfm_unreg():
|
||||
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||
@app.route('/user/<uid>/lastfm/unlink')
|
||||
def lastfm_unreg(uid):
|
||||
if uid == 'me':
|
||||
lfm = LastFm(UserManager.get(store, session.get('userid'))[1], app.logger)
|
||||
else:
|
||||
if not UserManager.get(store, session.get('userid'))[1].admin:
|
||||
return redirect(url_for('index'))
|
||||
lfm = LastFm(UserManager.get(store, uuid.UUID(uid))[1], app.logger)
|
||||
lfm.unlink_account()
|
||||
store.commit()
|
||||
flash('Unliked LastFM account')
|
||||
return redirect(url_for('user_profile'))
|
||||
return redirect(url_for('user_profile', uid = uid))
|
||||
|
||||
@app.route('/user/login', methods = [ 'GET', 'POST'])
|
||||
def login():
|
||||
|
@ -18,8 +18,20 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-#}
|
||||
{% extends "layout.html" %}
|
||||
{% block navbar_users %}
|
||||
{% if session.username != user.name %}
|
||||
<li class="active"><a href="{{ url_for('user_index') }}">Users <span
|
||||
class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block navbar_profile %}
|
||||
<li class="active"><a href="{{ url_for('user_profile') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% if session.username == user.name %}
|
||||
<li class="active"><a href="{{ url_for('user_profile', uid = 'me') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="page-header first-header">
|
||||
|
@ -18,8 +18,20 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-#}
|
||||
{% extends "layout.html" %}
|
||||
{% block navbar_users %}
|
||||
{% if session.username != user %}
|
||||
<li class="active"><a href="{{ url_for('user_index') }}">Users <span
|
||||
class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block navbar_profile %}
|
||||
<li class="active"><a href="{{ url_for('user_profile') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% if session.username == user %}
|
||||
<li class="active"><a href="{{ url_for('user_profile', uid = 'me') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="page-header first-header">
|
||||
|
44
supysonic/templates/change_username.html
Normal file
44
supysonic/templates/change_username.html
Normal file
@ -0,0 +1,44 @@
|
||||
{#-
|
||||
This file is part of Supysonic.
|
||||
|
||||
Supysonic is a Python implementation of the Subsonic server API.
|
||||
Copyright (C) 2013 Alban 'spl0k' Féron
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
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/>.
|
||||
-#}
|
||||
{% extends "layout.html" %}
|
||||
{% block navbar_users %}
|
||||
<li class="active"><a href="{{ url_for('user_index') }}">Users <span
|
||||
class="sr-only">(current)</span></a></li>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="page-header first-header">
|
||||
<h2>{{ user.name }}</h2>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label class="sr-only" for="user">Username</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><span class="glyphicon glyphicon-user"></span></div>
|
||||
<input type="text" class="form-control" id="user" name="user" value="{{ user.name }}" placeholder="Username" />
|
||||
<span class="input-group-addon">
|
||||
<label for="admin">Admin</label>
|
||||
<input type="checkbox" id="admin" name="admin" {{ 'checked="checked"' if user.admin }} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-default" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
@ -75,7 +75,7 @@
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
{% block navbar_profile %}
|
||||
<li><a href="{{ url_for('user_profile') }}">{{ session.username }}</a></li>
|
||||
<li><a href="{{ url_for('user_profile', uid = 'me')}}">{{ session.username }}</a></li>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
@ -18,13 +18,26 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-#}
|
||||
{% extends "layout.html" %}
|
||||
{% block navbar_users %}
|
||||
{% if session.username != user.name %}
|
||||
<li class="active"><a href="{{ url_for('user_index') }}">Users <span
|
||||
class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block navbar_profile %}
|
||||
<li class="active"><a href="{{ url_for('user_profile') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% if session.username == user.name %}
|
||||
<li class="active"><a href="{{ url_for('user_profile', uid = 'me') }}">{{ session.username }} <span class="sr-only">(current)</span></a></li>
|
||||
{% else %}
|
||||
{{ super() }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="page-header first-header">
|
||||
<h2>{{ user.name }}{% if user.admin %} <small><span class="glyphicon
|
||||
glyphicon-certificate" data-toggle="tooltip" data-placement="right" title="You're an admin!"></span></small>{% endif %}</h2>
|
||||
glyphicon-certificate" data-toggle="tooltip" data-placement="right"
|
||||
title="{% if session.username == user.name %}You're an admin!{% else %}The user is an admin!{% endif %}"></span></small>{% endif %}</h2>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@ -35,7 +48,11 @@
|
||||
<div class="input-group-addon">User eMail</div>
|
||||
<input type="text" class="form-control" id="email" placeholder="{{ user.mail }}" readonly>
|
||||
<div class="input-group-btn">
|
||||
<a href="{{ url_for('change_mail') }}" class="btn btn-default">Change eMail</a>
|
||||
{% if session.username == user.name %}
|
||||
<a href="{{ url_for('change_mail', uid = 'me') }}" class="btn btn-default">Change eMail</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('change_mail', uid = user.id) }}" class="btn btn-default">Change eMail</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,12 +68,20 @@
|
||||
{% if user.lastfm_session %}
|
||||
<input type="text" class="form-control" id="lastfm" placeholder="{% if user.lastfm_status %}Linked{% else %}Invalid session{% endif %}" readonly>
|
||||
<div class="input-group-btn">
|
||||
<a href="{{ url_for('lastfm_unreg') }}" class="btn btn-default">Unlink</a>
|
||||
{% if session.username == user.name %}
|
||||
<a href="{{ url_for('lastfm_unreg', uid = 'me') }}" class="btn btn-default">Unlink</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('lastfm_unreg', uid = user.id) }}" class="btn btn-default">Unlink</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<input type="text" class="form-control" id="lastfm" placeholder="Unlinked" readonly>
|
||||
<div class="input-group-btn">
|
||||
<a href="http://www.last.fm/api/auth/?api_key={{ api_key }}&cb={{ request.url_root[:-(request.script_root|length+1)] + url_for('lastfm_reg') }}" class="btn btn-default">Link</a>
|
||||
{% if session.username == user.name %}
|
||||
<a href="http://www.last.fm/api/auth/?api_key={{ api_key }}&cb={{ request.url_root[:-(request.script_root|length+1)] + url_for('lastfm_reg', uid = 'me') }}" class="btn btn-default">Link</a>
|
||||
{% else %}
|
||||
<a href="http://www.last.fm/api/auth/?api_key={{ api_key }}&cb={{ request.url_root[:-(request.script_root|length+1)] + url_for('lastfm_reg', uid = user.id) }}" class="btn btn-default">Link</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
@ -67,7 +92,12 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ url_for('change_password') }}" class="btn btn-default">Change password</a></li>
|
||||
{% if session.username == user.name %}
|
||||
<a href="{{ url_for('change_password', uid = 'me') }}" class="btn btn-default">Change password</a></li>
|
||||
{% else %}
|
||||
<a href="{{ url_for('change_username', uid = user.id) }}" class="btn btn-default">Change username or admin status</a></li>
|
||||
<a href="{{ url_for('change_password', uid = user.id) }}" class="btn btn-default">Change password</a></li>
|
||||
{% endif %}
|
||||
{% if clients.count() %}
|
||||
<div class="page-header">
|
||||
<h2>Clients</h2>
|
||||
|
@ -32,7 +32,10 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr><td>{{ user.name }}</td><td>{{ user.mail }}</td><td>{{ user.admin }}</td><td>{{ user.last_play_date }}</td><td>
|
||||
<tr>
|
||||
<td>{% if session.username == user.name %}{{ user.name }}{% else %}
|
||||
<a href="{{ url_for('user_profile', uid = user.id) }}">{{ user.name }}</a>{% endif %}</td>
|
||||
<td>{{ user.mail }}</td><td>{{ user.admin }}</td><td>{{ user.last_play_date }}</td><td>
|
||||
<a href="{{ url_for('del_user', uid = user.id) }}" aria-label="Delete user">
|
||||
<span class="glyphicon glyphicon-remove-circle" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Delete user"></span></a></td></tr>
|
||||
{% endfor %}
|
||||
|
Loading…
Reference in New Issue
Block a user