|  | @@ -14,6 +14,7 @@ import uuid
 | 
	
		
			
			| 14 | 14 |  from datetime import datetime
 | 
	
		
			
			| 15 | 15 |  from hashlib import md5
 | 
	
		
			
			| 16 | 16 |  from hashlib import sha256
 | 
	
		
			
			|  | 17 | +from typing import TYPE_CHECKING
 | 
	
		
			
			| 17 | 18 |  
 | 
	
		
			
			| 18 | 19 |  from sqlalchemy import Column
 | 
	
		
			
			| 19 | 20 |  from sqlalchemy import ForeignKey
 | 
	
	
		
			
			|  | @@ -32,6 +33,8 @@ from tracim.lib.utils import lazy_ugettext as l_
 | 
	
		
			
			| 32 | 33 |  from tracim.model import DBSession
 | 
	
		
			
			| 33 | 34 |  from tracim.model import DeclarativeBase
 | 
	
		
			
			| 34 | 35 |  from tracim.model import metadata
 | 
	
		
			
			|  | 36 | +if TYPE_CHECKING:
 | 
	
		
			
			|  | 37 | +    from tracim.model.data import Workspace
 | 
	
		
			
			| 35 | 38 |  
 | 
	
		
			
			| 36 | 39 |  __all__ = ['User', 'Group', 'Permission']
 | 
	
		
			
			| 37 | 40 |  
 | 
	
	
		
			
			|  | @@ -174,7 +177,7 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 174 | 177 |          return DBSession.query(cls).filter_by(email=username).first()
 | 
	
		
			
			| 175 | 178 |  
 | 
	
		
			
			| 176 | 179 |      @classmethod
 | 
	
		
			
			| 177 |  | -    def _hash_password(cls, cleartext_password):
 | 
	
		
			
			|  | 180 | +    def _hash_password(cls, cleartext_password: str) -> str:
 | 
	
		
			
			| 178 | 181 |          salt = sha256()
 | 
	
		
			
			| 179 | 182 |          salt.update(os.urandom(60))
 | 
	
		
			
			| 180 | 183 |          salt = salt.hexdigest()
 | 
	
	
		
			
			|  | @@ -204,7 +207,7 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 204 | 207 |          self._password = self._hash_password(cleartext_password)
 | 
	
		
			
			| 205 | 208 |          self.update_webdav_digest_auth(cleartext_password)
 | 
	
		
			
			| 206 | 209 |  
 | 
	
		
			
			| 207 |  | -    def _get_password(self):
 | 
	
		
			
			|  | 210 | +    def _get_password(self) -> str:
 | 
	
		
			
			| 208 | 211 |          """Return the hashed version of the password."""
 | 
	
		
			
			| 209 | 212 |          return self._password
 | 
	
		
			
			| 210 | 213 |  
 | 
	
	
		
			
			|  | @@ -225,14 +228,14 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 225 | 228 |                                                 descriptor=property(_get_hash_digest,
 | 
	
		
			
			| 226 | 229 |                                                                     _set_hash_digest))
 | 
	
		
			
			| 227 | 230 |  
 | 
	
		
			
			| 228 |  | -    def update_webdav_digest_auth(self, cleartext_password) -> None:
 | 
	
		
			
			|  | 231 | +    def update_webdav_digest_auth(self, cleartext_password: str) -> None:
 | 
	
		
			
			| 229 | 232 |          self.webdav_left_digest_response_hash \
 | 
	
		
			
			| 230 | 233 |              = '{username}:/:{cleartext_password}'.format(
 | 
	
		
			
			| 231 | 234 |                  username=self.email,
 | 
	
		
			
			| 232 | 235 |                  cleartext_password=cleartext_password,
 | 
	
		
			
			| 233 | 236 |              )
 | 
	
		
			
			| 234 | 237 |  
 | 
	
		
			
			| 235 |  | -    def validate_password(self, cleartext_password):
 | 
	
		
			
			|  | 238 | +    def validate_password(self, cleartext_password: str) -> bool:
 | 
	
		
			
			| 236 | 239 |          """
 | 
	
		
			
			| 237 | 240 |          Check the password against existing credentials.
 | 
	
		
			
			| 238 | 241 |  
 | 
	
	
		
			
			|  | @@ -253,7 +256,7 @@ class User(DeclarativeBase):
 | 
	
		
			
			| 253 | 256 |                  self.update_webdav_digest_auth(cleartext_password)
 | 
	
		
			
			| 254 | 257 |          return result
 | 
	
		
			
			| 255 | 258 |  
 | 
	
		
			
			| 256 |  | -    def get_display_name(self, remove_email_part=False):
 | 
	
		
			
			|  | 259 | +    def get_display_name(self, remove_email_part: bool=False) -> str:
 | 
	
		
			
			| 257 | 260 |          """
 | 
	
		
			
			| 258 | 261 |          Get a name to display from corresponding member or email.
 | 
	
		
			
			| 259 | 262 |  
 |