junikimm717
2 years ago
commit
1f9aa50769
14 changed files with 728 additions and 0 deletions
-
162.gitignore
-
3.vscode/.gitignore
-
17.vscode/settings.json
-
117app.py
-
11errors.py
-
295poetry.lock
-
19pyproject.toml
-
5templates/admin.html
-
28templates/base.html
-
3templates/errors/403.html
-
3templates/errors/404.html
-
3templates/index.html
-
18templates/login.html
-
44templates/register.html
@ -0,0 +1,162 @@ |
|||||
|
.idea |
||||
|
/instance |
||||
|
# Byte-compiled / optimized / DLL files |
||||
|
__pycache__/ |
||||
|
*.py[cod] |
||||
|
*$py.class |
||||
|
|
||||
|
# C extensions |
||||
|
*.so |
||||
|
|
||||
|
# Distribution / packaging |
||||
|
.Python |
||||
|
build/ |
||||
|
develop-eggs/ |
||||
|
dist/ |
||||
|
downloads/ |
||||
|
eggs/ |
||||
|
.eggs/ |
||||
|
lib/ |
||||
|
lib64/ |
||||
|
parts/ |
||||
|
sdist/ |
||||
|
var/ |
||||
|
wheels/ |
||||
|
share/python-wheels/ |
||||
|
*.egg-info/ |
||||
|
.installed.cfg |
||||
|
*.egg |
||||
|
MANIFEST |
||||
|
|
||||
|
# PyInstaller |
||||
|
# Usually these files are written by a python script from a template |
||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||
|
*.manifest |
||||
|
*.spec |
||||
|
|
||||
|
# Installer logs |
||||
|
pip-log.txt |
||||
|
pip-delete-this-directory.txt |
||||
|
|
||||
|
# Unit test / coverage reports |
||||
|
htmlcov/ |
||||
|
.tox/ |
||||
|
.nox/ |
||||
|
.coverage |
||||
|
.coverage.* |
||||
|
.cache |
||||
|
nosetests.xml |
||||
|
coverage.xml |
||||
|
*.cover |
||||
|
*.py,cover |
||||
|
.hypothesis/ |
||||
|
.pytest_cache/ |
||||
|
cover/ |
||||
|
|
||||
|
# Translations |
||||
|
*.mo |
||||
|
*.pot |
||||
|
|
||||
|
# Django stuff: |
||||
|
*.log |
||||
|
local_settings.py |
||||
|
db.sqlite3 |
||||
|
db.sqlite3-journal |
||||
|
|
||||
|
# Flask stuff: |
||||
|
instance/ |
||||
|
.webassets-cache |
||||
|
|
||||
|
# Scrapy stuff: |
||||
|
.scrapy |
||||
|
|
||||
|
# Sphinx documentation |
||||
|
docs/_build/ |
||||
|
|
||||
|
# PyBuilder |
||||
|
.pybuilder/ |
||||
|
target/ |
||||
|
|
||||
|
# Jupyter Notebook |
||||
|
.ipynb_checkpoints |
||||
|
|
||||
|
# IPython |
||||
|
profile_default/ |
||||
|
ipython_config.py |
||||
|
|
||||
|
# pyenv |
||||
|
# For a library or package, you might want to ignore these files since the code is |
||||
|
# intended to run in multiple environments; otherwise, check them in: |
||||
|
# .python-version |
||||
|
|
||||
|
# pipenv |
||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||
|
# install all needed dependencies. |
||||
|
#Pipfile.lock |
||||
|
|
||||
|
# poetry |
||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more |
||||
|
# commonly ignored for libraries. |
||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
||||
|
#poetry.lock |
||||
|
|
||||
|
# pdm |
||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. |
||||
|
#pdm.lock |
||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it |
||||
|
# in version control. |
||||
|
# https://pdm.fming.dev/#use-with-ide |
||||
|
.pdm.toml |
||||
|
|
||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm |
||||
|
__pypackages__/ |
||||
|
|
||||
|
# Celery stuff |
||||
|
celerybeat-schedule |
||||
|
celerybeat.pid |
||||
|
|
||||
|
# SageMath parsed files |
||||
|
*.sage.py |
||||
|
|
||||
|
# Environments |
||||
|
.env |
||||
|
.venv |
||||
|
env/ |
||||
|
venv/ |
||||
|
ENV/ |
||||
|
env.bak/ |
||||
|
venv.bak/ |
||||
|
|
||||
|
# Spyder project settings |
||||
|
.spyderproject |
||||
|
.spyproject |
||||
|
|
||||
|
# Rope project settings |
||||
|
.ropeproject |
||||
|
|
||||
|
# mkdocs documentation |
||||
|
/site |
||||
|
|
||||
|
# mypy |
||||
|
.mypy_cache/ |
||||
|
.dmypy.json |
||||
|
dmypy.json |
||||
|
|
||||
|
# Pyre type checker |
||||
|
.pyre/ |
||||
|
|
||||
|
# pytype static type analyzer |
||||
|
.pytype/ |
||||
|
|
||||
|
# Cython debug symbols |
||||
|
cython_debug/ |
||||
|
|
||||
|
# PyCharm |
||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can |
||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore |
||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear |
||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder. |
||||
|
#.idea/ |
@ -0,0 +1,3 @@ |
|||||
|
* |
||||
|
!settings.json |
||||
|
!.gitignore |
@ -0,0 +1,17 @@ |
|||||
|
{ |
||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode", |
||||
|
"editor.tabSize": 4, |
||||
|
"[python]": { |
||||
|
"editor.wordBasedSuggestions": false, |
||||
|
"editor.defaultFormatter": null |
||||
|
}, |
||||
|
/* |
||||
|
"python.formatting.provider": "autopep8", |
||||
|
"python.formatting.autopep8Args": [ |
||||
|
"--max-line-length", |
||||
|
"120", |
||||
|
"--experimental" |
||||
|
], |
||||
|
*/ |
||||
|
"editor.bracketPairColorization.enabled": true |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
|
|
||||
|
from flask import Flask, render_template, session, request, abort, redirect, url_for |
||||
|
from flask_sqlalchemy import SQLAlchemy |
||||
|
import bcrypt |
||||
|
|
||||
|
db: SQLAlchemy = SQLAlchemy() |
||||
|
app = Flask(__name__) |
||||
|
|
||||
|
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db" |
||||
|
app.secret_key = '98d31240f9fbe14c8083586db49c19c3a8d3f726' |
||||
|
|
||||
|
|
||||
|
class Admin(db.Model): |
||||
|
id = db.Column(db.Integer, primary_key=True) |
||||
|
username = db.Column(db.String, unique=True, nullable=False) |
||||
|
password = db.Column(db.String, nullable=False) |
||||
|
query: db.Query |
||||
|
|
||||
|
@classmethod |
||||
|
def generate_password(cls, pw: str): |
||||
|
return bcrypt.hashpw(pw, bcrypt.gensalt(12)) |
||||
|
|
||||
|
@classmethod |
||||
|
def authenticate(cls, username: str, pw: str): |
||||
|
user = Admin.query.filter_by(username=username).one_or_none() |
||||
|
if user and bcrypt.checkpw(pw, user.password): |
||||
|
session['admin'] = user.username |
||||
|
return user |
||||
|
else: |
||||
|
return None |
||||
|
|
||||
|
@classmethod |
||||
|
def exists(cls): |
||||
|
user = Admin.query.one_or_none() |
||||
|
return True if user else False |
||||
|
|
||||
|
@classmethod |
||||
|
def authorize(cls): |
||||
|
if not session.get('admin'): |
||||
|
return redirect(url_for("admin_login")) |
||||
|
|
||||
|
# Error Handlers |
||||
|
|
||||
|
@app.errorhandler(404) |
||||
|
def handler_404(msg): |
||||
|
return render_template("errors/404.html") |
||||
|
|
||||
|
|
||||
|
@app.errorhandler(403) |
||||
|
def handler_403(msg): |
||||
|
return render_template("errors/403.html") |
||||
|
|
||||
|
|
||||
|
# Admin routes |
||||
|
@app.route('/admin') |
||||
|
def admin_root(): |
||||
|
if login := Admin.authorize(): |
||||
|
return login |
||||
|
return render_template("admin.html", user=session.get("admin")) |
||||
|
|
||||
|
|
||||
|
@app.route('/admin/create', methods=['GET', 'POST']) |
||||
|
def admin_create(): |
||||
|
if Admin.exists(): |
||||
|
if login := Admin.authorize(): |
||||
|
return login |
||||
|
if request.method == "GET": |
||||
|
return render_template("register.html") |
||||
|
else: |
||||
|
username, pw = request.form.get('username'), request.form.get('password') |
||||
|
if username is None or pw is None: |
||||
|
return render_template("register.html", fail="Invalid Input.") |
||||
|
elif db.session.execute(db.select(Admin).filter_by(username=username)).fetchone(): |
||||
|
return render_template("register.html", fail="Username already exists.") |
||||
|
else: |
||||
|
db.session.add(Admin(username=username, password=Admin.generate_password(pw))) |
||||
|
db.session.commit() |
||||
|
return render_template("register.html", success=True) |
||||
|
|
||||
|
|
||||
|
@app.route('/admin/login', methods=['GET', 'POST']) |
||||
|
def admin_login(): |
||||
|
if request.method == "POST": |
||||
|
username, pw = request.form.get('username', ''), request.form.get('password', '') |
||||
|
if Admin.authenticate(username, pw): |
||||
|
return render_template("login.html", success=True) |
||||
|
else: |
||||
|
return render_template("login.html", fail="Could not authenticate.") |
||||
|
else: |
||||
|
return render_template("login.html") |
||||
|
|
||||
|
|
||||
|
@app.route('/admin/logout', methods=['GET']) |
||||
|
def admin_logout(): |
||||
|
session.pop('admin') |
||||
|
return redirect(url_for('home')) |
||||
|
|
||||
|
|
||||
|
@app.route("/") |
||||
|
def home(): |
||||
|
if Admin.exists(): |
||||
|
return render_template("index.html") |
||||
|
else: |
||||
|
return redirect(url_for("admin_create")) |
||||
|
|
||||
|
|
||||
|
@app.route("/search") |
||||
|
def search(): |
||||
|
return "searching url" |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
db.init_app(app) |
||||
|
with app.app_context(): |
||||
|
db.create_all() |
||||
|
app.run(debug=True) |
@ -0,0 +1,11 @@ |
|||||
|
from flask import render_template, Flask |
||||
|
|
||||
|
|
||||
|
def configure_app(app: Flask): |
||||
|
@app.errorhandler(404) |
||||
|
def handler_404(msg): |
||||
|
return render_template("errors/404.html") |
||||
|
|
||||
|
@app.errorhandler(403) |
||||
|
def handler_403(msg): |
||||
|
return render_template("errors/403.html") |
@ -0,0 +1,295 @@ |
|||||
|
[[package]] |
||||
|
name = "autopep8" |
||||
|
version = "2.0.1" |
||||
|
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" |
||||
|
category = "dev" |
||||
|
optional = false |
||||
|
python-versions = ">=3.6" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
pycodestyle = ">=2.10.0" |
||||
|
tomli = {version = "*", markers = "python_version < \"3.11\""} |
||||
|
|
||||
|
[[package]] |
||||
|
name = "click" |
||||
|
version = "8.1.3" |
||||
|
description = "Composable command line interface toolkit" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
colorama = {version = "*", markers = "platform_system == \"Windows\""} |
||||
|
|
||||
|
[[package]] |
||||
|
name = "colorama" |
||||
|
version = "0.4.6" |
||||
|
description = "Cross-platform colored terminal text." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "flask" |
||||
|
version = "2.2.2" |
||||
|
description = "A simple framework for building complex web applications." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
click = ">=8.0" |
||||
|
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} |
||||
|
itsdangerous = ">=2.0" |
||||
|
Jinja2 = ">=3.0" |
||||
|
Werkzeug = ">=2.2.2" |
||||
|
|
||||
|
[package.extras] |
||||
|
async = ["asgiref (>=3.2)"] |
||||
|
dotenv = ["python-dotenv"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "flask-sqlalchemy" |
||||
|
version = "3.0.2" |
||||
|
description = "Add SQLAlchemy support to your Flask application." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
Flask = ">=2.2" |
||||
|
SQLAlchemy = ">=1.4.18" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "greenlet" |
||||
|
version = "2.0.1" |
||||
|
description = "Lightweight in-process concurrent programming" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" |
||||
|
|
||||
|
[package.extras] |
||||
|
docs = ["sphinx", "docutils (<0.18)"] |
||||
|
test = ["objgraph", "psutil", "faulthandler"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "importlib-metadata" |
||||
|
version = "5.2.0" |
||||
|
description = "Read metadata from Python packages" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
zipp = ">=0.5" |
||||
|
|
||||
|
[package.extras] |
||||
|
docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "sphinx-lint", "jaraco.tidelift (>=1.4)"] |
||||
|
perf = ["ipython"] |
||||
|
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8", "importlib-resources (>=1.3)"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "itsdangerous" |
||||
|
version = "2.1.2" |
||||
|
description = "Safely pass data to untrusted environments and back." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "jinja2" |
||||
|
version = "3.1.2" |
||||
|
description = "A very fast and expressive template engine." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
MarkupSafe = ">=2.0" |
||||
|
|
||||
|
[package.extras] |
||||
|
i18n = ["Babel (>=2.7)"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "markupsafe" |
||||
|
version = "2.1.1" |
||||
|
description = "Safely add untrusted strings to HTML/XML markup." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "py-bcrypt" |
||||
|
version = "0.4" |
||||
|
description = "bcrypt password hashing and key derivation" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = "*" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "pycodestyle" |
||||
|
version = "2.10.0" |
||||
|
description = "Python style guide checker" |
||||
|
category = "dev" |
||||
|
optional = false |
||||
|
python-versions = ">=3.6" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "sqlalchemy" |
||||
|
version = "1.4.45" |
||||
|
description = "Database Abstraction Library" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} |
||||
|
|
||||
|
[package.extras] |
||||
|
aiomysql = ["greenlet (!=0.4.17)", "aiomysql"] |
||||
|
aiosqlite = ["typing_extensions (!=3.10.0.1)", "greenlet (!=0.4.17)", "aiosqlite"] |
||||
|
asyncio = ["greenlet (!=0.4.17)"] |
||||
|
asyncmy = ["greenlet (!=0.4.17)", "asyncmy (>=0.2.3,!=0.2.4)"] |
||||
|
mariadb_connector = ["mariadb (>=1.0.1,!=1.1.2)"] |
||||
|
mssql = ["pyodbc"] |
||||
|
mssql_pymssql = ["pymssql"] |
||||
|
mssql_pyodbc = ["pyodbc"] |
||||
|
mypy = ["sqlalchemy2-stubs", "mypy (>=0.910)"] |
||||
|
mysql = ["mysqlclient (>=1.4.0,<2)", "mysqlclient (>=1.4.0)"] |
||||
|
mysql_connector = ["mysql-connector-python"] |
||||
|
oracle = ["cx_oracle (>=7,<8)", "cx_oracle (>=7)"] |
||||
|
postgresql = ["psycopg2 (>=2.7)"] |
||||
|
postgresql_asyncpg = ["greenlet (!=0.4.17)", "asyncpg"] |
||||
|
postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] |
||||
|
postgresql_psycopg2binary = ["psycopg2-binary"] |
||||
|
postgresql_psycopg2cffi = ["psycopg2cffi"] |
||||
|
pymysql = ["pymysql (<1)", "pymysql"] |
||||
|
sqlcipher = ["sqlcipher3-binary"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "tomli" |
||||
|
version = "2.0.1" |
||||
|
description = "A lil' TOML parser" |
||||
|
category = "dev" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "types-flask-sqlalchemy" |
||||
|
version = "2.5.9" |
||||
|
description = "Typing stubs for Flask-SQLAlchemy" |
||||
|
category = "dev" |
||||
|
optional = false |
||||
|
python-versions = "*" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
types-SQLAlchemy = "*" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "types-sqlalchemy" |
||||
|
version = "1.4.53.19" |
||||
|
description = "Typing stubs for SQLAlchemy" |
||||
|
category = "dev" |
||||
|
optional = false |
||||
|
python-versions = "*" |
||||
|
|
||||
|
[[package]] |
||||
|
name = "werkzeug" |
||||
|
version = "2.2.2" |
||||
|
description = "The comprehensive WSGI web application library." |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.dependencies] |
||||
|
MarkupSafe = ">=2.1.1" |
||||
|
|
||||
|
[package.extras] |
||||
|
watchdog = ["watchdog"] |
||||
|
|
||||
|
[[package]] |
||||
|
name = "zipp" |
||||
|
version = "3.11.0" |
||||
|
description = "Backport of pathlib-compatible object wrapper for zip files" |
||||
|
category = "main" |
||||
|
optional = false |
||||
|
python-versions = ">=3.7" |
||||
|
|
||||
|
[package.extras] |
||||
|
docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] |
||||
|
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] |
||||
|
|
||||
|
[metadata] |
||||
|
lock-version = "1.1" |
||||
|
python-versions = "^3.9" |
||||
|
content-hash = "54b3e8cb9fa3e9c6b85642bc519182772dac7ede4030fa8209e2510ccdbcd90c" |
||||
|
|
||||
|
[metadata.files] |
||||
|
autopep8 = [] |
||||
|
click = [ |
||||
|
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, |
||||
|
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, |
||||
|
] |
||||
|
colorama = [] |
||||
|
flask = [] |
||||
|
flask-sqlalchemy = [] |
||||
|
greenlet = [] |
||||
|
importlib-metadata = [] |
||||
|
itsdangerous = [] |
||||
|
jinja2 = [ |
||||
|
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, |
||||
|
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, |
||||
|
] |
||||
|
markupsafe = [ |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, |
||||
|
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, |
||||
|
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, |
||||
|
] |
||||
|
py-bcrypt = [] |
||||
|
pycodestyle = [] |
||||
|
sqlalchemy = [] |
||||
|
tomli = [ |
||||
|
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, |
||||
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, |
||||
|
] |
||||
|
types-flask-sqlalchemy = [] |
||||
|
types-sqlalchemy = [] |
||||
|
werkzeug = [] |
||||
|
zipp = [] |
@ -0,0 +1,19 @@ |
|||||
|
[tool.poetry] |
||||
|
name = "flask-sample" |
||||
|
version = "0.1.0" |
||||
|
description = "" |
||||
|
authors = ["junikimm717 <68165832+junikimm717@users.noreply.github.com>"] |
||||
|
|
||||
|
[tool.poetry.dependencies] |
||||
|
python = "^3.9" |
||||
|
flask-sqlalchemy = "^3.0.2" |
||||
|
Flask = "^2.2.2" |
||||
|
py-bcrypt = "^0.4" |
||||
|
|
||||
|
[tool.poetry.dev-dependencies] |
||||
|
autopep8 = "^2.0.1" |
||||
|
types-Flask-SQLAlchemy = "^2.5.9" |
||||
|
|
||||
|
[build-system] |
||||
|
requires = ["poetry-core>=1.0.0"] |
||||
|
build-backend = "poetry.core.masonry.api" |
@ -0,0 +1,5 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
{% block content %} |
||||
|
<h1>Admin Dashboard</h1> |
||||
|
<p>You are {{user}}</p> |
||||
|
{% endblock %} |
@ -0,0 +1,28 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8" /> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
|
<title>DWalker Website</title> |
||||
|
<meta |
||||
|
name="description" |
||||
|
content="A website for aggregating and searching exposome data" |
||||
|
/> |
||||
|
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css" /> |
||||
|
</head> |
||||
|
<body> |
||||
|
<header> |
||||
|
<nav> |
||||
|
<a href="{{ url_for('home') }}">Home</a> |
||||
|
{% if session.admin %} |
||||
|
<a href="{{ url_for('admin_root') }}">Admin</a> |
||||
|
<a href="{{ url_for('admin_logout') }}">Logout</a> |
||||
|
{% else %} |
||||
|
<a href="{{ url_for('admin_login') }}">Login</a> |
||||
|
{% endif %} |
||||
|
</nav> |
||||
|
</header> |
||||
|
<main>{% block content %} {% endblock %}</main> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,3 @@ |
|||||
|
{% extends 'base.html' %} {%block content%} |
||||
|
<h1>403 Forbidden</h1> |
||||
|
{%endblock%} |
@ -0,0 +1,3 @@ |
|||||
|
{% extends 'base.html' %} {%block content%} |
||||
|
<h1>404 Not Found</h1> |
||||
|
{%endblock%} |
@ -0,0 +1,3 @@ |
|||||
|
{% extends 'base.html' %} {%block content%} |
||||
|
<h1>Exposome Database Website</h1> |
||||
|
{%endblock%} |
@ -0,0 +1,18 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
{% block content %} |
||||
|
<h1>Admin Login</h1> |
||||
|
<form method="post"> |
||||
|
<label for="username">Username:</label> |
||||
|
<input id="username" name="username" type="text" required="required"> |
||||
|
<br> |
||||
|
<label for="password">Password:</label> |
||||
|
<input id="password" name="password" type="password" required="required"> |
||||
|
<br> |
||||
|
<input type="submit" value="Submit"> |
||||
|
</form> |
||||
|
{% if success %} |
||||
|
<p style="color:darkgreen">Login Successful!</p> |
||||
|
{% elif fail %} |
||||
|
<p style="color:darkred">Login Failed. Please try again.</p> |
||||
|
{% endif %} |
||||
|
{% endblock %} |
@ -0,0 +1,44 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
{% block content %} |
||||
|
<h1>Admin Login</h1> |
||||
|
<script defer> |
||||
|
window.onload = () => { |
||||
|
const uname_el = document.getElementById("username") |
||||
|
const pw_el = document.getElementById("password") |
||||
|
const rec_el = document.getElementById("reconfirm") |
||||
|
function check_equal() { |
||||
|
const uname = uname_el.value |
||||
|
const pw = pw_el.value |
||||
|
const rec = rec_el.value |
||||
|
if (pw.length > 0 && rec === pw && uname.length > 0) { |
||||
|
console.log("happens!") |
||||
|
document.getElementById("matches").innerHTML = `<div style='color:darkgreen'>Matches!</div>` |
||||
|
document.getElementById("submit").disabled = false |
||||
|
} else { |
||||
|
document.getElementById("matches").innerHTML = `<div style='color:darkred'>Does not Match!</div>` |
||||
|
document.getElementById("submit").disabled = true |
||||
|
} |
||||
|
} |
||||
|
uname_el.addEventListener("input", check_equal) |
||||
|
pw_el.addEventListener("input", check_equal) |
||||
|
rec_el.addEventListener("input", check_equal) |
||||
|
} |
||||
|
</script> |
||||
|
<form method="post"> |
||||
|
<label for="username">Username:</label> |
||||
|
<input id="username" name="username" type="text" required="required"> |
||||
|
<br> |
||||
|
<label for="password">Password:</label> |
||||
|
<input id="password" name="password" type="password" required="required"> |
||||
|
<br> |
||||
|
<label for="reconfirm">Reconfirm Password: <span id="matches"></span></label> |
||||
|
<input id="reconfirm" name="reconfirm" type="password" required="required"> |
||||
|
<br> |
||||
|
<input type="submit" value="Submit" disabled="disabled" id="submit"> |
||||
|
</form> |
||||
|
{% if success %} |
||||
|
<p style="color:darkgreen">Login Successful!</p> |
||||
|
{% elif fail %} |
||||
|
<p style="color:darkred">Login Failed. Please try again. {{fail}}</p> |
||||
|
{% endif %} |
||||
|
{% endblock %} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue