from flask import g, request, redirect, render_template, url_for, flash, \ session, get_flashed_messages, abort from flask.ext.login import login_required, login_user, logout_user, \ current_user from urlparse import urlparse from sqlalchemy import and_ from datetime import datetime import uuid from app import app, db from models import User, Group, Member, Pad, Session from forms import CreateGroup, DeleteForm, ChangeGroup, CreatePad, ChangePad, \ LoginForm from utils.login import auth from utils.viewdecorators import templated from utils.request import after_this_request from utils.filters import * import utils.pagination @app.route('/login', methods=['GET', 'POST']) @templated() def login(): form = LoginForm() if form.validate_on_submit(): user = auth(app.config['LDAP'], User, form.user.data, form.password.data) if user is not None: user.last_login = datetime.now() db.session.commit() login_user(user) db.session.commit() session['uuid'] = unicode(uuid.uuid4()) return form.redirect('index') flash('Wrong user or password') return dict(form=form) @app.route('/logout', methods=['GET']) def logout(): logout_user() if 'uuid' in session: Session.query.filter(Session.uuid == session['uuid']).delete() del session['uuid'] return redirect(url_for('index')) @app.route('/', methods=['GET', 'POST']) @templated() @login_required def index(): form = CreateGroup(request.form) if form.validate_on_submit(): group = Group() form.populate_obj(group) db.session.add(group) form = CreateGroup() Member.create(user=current_user, group=group, admin=True, active=True) db.session.commit() memberships = Member.query.filter( Member.user == current_user, Member.active == True, ).all() groups = sorted([member.group for member in memberships], key=(lambda group: group.name)) return dict(groups=groups, create_form=form) @app.route('/_browse/', defaults={'page': 1}) @app.route('/_browse/') @templated() @login_required def browse(page): public_groups = Group.query.filter( Group.browsable == True, ).order_by(Group.name) pageination = public_groups.paginate(page, 10) return {'groups': pageination.items, 'count': pageination.total, 'pagination': pageination, 'breadcrumbs': [{'text': 'Public groups'}]} @app.route('//_delete/', methods=['GET', 'POST']) @templated() @login_required def group_delete(group_name): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() form = DeleteForm(request.form) if form.validate_on_submit(): if form.sure.data == 'yes': db.session.delete(group) db.session.commit() return redirect(url_for('index')) return {'group': group, 'delete_form': form, 'breadcrumbs': [{'href': url_for('group', group_name=group.name), 'text': group}, {'text': 'Delete group'}]} @app.route('//_change/', methods=['GET', 'POST']) @templated() @login_required def group_change(group_name): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() form = ChangeGroup(request.form, obj=group) if form.validate_on_submit(): del form.name form.populate_obj(group) db.session.commit() return redirect(url_for('group', group_name=group.name)) return {'group': group, 'change_form': form, 'breadcrumbs': [{'href': url_for('group', group_name=group.name), 'text': group}, {'text': 'Edit group'}]} @app.route('//_join///') @login_required def group_join(group_name, member_id, accept): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() member = Member.query.filter( Member.id == member_id, Member.group == group, Member.active == False, ).first_or_404() if accept == 'yes': member.active = True db.session.commit() elif accept == 'no': db.session.delete(member) db.session.commit() return redirect(url_for('group', group_name=group_name)) @app.route('//_create_pad/', methods=['GET', 'POST']) @templated('pad_change.html') @login_required def pad_create(group_name): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() form = CreatePad(request.form, group=group) if form.validate_on_submit(): pad = Pad() form.populate_obj(pad) pad.group = group db.session.add(pad) db.session.commit() return redirect(url_for('group', group_name = group_name)) return {'group': group, 'change_form': form, 'breadcrumbs': [{'href': url_for('group', group_name=group.name), 'text': group}, {'text': 'Create pad'}]} @app.route('///_edit/', methods=['GET', 'POST']) @templated() @login_required def pad_change(group_name, pad_name): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() pad = Pad.query.filter( Pad.name == pad_name, Pad.group == group, ).first_or_404() form = ChangePad(request.form, obj=pad) if form.validate_on_submit(): del form.name form.populate_obj(pad) db.session.commit() return redirect(url_for('group', group_name=group.name)) return {'group': group, 'pad': pad, 'change_form': form, 'breadcrumbs': [{'href': url_for('group', group_name=group.name), 'text': group}, {'text': 'Edit pad: %s' % pad.name}]} @app.route('///_delete/', methods=['GET', 'POST']) @templated() @login_required def pad_delete(group_name, pad_name): group = Group.query.filter( Group.name == group_name, Group.members.any(and_(Member.user == current_user, Member.admin == True, Member.active == True)), ).first_or_404() pad = Pad.query.filter( Pad.name == pad_name, Pad.group == group, ).first_or_404() form = DeleteForm(request.form) if form.validate_on_submit(): if form.sure.data == 'yes': db.session.delete(pad) db.session.commit() return redirect(url_for('group', group_name=group.name)) return {'group': group, 'pad': pad, 'delete_form': form, 'breadcrumbs': [{'href': url_for('group', group_name=group.name), 'text': group}, {'text': 'Delete pad: %s' % pad.name}]} @app.route('///') @templated() @login_required def pad(group_name, pad_name): group = Group.query.filter( Group.name == group_name, ).first_or_404() member = Member.query.filter( Member.group == group, Member.user == current_user, Member.active == True, ).first() if member is None: if not group.public: abort(404) flash('You are not member of this group. You may request membership.') return redirect(url_for('public_group', group_name = group.name)) pad = Pad.query.filter( Pad.name == pad_name, Pad.group == group, ).first() if pad is None: if not member.admin: abort(404) flash('Pad "%s" not found.' % pad_name) return redirect(url_for('group', group_name = group_name)) api_session = Session.query.filter( Session.group == group, Session.user == current_user, Session.uuid == session['uuid'], ).first() if api_session is None or not api_session.is_valid(): if api_session: db.session.delete(api_session) Session.create(user=current_user, group=group, uuid=session['uuid']) db.session.commit() sessions = Session.query.filter( Session.user == current_user, Session.uuid == session['uuid'], ).all() @after_this_request def set_session(response): response.set_cookie('sessionID' , '%2C'.join([s.api_id for s in sessions])) # ignore user logged in messages get_flashed_messages() return {'pad': pad, 'host': 'https://%s' % urlparse(request.url).hostname} @app.route('//', methods=['GET', 'POST']) @templated() @login_required def group(group_name): group = Group.query.filter( Group.name == group_name, ).first_or_404() membership = Member.query.filter( Member.user == current_user, Member.group == group, ).first() if membership is None and request.method == 'POST': membership = Member.create(user=current_user, group=group) db.session.commit() breadcrumbs = [{'text': group}] if group.browsable and (membership is None or not membership.active): breadcrumbs.insert(0, {'text': 'Public groups', 'href': url_for('browse')}) return {'group': group, 'membership': membership, 'pads': group.pads, 'members': group.members, 'breadcrumbs': breadcrumbs}