diff --git a/app/admin/views.py b/app/admin/views.py index 96f75edbc879cb9832b7c7db5bb19ec79f488e94..69aad416a49850f6927de0a9b15f5427eb978a44 100644 --- a/app/admin/views.py +++ b/app/admin/views.py @@ -51,12 +51,6 @@ class AdminModelView(sqla.ModelView): return current_user.is_authenticated and current_user.is_admin -class GroupAdmin(AdminModelView): - can_create = False - can_edit = False - can_delete = False - - class UserAdmin(AdminModelView): can_create = False can_edit = False diff --git a/app/factory.py b/app/factory.py index 1bdfe498431328d6151cd0ec2f0d8da0811b1cce..79bc8567227c267035a24cd4e428b40586811936 100644 --- a/app/factory.py +++ b/app/factory.py @@ -15,7 +15,7 @@ from whitenoise import WhiteNoise from . import settings, models from .extensions import (db, migrate, login_manager, ldap_manager, bootstrap, admin, mail, jwt, toolbar, redis_store, fsession, cache) -from .admin.views import (AdminModelView, ItemAdmin, UserAdmin, GroupAdmin, TokenAdmin, +from .admin.views import (AdminModelView, ItemAdmin, UserAdmin, TokenAdmin, NetworkAdmin) from .main.views import bp as main from .inventory.views import bp as inventory @@ -107,7 +107,6 @@ def create_app(config=None): cache.init_app(app) admin.init_app(app) - admin.add_view(GroupAdmin(models.Group, db.session)) admin.add_view(UserAdmin(models.User, db.session, endpoint='users')) admin.add_view(TokenAdmin(models.Token, db.session)) admin.add_view(AdminModelView(models.Action, db.session)) diff --git a/app/models.py b/app/models.py index 89ed0720e2f2479e3683d7114108a4be17b1994f..fa52ac24a0c84f865d4920b396e5ad17bcc926c0 100644 --- a/app/models.py +++ b/app/models.py @@ -16,7 +16,6 @@ import sqlalchemy as sa from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.dialects import postgresql from sqlalchemy.orm import validates -from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy_continuum import make_versioned, version_class from citext import CIText from flask import current_app @@ -67,6 +66,7 @@ def get_temporary_ics_id(): @login_manager.user_loader +@cache.memoize(timeout=1800) def load_user(user_id): """User loader callback for flask-login @@ -95,28 +95,6 @@ def save_user(dn, username, data, memberships): return user -# Table required for Many-to-Many relationships between users and groups -usergroups_table = db.Table( - 'usergroups', - db.Column('user_id', db.Integer, db.ForeignKey('user_account.id')), - db.Column('group_id', db.Integer, db.ForeignKey('group.id')) -) - - -class Group(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.Text, nullable=False, unique=True) - - def __str__(self): - return self.name - - -def find_or_create_group(name): - """Return the existing group or a newly created one""" - group = Group.query.filter_by(name=name).first() - return group or Group(name=name) - - class User(db.Model, UserMixin): # "user" is a reserved word in postgresql # so let's use another name @@ -126,12 +104,7 @@ class User(db.Model, UserMixin): username = db.Column(db.Text, nullable=False, unique=True) display_name = db.Column(db.Text, nullable=False) email = db.Column(db.Text) - grp = db.relationship('Group', secondary=usergroups_table, - backref=db.backref('members', lazy='dynamic')) - # Proxy the 'name' attribute from the 'grp' relationship - # See http://docs.sqlalchemy.org/en/latest/orm/extensions/associationproxy.html - groups = association_proxy('grp', 'name', - creator=find_or_create_group) + groups = db.Column(postgresql.ARRAY(db.Text)) tokens = db.relationship("Token", backref="user") def get_id(self): diff --git a/app/user/views.py b/app/user/views.py index 473f9bc80ac0d8a3859bc48f2b81c9f08ab35278..9440dfc43a524e267467f1a4a2729761e5828e83 100644 --- a/app/user/views.py +++ b/app/user/views.py @@ -14,6 +14,8 @@ from flask import (Blueprint, render_template, request, redirect, url_for, from flask_login import login_user, logout_user, login_required, current_user from flask_ldap3_login.forms import LDAPLoginForm from .forms import TokenForm +from ..extensions import cache, db +from ..models import load_user from .. import tokens, utils bp = Blueprint('user', __name__) @@ -31,6 +33,8 @@ def login(): @bp.route('/logout') @login_required def logout(): + # Don't forget to remove the user from the cache + cache.delete_memoized(load_user, str(current_user.id)) logout_user() return redirect(url_for('user.login')) @@ -38,6 +42,10 @@ def logout(): @bp.route('/profile', methods=['GET', 'POST']) @login_required def profile(): + if current_user not in db.session: + # If the current user is cached, it won't be in the sqlalchemy session + # Add it to access the user.tokens relationship in the template + db.session.add(current_user) # Try to get the generated token from the session token = session.pop('generated_token', None) form = TokenForm(request.form)