Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from datetime import datetime, timedelta
- from typing import List, Optional
- from flask import flash
- from flask_login import UserMixin
- from flask_sqlalchemy import SQLAlchemy
- from sqlalchemy import Boolean, Integer, String, ForeignKey
- from sqlalchemy.orm import Mapped, mapped_column, relationship
- from app.email_password_reset.models import RouteToken
- from app.payment.models import Payments
- from app.postinfo.models import Posts
- from app.songroute.models import songs
- db = SQLAlchemy()
- class User(UserMixin, db.Model):
- __tablename__ = 'user'
- '''
- One to One relationship between 2 tables.
- The One relationship is User and the other 1 relationship is route_token + UserRole
- One to Many relationship between 2 tables.
- The One relationship is User and the Many relationships is Posts + Payments
- '''
- id: Mapped[int] = mapped_column(primary_key=True)
- # unique blocks the same username etc
- # I can't have Nullable=False because it will make me add the columns everytime I add a column in User table
- username: Mapped[str] = mapped_column(String(80), index=True, unique=True)
- hashed_password: Mapped[str] = mapped_column(String(128))
- email: Mapped[str] = mapped_column(String(700), index=True)
- registration_confirmation_email: Mapped[bool] = mapped_column(Boolean, default=False)
- profile_pic_name: Mapped[Optional[str]] = mapped_column(String())
- # token and etc information sent in an email. This is the email_login_confirmation route.
- emailed_token: Mapped[Optional[str]] = mapped_column(String())
- time_token_expired: Mapped[Optional[datetime]] = mapped_column(index=True)
- attempts_token_tried: Mapped[int] = mapped_column(Integer, default=0)
- # relationship connects the tables.
- #rel_verification_emailed_token: ["VerificationEmailToken"] = relationship(back_populates="rel_user")
- # The 1 tables below is the "one" relationship connection between the tables.
- # The reason I am not using "List[]" is because this is a 1 to 1 relationship
- rel_route_token: Mapped["RouteToken"] = relationship(back_populates="rel_user_routetoken")
- # The 2 tables below is the "one" relationship connection between the tables.
- rel_posts: Mapped[List["Posts"]] = relationship(back_populates="rel_user_posts")
- rel_payments: Mapped[List["Payments"]] = relationship(back_populates="rel_user_payments")
- # The 1 tables below is the "one" relationship connection between the tables.
- rel_user_role: Mapped["UserRole"] = relationship(back_populates="rel_user_user_role")
- # The 3 methods below are added to the columns email_token + time_token_expired + attempts_token_tried in the User and RouteToken table.
- # And the 3 methods are used in the function send_registration_token_email + send_password_reset_token_email that sends an email.
- # This method contains the token in the email
- def create_emailed_token_db(self):
- '''create the 6 char token for the form and add it to the db'''
- created_emailed_token = secrets.token_hex(3)
- self.emailed_token = created_emailed_token
- db.session.commit()
- def count_attempts_token_tried(self):
- self.attempts_token_tried += 1
- db.session.commit()
- # flash(user_db.attempts_token_tried ) # remove after testing.
- # now is added because of pytest + now represents the current time
- def create_time_token_db(self, now):
- '''create the time the token lasts/expires and add it to the db'''
- current_time = now
- # add time_token_expired
- thirty_min = timedelta(minutes=30)
- current_time_plus_30_minutes = current_time + thirty_min
- self.time_token_expired = current_time_plus_30_minutes
- db.session.commit()
- # now is added because of pytest + now represents the current time
- def check_expired_token(self, now):
- '''
- The method checks 2 things. It checks if the token has exceeded 30 min and the maximum emails has not been exceeded.
- 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.
- This happens because I want a new token and a I have 30 min to use the new token.
- '''
- time_token_expired_db = self.time_token_expired
- current_time = now
- # current 12:00
- # expired token 12 33
- # ex token created at 9:33pm and token expires at 9:30pm.
- # Wait until the token expires to let the user get more emails.
- # needed "attempts_token_tried_db <= 5"?
- if current_time > time_token_expired_db and self.attempts_token_tried <= 5:
- # should I just create a new function for pytest?
- self.emailed_token = None
- self.time_token_expired = None
- db.session.commit()
- # only works during pytest
- print('check_expired_token, success')
- flash('Your token has expired. Please click resend email for a new email.')
- # now is added because of pytest + now represents the current time
- # is this secure?
- def wait_max_thirty_min_for_new_token(self, now):
- '''
- Wait a max of 30 min before getting the last emailed token.
- This only happens when creating the last token.
- '''
- time_token_expired_db = self.time_token_expired
- # executes at 9:00 <= 9:30pm
- current_time = now
- if self.attempts_token_tried >= 5 and current_time <= time_token_expired_db:
- # only works duringb pytest
- print('wait_max_thirty_min_for_new_token, success')
- # create times for the created token + expired token
- # better wording.
- flash('You have requested to many tokens. Please wait 30 minutes for a new token from when you recieved youe last token.')
- # is this secure?
- return 'will redirect to email_login_confirmation route'
- # now is added because of pytest + now represents the current time
- # is this secure?
- def reset_attempts_token_tried_to_0(user_db, now):
- '''
- if the max attempts of the token tried is exceeded + the
- token is expired reset the attwempts_token_tried to 0.
- '''
- # why doesn't work
- time_token_expired_db = user_db.time_token_expired
- # executes at 9:00 <= 9:30pm
- current_time = now
- if user_db.attempts_token_tried >= 5 and current_time >= time_token_expired_db:
- # should I just create a new function for pytest?
- user_db.emailed_token = None
- user_db.time_token_expired = None
- user_db.attempts_token_tried = 0
- db.session.commit()
- # change to print
- 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.')
- # redirect to login so I won't redirect /resend_token/<username_db> click on the link and a email is sent automatically.
- # is this secure?
- return 'going to redirect to login'
- def __repr__(self):
- return '<User {}>'.format(self.username)
Advertisement
Add Comment
Please, Sign In to add comment