Guest User

Untitled

a guest
Nov 16th, 2025
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.30 KB | None | 0 0
  1. from datetime import datetime, timedelta
  2. from typing import List, Optional
  3.  
  4. from flask import flash
  5. from flask_login import UserMixin
  6. from flask_sqlalchemy import SQLAlchemy
  7. from sqlalchemy import Boolean, Integer, String, ForeignKey
  8. from sqlalchemy.orm import Mapped, mapped_column, relationship
  9.  
  10. from app.email_password_reset.models import RouteToken
  11. from app.payment.models import Payments
  12. from app.postinfo.models import Posts
  13. from app.songroute.models import songs
  14.  
  15. db = SQLAlchemy()
  16.  
  17. class User(UserMixin, db.Model):
  18. __tablename__ = 'user'
  19.  
  20. '''
  21.  
  22. One to One relationship between 2 tables.
  23. The One relationship is User and the other 1 relationship is route_token + UserRole
  24.  
  25.  
  26. One to Many relationship between 2 tables.
  27. The One relationship is User and the Many relationships is Posts + Payments
  28. '''
  29. id: Mapped[int] = mapped_column(primary_key=True)
  30. # unique blocks the same username etc
  31. # I can't have Nullable=False because it will make me add the columns everytime I add a column in User table
  32. username: Mapped[str] = mapped_column(String(80), index=True, unique=True)
  33. hashed_password: Mapped[str] = mapped_column(String(128))
  34. email: Mapped[str] = mapped_column(String(700), index=True)
  35. registration_confirmation_email: Mapped[bool] = mapped_column(Boolean, default=False)
  36. profile_pic_name: Mapped[Optional[str]] = mapped_column(String())
  37. # token and etc information sent in an email. This is the email_login_confirmation route.
  38. emailed_token: Mapped[Optional[str]] = mapped_column(String())
  39. time_token_expired: Mapped[Optional[datetime]] = mapped_column(index=True)
  40. attempts_token_tried: Mapped[int] = mapped_column(Integer, default=0)
  41. # relationship connects the tables.
  42. #rel_verification_emailed_token: ["VerificationEmailToken"] = relationship(back_populates="rel_user")
  43.  
  44. # The 1 tables below is the "one" relationship connection between the tables.
  45. # The reason I am not using "List[]" is because this is a 1 to 1 relationship
  46. rel_route_token: Mapped["RouteToken"] = relationship(back_populates="rel_user_routetoken")
  47. # The 2 tables below is the "one" relationship connection between the tables.
  48. rel_posts: Mapped[List["Posts"]] = relationship(back_populates="rel_user_posts")
  49. rel_payments: Mapped[List["Payments"]] = relationship(back_populates="rel_user_payments")
  50. # The 1 tables below is the "one" relationship connection between the tables.
  51. rel_user_role: Mapped["UserRole"] = relationship(back_populates="rel_user_user_role")
  52.  
  53. # The 3 methods below are added to the columns email_token + time_token_expired + attempts_token_tried in the User and RouteToken table.
  54. # And the 3 methods are used in the function send_registration_token_email + send_password_reset_token_email that sends an email.
  55.  
  56. # This method contains the token in the email
  57. def create_emailed_token_db(self):
  58. '''create the 6 char token for the form and add it to the db'''
  59. created_emailed_token = secrets.token_hex(3)
  60. self.emailed_token = created_emailed_token
  61. db.session.commit()
  62.  
  63.  
  64. def count_attempts_token_tried(self):
  65. self.attempts_token_tried += 1
  66. db.session.commit()
  67. # flash(user_db.attempts_token_tried ) # remove after testing.
  68.  
  69.  
  70. # now is added because of pytest + now represents the current time
  71. def create_time_token_db(self, now):
  72. '''create the time the token lasts/expires and add it to the db'''
  73. current_time = now
  74. # add time_token_expired
  75. thirty_min = timedelta(minutes=30)
  76. current_time_plus_30_minutes = current_time + thirty_min
  77. self.time_token_expired = current_time_plus_30_minutes
  78. db.session.commit()
  79.  
  80. # now is added because of pytest + now represents the current time
  81. def check_expired_token(self, now):
  82. '''
  83. The method checks 2 things. It checks if the token has exceeded 30 min and the maximum emails has not been exceeded.
  84.  
  85. If the time has exceeded 30 min or it has not exceeded 5 emails it makes the token received in the email as 0 and makes the time of the token lasts to 0.
  86. This happens because I want a new token and a I have 30 min to use the new token.
  87. '''
  88.  
  89. time_token_expired_db = self.time_token_expired
  90. current_time = now
  91. # current 12:00
  92. # expired token 12 33
  93. # ex token created at 9:33pm and token expires at 9:30pm.
  94. # Wait until the token expires to let the user get more emails.
  95. # needed "attempts_token_tried_db <= 5"?
  96. if current_time > time_token_expired_db and self.attempts_token_tried <= 5:
  97. # should I just create a new function for pytest?
  98. self.emailed_token = None
  99. self.time_token_expired = None
  100. db.session.commit()
  101. # only works during pytest
  102. print('check_expired_token, success')
  103. flash('Your token has expired. Please click resend email for a new email.')
  104.  
  105.  
  106.  
  107.  
  108.  
  109. # now is added because of pytest + now represents the current time
  110. # is this secure?
  111. def wait_max_thirty_min_for_new_token(self, now):
  112. '''
  113. Wait a max of 30 min before getting the last emailed token.
  114. This only happens when creating the last token.
  115. '''
  116. time_token_expired_db = self.time_token_expired
  117. # executes at 9:00 <= 9:30pm
  118. current_time = now
  119. if self.attempts_token_tried >= 5 and current_time <= time_token_expired_db:
  120. # only works duringb pytest
  121. print('wait_max_thirty_min_for_new_token, success')
  122. # create times for the created token + expired token
  123. # better wording.
  124. flash('You have requested to many tokens. Please wait 30 minutes for a new token from when you recieved youe last token.')
  125. # is this secure?
  126. return 'will redirect to email_login_confirmation route'
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. # now is added because of pytest + now represents the current time
  134. # is this secure?
  135. def reset_attempts_token_tried_to_0(user_db, now):
  136. '''
  137. if the max attempts of the token tried is exceeded + the
  138. token is expired reset the attwempts_token_tried to 0.
  139. '''
  140. # why doesn't work
  141. time_token_expired_db = user_db.time_token_expired
  142. # executes at 9:00 <= 9:30pm
  143. current_time = now
  144.  
  145. if user_db.attempts_token_tried >= 5 and current_time >= time_token_expired_db:
  146. # should I just create a new function for pytest?
  147. user_db.emailed_token = None
  148. user_db.time_token_expired = None
  149. user_db.attempts_token_tried = 0
  150. db.session.commit()
  151.  
  152. # change to print
  153. flash('You have waited long enough for a new a token. Please login again and you will be sent a email with instructions before you can login.')
  154. # redirect to login so I won't redirect /resend_token/<username_db> click on the link and a email is sent automatically.
  155. # is this secure?
  156. return 'going to redirect to login'
  157.  
  158. def __repr__(self):
  159. return '<User {}>'.format(self.username)
  160.  
  161.  
Advertisement
Add Comment
Please, Sign In to add comment