I'm new to flask so bear with me. I'm creating a sign-up flow via flask-security-too. How can I assign a user role on sign-up? I'm following the second (SQLAcademy + session) example from here. I have tried to update
class ExtendedRegisterForm(RegisterForm):
first_name = StringField('First Name', [DataRequired()])
last_name = StringField('Last Name', [DataRequired()])
roles = SelectField('Roles', choices=["user"]) #<- updated here
and also created a new "register_user.html" which adds a new field for role "user":
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% include "security/_messages.html" %}
<h1>Registrer</h1>
<form action="{{ url_for_security('register') }}" method="POST" name="register_user_form">
{{ register_user_form.hidden_tag() }}
{{ render_field_with_errors(register_user_form.email) }}
{{ render_field_with_errors(register_user_form.password) }}
{% if register_user_form.password_confirm %}
{{ render_field_with_errors(register_user_form.password_confirm) }}
{% endif %}
{{ render_field_with_errors(register_user_form.first_name) }}
{{ render_field_with_errors(register_user_form.last_name) }}
{{ render_field_with_errors(register_user_form.roles) }} <!-- updated mainly here -->
{{ render_field(register_user_form.submit) }}
</form>
{% include "security/_menu.html" %}
Models and database looks like as specified in the example above. I have also set
app.config["SECURITY_REGISTERABLE"] = True
app.config["SECURITY_RECOVERABLE"] = True
And set-up e-mail. However, when I run this, I get this error:
Traceback (most recent call last):
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 2213, in __call__
return self.wsgi_app(environ, start_response)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 2193, in wsgi_app
response = self.handle_exception(e)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 1486, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask/app.py", line 1469, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask_security/decorators.py", line 632, in wrapper
return f(*args, **kwargs)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask_security/views.py", line 299, in register
user = register_user(form)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask_security/registerable.py", line 46, in register_user
user = _datastore.create_user(**user_model_kwargs)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask_security/datastore.py", line 470, in create_user
kwargs = self._prepare_create_user_args(**kwargs)
File "/opt/homebrew/Caskroom/miniforge/base/envs/flask_security_too/lib/python3.10/site-packages/flask_security/datastore.py", line 214, in _prepare_create_user_args
roles[i] = self.find_role(rn)
TypeError: 'str' object does not support item assignment
And the role "user" is not assigned. Why?
If I read your question correctly - you want to administratively add the “user” role to all newly registered users. If so - don’t add things to the form - since that is really meant for user input. For this use case - register a signal handler. See the docs at: https://flask-security-too.readthedocs.io/en/stable/api.html#signals
You want the user_registered signal - that will pass you the completely filled in user model - which you can then use userdatastore.add_role_to_user(user, “user”)