flask-rbac
flask-rbac copied to clipboard
TypeError: <app.models.user.AnonymousUser object at 0x7fd11ad8a590> is not an instance of <class 'flask_sqlalchemy._ BoundDeclarativeMeta'>
I was trying to use flask_rbac with flask_Login Manager AnonymousUserMixin. my Role Model ` from app import db, rbac from flask_rbac import RoleMixin
roles_parents = db.Table( 'roles_parents', db.Column('role_id', db.Integer, db.ForeignKey('role.id')), db.Column('parent_id', db.Integer, db.ForeignKey('role.id')) )
@rbac.as_role_model class Role(db.Model, RoleMixin): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(20)) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, default=db.func.current_timestamp( ), onupdate=db.func.current_timestamp()) parents = db.relationship( 'Role', secondary=roles_parents, primaryjoin=(id == roles_parents.c.role_id), secondaryjoin=(id == roles_parents.c.parent_id), backref=db.backref('children', lazy='dynamic') )
def __init__(self, name):
RoleMixin.__init__(self)
self.name = name
def add_parent(self, parent):
# You don't need to add this role to parent's children set,
# relationship between roles would do this work automatically
self.parents.append(parent)
def add_parents(self, *parents):
for parent in parents:
self.add_parent(parent)
@staticmethod
def get_by_name(name):
return Role.query.filter_by(name=name).first()
def __repr__(self):
return 'Role <%r>' % self.name`
###My User Model: ` import flask_login as fl @rbac.as_user_model class User(UserMixin, db.Model, fl.UserMixin):
id = db.Column(db.Integer, primary_key=True)
# User Name
username = db.Column(db.String(128), nullable=False,
unique=True, index=True)
# Identification Data: email & password
email = db.Column(db.String(128), nullable=False, index=True)
password_hash = db.Column(db.String(128), nullable=False)
# Authorisation Data: role & status
status = db.Column(db.SmallInteger, nullable=True, default=True)
# New instance instantiation procedure
date_created = db.Column(db.DateTime, default=db.func.current_timestamp())
date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(
), onupdate=db.func.current_timestamp())
roles = db.relationship(
'Role',
secondary=users_roles,
backref=db.backref('roles', lazy='dynamic')
)
@loginManager.user_loader def load_user(user_id): return User.query.get(int(user_id)) `
I use a separate AnonymousUser class to handle Anonymous user. the main reason is to protect my flask-admin routes from unauthorized entry. ` from flask_login import AnonymousUserMixin class AnonymousUser(fl.AnonymousUserMixin): ''' Added this to protect flask-admin blueprint '''
def is_admin(self):
return False
loginManager.anonymous_user = AnonymousUserI get following error:File "/home/rezwan/visual_code_projects/flask_boilerplate_new/venv/lib/python2.7/site-packages/flask_rbac/init.py", line 362, in _authenticate
(current_user, self.user_model.class))
TypeError: <app.models.user.AnonymousUser object at 0x7fe2fd7085d0> is not an instance of <class 'flask_sqlalchemy.
BoundDeclarativeMeta'>If I don't use tha class I get follwing error:TypeError: <flask_login.mixins.AnonymousUserMixin object at 0x7f9b97dbd410> is not an instance of <class 'flask_sqlalchemy._BoundDeclarativeMeta'>`
What is the proper way to handle anonymous user or use rbac with AnonymousUSerMixin
@rbac.set_user_loader
def get_current_user():
return flask_login.current_user._get_current_object()
See maxcountryman/flask-login#9. Would be nice if this was done automatically if Flask-Login is installed.
from flask_login import current_user
from flask_rbac import RBAC
rbac = RBAC()
def setup_rbac(app):
rbac.init_app(app)
from smartsapp.models.users import User, Role
rbac.set_role_model(Role)
rbac.set_user_model(User)
rbac.set_user_loader(lambda *args: current_user)