title: Admin(only) registration of users, Flask-Security
body: <p>I'm currently building a login for a webapp using Flask-Security (which includes Flask-WTForms, Flask-SQLalchemy and Flask-Login). I've been able to fairly painlessly set up the majority of my login flow, including forgotten password; however I want to make it so that the only way users can be registered is through a page only accessible to the admins. I've managed to configure Roles (Admin, User) and set up the following  view:</p>
  
  <pre><code>@app.route('/adminregister')
  @roles_accepted('admin')
  def adminregister():
      return render_template('*')
  </code></pre>
  
  <p>This creates the portal that is successfully limited to accounts with an Admin role. I'm unsure how to proceed for here however, as Flask-security has no built in means to enable what I'm trying to do.</p>
  
  <p>I've overridden RegisterForm already to enforce password rules through a regexp:</p>
  
  <pre><code># fixed register form
  class ExtendedRegisterForm(RegisterForm):
  password = TextField('Password', [validators.Required(), validators.Regexp(r'(?=.*?[0-9])(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[$-/:-?{-~!"^_`\[\]])')])
  </code></pre>
  
  <p>Basically I want a form, located at /adminregister, that when visited by an admin allows for the entry of an email address, at which point first the user is created in the database with a random and secure password, and then a similar process to a forgotten password happens and a 1 time password code is created to reset the password. </p>
  
  <p>Useful things I've looked at:</p>
  
  <ol>
  <li><p>Within flask-security/views.py there is the forgotten passsword code:</p>
  
  <pre><code>def forgot_password():
  """View function that handles a forgotten password request."""
  
  form_class = _security.forgot_password_form
  
  if request.json:
      form = form_class(MultiDict(request.json))
  else:
      form = form_class()
  
  if form.validate_on_submit():
      send_reset_password_instructions(form.user)
      if request.json is None:
          do_flash(*get_message('PASSWORD_RESET_REQUEST', email=form.user.email))
  
  if request.json:
      return _render_json(form, include_user=False)
  
  return _security.render_template(config_value('FORGOT_PASSWORD_TEMPLATE'),
                               forgot_password_form=form,
                               **_ctx('forgot_password'))
  </code></pre></li>
  <li><p>Within flask_security/registerable.py there is the code for register_user</p>
  
  <pre><code>def register_user(**kwargs):
  confirmation_link, token = None, None
  kwargs['password'] = encrypt_password(kwargs['password'])
  user = _datastore.create_user(**kwargs)
  _datastore.commit()
  
  if _security.confirmable:
      confirmation_link, token = generate_confirmation_link(user)
      do_flash(*get_message('CONFIRM_REGISTRATION', email=user.email))
  
  user_registered.send(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)
  
  return user
  </code></pre></li>
  </ol>
  
  <p>I want to somehow combine these two, so that upon submission of a form with the sole field "Email" at '/adminregister' the email is added with a secure, random password in the database and the email address is sent an email with a link to change there password (and ideally a message explaining). I'm not even sure where I would add such code, as there is nothing to specifically override, especially as I can't find a way to override RegisterForm to have FEWER fields and the same functionality.</p>
  
  <p>The structure of my code is in line with the flask-security documentation's <a href="https://pythonhosted.org/Flask-Security/quickstart.html" rel="nofollow">quickstart</a>.</p>
  
  <p>Thank you in advance for any guidance you can offer.</p>