2015-06-19 15 views
12

Sto provando ad utilizzare il segnale user_registered per impostare i ruoli predefiniti per gli utenti quando si registrano usando la sicurezza delle palline come nel seguente collegamento: Setting Default Role in Flask SecurityFlask-Security user_registered Segnale non ricevuto in Python 3.3, ma funziona in 2.7

nelle mie ricerche posso vedere che c'era un bug che è stato già affrontato per questo in boccetta-security: Not getting signal from flask-security, Fix - user_registered signal problem

ho provato quanto segue per dimostrare se il segnale viene ricevuto dal gestore, senza qualsiasi fortuna:

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

Questo, tuttavia, non viene mai chiamato anche se l'utente viene registrato e il segnale deve essere inviato.

Se aiuta Ho impostato la configurazione di pallone-sicurezza nel modo seguente:

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 

I segnali provenienti Flask-Login e Flask-Principal stanno lavorando per me, come sono riuscito a confermare che i seguenti frammenti di codice con successo stampa quando i segnali vengono inviati:

@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) 

Per la mia messa a punto sto usando Python 3.3 (anaconda) e utilizzando il seguente: Flask == 0.10.1, pallone-login == 0.2.11, boccetta-preside == 0.4.0, == pallone-sicurezza 1.7.4, lampeggiatore == 1.3. Avendo osservato i segnali sia in fiasco-login che in fiasco di sicurezza, non sono sicuro del perché i segnali di sicurezza delle fiasche non funzionerebbero.

EDIT:

Se aggiungo print(user_registered.receivers) ad un percorso nella mia app mostrerà che ho un ricevitore: {139923381372400: <function user_registered_sighandler at 0x7f42737145f0>}. Se metto la stessa istruzione di stampa all'interno del registerable.py di pallone-sicurezza poco prima del user_registered.send(app._get_current_object(),user=user, confirm_token=token) allora elenca nessun ricevitori: {}

EDIT2:

problema sembra essere correlato all'utilizzo di python 3.3. Ho creato un ambiente python 2.7 e il codice user_registered ha funzionato come previsto.

codice completo per riprodurre: template

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:

<!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> 

risposta

0

Se l'importazione per user_registered è cambiato a quanto segue:

quindi il segnale funzionerà come previsto in python 3.3 e chiama la funzione user_registered_sighandler quando un utente è registrato.

Il segnale user_registered viene importato nel file __init__.py per la sicurezza del pallone, quindi è disponibile anche al livello superiore del pacchetto.

+0

: è ora 'da flask_security import user_registered' –

0

sono stato in grado di fare questo con qualcosa di simile:

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

Grazie per la risposta @BrandonRose. Questo non risolve il mio problema, comunque. Quale versione di python e dei moduli associati stai usando? Anche se aggiungo un modulo di registro esteso e utilizzo i parametri di funzione che hai usato, la mia funzione non viene chiamata. – khammel

+0

2.7, anche se ripensandoci, in realtà non vedo nel tuo codice dove definisci il ruolo predefinito. Se funziona a 2,7 puoi usare 2.7 per eseguire l'app? Se usi supervisord puoi specificare il tuo pythonpath solo per l'app, anche se stai eseguendo python 3 per altre attività. – brandomr

+0

La definizione del ruolo predefinito non era il mio problema. Il problema era/è che il segnale non è mai stato ricevuto. Ho usato i segnali della casetta peewee come soluzione alternativa. Aggiornamento – khammel

Problemi correlati