title: python flask-security: encryption error "hash could not be identified"
body: <p>I'm using Flask-Security in a Flask project. Basically everything works, until I try to turn on password encryption. Basically I followed this: <a href="http://packages.python.org/Flask-Security/configuration.html" rel="nofollow">http://packages.python.org/Flask-Security/configuration.html</a>
  Which led to me adding this:</p>
  
  <pre><code>app.config['SECURITY_PASSWORD_HASH'] = 'bcrypt'
  app.config['SECURITY_PASSWORD_SALT'] = '$2a$16$PnnIgfMwkOjGX4SkHqSOPO'
  </code></pre>
  
  <p>This results in a error unfortunately:</p>
  
  <pre><code>File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
  return self.wsgi_app(environ, start_response)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
  response = self.make_response(self.handle_exception(e))
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
  response = self.full_dispatch_request()
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
  rv = self.handle_user_exception(e)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
  rv = self.dispatch_request()
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request
  return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask_security/decorators.py", line 171, in wrapper
  return f(*args, **kwargs)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask_security/views.py", line 72, in login
  if form.validate_on_submit():
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask_wtf/form.py", line 123, in validate_on_submit
  return self.is_submitted() and self.validate()
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask_security/forms.py", line 165, in validate
  if not verify_password(self.password.data, self.user.password):
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/flask_security/utils.py", line 84, in verify_password
  return _pwd_context.verify(get_hmac(password), password_hash)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/passlib/context.py", line 2534, in verify
  record = self._get_or_identify_record(hash, scheme, category)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/passlib/context.py", line 2258, in _get_or_identify_record
  return self._identify_record(hash, category)
  File "/home/geoadmin/.virtualenvs/flask/lib/python2.7/site-packages/passlib/context.py", line 1455, in identify_record
  raise ValueError("hash could not be identified")
  ValueError: hash could not be identified
  </code></pre>
  
  <p>I'm rather clueless as to what's happening. I thought i generated a good bcrypt hash, but there are no real examples on the website for password encryption and the error itself confuses me :/</p>
  
  <p>Software used:
  - Ubuntu 12.04LTS
  - Python 2.7.2
  - FLask 0.9
  - Flask-Security 1.5.4
  - Running on MongoDB 2.2 through MongoAlchemy</p>
  
  <p>Thanks for your help!!</p>
  
  <p>Edit: thanks to Bikeshedder, this is the likely culprit:</p>
  
  <pre><code># Create a user to test with
  @app.before_first_request
  def create_user():
      user_datastore.create_user(email='test@test.net', password='testerdetest')
  </code></pre>
  
  <p>I assumed that the create_user method would automatically encrypt the password. But apparently it doesn't... The documentation isn't really clear here:</p>
  
  <pre><code>Class flask_security.datastore.MongoEngineUserDatastore(db, user_model, role_model)
  A MongoEngine datastore implementation for Flask-Security that assumes the use of the Flask-MongoEngine extension.
  create_user(**kwargs)
  Creates and returns a new user from the given parameters.
  </code></pre>
  
  <p>Edit 2: Working further on BikeShedder's suggestion, I changed my standard user creation to this:</p>
  
  <pre><code># Create a user to test with
  @app.before_first_request
  def create_user():
      user_datastore.create_user(email='test@test.net', password=bcrypt.hashpw('testerdetest', app.config['SECURITY_PASSWORD_SALT'])
  </code></pre>
  
  <p>So that solves the error, but it gives me an "Invalid password", meaning that flask-security does something different than I do in my encrypting... argh!</p>
  
  <p>Edit 3: changed from bcrypt to passlib (which flask-security also uses)</p>
  
  <pre><code>app.config['SECURITY_PASSWORD_SALT'] = '/2aX16zPnnIgfMwkOjGX4S'
  </code></pre>
  
  <p>and</p>
  
  <pre><code>user_datastore.create_user(email='test@test.net', password=passlib.hash.bcrypt.encrypt('testerdetest', salt=app.config['SECURITY_PASSWORD_SALT']))
  </code></pre>
  
  <p>still get an invalid pw :(
  If i look at the source code at <a href="https://github.com/mattupstate/flask-security/blob/develop/flask_security/utils.py" rel="nofollow">https://github.com/mattupstate/flask-security/blob/develop/flask_security/utils.py</a> it seems it only uses a sha512 encryption... I don't understand the documentation then...</p>
  
  <p>Edit 5: solved (thanks for putting me on the right direction!)
  flask.ext.security.utils.encrypt_password() did the trick. However, i'm still in doubt whether it really is bcrypt or not, but okay, it's encrypted at least...</p>