2015-06-19 11 views
12

Ich versuche, das user_registered Signal zu verwenden, um Standardrollen für Benutzer einzurichten, wenn sie sich unter dem folgenden Link registrieren: Setting Default Role in Flask SecurityFlask-Sicherheit user_registered Signal nicht in Python 3.3 empfangen, aber funktioniert in 2.7

in meinen Recherchen kann ich sehen, dass ein Fehler war, die dafür in Kolben-Sicherheit bereits angesprochen wurde: Not getting signal from flask-security, Fix - user_registered signal problem

ich habe versucht, durch den Handler die folgenden zu beweisen, wenn das Signal empfangen wird, ohne irgendein Glück:

@user_registered.connect_via(app) 
def user_registered_sighandler(sender, **extra): 
    print("print-user_registered_sighandler:", extra) 

Dies wird jedoch nie aufgerufen, obwohl der Benutzer registriert und das Signal gesendet werden soll.

Wenn es hilft ich die Kolben-Sicherheitskonfiguration festgelegt haben, wie folgt:

app.config['SECURITY_REGISTERABLE'] = True 
app.config['SECURITY_CONFIRMABLE'] = False 
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False 
app.config['SECURITY_CHANGEABLE'] = True 
app.config['SECURITY_SEND_PASSWORD_CHANGE_EMAIL'] = False 

Signale von Flask-Anmeldung und Flask-Haupt für mich arbeiten, wie ich erfolgreich, dass die folgenden Code-Schnipsel zu verwaltenden bestätigen Druck, wenn die Signale gesendet werden:

@user_logged_out.connect_via(app) 
def on_user_logged_out(sender, user): 
    print('USER LOG OUT: made it in',user) 

@identity_changed.connect_via(app) 
def identity_changed_ok(sender,identity): 
    print('Identity changed:',identity) 

Für meine Einstellung ich verwende python 3.3 (Anaconda) und mit der folgenden: Flask == 0.10.1, Kolben-login == 0.2.11, Kolben-Haupt == 0.4.0, Kolbensicherheit == 1.7.4, Blinker == 1.3. Nachdem ich mir die Signale sowohl in der Flasche als auch in der Flasche angeschaut habe, bin ich mir nicht sicher, warum die Flaschensicherheitssignale nicht funktionieren würden.

EDIT:

Wenn ich print(user_registered.receivers) auf einer Route in meiner App hinzufügen, wird es zeigen, dass ich einen Empfänger haben: {139923381372400: <function user_registered_sighandler at 0x7f42737145f0>}. Wenn ich diese gleiche print-Anweisung innerhalb der registerable.py von Kolben-Sicherheit setzte kurz vor den user_registered.send(app._get_current_object(),user=user, confirm_token=token) dann listet es keinen Empfänger: {}

EDIT2:

Problem scheint mit Python 3.3 bezogen werden. Ich habe eine Python 2.7-Umgebung erstellt, und der user_registered-Code hat wie erwartet funktioniert.

Voll Code zu reproduzieren:

from flask import Flask,render_template 
from playhouse.flask_utils import FlaskDB 
import os 
from flask.ext.security import Security, PeeweeUserDatastore 
from flask.ext.security.signals import user_registered 
from flask.ext.login import user_logged_out 
from peewee import * 
from playhouse.signals import Model 
from flask.ext.security import UserMixin,RoleMixin 

app = Flask(__name__) 

app.config['ADMIN_PASSWORD']='secret' 
app.config['APP_DIR']=os.path.dirname(os.path.realpath(__file__)) 
app.config['DATABASE']='sqliteext:///%s' % os.path.join(app.config['APP_DIR'], 'blog.db') 
app.config['SECRET_KEY'] = 'shhh, secret!' 
app.config['SECURITY_REGISTERABLE'] = True 
app.config['SECURITY_CONFIRMABLE'] = False 
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False 

flask_db = FlaskDB() 
flask_db.init_app(app) 
database = flask_db.database 

class BaseModel(Model): 
    class Meta: 
     database=flask_db.database 


class User(BaseModel, UserMixin): 
    email=CharField() 
    password=CharField() 
    active = BooleanField(default=True) 
    confirmed_at = DateTimeField(null=True) 

    def is_active(self): 
     return True 

    def is_anonymous(self): 
     return False 

    def is_authenticated(self): 
     return True 


class Role(BaseModel, RoleMixin): 
    name = CharField(unique=True) 
    description = TextField(null=True) 


class UserRoles(BaseModel): 
    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) 


user_datastore = PeeweeUserDatastore(database, User, Role, UserRoles) 
security = Security(app, user_datastore) 

@user_registered.connect_via(app) 
def user_registered_sighandler(sender,**extra): 
    print("print-user_registered_sighandler") 

@user_logged_out.connect_via(app) 
def on_user_logged_out(sender, user): 
    print('USER LOG OUT: made it in',user) 

@app.route('/') 
def index(): 
    print(user_registered.receivers) 
    return render_template('base.html') 

database.create_tables([User,Role,UserRoles], safe=True) 
app.run(debug=True) 

base.html Vorlage:

<!doctype html> 
<html> 
    <head> 
    <title>Blog</title> 
    </head> 
    <body> 
      <ul> 
      {% if current_user.is_authenticated() %} 
       <li><a href="{{ url_for('security.logout',next='/') }}">Log out</a></li> 
       <li><a href="{{ url_for('security.register') }}">Register</a></li> 
     {% else %} 
     <li><a href="{{ url_for('security.login',next='/') }}">Login</a></li> 
     <li><a href="{{ url_for('security.register') }}">Register</a></li> 
      {% endif %} 
      {% block extra_header %}{% endblock %} 
      </ul> 
    </body> 
</html> 

Antwort

0

Wenn der Import für user_registered wird zu folgendem geändert:

from flask.ext.security import user_registered 

dann wird das Signal wie erwartet in Python 3.3 funktionieren und die user_registered_sighandler Funktion aufrufen, wenn ein Benutzer registriert ist.

Das Signal user_registered wird in die Datei __init__.py für flash-security importiert, daher ist es auch auf der obersten Ebene des Pakets verfügbar.

+0

Update: Es ist jetzt 'from flask_security import user_registered' –

0

Ich konnte dies wie mit etwas tun:

security = Security(app, user_datastore, 
     register_form=ExtendedRegisterForm) 


@user_registered.connect_via(app) 
def user_registered_sighandler(app, user, confirm_token): 
    default_role = user_datastore.find_role("Pending") 
    user_datastore.add_role_to_user(user, default_role) 
    db.session.commit() 
+0

Danke für die Antwort @BrandonRose. Dies löst jedoch mein Problem nicht. Welche Version von Python und die zugehörigen Module verwenden Sie? Selbst wenn ich ein erweitertes Registerformular anlege und die Funktionsparameter verwende, die Sie benutzt haben, wird meine Funktion nicht aufgerufen. – khammel

+0

2.7, obwohl ich zurückschaue, sehe ich eigentlich nicht in deinem Code, wo du die Standardrolle definierst. Wenn es in 2.7 funktioniert, können Sie 2.7 verwenden, um die App auszuführen? Wenn Sie Supervisord verwenden, können Sie Ihren Pythonpfad nur für die App angeben, auch wenn Sie Python 3 für andere Aufgaben ausführen. – brandomr

+0

Das Definieren der Standardrolle war nicht mein Problem. Problem war/ist, dass das Signal nie empfangen wurde. Ich habe die Peewee-Playhouse-Signale als Workaround benutzt. – khammel

Verwandte Themen