Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
views.py 2.41 KiB
# -*- coding: utf-8 -*-
"""
app.admin.views
~~~~~~~~~~~~~~~

This module customizes the admin views.

:copyright: (c) 2017 European Spallation Source ERIC
:license: BSD 2-Clause, see LICENSE for more details.

"""
from wtforms import validators, fields
from flask_admin.contrib import sqla
from flask_admin.model.form import converts
from flask_login import current_user
from ..validators import IPNetwork, ICS_ID_RE


# Monkey patch flask-admin Unique validator to disable it
# Flask-admin automatically adds an unique validator that queries
# the database. For some fields like INET and MACADDR, if the value
# is invalid the database raises an exception. It's nicer to let the
# field validator catches the incorrect format.
# It's also better to let the database catch unicity error anyway.
sqla.form.Unique.__call__ = lambda x, y, z: None


# Add custom model converter for CIText type
# See https://github.com/flask-admin/flask-admin/issues/1196
class AppAdminModelConverter(sqla.form.AdminModelConverter):

    @converts('CIText')
    def conv_CIText(self, field_args, **extra):
        return fields.TextAreaField(**field_args)

    @converts('sqlalchemy.dialects.postgresql.base.CIDR')
    def conv_PGCidr(self, field_args, **extra):
        field_args['validators'].append(IPNetwork())
        return fields.StringField(**field_args)


class AdminModelView(sqla.ModelView):
    model_form_converter = AppAdminModelConverter

    # Replace TextAreaField (default for Text) with StringField
    form_overrides = {
        'name': fields.StringField,
    }

    def is_accessible(self):
        return current_user.is_authenticated and current_user.is_admin


class UserAdmin(AdminModelView):
    can_create = False
    can_edit = False
    can_delete = False


class TokenAdmin(AdminModelView):
    can_create = False
    can_edit = False


class ItemAdmin(AdminModelView):

    # Replace TextAreaField (default for Text) with StringField
    form_overrides = {
        'ics_id': fields.StringField,
        'serial_number': fields.StringField,
    }

    form_args = {
        'ics_id': {
            'label': 'ICS id',
            'validators': [validators.Regexp(ICS_ID_RE, message='ICS id shall match [A-Z]{3}[0-9]{3}')],
            'filters': [lambda x: x or None],
        }
    }


class NetworkAdmin(AdminModelView):

    # Replace TextAreaField (default for Text) with StringField
    form_overrides = {
        'vlan_name': fields.StringField,
    }