1

我喜欢 peewee 和 Flask 的安全性,它们可以很好地协同工作,但我无法让 peewee 的管理功能正常工作。我真的不确定如何做到这一点,但我真的很想同时使用两者。我已经尝试了很多东西,但似乎没有任何效果。

我当前的代码如下所示:

import datetime
from flask import Flask, abort, redirect, render_template, url_for, flash, request
from flask_peewee.auth import Auth, BaseUser
from flask_peewee.db import Database
from flask_peewee.admin import Admin, ModelAdmin
from flask_peewee.rest import RestAPI, UserAuthentication
from peewee import *
from flask.ext.security import *
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['DATABASE'] = {
    'name': 'ee.db',
    'engine': 'peewee.SqliteDatabase',
}

# Create database connection object
db = Database(app)

class Role(db.Model, RoleMixin):
    name = TextField(unique=True)
    description = TextField(null=True)

class RoleAdmin(ModelAdmin):
    columns = ('name', 'description')

class User(db.Model, UserMixin):
    username = TextField()
    password = TextField()
    email = TextField()
    role = ForeignKeyField(Role)
    active = BooleanField(default=True)
    confirmed_at = DateTimeField(null=True)

class UserAdmin(ModelAdmin):
    columns = ('username', 'email', 'role', 'active', 'confirmed_at')

class UserRoles(db.Model):
    user = ForeignKeyField(User, related_name='roles')
    role = ForeignKeyField(Role, related_name='users')
    name = property(lambda self: self.role.name)
    description = property(lambda self: self.role.description)

class UserRolesAdmin(ModelAdmin):
    columns = ('user', 'role', 'name', 'description')

class Note(db.Model):
    user = ForeignKeyField(User, related_name='notes')
    title = CharField()
    message = TextField()
    created = DateTimeField(default=datetime.datetime.now)
    def __unicode__(self):
        return '%s: %s %s' % (self.user.username, self.message, self.created)

class NoteAdmin(ModelAdmin):
    columns = ("user", "message", "created")
    foreign_key_lookups = {'user': 'username'}


class CustomAuth(Auth):
    def get_user_model(self):
        return User

    def get_model_admin(self):
        return UserAdmin

class CustomAdmin(Admin):
    def check_user_permission(self, user):
        if has_role(current_user).name == "admin":
            return True

# Setup Flask-Security
user_datastore = PeeweeUserDatastore(db, User, Role, UserRoles)
security = Security(app, user_datastore)

#Setup Flask-Peewee admin
auth = CustomAuth(app, db)
admin = CustomAdmin(app, auth)
admin.register(Note, NoteAdmin)
admin.register(User, UserAdmin)
admin.setup()

#create a RestAPI container
api = RestAPI(app)
#register the Note model
api.register(Note)
api.setup()

#instantiate the user auth
user_auth = UserAuthentication(auth)

# Views
@app.route("/")
@login_required
def index():
    messages = Note.select()
    return render_template("base.html",
    notes = messages,
    username = current_user.username,
    role = current_user.role.name
    )

@app.route("/add", methods = ['post'])
@login_required
def add():
    user = current_user
    now = datetime.datetime.now()
    Note.create(user = current_user.get_id(), title = request.form["title"], message = request.form["message"], created = now)
    flash('New entry was successfully posted')
    return redirect(url_for('index'))

@app.route("/delete/<id>")
@login_required
def delete(id):
    note = Note.get(Note.id == id)
    note.delete_instance()
    flash('Entry was successfully removed')
    return redirect(url_for('index'))

if __name__ == '__main__':
    for Model in (Role, User, UserRoles):
        Model.drop_table(fail_silently=True)
        Model.create_table(fail_silently=True)
    user_datastore.create_role(name="admin", description="admin")
    user_datastore.create_user(username="Ben", email='hello', password='password', active=True, confirmed_at=datetime.datetime(1935,9,9,9,9), role=1)
    user_datastore.add_role_to_user('hello', "admin")
    Note.create_table(fail_silently=True)
    app.run(port = 8080)

当我尝试登录 Peewee Admin 时,我收到以下错误:`AttributeError: 'User' object has no attribute 'check_password'

编辑:

完整调试:

File "/anaconda/lib/python2.7/site-packages/flask_peewee/auth.py", line 170, in login

form.password.data,

File "/anaconda/lib/python2.7/site-packages/flask_peewee/auth.py", line 128, in authenticate

 if not user.check_password(password):

AttributeError: 'User' object has no attribute 'check_password

我真的不明白为什么这会引发 AttributeError。注册密码,并导入 BaseUser 类(check_password 需要)。我究竟做错了什么?

4

1 回答 1

0

您的 User 类需要实现 check_password 和 set_password 方法,因为 Flask-Peewee 调用它们来验证请求和更新模型。

Flask-Peewee 提供了一个类 BaseUser,它具有可以混合到 User 中的简单实现,但是当您还使用 Flask-Security 时,这可能没有用。您需要自己实现这些方法,它们调用 Flask-Security 来比较和散列密码,因为这两个项目的密码散列方法不同,并且您只在数据库中保存一个散列。

于 2014-10-10T20:20:48.043 回答