mgt c10 checkpoint
This commit is contained in:
		@@ -10,7 +10,7 @@ RUN apt update && apt install -y \
 | 
				
			|||||||
WORKDIR /code
 | 
					WORKDIR /code
 | 
				
			||||||
COPY requirements.txt /code
 | 
					COPY requirements.txt /code
 | 
				
			||||||
RUN target=/root/.cache/pip \
 | 
					RUN target=/root/.cache/pip \
 | 
				
			||||||
    pip3 install -r requirements.txt
 | 
					    pip3 install --root-user-action=ignore -q -r requirements.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Need to make this explicit as part of expansion, no migrations or venv
 | 
					# Need to make this explicit as part of expansion, no migrations or venv
 | 
				
			||||||
COPY . .
 | 
					COPY . .
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@ pip install flask-migrate
 | 
				
			|||||||
pip install flask-login
 | 
					pip install flask-login
 | 
				
			||||||
pip install email-validator
 | 
					pip install email-validator
 | 
				
			||||||
pip install pydenticon
 | 
					pip install pydenticon
 | 
				
			||||||
 | 
					pip install flask-mail
 | 
				
			||||||
 | 
					pip install pyjwt
 | 
				
			||||||
Prod only, require sys packages:
 | 
					Prod only, require sys packages:
 | 
				
			||||||
pip install mariadb
 | 
					pip install mariadb
 | 
				
			||||||
pip install uwsgi
 | 
					pip install uwsgi
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ from flask_migrate import Migrate
 | 
				
			|||||||
from flask_login import LoginManager
 | 
					from flask_login import LoginManager
 | 
				
			||||||
import logging, sys
 | 
					import logging, sys
 | 
				
			||||||
from logging.handlers import SMTPHandler
 | 
					from logging.handlers import SMTPHandler
 | 
				
			||||||
 | 
					from flask_mail import Mail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app = Flask(__name__)
 | 
					app = Flask(__name__)
 | 
				
			||||||
app.config.from_object(Config)
 | 
					app.config.from_object(Config)
 | 
				
			||||||
@@ -12,6 +13,7 @@ db = SQLAlchemy(app)
 | 
				
			|||||||
migrate = Migrate(app, db)
 | 
					migrate = Migrate(app, db)
 | 
				
			||||||
login = LoginManager(app)
 | 
					login = LoginManager(app)
 | 
				
			||||||
login.login_view = 'login'
 | 
					login.login_view = 'login'
 | 
				
			||||||
 | 
					mail=Mail(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if not app.debug:
 | 
					if not app.debug:
 | 
				
			||||||
    if app.config['MAIL_SERVER']:
 | 
					    if app.config['MAIL_SERVER']:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								backend/app/email.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								backend/app/email.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					from flask_mail import Message
 | 
				
			||||||
 | 
					from app import mail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def send_email(subject, sender, recipients, text_body, html_body):
 | 
				
			||||||
 | 
					    msg = Message(subject, sender=sender, recipients=recipients)
 | 
				
			||||||
 | 
					    msg.body = text_body
 | 
				
			||||||
 | 
					    msg.html = html_body
 | 
				
			||||||
 | 
					    mail.send(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,6 +43,10 @@ class EditProfileForm(FlaskForm):
 | 
				
			|||||||
            if user is not None:
 | 
					            if user is not None:
 | 
				
			||||||
                raise ValidationError('Please use a different username.')
 | 
					                raise ValidationError('Please use a different username.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ResetPasswordRequestForm(FlaskForm):
 | 
				
			||||||
 | 
					    email = StringField('Email', validators=[DataRequired(), Email()])
 | 
				
			||||||
 | 
					    submit = SubmitField('Request Password Reset')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PostForm(FlaskForm):
 | 
					class PostForm(FlaskForm):
 | 
				
			||||||
    post = TextAreaField('Post:', validators=[DataRequired(), Length(min=1, max=140)])
 | 
					    post = TextAreaField('Post:', validators=[DataRequired(), Length(min=1, max=140)])
 | 
				
			||||||
    submit = SubmitField('Submit')
 | 
					    submit = SubmitField('Submit')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,9 @@ from datetime import datetime, timezone
 | 
				
			|||||||
import sqlalchemy as sa
 | 
					import sqlalchemy as sa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from app import app, db
 | 
					from app import app, db
 | 
				
			||||||
from app.forms import LoginForm, RegistrationForm, EditProfileForm, EmptyForm, PostForm
 | 
					from app.forms import LoginForm, RegistrationForm, EditProfileForm, EmptyForm, PostForm, ResetPasswordRequestForm
 | 
				
			||||||
from app.models import User, Post
 | 
					from app.models import User, Post
 | 
				
			||||||
 | 
					#from app.email import send_password_reset_email
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.before_request
 | 
					@app.before_request
 | 
				
			||||||
def before_request():
 | 
					def before_request():
 | 
				
			||||||
@@ -149,4 +150,17 @@ def unfollow(username):
 | 
				
			|||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return redirect(url_for('index'))
 | 
					        return redirect(url_for('index'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/reset_password_request', methods=['GET', 'POST'])
 | 
				
			||||||
 | 
					def reset_password_request():
 | 
				
			||||||
 | 
					    if current_user.is_authenticated:
 | 
				
			||||||
 | 
					        return redirect(url_for('index'))
 | 
				
			||||||
 | 
					    form = ResetPasswordRequestForm()
 | 
				
			||||||
 | 
					    if form.validate_on_submit():
 | 
				
			||||||
 | 
					        user = db.session.scalar(sa.select(User).where(User.email == form.email.data))
 | 
				
			||||||
 | 
					        if user:
 | 
				
			||||||
 | 
					            send_password_reset_email(user)
 | 
				
			||||||
 | 
					        flash('Password reset sent.')
 | 
				
			||||||
 | 
					        return redirect(url_for('login'))
 | 
				
			||||||
 | 
					    return render_template('reset_password_request.html', title='Reset Password', form=form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@
 | 
				
			|||||||
	</form>
 | 
						</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<p><a href="{{ url_for('register') }}">Register Here</a></p>
 | 
						<p><a href="{{ url_for('register') }}">Register Here</a></p>
 | 
				
			||||||
 | 
						<p><a href="{{ url_for('reset_password_request') }}">Reset Password</a></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								backend/app/templates/reset_password_request.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								backend/app/templates/reset_password_request.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
						<h1>Reset Password</h1>
 | 
				
			||||||
 | 
						<form action="" method="post">
 | 
				
			||||||
 | 
							{{ form.hidden_tag() }}
 | 
				
			||||||
 | 
							<p>
 | 
				
			||||||
 | 
								{{ form.email.label }}<br>
 | 
				
			||||||
 | 
								{{ form.email(size=64) }}<br>
 | 
				
			||||||
 | 
								{% for error in form.email.errors %}
 | 
				
			||||||
 | 
								<span style="color: red;">[{{ error }}]</span>
 | 
				
			||||||
 | 
								{% endfor %}
 | 
				
			||||||
 | 
							</p>
 | 
				
			||||||
 | 
							<p>{{ form.submit() }}</p>
 | 
				
			||||||
 | 
						</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -8,8 +8,8 @@ class Config:
 | 
				
			|||||||
    #SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'zapp.db')
 | 
					    #SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'zapp.db')
 | 
				
			||||||
    SQLALCHEMY_DATABASE_URI = 'mariadb+mariadbconnector://flasku:' + os.environ.get('MYSQL_PASSWORD') + '@db:3306/flask'
 | 
					    SQLALCHEMY_DATABASE_URI = 'mariadb+mariadbconnector://flasku:' + os.environ.get('MYSQL_PASSWORD') + '@db:3306/flask'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #MAIL_SERVER = 'pmb'
 | 
					    MAIL_SERVER = 'pmb'
 | 
				
			||||||
    MAIL_SERVER = ''
 | 
					    #MAIL_SERVER = ''
 | 
				
			||||||
    MAIL_PORT = 25
 | 
					    MAIL_PORT = 25
 | 
				
			||||||
    MAIL_USE_TLS = False
 | 
					    MAIL_USE_TLS = False
 | 
				
			||||||
    MAIL_USERNAME = ''
 | 
					    MAIL_USERNAME = ''
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ dnspython==2.6.1
 | 
				
			|||||||
email_validator==2.2.0
 | 
					email_validator==2.2.0
 | 
				
			||||||
Flask==3.0.3
 | 
					Flask==3.0.3
 | 
				
			||||||
Flask-Login==0.6.3
 | 
					Flask-Login==0.6.3
 | 
				
			||||||
 | 
					Flask-Mail==0.10.0
 | 
				
			||||||
Flask-Migrate==4.0.7
 | 
					Flask-Migrate==4.0.7
 | 
				
			||||||
Flask-SQLAlchemy==3.1.1
 | 
					Flask-SQLAlchemy==3.1.1
 | 
				
			||||||
Flask-WTF==1.2.1
 | 
					Flask-WTF==1.2.1
 | 
				
			||||||
@@ -13,17 +14,15 @@ idna==3.7
 | 
				
			|||||||
itsdangerous==2.2.0
 | 
					itsdangerous==2.2.0
 | 
				
			||||||
Jinja2==3.1.4
 | 
					Jinja2==3.1.4
 | 
				
			||||||
Mako==1.3.5
 | 
					Mako==1.3.5
 | 
				
			||||||
 | 
					mariadb==1.1.10
 | 
				
			||||||
MarkupSafe==2.1.5
 | 
					MarkupSafe==2.1.5
 | 
				
			||||||
 | 
					packaging==24.1
 | 
				
			||||||
pillow==10.4.0
 | 
					pillow==10.4.0
 | 
				
			||||||
pydenticon==0.3.1
 | 
					pydenticon==0.3.1
 | 
				
			||||||
 | 
					PyJWT==2.9.0
 | 
				
			||||||
python-dotenv==1.0.1
 | 
					python-dotenv==1.0.1
 | 
				
			||||||
SQLAlchemy==2.0.31
 | 
					SQLAlchemy==2.0.31
 | 
				
			||||||
typing_extensions==4.12.2
 | 
					typing_extensions==4.12.2
 | 
				
			||||||
 | 
					uWSGI==2.0.26
 | 
				
			||||||
Werkzeug==3.0.3
 | 
					Werkzeug==3.0.3
 | 
				
			||||||
WTForms==3.1.2
 | 
					WTForms==3.1.2
 | 
				
			||||||
mariadb==1.1.10
 | 
					 | 
				
			||||||
packaging==24.1
 | 
					 | 
				
			||||||
setuptools==72.1.0
 | 
					 | 
				
			||||||
uWSGI==2.0.26
 | 
					 | 
				
			||||||
wheel==0.43.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user