# -*- coding: utf-8 -*- """ grumpy.webapp ~~~~~~~~~~~~~ This module contains web application data. :copyright: (c) by 2010 Priit Laes. :license: BSD, see LICENSE for details. """ import hashlib, random from flask import (flash, g, jsonify, redirect, render_template, request, \ session, url_for) from flaskext.openid import OpenID from . import app from .models import db, Category, Developer, Package, User from .utils import requires_auth, requires_auth_basic, send_email # OpenID support oid = OpenID(app) @app.before_request def before_request(): g.user = None if 'openid' in session: g.user = User.query.filter_by(openid=session['openid']).first() @app.route('/') def dashboard(): if g.user is None: return redirect(url_for('index')) # Fetch maintainer info dev = Developer.query.filter_by(email=g.user.email).first() pkgs = None if dev and len(dev.packages): pkgs = dev.packages return render_template('dashboard.html', pkgs=pkgs) @app.route('/browse/') def index(): cats = Category.query.order_by(Category.name.asc()).all() return render_template('index.html', cats=cats) @app.route('/account/') @requires_auth def account(): return render_template('account.html') @app.route('/browse//') def browse_cat(cat): if cat: c = Category.query.filter_by(name=cat).first() pkgs = Package.query.filter_by(category=c) \ .order_by(Package.pkg.asc()).all() if pkgs: return render_template('browse_cat.html', cat=cat, pkgs=pkgs) flash('Category "%s" does not exist' % cat) return redirect(url_for('index')) @app.route('/browse///') def browse_pkg(cat, pkg): if cat and pkg: c = Category.query.filter_by(name=cat).first() if c: package = Package.query.filter_by(category=c) \ .filter_by(pkg=pkg).first() if package: return render_template('browse_pkg.html', cat=cat, pkg=package, qa=package.qaissues) flash('Package "%s/%s" does not exist' % (cat, pkg)) return redirect(url_for('browse_cat', cat=cat)) @app.route('/login/', methods=['GET', 'POST']) @oid.loginhandler def login(): if g.user is not None: return redirect(oid.get_next_url()) if request.method == 'POST': openid = request.form.get('openid') if openid: return oid.try_login(openid, ask_for=['email']) return render_template('login.html', next=oid.get_next_url(), error=oid.fetch_error()) @app.route('/logout/') def logout(): session.pop('openid', None) flash(u'You have been signed out') return redirect(oid.get_next_url()) @oid.after_login def create_or_login(resp): session['openid'] = resp.identity_url user = User.query.filter_by(openid=resp.identity_url).first() if user is not None: flash(u'Successfully logged in') g.user = user return redirect(oid.get_next_url()) return redirect(url_for('create_account', next=oid.get_next_url(), email=resp.email)) @app.route('/create-account/', methods=['GET', 'POST']) def create_account(): if g.user is not None or 'openid' not in session: return redirect(url_for('index')) if request.method == 'POST': email = request.form['email'].strip() if not email: flash(u'Error: you need to provide @gentoo.org email') # XXX: remove plaes.org, that's for testing purposes ;) elif not email.endswith(('@gentoo.org', '@plaes.org')): flash(u'You need to be a valid Gentoo developer to sign up') else: user = User(email, session['openid']) db.session.add(user) db.session.commit() send_email(email, u'Gentoo Grumpy registration confirmation', \ render_template('email/registration.txt', user=user)) flash(u'Account successfully created') return redirect(oid.get_next_url()) return render_template('create_account.html', next=oid.get_next_url()) @app.route('/confirm-account//') def confirm_account(email): user = User.query.filter_by(email=email).first() if not user: flash(u'Invalid email: "%s"' % email) return redirect(url_for('index')) if user.regtoken is None: flash(u'Account been already confirmed') return redirect(url_for('index')) if user.regtoken != request.args.get('token'): flash(u'Invalid token specified') return render_template('confirm_account.html', success=False) user.regtoken = None db.session.commit() return render_template('confirm_account.html', success=True) @app.route('/_api/1.0/account/generate_api_key', methods=['POST']) @requires_auth def api_generate_api_key(): salt = random.randrange(1000, 10000) g.user.apitoken = hashlib.md5("%s$%d" % (g.user.email, salt)).hexdigest() db.session.commit() return jsonify(dict(apikey=g.user.apitoken)) @app.route('/_api/1.0/tinderbox/') @requires_auth_basic def tinderbox_api(): return jsonify(dict(success=False))