A couple of things are important to note for this commit: - it only implements the new access control for alias and admin management - the access control code is located in access.py The idea behind simpler access control is auditability. There have been a couple of bugs related to functions not checking permissions properly. If checking permissions is as simple as decorating a function, exporting the permission scheme for an audit should be simple. Also, this still does not address the information leakage related to 404 errors when an object does not exist, independently of permissions the user has over the domain.
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
from freeposte.admin import app, db, models, forms, access
|
|
|
|
import os
|
|
import flask
|
|
import flask_login
|
|
import wtforms_components
|
|
|
|
|
|
@app.route('/alias/list/<domain_name>', methods=['GET'])
|
|
@access.domain_admin(models.Domain, 'domain_name')
|
|
def alias_list(domain_name):
|
|
domain = models.Domain.query.get(domain_name) or flask.abort(404)
|
|
return flask.render_template('alias/list.html', domain=domain)
|
|
|
|
|
|
@app.route('/alias/create/<domain_name>', methods=['GET', 'POST'])
|
|
@access.domain_admin(models.Domain, 'domain_name')
|
|
def alias_create(domain_name):
|
|
domain = models.Domain.query.get(domain_name) or flask.abort(404)
|
|
if domain.max_aliases and len(domain.aliases) >= domain.max_aliases:
|
|
flask.flash('Too many aliases for domain %s' % domain, 'error')
|
|
return flask.redirect(
|
|
flask.url_for('.alias_list', domain_name=domain.name))
|
|
form = forms.AliasForm()
|
|
if form.validate_on_submit():
|
|
if domain.has_email(form.localpart.data):
|
|
flask.flash('Email is already used', 'error')
|
|
else:
|
|
alias = models.Alias(domain=domain)
|
|
form.populate_obj(alias)
|
|
db.session.add(alias)
|
|
db.session.commit()
|
|
flask.flash('Alias %s created' % alias)
|
|
return flask.redirect(
|
|
flask.url_for('.alias_list', domain_name=domain.name))
|
|
return flask.render_template('alias/create.html',
|
|
domain=domain, form=form)
|
|
|
|
|
|
@app.route('/alias/edit/<alias>', methods=['GET', 'POST'])
|
|
@access.domain_admin(models.Alias, 'alias')
|
|
def alias_edit(alias):
|
|
alias = models.Alias.query.get(alias) or flask.abort(404)
|
|
form = forms.AliasForm(obj=alias)
|
|
wtforms_components.read_only(form.localpart)
|
|
if form.validate_on_submit():
|
|
form.populate_obj(alias)
|
|
db.session.commit()
|
|
flask.flash('Alias %s updated' % alias)
|
|
return flask.redirect(
|
|
flask.url_for('.alias_list', domain_name=alias.domain.name))
|
|
return flask.render_template('alias/edit.html',
|
|
form=form, alias=alias, domain=alias.domain)
|
|
|
|
|
|
@app.route('/alias/delete/<alias>', methods=['GET', 'POST'])
|
|
@access.domain_admin(models.Alias, 'alias')
|
|
@access.confirmation_required("delete {alias}")
|
|
def alias_delete(alias):
|
|
alias = models.Alias.query.get(alias) or flask.abort(404)
|
|
db.session.delete(alias)
|
|
db.session.commit()
|
|
flask.flash('Alias %s deleted' % alias)
|
|
return flask.redirect(
|
|
flask.url_for('.alias_list', domain_name=alias.domain.name))
|