| |
@@ -3,6 +3,7 @@
|
| |
import json
|
| |
import logging
|
| |
import os
|
| |
+ import urlparse
|
| |
import uuid
|
| |
|
| |
import flask
|
| |
@@ -12,7 +13,7 @@
|
| |
import pygments.formatters
|
| |
import six
|
| |
|
| |
- from flask.ext.openid import OpenID
|
| |
+ from flask.ext.oidc import OpenIDConnect
|
| |
|
| |
import fmn.lib
|
| |
import hubs.models
|
| |
@@ -75,6 +76,17 @@
|
| |
and flask.g.auth.logged_in
|
| |
|
| |
|
| |
+ def is_safe_url(target):
|
| |
+ """ Checks that the target url is safe and sending to the current
|
| |
+ website not some other malicious one.
|
| |
+ """
|
| |
+ ref_url = urlparse.urlparse(flask.request.host_url)
|
| |
+ test_url = urlparse.urlparse(
|
| |
+ urlparse.urljoin(flask.request.host_url, target))
|
| |
+ return test_url.scheme in ('http', 'https') and \
|
| |
+ ref_url.netloc == test_url.netloc
|
| |
+
|
| |
+
|
| |
@app.template_filter('commas')
|
| |
def commas(numeric):
|
| |
return "{:,.2f}".format(numeric)
|
| |
@@ -89,7 +101,7 @@
|
| |
@app.route('/')
|
| |
def index():
|
| |
if not authenticated():
|
| |
- return flask.redirect(flask.url_for('login_fedora'))
|
| |
+ return flask.redirect(flask.url_for('login'))
|
| |
|
| |
return flask.redirect(flask.url_for('hub', name=flask.g.auth.nickname))
|
| |
|
| |
@@ -97,7 +109,7 @@
|
| |
@app.route('/groups')
|
| |
def groups():
|
| |
if not authenticated():
|
| |
- return flask.redirect(flask.url_for('login_fedora'))
|
| |
+ return flask.redirect(flask.url_for('login'))
|
| |
|
| |
# Get the list of promoted and non-promoted group hubs from the DB
|
| |
promoted_names = app.config.get('PROMOTED_GROUPS')
|
| |
@@ -446,69 +458,43 @@
|
| |
return flask.redirect(SOURCE_URL + fname)
|
| |
|
| |
|
| |
- # Set up OpenID in stateless mode
|
| |
- oid = OpenID(app,
|
| |
- safe_roots=[],
|
| |
- store_factory=lambda: None,
|
| |
- url_root_as_trust_root=True)
|
| |
+ # Set up OpenIDConnect
|
| |
+ OIDC = OpenIDConnect(app, credentials_store=flask.session )
|
| |
|
| |
|
| |
@app.route('/login/', methods=('GET', 'POST'))
|
| |
@app.route('/login', methods=('GET', 'POST'))
|
| |
- @oid.loginhandler
|
| |
+ @OIDC.require_login
|
| |
def login():
|
| |
default = flask.url_for('index')
|
| |
next_url = flask.request.args.get('next', default)
|
| |
- if authenticated():
|
| |
- return flask.redirect(next_url)
|
| |
-
|
| |
- openid_server = flask.request.form.get('openid', None)
|
| |
- if openid_server:
|
| |
- return oid.try_login(
|
| |
- openid_server, ask_for=['email', 'fullname', 'nickname'],
|
| |
- ask_for_optional=[])
|
| |
-
|
| |
- return flask.render_template(
|
| |
- 'login.html', next=oid.get_next_url(), error=oid.fetch_error())
|
| |
+ if is_safe_url(next_url):
|
| |
+ return_point = next_url
|
| |
+ else:
|
| |
+ return_point = default
|
| |
|
| |
+ hubs.models.User.get_or_create(
|
| |
+ session, username=flask.g.auth.nickname, fullname=flask.g.auth.fullname)
|
| |
|
| |
- @app.route('/login/fedora/')
|
| |
- @app.route('/login/fedora')
|
| |
- @oid.loginhandler
|
| |
- def login_fedora():
|
| |
- # default = flask.url_for('profile_redirect')
|
| |
- # next_url = flask.request.args.get('next', default)
|
| |
- return oid.try_login(
|
| |
- 'https://id.fedoraproject.org',
|
| |
- ask_for=['email', 'fullname', 'nickname'],
|
| |
- ask_for_optional=[])
|
| |
+ return flask.redirect(return_point)
|
| |
|
| |
|
| |
@app.route('/logout/')
|
| |
@app.route('/logout')
|
| |
def logout():
|
| |
- if 'openid' in flask.app.session:
|
| |
- flask.app.session.pop('openid')
|
| |
- return flask.redirect(flask.url_for('index'))
|
| |
+ next_url = flask.url_for('index')
|
| |
+ if 'next' in flask.request.values: # pragma: no cover
|
| |
+ if is_safe_url(flask.request.args['next']):
|
| |
+ next_url = flask.request.values['next']
|
| |
|
| |
+ if next_url == flask.url_for('login'): # pragma: no cover
|
| |
+ next_url = flask.url_for('index')
|
| |
|
| |
- @oid.after_login
|
| |
- def after_openid_login(resp):
|
| |
- default = flask.url_for('index')
|
| |
- if not resp.identity_url:
|
| |
- return flask.redirect(default)
|
| |
-
|
| |
- openid_url = resp.identity_url
|
| |
- flask.app.session['openid'] = openid_url
|
| |
- flask.app.session['fullname'] = resp.fullname
|
| |
- flask.app.session['nickname'] = resp.nickname or resp.fullname
|
| |
- flask.app.session['email'] = resp.email
|
| |
-
|
| |
- openid = openid_url.strip('/').split('/')[-1]
|
| |
- hubs.models.User.get_or_create(
|
| |
- session, openid=openid, fullname=resp.fullname)
|
| |
+ if authenticated():
|
| |
+ OIDC.logout()
|
| |
+ flask.session.auth = None
|
| |
+ flask.flash('You have been logged out')
|
| |
|
| |
- next_url = flask.request.args.get('next', default)
|
| |
return flask.redirect(next_url)
|
| |
|
| |
|
| |
@@ -521,7 +507,7 @@
|
| |
if not authenticated():
|
| |
flask.flash('Login required', 'errors')
|
| |
return flask.redirect(flask.url_for(
|
| |
- 'login_fedora', next=flask.request.url))
|
| |
+ 'login', next=flask.request.url))
|
| |
|
| |
return function(*args, **kwargs)
|
| |
|
| |
@@ -530,21 +516,30 @@
|
| |
|
| |
@app.before_request
|
| |
def check_auth():
|
| |
+ flask.session.permanent = True
|
| |
flask.g.fedmsg_config = fedmsg_config
|
| |
- flask.g.auth = munch.Munch(logged_in=False)
|
| |
- if 'openid' in flask.session:
|
| |
- openid = flask.session.get('openid')
|
| |
- if isinstance(openid, six.binary_type):
|
| |
- openid = openid.decode('utf-8')
|
| |
- openid = openid.strip('/').split('/')[-1]
|
| |
- flask.g.auth.logged_in = True
|
| |
- flask.g.auth.openid = openid
|
| |
- flask.g.auth.user = hubs.models.User.by_openid(session, openid)
|
| |
- flask.g.auth.openid_url = flask.session.get('openid')
|
| |
- flask.g.auth.fullname = flask.session.get('fullname', None)
|
| |
- flask.g.auth.nickname = flask.session.get('nickname', None)
|
| |
- flask.g.auth.email = flask.session.get('email', None)
|
| |
- flask.g.auth.avatar = username2avatar(flask.g.auth.nickname)
|
| |
+
|
| |
+ if OIDC.user_loggedin:
|
| |
+ if not hasattr(flask.session, 'auth') or not flask.session.auth:
|
| |
+ flask.session.auth = munch.Munch(
|
| |
+ fullname=OIDC.user_getfield('name'),
|
| |
+ nickname=OIDC.user_getfield('nickname') \
|
| |
+ or OIDC.user_getfield('sub'),
|
| |
+ email=OIDC.user_getfield('email'),
|
| |
+ timezone=OIDC.user_getfield('zoneinfo'),
|
| |
+ cla_done=\
|
| |
+ 'http://admin.fedoraproject.org/accounts/cla/done' \
|
| |
+ in OIDC.user_getfield('cla'),
|
| |
+ groups=OIDC.user_getfield('groups'),
|
| |
+ logged_in=True,
|
| |
+ )
|
| |
+ flask.session.auth.avatar=username2avatar(
|
| |
+ flask.session.auth.nickname)
|
| |
+ flask.session.auth.user = hubs.models.User.by_username(
|
| |
+ session, flask.session.auth.nickname)
|
| |
+ flask.g.auth = flask.session.auth
|
| |
+ else:
|
| |
+ flask.g.auth = munch.Munch(logged_in=False)
|
| |
|
| |
|
| |
def get_hub(session, name):
|
| |
@@ -581,7 +576,7 @@
|
| |
@login_required
|
| |
def hub_subscribe(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
hub.subscribe(session, user)
|
| |
session.commit()
|
| |
return flask.redirect(flask.url_for('hub', name=hub.name))
|
| |
@@ -591,7 +586,7 @@
|
| |
@login_required
|
| |
def hub_unsubscribe(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
try:
|
| |
hub.unsubscribe(session, user)
|
| |
except KeyError:
|
| |
@@ -604,7 +599,7 @@
|
| |
@login_required
|
| |
def hub_star(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
hub.subscribe(session, user, role='stargazer')
|
| |
session.commit()
|
| |
return flask.redirect(flask.url_for('hub', name=hub.name))
|
| |
@@ -614,7 +609,7 @@
|
| |
@login_required
|
| |
def hub_unstar(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
try:
|
| |
hub.unsubscribe(session, user, role='stargazer')
|
| |
except KeyError:
|
| |
@@ -627,7 +622,7 @@
|
| |
@login_required
|
| |
def hub_join(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
hub.subscribe(session, user, role='member')
|
| |
session.commit()
|
| |
return flask.redirect(flask.url_for('hub', name=hub.name))
|
| |
@@ -637,7 +632,7 @@
|
| |
@login_required
|
| |
def hub_leave(hub):
|
| |
hub = get_hub(session, hub)
|
| |
- user = hubs.models.User.by_openid(session, flask.g.auth.openid)
|
| |
+ user = hubs.models.User.by_username(session, flask.g.auth.nickname)
|
| |
try:
|
| |
hub.unsubscribe(session, user, role='member')
|
| |
except KeyError:
|
| |
Perhaps instead just have runserver.py set this to False?
Since runserver itself is meant for development setups.