Implement the decorator-based access control for all views

master
Pierre Jaury 8 years ago
parent 4e4f2b8037
commit ee9a416696

@ -53,7 +53,12 @@ def domain_admin(args, kwargs, model, key):
@permissions_wrapper @permissions_wrapper
def owner(args, kwargs, model, key): def owner(args, kwargs, model, key):
obj = model.query.get(kwargs[key]) # if no key is provided but the model is User, then return the current
# user
if kwargs[key] is None and model == models.User:
obj = model.query.get(flask_login.current_user.email)
else:
obj = model.query.get(kwargs[key])
if not obj: if not obj:
flask.abort(404) flask.abort(404)
else: else:

@ -1,5 +1,5 @@
from freeposte import dockercli from freeposte import dockercli
from freeposte.admin import app, db, models, forms, utils from freeposte.admin import app, db, models, forms, utils, access
import os import os
import flask import flask
@ -7,7 +7,7 @@ import flask_login
@app.route('/', methods=["GET"]) @app.route('/', methods=["GET"])
@flask_login.login_required @access.authenticated
def index(): def index():
return flask.redirect(flask.url_for('.user_settings')) return flask.redirect(flask.url_for('.user_settings'))
@ -26,14 +26,14 @@ def login():
@app.route('/logout', methods=['GET']) @app.route('/logout', methods=['GET'])
@flask_login.login_required @access.authenticated
def logout(): def logout():
flask_login.logout_user() flask_login.logout_user()
return flask.redirect(flask.url_for('.index')) return flask.redirect(flask.url_for('.index'))
@app.route('/services', methods=['GET']) @app.route('/services', methods=['GET'])
@flask_login.login_required @access.global_admin
def services(): def services():
utils.require_global_admin() utils.require_global_admin()
containers = {} containers = {}

@ -1,4 +1,4 @@
from freeposte.admin import app, db, models, forms, utils from freeposte.admin import app, db, models, forms, utils, access
from freeposte import app as flask_app from freeposte import app as flask_app
import os import os
@ -8,15 +8,14 @@ import wtforms_components
@app.route('/domain', methods=['GET']) @app.route('/domain', methods=['GET'])
@flask_login.login_required @access.authenticated
def domain_list(): def domain_list():
return flask.render_template('domain/list.html') return flask.render_template('domain/list.html')
@app.route('/domain/create', methods=['GET', 'POST']) @app.route('/domain/create', methods=['GET', 'POST'])
@flask_login.login_required @access.global_admin
def domain_create(): def domain_create():
utils.require_global_admin()
form = forms.DomainForm() form = forms.DomainForm()
if form.validate_on_submit(): if form.validate_on_submit():
if models.Domain.query.get(form.name.data): if models.Domain.query.get(form.name.data):
@ -32,10 +31,9 @@ def domain_create():
@app.route('/domain/edit/<domain_name>', methods=['GET', 'POST']) @app.route('/domain/edit/<domain_name>', methods=['GET', 'POST'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def domain_edit(domain_name): def domain_edit(domain_name):
utils.require_global_admin() domain = models.Domain.query.get(domain_name) or flask.abort(404)
domain = utils.get_domain_admin(domain_name)
form = forms.DomainForm(obj=domain) form = forms.DomainForm(obj=domain)
wtforms_components.read_only(form.name) wtforms_components.read_only(form.name)
if form.validate_on_submit(): if form.validate_on_submit():
@ -48,11 +46,10 @@ def domain_edit(domain_name):
@app.route('/domain/delete/<domain_name>', methods=['GET', 'POST']) @app.route('/domain/delete/<domain_name>', methods=['GET', 'POST'])
@access.global_admin
@utils.confirmation_required("delete {domain_name}") @utils.confirmation_required("delete {domain_name}")
@flask_login.login_required
def domain_delete(domain_name): def domain_delete(domain_name):
utils.require_global_admin() domain = models.Domain.query.get(domain_name) or flask.abort(404)
domain = utils.get_domain_admin(domain_name)
db.session.delete(domain) db.session.delete(domain)
db.session.commit() db.session.commit()
flask.flash('Domain %s deleted' % domain) flask.flash('Domain %s deleted' % domain)
@ -60,18 +57,18 @@ def domain_delete(domain_name):
@app.route('/domain/details/<domain_name>', methods=['GET']) @app.route('/domain/details/<domain_name>', methods=['GET'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def domain_details(domain_name): def domain_details(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
return flask.render_template('domain/details.html', domain=domain, return flask.render_template('domain/details.html', domain=domain,
config=flask_app.config) config=flask_app.config)
@app.route('/domain/genkeys/<domain_name>', methods=['GET', 'POST']) @app.route('/domain/genkeys/<domain_name>', methods=['GET', 'POST'])
@access.domain_admin(models.Domain, 'domain_name')
@utils.confirmation_required("regenerate keys for {domain_name}") @utils.confirmation_required("regenerate keys for {domain_name}")
@flask_login.login_required
def domain_genkeys(domain_name): def domain_genkeys(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
domain.generate_dkim_key() domain.generate_dkim_key()
return flask.redirect( return flask.redirect(
flask.url_for(".domain_details", domain_name=domain_name)) flask.url_for(".domain_details", domain_name=domain_name))

@ -1,4 +1,4 @@
from freeposte.admin import app, db, models, forms, utils from freeposte.admin import app, db, models, forms, utils, access
import os import os
import flask import flask
@ -8,17 +8,19 @@ import wtforms_components
@app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/fetch/list', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/fetch/list/<user_email>', methods=['GET']) @app.route('/fetch/list/<user_email>', methods=['GET'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def fetch_list(user_email): def fetch_list(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
return flask.render_template('fetch/list.html', user=user) return flask.render_template('fetch/list.html', user=user)
@app.route('/fetch/create', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/fetch/create', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/fetch/create/<user_email>', methods=['GET', 'POST']) @app.route('/fetch/create/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def fetch_create(user_email): def fetch_create(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.FetchForm() form = forms.FetchForm()
if form.validate_on_submit(): if form.validate_on_submit():
fetch = models.Fetch(user=user) fetch = models.Fetch(user=user)
@ -32,9 +34,9 @@ def fetch_create(user_email):
@app.route('/fetch/edit/<fetch_id>', methods=['GET', 'POST']) @app.route('/fetch/edit/<fetch_id>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.Fetch, 'fetch_id')
def fetch_edit(fetch_id): def fetch_edit(fetch_id):
fetch = utils.get_fetch(fetch_id) fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
form = forms.FetchForm(obj=fetch) form = forms.FetchForm(obj=fetch)
if form.validate_on_submit(): if form.validate_on_submit():
form.populate_obj(fetch) form.populate_obj(fetch)
@ -48,9 +50,9 @@ def fetch_edit(fetch_id):
@app.route('/fetch/delete/<fetch_id>', methods=['GET', 'POST']) @app.route('/fetch/delete/<fetch_id>', methods=['GET', 'POST'])
@utils.confirmation_required("delete a fetched account") @utils.confirmation_required("delete a fetched account")
@flask_login.login_required @access.owner(models.Fetch, 'fetch_id')
def fetch_delete(fetch_id): def fetch_delete(fetch_id):
fetch = utils.get_fetch(fetch_id) fetch = models.Fetch.query.get(fetch_id) or flask.abort(404)
db.session.delete(fetch) db.session.delete(fetch)
db.session.commit() db.session.commit()
flask.flash('Fetch configuration delete') flask.flash('Fetch configuration delete')

@ -1,4 +1,4 @@
from freeposte.admin import app, db, models, forms, utils from freeposte.admin import app, db, models, forms, utils, access
import os import os
import flask import flask
@ -7,16 +7,16 @@ import wtforms_components
@app.route('/manager/list/<domain_name>', methods=['GET']) @app.route('/manager/list/<domain_name>', methods=['GET'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def manager_list(domain_name): def manager_list(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
return flask.render_template('manager/list.html', domain=domain) return flask.render_template('manager/list.html', domain=domain)
@app.route('/manager/create/<domain_name>', methods=['GET', 'POST']) @app.route('/manager/create/<domain_name>', methods=['GET', 'POST'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def manager_create(domain_name): def manager_create(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
form = forms.ManagerForm() form = forms.ManagerForm()
form.manager.choices = [ form.manager.choices = [
(user.email, user.email) for user in (user.email, user.email) for user in
@ -40,6 +40,7 @@ def manager_create(domain_name):
@utils.confirmation_required("remove manager {manager}") @utils.confirmation_required("remove manager {manager}")
@flask_login.login_required @flask_login.login_required
def manager_delete(manager): def manager_delete(manager):
# TODO fix this behaviour
user = utils.get_user(manager, admin=True) user = utils.get_user(manager, admin=True)
domain = utils.get_domain_admin(user.domain_name) domain = utils.get_domain_admin(user.domain_name)
if user in domain.managers: if user in domain.managers:

@ -1,4 +1,4 @@
from freeposte.admin import app, db, models, forms, utils from freeposte.admin import app, db, models, forms, utils, access
import os import os
import flask import flask
@ -7,16 +7,16 @@ import wtforms_components
@app.route('/user/list/<domain_name>', methods=['GET']) @app.route('/user/list/<domain_name>', methods=['GET'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def user_list(domain_name): def user_list(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
return flask.render_template('user/list.html', domain=domain) return flask.render_template('user/list.html', domain=domain)
@app.route('/user/create/<domain_name>', methods=['GET', 'POST']) @app.route('/user/create/<domain_name>', methods=['GET', 'POST'])
@flask_login.login_required @access.domain_admin(models.Domain, 'domain_name')
def user_create(domain_name): def user_create(domain_name):
domain = utils.get_domain_admin(domain_name) domain = models.Domain.query.get(domain_name) or flask.abort(404)
if domain.max_users and len(domain.users) >= domain.max_users: if domain.max_users and len(domain.users) >= domain.max_users:
flask.flash('Too many users for domain %s' % domain, 'error') flask.flash('Too many users for domain %s' % domain, 'error')
return flask.redirect( return flask.redirect(
@ -39,9 +39,9 @@ def user_create(domain_name):
@app.route('/user/edit/<user_email>', methods=['GET', 'POST']) @app.route('/user/edit/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.domain_admin(models.User, 'user_email')
def user_edit(user_email): def user_edit(user_email):
user = utils.get_user(user_email, True) user = models.User.query.get(user_email) or flask.abort(404)
form = forms.UserForm(obj=user) form = forms.UserForm(obj=user)
wtforms_components.read_only(form.localpart) wtforms_components.read_only(form.localpart)
form.pw.validators = [] form.pw.validators = []
@ -57,10 +57,10 @@ def user_edit(user_email):
@app.route('/user/delete/<user_email>', methods=['GET', 'POST']) @app.route('/user/delete/<user_email>', methods=['GET', 'POST'])
@access.domain_admin(models.User, 'user_email')
@utils.confirmation_required("delete {user_email}") @utils.confirmation_required("delete {user_email}")
@flask_login.login_required
def user_delete(user_email): def user_delete(user_email):
user = utils.get_user(user_email, True) user = models.User.query.get(user_email) or flask.abort(404)
db.session.delete(user) db.session.delete(user)
db.session.commit() db.session.commit()
flask.flash('User %s deleted' % user) flask.flash('User %s deleted' % user)
@ -70,9 +70,10 @@ def user_delete(user_email):
@app.route('/user/settings', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/user/settings', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/user/usersettings/<user_email>', methods=['GET', 'POST']) @app.route('/user/usersettings/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def user_settings(user_email): def user_settings(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.UserSettingsForm(obj=user) form = forms.UserSettingsForm(obj=user)
if form.validate_on_submit(): if form.validate_on_submit():
form.populate_obj(user) form.populate_obj(user)
@ -86,9 +87,10 @@ def user_settings(user_email):
@app.route('/user/password', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/user/password', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/user/password/<user_email>', methods=['GET', 'POST']) @app.route('/user/password/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def user_password(user_email): def user_password(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.UserPasswordForm() form = forms.UserPasswordForm()
if form.validate_on_submit(): if form.validate_on_submit():
if form.pw.data != form.pw2.data: if form.pw.data != form.pw2.data:
@ -105,9 +107,10 @@ def user_password(user_email):
@app.route('/user/forward', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/user/forward', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/user/forward/<user_email>', methods=['GET', 'POST']) @app.route('/user/forward/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def user_forward(user_email): def user_forward(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.UserForwardForm(obj=user) form = forms.UserForwardForm(obj=user)
if form.validate_on_submit(): if form.validate_on_submit():
form.populate_obj(user) form.populate_obj(user)
@ -121,9 +124,10 @@ def user_forward(user_email):
@app.route('/user/reply', methods=['GET', 'POST'], defaults={'user_email': None}) @app.route('/user/reply', methods=['GET', 'POST'], defaults={'user_email': None})
@app.route('/user/reply/<user_email>', methods=['GET', 'POST']) @app.route('/user/reply/<user_email>', methods=['GET', 'POST'])
@flask_login.login_required @access.owner(models.User, 'user_email')
def user_reply(user_email): def user_reply(user_email):
user = utils.get_user(user_email) user_email = user_email or flask_login.current_user.email
user = models.User.query.get(user_email) or flask.abort(404)
form = forms.UserReplyForm(obj=user) form = forms.UserReplyForm(obj=user)
if form.validate_on_submit(): if form.validate_on_submit():
form.populate_obj(user) form.populate_obj(user)

Loading…
Cancel
Save