def get(self): """ Sends an e-mail to the user to make him create a new password. Request Parameters ---------- email : string User's e-mail Example: [email protected] Returns ------- None Sends an e-mail with a link to create a new password. """ logging.info('AuthForgotPassword.get()') email = request.args.get('email') logging.info('AuthForgotPassword.get() - email: %s', email) # validate request body data, status = validate({'email': email}, 'forgot_password') if status is False: logging.error('AuthForgotPassword.get() - errors: %s', data) raise BadRequest('Invalid e-mail format!') token = auth_forgot_password_business.send_an_email_to(email) if FLASK_ENV == 'development': return {'token': token} return Response(status=200)
def __thread_send_email(email_subject, email_from, email_from_password, email_to, email_content, email_smtp_host, email_smtp_port): msg = Message() msg['Subject'] = email_subject msg['From'] = email_from msg['To'] = email_to msg.add_header('Content-Type', 'text/html') msg.set_payload(email_content) logging.info('send_email() - sending an e-mail to `%s`...', email_to) try: s = SMTP(host=email_smtp_host, port=email_smtp_port) s.starttls() s.login(msg['From'], email_from_password) s.sendmail(msg['From'], [msg['To']], msg.as_string()) s.quit() logging.info( 'send_email() - e-mail to `%s` has been sent successfully!', email_to) except SMTPException as error: logging.error('send_email() - unable to send an e-mail to `%s`.', email_to) logging.error('send_email() - error: `%s`.', error) raise error
def send_an_email_to(self, email): """Sends an e-mail to a user.""" user = self.db_ps_register.select_from_user(email=email) # if an empty list (i.e. user == []), then raise an exception if not user: logging.error( 'AuthForgotPasswordBusiness.send_an_email_to() - e-mail was not found.' ) raise NotFound('E-mail was not found.') token = token_urlsafe(32) # save the token in the database self.db_ps_register.insert_into_security(user[0]['username'], token) link = URL_CATALOG_RESET_PASSWORD + '?token={}'.format(token) logging.info( 'AuthForgotPasswordBusiness.send_an_email_to() - link: %s', link) send_email_forgot_password(email, link) return token
def post(self): """ Logs a user into the system Request Parameters ---------- request.data : bytes JSON in bytes format that contains email and password information of a user Example: b'{"email": "*****@*****.**", "password": "******"}' Returns ------- string Token related to the logged user """ logging.info('AuthLogin.post()\n') body = request.data if body == b'': raise BadRequest('Request data is empty.') # get request data (bytes) and convert it to dict body = loads(body.decode('utf-8')) # validate request body data, status = validate(body, 'login') if status is False: logging.error('AuthLogin.get() - errors: %s', data) raise BadRequest(data) logging.info('AuthLogin.post() - data[\'email\']: %s', data['email']) # validate user login token, user_info = auth_login_business.login(data['email'], data['password']) # logging.info('AuthLogin.post() - user_info[username]: %s', user_info['username']) # logging.info('AuthLogin.post() - user_info[email]: %s', user_info['email']) # if there is not a token (i.e. empty string), then raise an error if not token or not user_info: raise InternalServerError('Error during login.') return { "access_token": token, "username": user_info['username'], "name": user_info['name'], "email": user_info['email'], "password": data['password'] }
def _create_engine(self): from os import getenv # MYSQL connection MYSQL_DB_USER = getenv('MYSQL_DB_USER', 'test') MYSQL_DB_PASSWORD = getenv('MYSQL_DB_PASSWORD', 'test') MYSQL_DB_HOST = getenv('MYSQL_DB_HOST', 'localhost') MYSQL_DB_PORT = getenv('MYSQL_DB_PORT', '3306') MYSQL_DB_DATABASE = getenv('MYSQL_DB_DATABASE', 'database') engine_connection = ( f'mysql+pymysql://{MYSQL_DB_USER}:{MYSQL_DB_PASSWORD}@' f'{MYSQL_DB_HOST}:{MYSQL_DB_PORT}/{MYSQL_DB_DATABASE}') try: # `NullPool prevents the Engine from using any connection more than once` self.engine = create_engine(engine_connection, poolclass=NullPool) except SQLAlchemyError as error: logging.error( 'MySQLConnection._create_engine() - An error occurred during engine creation.' ) logging.error( f'MySQLConnection._create_engine() - error.code: {error.code} - error.args: {error.args}' ) logging.error( f'MySQLConnection._create_engine() - error: {error}\n') raise SQLAlchemyError(error)
def reset_password(self, email, password, token, **kwargs): """Resets a user password.""" logging.info('reset_password - email: %s', email) # logging.debug('reset_password - password: %s', password) logging.info('reset_password - token: %s', token) user = self.db_ps_register.select_from_user(email=email) # if an empty list (i.e. user == []), then raise an exception if not user: logging.error('reset_password - e-mail was not found.') raise NotFound('E-mail was not found.') username = user[0]['username'] security = self.db_ps_register.select_from_security(username=username, token=token) logging.info('reset_password - security: %s', security) # if an empty list (i.e. user == []), then raise an exception if not security: logging.error('reset_password - token was not found.') raise NotFound('Token was not found.') # update the user password self.db_ps_register.update_user(username=username, password=password) logging.info( 'reset_password - user password has been reset successfully!') # delete the token from the database self.db_ps_register.delete_from_security(username=username, token=token) logging.info( 'reset_password - user token has been removed successfully!')
def post(self): """ Resets the user password. Request Parameters ---------- request.data : bytes JSON in bytes format that contains email, password and token information of a user Example: b'{"email": "*****@*****.**", "password": "******", "token": "123456"}' Returns ------- None """ logging.info('AuthResetPassword.get()') body = request.data if body == b'' or body == b'{}': logging.error('AuthResetPassword.get() - request data is empty.') raise BadRequest('Request data is empty.') # get request data (bytes) and convert it to dict body = loads(body.decode('utf-8')) logging.info('AuthResetPassword.get() - body: %s', body) # validate request body data, status = validate(body, 'reset_password') if status is False: logging.error('AuthResetPassword.get() - errors: %s', data) raise BadRequest('Invalid data information.') auth_reset_password_business.reset_password(**body) return Response(status=200)
def execute(self, query: str, params: dict = None, is_transaction: bool = False): """Executes a query.""" # logging.info('PostgreSQLConnection.execute()') # logging.info(f'PostgreSQLConnection.execute() - is_transaction: {is_transaction}') # logging.info(f'PostgreSQLConnection.execute() - query: {query}') # logging.info(f'PostgreSQLConnection.execute() - text(query): {text(query)}') # logging.info(f'PostgreSQLConnection.execute() - params: {params}') try: # INSERT, UPDATE and DELETE if is_transaction: with self.engine.begin() as connection: # runs a transaction result = connection.execute(text(query), params) try: # if 'query' was an 'INSERT...RETURNING' statement, # then it returns the inserted record 'id', # else it raises an Exception and return None [value] = result.fetchone() return value except SQLAlchemyError: return None # SELECT (return ResultProxy) # with self.engine.connect() as connection: # # convert rows from ResultProxy to list and return the object # return list(connection.execute(query)) # SELECT (return dataframe) return read_sql(text(query), params=params, con=self.engine) except SQLAlchemyError as error: logging.error( 'execute() - An error occurred during query execution.') logging.error( f'execute() - error.code: {error.code} - error.args: {error.args}' ) logging.error(f'execute() - error: {error}\n') raise SQLAlchemyError(error) from None
def create_engine(self): """Creates engine connection.""" engine_connection = ( f'postgresql+psycopg2://{self.PGUSER}:{self.PGPASSWORD}' f'@{self.PGHOST}:{self.PGPORT}/{self.PGDATABASE}') try: # `NullPool prevents the Engine from using any connection more than once` self.engine = create_engine(engine_connection, poolclass=NullPool) except SQLAlchemyError as error: logging.error( '_create_engine() - An error occurred during engine creation.') logging.error( f'_create_engine() - error.code: {error.code} - error.args: {error.args}' ) logging.error(f'_create_engine() - error: {error}\n') raise SQLAlchemyError(error) from None
def execute(self, query: str, params: dict = None, is_transaction: bool = False): # logging.info(f'MySQLConnection.execute - is_transaction: {is_transaction}') # logging.info(f'MySQLConnection.execute - query: {query}') # logging.info(f'MySQLConnection.execute - text(query): {text(query)}') # logging.info(f'MySQLConnection.execute - params: {params}') try: # INSERT, UPDATE and DELETE if is_transaction: with self.engine.begin() as connection: # runs a transaction result = connection.execute(text(query), params) # if 'query' was a 'INSERT' statement, then it returns the inserted record 'id', # else it returns '0' return str(result.lastrowid) # SELECT (return ResultProxy) # with self.engine.connect() as connection: # # convert rows from ResultProxy to list and return the object # return list(connection.execute(query)) # SELECT (return dataframe) return read_sql(text(query), params=params, con=self.engine) except SQLAlchemyError as error: logging.error( 'MySQLConnection.execute - An error occurred during query execution.' ) logging.error( f'MySQLConnection.execute - error.code: {error.code} - error.args: {error.args}' ) logging.error(f'MySQLConnection.execute - error: {error}\n') raise SQLAlchemyError(error)