我想将Flask-Security与RethinkDB一起使用,但我无法让我的自定义RethinkDBUserDatastore正常工作。下面是我为自定义数据存储创建的代码,以及Flask-Security文档中的改编示例应用程序。
from flask_security import UserMixin, RoleMixin
from flask_security.datastore import Datastore
from flask_security.datastore import UserDatastore
import rethinkdb as r
class Bunch(object):
def __init__(self, obj, **kws):
self.__dict__.update(obj)
self.__dict__.update(kws)
def __repr__(self):
return 'Bunch({})'.format(repr(self.__dict__))
class User(Bunch, UserMixin):
def __init__(self, *args, **kwargs):
super(User, self).__init__(*args, **kwargs)
if not hasattr(self, 'active'):
self.active = True
if not hasattr(self, 'roles'):
self.roles = []
class Role(Bunch, RoleMixin):
def __init__(self, *args, **kwargs):
super(Role, self).__init__(*args, **kwargs)
class RethinkDBDatastore(Datastore):
def commit(self):
pass
def put(self, model):
return model
def delete(self, model):
pass
class RethinkDBUserDatastore(UserDatastore):
def __init__(self, db_conn, user_table='users', role_table='roles', user_pk='id', role_pk='id'):
self.db_conn = db_conn
self.user_table = user_table
self.role_table = role_table
self.user_pk = user_pk
self.role_pk = role_pk
RethinkDBDatastore.__init__(self, db=db_conn)
def commit(self):
pass
def get_user(self, id_or_email):
obj = r.table(self.user_table).get(id_or_email).run(self.db_conn)
return User(obj)
def find_user(self, **query):
return User(r.table(self.user_table).filter(query)[0].run(self.db_conn))
def find_role(self, **query):
return Role(r.table(self.role_table).filter(query)[0].run(self.db_conn))
def add_role_to_user(self, user, role):
return r.table(self.user_table) \
.get(user[self.user_pk]) \
.update({'roles': r.row['roles'].default([]).set_insert(role.name)}) \
.run(self.db_conn)
def remove_role_from_user(self, user, role):
return r.table(self.user_table) \
.get(user[self.user_pk]) \
.update({'roles': r.row['roles'].default([]).set_difference([role.name])}) \
.run(self.db_conn)
def toggle_active(self, user):
user['active'] = not user.get('active', True)
return True
def deactivate_user(self, user):
active = user.get('active', True)
if active:
user['active'] = False
return True
return False
def activate_user(self, user):
active = user.get('active', True)
if not active:
user['active'] = True
return True
return False
def create_role(self, **role):
result = r.table(self.role_table).insert(role, return_changes='always').run(self.db_conn)
return result['changes'][0]['new_val']
def create_user(self, **user):
if 'roles' in user:
user['roles'] = [role['name'] for role in roles]
if 'id' not in user:
user['id'] = user['email'] or user['username']
result = r.table(self.user_table).insert(user, return_changes='always').run(self.db_conn)
return result['changes'][0]['new_val']
def delete_user(self, user):
r.table(self.user_table).get(user[self.user_pk]).delete().run(self.db_conn)
文件是基于为SQLAlchemy和Mongo提供的示例创建相关数据存储对象所必需的Flask-Security类的实现。以下是我正在使用的当前源代码:
flask_security_example.py
create_user
文件是我为测试此数据存储适配器而创建的示例应用程序。它运行,但在尝试使用import bcrypt
import rethinkdb as r
from flask import Flask, render_template
from flask_security import Security, login_required
from rethinkdb import ReqlRuntimeError
from rethinkdb import ReqlOpFailedError
from rethinkdb_security import RethinkDBUserDatastore
# Get database connection information
DB_HOST = os.environ.get('DB_HOST', 'localhost')
DB_PORT = os.environ.get('DB_PORT', 28015)
DB_NAME = os.environ.get('DB_NAME', 'flask_security')
DB_TABLE = os.environ.get('DB_TABLE', 'users')
# Create app
APP = Flask(__name__)
APP.config['DEBUG'] = True
APP.config['SECRET_KEY'] = 'super-secret'
APP.config['SECURITY_PASSWORD_SALT'] = bcrypt.gensalt()
# Create the database connection
DB_CONN = r.connect(host=DB_HOST, port=DB_PORT, db=DB_NAME)
# Setup Flask-Security
USER_DATASTORE = RethinkDBUserDatastore(DB_CONN, user_table=DB_TABLE)
SECURITY = Security(APP, USER_DATASTORE)
# Create a user to test with
@APP.before_first_request
def create_user():
try:
r.db_create(DB_NAME).run(DB_CONN)
except ReqlRuntimeError:
pass
try:
r.db(DB_NAME).table_create(DB_TABLE).run(DB_CONN)
except ReqlOpFailedError:
pass
USER_DATASTORE.create_user(email='test@test.com', password='password')
# Views
@APP.route('/')
@login_required
def home():
return "Hello, world."
if __name__ == '__main__':
APP.run()
函数中创建的示例用户进行身份验证时会引发错误。
int x = vec[]
有什么特别的东西我做错了或者可以给出一些关于如何为Flask-Security创建自定义数据存储适配器的指导?