Search code examples
pythonflaskflask-security

Error extending RegisterForm in flask-security


I am experiencing difficulty extending the registration aparatus of flask-security.

I have extended the RegisterForm:

class ExtendedRegisterForm(RegisterForm):
    payroll_no = IntegerField('Payroll Number', validators=[DataRequired(message=(u'Please include a payroll number'))])
    firstname = TextField('First Name')
    surname = TextField('Surname')
    position = QuerySelectField(u'Position', query_factory=getPosition, get_label='name', allow_blank=False)
    mobile = TextField('Mobile', [InputRequired(), is_10])

I am attempting to call register_user() from a view (I have disabled SECURITY_REGISTERABLE) and direct to my own registration page.

Whilst it is validating fine, I am getting the following error:

TypeError: "register_user() got an unexpected keyword argument 'surname'"

My user model matches my Form:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(80), unique=True)
    password = db.Column(db.String)
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    firstname = db.Column(db.String(20))
    surname = db.Column(db.String(30))
    position_id = db.Column(db.Integer, db.ForeignKey('position.id'))
    mobile = db.Column(db.String)
    payroll_no = db.Column(db.Integer)

Assistance most appreciated.

Unfortunately the answer (I am fairly sure) will not lie in moving to a context processor or other solution: My project has multiple 'splash' pages and I need a way to set a specific role to that user based on the way they got to the registration page; Ie. user who found site A needs Role A, user who found site B needs Role B.


Solution

  • The solution was very simple. I imported all of the necessary registration components and called the following function, passing it the form. Since I have multiple accounts (as the app acts as a backend for multiple sites) I also pass it an account_id integer so the user becomes associated with the correct account.

    from project import app, db, security, user_datastore
    from project.models import User
    from flask.ext.security.confirmable import generate_confirmation_link
    from flask.ext.security.utils import do_flash, get_message, config_value, send_mail, encrypt_password
    from flask.ext.security.signals import user_registered
    from flask import current_app
    
    
    def register_my_user(form, account_id):
        form_data = form.to_dict()
        form_data['password']=encrypt_password(form_data['password'])
        user = user_datastore.create_user(**form_data)
        user.account_id = account_id
        db.session.commit()
        confirmation_link, token = generate_confirmation_link(user)
        do_flash(*get_message('CONFIRM_REGISTRATION', email=user.email))
        user_registered.send(current_app._get_current_object(),
                         user=user, confirm_token=token)
        if config_value('SEND_REGISTER_EMAIL'):
            send_mail(config_value('EMAIL_SUBJECT_REGISTER'), user.email, 'welcome',
                  user=user, confirmation_link=confirmation_link)  
    

    Pasted here in the hope that it can be of use to people trying to deconstruct the user registration components of flask-security