|  | @@ -174,29 +174,35 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 174 | 174 |          return DBSession.query(cls).filter_by(email=username).first()
 | 
	
		
			
			| 175 | 175 |  
 | 
	
		
			
			| 176 | 176 |      @classmethod
 | 
	
		
			
			| 177 |  | -    def _hash_password(cls, password):
 | 
	
		
			
			|  | 177 | +    def _hash_password(cls, cleartext_password):
 | 
	
		
			
			| 178 | 178 |          salt = sha256()
 | 
	
		
			
			| 179 | 179 |          salt.update(os.urandom(60))
 | 
	
		
			
			| 180 | 180 |          salt = salt.hexdigest()
 | 
	
		
			
			| 181 | 181 |  
 | 
	
		
			
			| 182 | 182 |          hash = sha256()
 | 
	
		
			
			| 183 | 183 |          # Make sure password is a str because we cannot hash unicode objects
 | 
	
		
			
			| 184 |  | -        hash.update((password + salt).encode('utf-8'))
 | 
	
		
			
			|  | 184 | +        hash.update((cleartext_password + salt).encode('utf-8'))
 | 
	
		
			
			| 185 | 185 |          hash = hash.hexdigest()
 | 
	
		
			
			| 186 | 186 |  
 | 
	
		
			
			| 187 |  | -        password = salt + hash
 | 
	
		
			
			|  | 187 | +        ciphertext_password = salt + hash
 | 
	
		
			
			| 188 | 188 |  
 | 
	
		
			
			| 189 | 189 |          # Make sure the hashed password is a unicode object at the end of the
 | 
	
		
			
			| 190 | 190 |          # process because SQLAlchemy _wants_ unicode objects for Unicode cols
 | 
	
		
			
			| 191 | 191 |          # FIXME - D.A. - 2013-11-20 - The following line has been removed since using python3. Is this normal ?!
 | 
	
		
			
			| 192 | 192 |          # password = password.decode('utf-8')
 | 
	
		
			
			| 193 | 193 |  
 | 
	
		
			
			| 194 |  | -        return password
 | 
	
		
			
			|  | 194 | +        return ciphertext_password
 | 
	
		
			
			| 195 | 195 |  
 | 
	
		
			
			| 196 |  | -    def _set_password(self, password):
 | 
	
		
			
			| 197 |  | -        """Hash ``password`` on the fly and store its hashed version."""
 | 
	
		
			
			| 198 |  | -        self._password = self._hash_password(password)
 | 
	
		
			
			| 199 |  | -        self.update_webdav_digest_auth(password)
 | 
	
		
			
			|  | 196 | +    def _set_password(self, cleartext_password: str) -> None:
 | 
	
		
			
			|  | 197 | +        """
 | 
	
		
			
			|  | 198 | +        Set ciphertext password from cleartext password.
 | 
	
		
			
			|  | 199 | +
 | 
	
		
			
			|  | 200 | +        Hash cleartext password on the fly,
 | 
	
		
			
			|  | 201 | +        Store its ciphertext version,
 | 
	
		
			
			|  | 202 | +        Update the WebDAV hash as well.
 | 
	
		
			
			|  | 203 | +        """
 | 
	
		
			
			|  | 204 | +        self._password = self._hash_password(cleartext_password)
 | 
	
		
			
			|  | 205 | +        self.update_webdav_digest_auth(cleartext_password)
 | 
	
		
			
			| 200 | 206 |  
 | 
	
		
			
			| 201 | 207 |      def _get_password(self):
 | 
	
		
			
			| 202 | 208 |          """Return the hashed version of the password."""
 | 
	
	
		
			
			|  | @@ -219,22 +225,22 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 219 | 225 |                                                 descriptor=property(_get_hash_digest,
 | 
	
		
			
			| 220 | 226 |                                                                      _set_hash_digest))
 | 
	
		
			
			| 221 | 227 |  
 | 
	
		
			
			| 222 |  | -    def update_webdav_digest_auth(self, password) -> None:
 | 
	
		
			
			|  | 228 | +    def update_webdav_digest_auth(self, cleartext_password) -> None:
 | 
	
		
			
			| 223 | 229 |          self.webdav_left_digest_response_hash \
 | 
	
		
			
			| 224 |  | -            = '{username}:/:{password}'.format(
 | 
	
		
			
			|  | 230 | +            = '{username}:/:{cleartext_password}'.format(
 | 
	
		
			
			| 225 | 231 |                  username=self.email,
 | 
	
		
			
			| 226 |  | -                password=password,
 | 
	
		
			
			|  | 232 | +                cleartext_password=cleartext_password,
 | 
	
		
			
			| 227 | 233 |              )
 | 
	
		
			
			| 228 | 234 |  
 | 
	
		
			
			| 229 | 235 |  
 | 
	
		
			
			| 230 |  | -    def validate_password(self, password):
 | 
	
		
			
			|  | 236 | +    def validate_password(self, cleartext_password):
 | 
	
		
			
			| 231 | 237 |          """
 | 
	
		
			
			| 232 | 238 |          Check the password against existing credentials.
 | 
	
		
			
			| 233 | 239 |  
 | 
	
		
			
			| 234 |  | -        :param password: the password that was provided by the user to
 | 
	
		
			
			| 235 |  | -            try and authenticate. This is the clear text version that we will
 | 
	
		
			
			| 236 |  | -            need to match against the hashed one in the database.
 | 
	
		
			
			| 237 |  | -        :type password: unicode object.
 | 
	
		
			
			|  | 240 | +        :param cleartext_password: the password that was provided by the user
 | 
	
		
			
			|  | 241 | +            to try and authenticate. This is the clear text version that we
 | 
	
		
			
			|  | 242 | +            will need to match against the hashed one in the database.
 | 
	
		
			
			|  | 243 | +        :type cleartext_password: unicode object.
 | 
	
		
			
			| 238 | 244 |          :return: Whether the password is valid.
 | 
	
		
			
			| 239 | 245 |          :rtype: bool
 | 
	
		
			
			| 240 | 246 |  
 | 
	
	
		
			
			|  | @@ -242,10 +248,10 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 242 | 248 |          result = False
 | 
	
		
			
			| 243 | 249 |          if self.password:
 | 
	
		
			
			| 244 | 250 |              hash = sha256()
 | 
	
		
			
			| 245 |  | -            hash.update((password + self.password[:64]).encode('utf-8'))
 | 
	
		
			
			|  | 251 | +            hash.update((cleartext_password + self.password[:64]).encode('utf-8'))
 | 
	
		
			
			| 246 | 252 |              result = self.password[64:] == hash.hexdigest()
 | 
	
		
			
			| 247 | 253 |              if result and not self.webdav_left_digest_response_hash:
 | 
	
		
			
			| 248 |  | -                self.update_webdav_digest_auth(password)
 | 
	
		
			
			|  | 254 | +                self.update_webdav_digest_auth(cleartext_password)
 | 
	
		
			
			| 249 | 255 |          return result
 | 
	
		
			
			| 250 | 256 |  
 | 
	
		
			
			| 251 | 257 |      def get_display_name(self, remove_email_part=False):
 |