Skip to content
Snippets Groups Projects
Commit 33ea022f authored by Nils Beyer's avatar Nils Beyer
Browse files

Feature: Authorize helper

parent a10ae18d
Branches
No related tags found
No related merge requests found
...@@ -66,7 +66,8 @@ CREATE TABLE IF NOT EXISTS `courses_data` ( ...@@ -66,7 +66,8 @@ CREATE TABLE IF NOT EXISTS `courses_data` (
`coursechapters` INTEGER NOT NULL DEFAULT 0, `coursechapters` INTEGER NOT NULL DEFAULT 0,
`autopublish` INTEGER NOT NULL DEFAULT 0, `autopublish` INTEGER NOT NULL DEFAULT 0,
`autovisible` INTEGER NOT NULL DEFAULT 0, `autovisible` INTEGER NOT NULL DEFAULT 0,
`profile` varchar(64) NOT NULL DEFAULT 'default' `profile` varchar(64) NOT NULL DEFAULT 'default',
`login_info` text NOT NULL DEFAULT ''
); );
CREATE TABLE IF NOT EXISTS `filesizes` ( CREATE TABLE IF NOT EXISTS `filesizes` (
`path` varchar(255) NOT NULL PRIMARY KEY, `path` varchar(255) NOT NULL PRIMARY KEY,
......
...@@ -31,7 +31,9 @@ editable_tables = { #pylint: disable=invalid-name ...@@ -31,7 +31,9 @@ editable_tables = { #pylint: disable=invalid-name
'external': {'type': 'boolean', 'description': 'Soll die Veranstaltung nicht im Drehplan angezeigt werden?'}, 'external': {'type': 'boolean', 'description': 'Soll die Veranstaltung nicht im Drehplan angezeigt werden?'},
'coursechapters': {'type': 'boolean', 'description': 'Sollen auf der Kursseite die Kapitelmarker der Videos angezeigt werden?'}, 'coursechapters': {'type': 'boolean', 'description': 'Sollen auf der Kursseite die Kapitelmarker der Videos angezeigt werden?'},
'autopublish': {'type': 'boolean', 'description': 'Sollen encodete Videos automatisch verschoben werden?'}, 'autopublish': {'type': 'boolean', 'description': 'Sollen encodete Videos automatisch verschoben werden?'},
'autovisible': {'type': 'boolean', 'description': 'Sollen neue Videos automatisch sichtbar sein?'}}, 'autovisible': {'type': 'boolean', 'description': 'Sollen neue Videos automatisch sichtbar sein?'},
'login_info': {'type': 'text', 'description': 'Zusätliche Informationen, die dem Nutzer angezeigt werden, wenn er sich anmelden muss.'}
},
'creationtime_fields': ['created_by', 'time_created', 'time_updated']}, 'creationtime_fields': ['created_by', 'time_created', 'time_updated']},
'lectures': { 'lectures': {
'table': 'lectures_data', 'table': 'lectures_data',
...@@ -48,7 +50,7 @@ editable_tables = { #pylint: disable=invalid-name ...@@ -48,7 +50,7 @@ editable_tables = { #pylint: disable=invalid-name
'jumplist': {'type': ''}, 'jumplist': {'type': ''},
'deleted': {'type': 'boolean'}, 'deleted': {'type': 'boolean'},
'live': {'type': 'boolean', 'description': 'Ist ein Livestream geplant? Muss gesetzt sein damit der RTMP Stream zugeordnet wird.'}, 'live': {'type': 'boolean', 'description': 'Ist ein Livestream geplant? Muss gesetzt sein damit der RTMP Stream zugeordnet wird.'},
'norecording': {'type': 'boolean', 'description:': 'Führt dazu, dass der Termin ausgegraut wird.'}, 'norecording': {'type': 'boolean', 'description': 'Führt dazu, dass der Termin ausgegraut wird.'},
'stream_settings': {'type': 'text'} 'stream_settings': {'type': 'text'}
}, },
'creationtime_fields': ['course_id', 'time_created', 'time_updated']}, 'creationtime_fields': ['course_id', 'time_created', 'time_updated']},
......
...@@ -321,11 +321,23 @@ def lecture(id, course=None, courseid=None): #pylint: disable=unused-argument,to ...@@ -321,11 +321,23 @@ def lecture(id, course=None, courseid=None): #pylint: disable=unused-argument,to
if not courses: if not courses:
return render_endpoint('courses', 'Diese Veranstaltung existiert nicht!'), 404 return render_endpoint('courses', 'Diese Veranstaltung existiert nicht!'), 404
chapters = query('SELECT * FROM chapters WHERE lecture_id = ? AND NOT deleted AND (? OR visible) ORDER BY time ASC', id, ismod()) chapters = query('SELECT * FROM chapters WHERE lecture_id = ? AND NOT deleted AND (? OR visible) ORDER BY time ASC', id, ismod())
username = password = None
password_set = False # Has the user set any username/password?
is_authorized = False # Is the user authenticated?
if request.authorization: if request.authorization:
username = request.authorization.username password_set = True
password = request.authorization.password if checkperm(perms, username=request.authorization.username, password=request.authorization.password):
if not checkperm(perms, username=username, password=password): is_authorized = True
elif 'auth_data' in session:
password_set = True
if checkperm_array(perms, session['auth_data']):
is_authorized = True
else:
if checkperm(perms):
is_authorized = True
if not is_authorized:
mode, text = permdescr(perms) mode, text = permdescr(perms)
if mode == 'rwth': if mode == 'rwth':
flash(text+'. <a target="_blank" class="reloadonclose" href="'+url_for('start_rwthauth')+'">Hier authorisieren</a>.', category='player') flash(text+'. <a target="_blank" class="reloadonclose" href="'+url_for('start_rwthauth')+'">Hier authorisieren</a>.', category='player')
...@@ -350,7 +362,27 @@ def lecture(id, course=None, courseid=None): #pylint: disable=unused-argument,to ...@@ -350,7 +362,27 @@ def lecture(id, course=None, courseid=None): #pylint: disable=unused-argument,to
else: else:
flash(text+'.', category='player') flash(text+'.', category='player')
return render_template('embed.html' if request.endpoint == 'embed' else 'lecture.html', return render_template('embed.html' if request.endpoint == 'embed' else 'lecture.html',
course=courses[0], lecture=lecture, videos=videos, chapters=chapters, seek=request.args.get('t')) course=courses[0], lecture=lecture, videos=videos, chapters=chapters, seek=request.args.get('t'),
isAuthorized=is_authorized, permtypes=permtypes(perms), passwordSet=password_set)
@app.route('/<course>/<int:id>/login', methods = ['POST'])
def sessionLogin(id, course): #pylint: disable=unused-argument,too-many-branches
if not 'auth_data' in session:
session['auth_data'] = {}
if not "username" in request.form and not "password" in request.form:
return "Bad request", 400
lecture = query('SELECT * FROM lectures WHERE id = ? AND (? OR visible)', id, ismod())[0]
perms = query('SELECT perm.* FROM perm WHERE ((NOT perm.deleted) AND (perm.lecture_id = ? OR perm.course_id = ?))',
lecture['id'], lecture['course_id'])
if checkperm(perms, username=request.form['username'], password=request.form['password']):
session['auth_data'][request.form['username']] = request.form['password']
session.modified = True
return redirect(url_for('lecture', course=course, id=id))
@app.route('/search') @app.route('/search')
...@@ -470,12 +502,21 @@ def auth(): #pylint: disable=too-many-branches ...@@ -470,12 +502,21 @@ def auth(): #pylint: disable=too-many-branches
url_path) url_path)
if not perms: if not perms:
return "Not found", 404 return "Not found", 404
auth = request.authorization
username = password = None is_authorized = False
if auth:
username = auth.username if request.authorization:
password = auth.password if checkperm(perms, username=request.authorization.username, password=request.authorization.password):
if checkperm(perms, username=username, password=password): is_authorized = True
elif 'auth_data' in session:
password_set = True
if checkperm_array(perms, session['auth_data']):
is_authorized = True
else:
if checkperm(perms):
is_authorized = True
if is_authorized:
try: try:
if not url_path.startswith('pub/hls/'): if not url_path.startswith('pub/hls/'):
modify('INSERT INTO log (id, `time`, `date`, video, source) VALUES (?, ?, ?, ?, 1)', modify('INSERT INTO log (id, `time`, `date`, video, source) VALUES (?, ?, ?, ?, 1)',
......
...@@ -109,6 +109,25 @@ def checkperm(perms, username=None, password=None): #pylint: disable=too-many-br ...@@ -109,6 +109,25 @@ def checkperm(perms, username=None, password=None): #pylint: disable=too-many-br
return True return True
return False return False
def checkperm_array(perms, auth_data):
for username, password in auth_data.items():
if checkperm(perms, username, password):
return True
# Authentication can also be performed without username/password
if checkperm(perms):
return True
return False
def permtypes(perms): #pylint: disable=too-many-branches,too-many-return-statements
perms = evalperm(perms)
perm_set = set()
for perm in perms:
perm_set.add(perm['type'])
return list(perm_set)
@app.template_filter() @app.template_filter()
def permdescr(perms): #pylint: disable=too-many-branches,too-many-return-statements def permdescr(perms): #pylint: disable=too-many-branches,too-many-return-statements
perms = evalperm(perms) perms = evalperm(perms)
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
</select> </select>
</td></tr> </td></tr>
<tr><td>Interne Bemerkungen:</td><td>{{ moderator_editor(['courses',course.id,'internal'], course.internal) }}</td></tr> <tr><td>Interne Bemerkungen:</td><td>{{ moderator_editor(['courses',course.id,'internal'], course.internal) }}</td></tr>
<tr><td>Login-Informationen:</td><td>{{ moderator_editor(['courses',course.id,'login_info'], course.login_info) }}</td></tr>
</tbody> </tbody>
</table> </table>
</div> </div>
......
{% from 'macros.html' import player %} {% from 'macros.html' import player %}
{% from 'macros.html' import authorize_helper %}
{% from 'macros.html' import video_download_btn %} {% from 'macros.html' import video_download_btn %}
{% from 'macros.html' import video_embed_btn %} {% from 'macros.html' import video_embed_btn %}
{% from 'macros.html' import vtttime %} {% from 'macros.html' import vtttime %}
...@@ -29,9 +30,13 @@ ...@@ -29,9 +30,13 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% if isAuthorized %}
<div class="col-xs-12" style="padding: 0px"> <div class="col-xs-12" style="padding: 0px">
{{ player(lecture, videos, get_flashed_messages(category_filter=['player']), seek=seek) }} {{ player(lecture, videos, get_flashed_messages(category_filter=['player']), seek=seek) }}
</div> </div>
{% else %}
{{ authorize_helper(course.login_info, permtypes, passwordSet, lecture, course) }}
{% endif %}
<div class="col-xs-12" style="padding-top: 15px;"> <div class="col-xs-12" style="padding-top: 15px;">
<button class="btn btn-default" id="hintnewchapter">{% if ismod() %}Neues Kapitel{% else %}Kapitelmarker vorschlagen{% endif %}</button> <button class="btn btn-default" id="hintnewchapter">{% if ismod() %}Neues Kapitel{% else %}Kapitelmarker vorschlagen{% endif %}</button>
......
...@@ -161,6 +161,63 @@ $(function() { ...@@ -161,6 +161,63 @@ $(function() {
</script> </script>
{% endmacro %} {% endmacro %}
{% macro authorize_helper(login_info, permtypes, passwordSet, lecture, course) %}
<div class="col-xs-12" style="padding: 10px; background-color: black; color:white;">
<h3 class="text-center mb2">Anmeldung erforderlich</h3>
{% if login_info %}
<p class="text-center">{{ login_info | safe }}</p>
{% endif %}
<div style="padding-bottom: 20px" class="container-fluid">
<div class="row">
{% if 'password' in permtypes %}
<div class="col-sm-4">
<h4 class="text-center"><span class="glyphicon glyphicon-lock" aria-hidden="true"></span> Benutzername/Passwort</h4>
{% if passwordSet %}
<p class="alert alert-warning">Das aktuell verwendete Passwort ist nicht gültig.</p>
{% endif %}
<form method="POST" action="{{url_for('sessionLogin', course=course.handle, id=lecture.id)}}">
<div class="form-group">
<label for="exampleInputEmail1">Benutzername</label>
<input type="text" class="form-control" id="username" name="username" placeholder="">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Passwort</label>
<input type="password" class="form-control" id="password" name="password" placeholder="">
</div>
<button type="submit" class="btn btn-default">Anmelden</button>
</form>
</div>
{% endif %}
{% if 'rwth' in permtypes %}
<div class="col-sm-4">
<h4 class="text-center"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> RWTH</h4>
<p>Für RWTH-Angehörige und aus dem RWTH-Netz verfügbar</p>
<a href="{{ url_for('start_rwthauth') }}" class="btn btn-default">Anmelden</a>
</div>
{% endif %}
{% if 'l2p' in permtypes or 'moodle' in permtypes %}
<div class="col-sm-4">
<h4 class="text-center"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> L2P/Moodle</h4>
<p>Für Teilnehmer der Veranstaltung verfügbar</p>
{% if 'l2p' in permtypes and not 'moodle' in permtypes %}
<a href="{{ url_for('start_l2pauth') }}" class="btn btn-default">Anmelden</a>
{% endif %}
{% if 'moodle' in permtypes and not 'l2p' in permtypes %}
<a href="{{ url_for('start_moodleauth') }}" class="btn btn-default">Anmelden</a>
{% endif %}
{% if 'moodle' in permtypes and 'l2p' in permtypes %}
<a href="{{ url_for('start_moodlel2pauth') }}" class="btn btn-default">Anmelden</a>
{% endif %}
</div>
{% endif %}
</div>
{% if 'l2p' not in permtypes and 'moodle' not in permtypes and 'rwth' not in permtypes and 'password' not in permtypes %}
<p class="alert alert-info" style="margin-top: 2em;">Nur für Fachschaftler verfügbar.</p>
{% endif %}
</div>
</div>
{% endmacro %}
{% macro course_list_item(course,show_semester=False) %} {% macro course_list_item(course,show_semester=False) %}
<li class="list-group-item list-group-item-condensed {% if (not course.visible) or (not course.listed) %}list-group-item-danger{% endif %}"> <li class="list-group-item list-group-item-condensed {% if (not course.visible) or (not course.listed) %}list-group-item-danger{% endif %}">
<div class="row"> <div class="row">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment