Guest User

Untitled

a guest
Aug 3rd, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.62 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import
  3. import datetime
  4. from ndb import model
  5. from webapp2_extends.utils import Unique, UniqueConstraintViolation, \
  6. check_password_hash, generate_password_hash
  7. from webapp2_extends.auth import create_session_id
  8.  
  9. DEBUG = True
  10.  
  11. class User(model.Model):
  12. """Universal user model. Can be used with App Engine's default users API,
  13. own auth or third party authentication methods (OpenId, OAuth etc).
  14. """
  15. #: Creation date.
  16. created = model.DateTimeProperty(auto_now_add=True)
  17. #: Modification date.
  18. updated = model.DateTimeProperty(auto_now=True)
  19. #: User defined unique name, also used as key_name.
  20. username = model.StringProperty(required=True)
  21. #: Password, only set for own authentication.
  22. password = model.StringProperty(required=False)
  23. #: User email
  24. email = model.StringProperty(required=False)
  25. # Admin flag.
  26. is_admin = model.BooleanProperty(default=False)
  27. #: Authentication identifier according to the auth method in use. Examples:
  28. #: * own|username
  29. #: * gae|user_id
  30. #: * openid|identifier
  31. #: * twitter|username
  32. #: * facebook|username
  33. auth_id = model.StringProperty(repeated=True)
  34. # Flag to persist the auth across sessions for third party auth.
  35. auth_remember = model.BooleanProperty(default=False)
  36. # Auth token, renewed periodically for improved security.
  37. session_id = model.StringProperty(required=True)
  38. # Auth token last renewal date.
  39. session_updated = model.DateTimeProperty(auto_now_add=True)
  40.  
  41. @classmethod
  42. def get_by_username(cls, username):
  43. return cls.query(cls.username == username).get()
  44.  
  45. @classmethod
  46. def get_by_auth_id(cls, auth_id):
  47. return cls.query(cls.auth_id == auth_id).get()
  48.  
  49. @classmethod
  50. def create(cls, username, auth_id, **kwargs):
  51. """Creates a new user and returns it. If the username already exists,
  52. returns None.
  53.  
  54. :param username:
  55. Unique username.
  56. :param auth_id:
  57. Authentication id, according the the authentication method used.
  58. :param email:
  59. Unique email address.
  60. :param kwargs:
  61. Additional entity attributes.
  62. :returns:
  63. The newly created user or None if the username already exists.
  64. """
  65. # Assemble the unique scope/value combinations.
  66. unique_username = 'User.username:%s' % username
  67. unique_auth_id = 'User.auth_id:%s' % auth_id
  68. # Create the unique username, auth_id and email.
  69. uniques = [unique_username, unique_auth_id]
  70. # TODO add email to parms in tipfy.auth so that
  71. # we don't have to use kwargs here
  72. if 'email' in kwargs:
  73. unique_email = 'User.email:%s' % kwargs['email']
  74. uniques.append(unique_email)
  75.  
  76. success, existing = Unique.create_multi(uniques)
  77.  
  78. if success or DEBUG:
  79. kwargs['username'] = username
  80. # make this a list so that we can have multiple auth methods.
  81. kwargs['auth_id'] = [auth_id]
  82. # Generate an initial session id.
  83. kwargs['session_id'] = create_session_id()
  84. if 'password_hash' in kwargs:
  85. # Password is already hashed.
  86. kwargs['password'] = kwargs.pop('password_hash')
  87. elif 'password' in kwargs:
  88. # Password is not hashed: generate a hash.
  89. kwargs['password'] = generate_password_hash(kwargs['password'])
  90. user = cls(**kwargs)
  91. user.put()
  92. return user
  93. else:
  94. # The ordering her is important. Email must come before
  95. # auth id or the error return will make little since to the user.
  96. if unique_email in existing:
  97. raise UniqueConstraintViolation('Email %s already '
  98. 'exists. Try logging in.' % kwargs['email'])
  99. if unique_username in existing:
  100. raise UniqueConstraintViolation('Username %s already '
  101. 'exists' % username)
  102.  
  103. if unique_auth_id in existing:
  104. raise UniqueConstraintViolation('Auth id %s already '
  105. 'exists' % auth_id)
  106.  
  107. def set_password(self, new_password):
  108. """Sets a new, plain password.
  109.  
  110. :param new_password:
  111. A plain, not yet hashed password.
  112. :returns:
  113. None.
  114. """
  115. self.password = generate_password_hash(new_password)
  116.  
  117. def check_password(self, password):
  118. """Checks if a password is valid. This is done with form login
  119.  
  120. :param password:
  121. Password to be checked.
  122. :returns:
  123. True is the password is valid, False otherwise.
  124. """
  125. if check_password_hash(self.password, password):
  126. return True
  127.  
  128. return False
  129.  
  130. def check_session(self, session_id):
  131. """Checks if an auth token is valid.
  132.  
  133. :param session_id:
  134. Token to be checked.
  135. :returns:
  136. True is the token id is valid, False otherwise.
  137. """
  138. if self.session_id == session_id:
  139. return True
  140.  
  141. return False
  142.  
  143. def renew_session(self, force=False, max_age=None):
  144. """Renews the session id if its expiration time has passed.
  145.  
  146. :param force:
  147. True to force the session id to be renewed, False to check
  148. if the expiration time has passed.
  149. :returns:
  150. None.
  151. """
  152. if not force:
  153. # Only renew the session id if it is too old.
  154. expires = datetime.timedelta(seconds=max_age)
  155. force = (self.session_updated + expires < datetime.datetime.now())
  156.  
  157. if force:
  158. self.session_id = create_session_id()
  159. self.session_updated = datetime.datetime.now()
  160. self.put()
  161.  
  162. def __unicode__(self):
  163. """Returns this entity's username.
  164.  
  165. :returns:
  166. Username, as unicode.
  167. """
  168. return unicode(self.username)
  169.  
  170. def __str__(self):
  171. """Returns this entity's username.
  172.  
  173. :returns:
  174. Username, as unicode.
  175. """
  176. return self.__unicode__()
  177.  
  178. def __eq__(self, obj):
  179. """Compares this user entity with another one.
  180.  
  181. :returns:
  182. True if both entities have same key, False otherwise.
  183. """
  184. if not obj:
  185. return False
  186.  
  187. return str(self.key) == str(obj.key)
  188.  
  189. def __ne__(self, obj):
  190. """Compares this user entity with another one.
  191.  
  192. :returns:
  193. True if both entities don't have same key, False otherwise.
  194. """
  195. return not self.__eq__(obj)
Add Comment
Please, Sign In to add comment