-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from israelias/backend
Backend
- Loading branch information
Showing
15 changed files
with
370 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: gunicorn backend.app:app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from flask_admin import Admin | ||
from .mongoview import MyAdminIndexView | ||
|
||
|
||
admin = Admin( | ||
name="Cheat-Hub Backend", | ||
index_view=MyAdminIndexView(), | ||
endpoint="admin", | ||
url="/admin", | ||
template_mode="bootstrap4", | ||
) | ||
|
||
|
||
def initialize_admin(app): | ||
admin.init_app(app) | ||
app.config["FLASK_ADMIN_SWATCH"] = "cerulean" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import os | ||
from flask_basicauth import BasicAuth | ||
|
||
basic_auth = BasicAuth() | ||
|
||
|
||
def initialize_basicauth(app): | ||
basic_auth.init_app(app) | ||
app.config["BASIC_AUTH_USERNAME"] = os.environ.get("BASIC_AUTH_USERNAME") | ||
app.config["BASIC_AUTH_PASSWORD"] = os.environ.get("BASIC_AUTH_PASSWORD") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import os | ||
from flask_mail import Mail | ||
|
||
if not os.path.exists("env.py"): | ||
pass | ||
else: | ||
import env | ||
|
||
mail = Mail() | ||
|
||
|
||
def initialize_mail(app): | ||
mail.init_app(app) | ||
app.config["MAIL_SERVER"] = os.environ.get("MAIL_SERVER") | ||
app.config["MAIL_PORT"] = int(os.environ.get("MAIL_PORT")) | ||
app.config["MAIL_USERNAME"] = os.environ.get("MAIL_USERNAME") | ||
app.config["MAIL_PASSWORD"] = os.environ.get("MAIL_PASSWORD") | ||
app.config["MAIL_DEFAULT_SENDER"] = os.environ.get("MAIL_DEFAULT_SENDER") | ||
app.config["MAIL_USE_SSL"] = True | ||
|
||
# MAIL_SERVER : default ‘localhost’ | ||
# MAIL_PORT : default 25 | ||
# MAIL_USE_TLS : default False | ||
# MAIL_USE_SSL : default False | ||
# MAIL_DEBUG : default app.debug | ||
# MAIL_USERNAME : default None | ||
# MAIL_PASSWORD : default None | ||
# MAIL_DEFAULT_SENDER : default None | ||
# MAIL_MAX_EMAILS : default None | ||
# MAIL_SUPPRESS_SEND : default app.testing | ||
# MAIL_ASCII_ATTACHMENTS : default False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from flask import Response, redirect | ||
from flask_admin import AdminIndexView, expose | ||
from flask_admin.contrib.mongoengine.view import ModelView | ||
from werkzeug.exceptions import HTTPException | ||
from .basicauth import basic_auth | ||
|
||
""" | ||
The following three classes are inherited from their respective base class, | ||
and are customized, to make flask_admin compatible with BasicAuth. | ||
""" | ||
|
||
|
||
class AuthException(HTTPException): | ||
def __init__(self, message): | ||
super().__init__( | ||
message, | ||
Response( | ||
"You could not be authenticated. Please refresh the page.", | ||
401, | ||
{"WWW-Authenticate": 'Basic realm="Login Required"'}, | ||
), | ||
) | ||
|
||
|
||
class MyModelView(ModelView): | ||
def is_accessible(self): | ||
if not basic_auth.authenticate(): | ||
raise AuthException("Not authenticated.") | ||
else: | ||
return True | ||
|
||
def inaccessible_callback(self, name, **kwargs): | ||
return redirect(basic_auth.challenge()) | ||
|
||
|
||
class MyAdminIndexView(AdminIndexView): | ||
def is_accessible(self): | ||
if not basic_auth.authenticate(): | ||
raise AuthException("Not authenticated.") | ||
else: | ||
return True | ||
|
||
def inaccessible_callback(self, name, **kwargs): | ||
return redirect(basic_auth.challenge()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from .admin import admin | ||
from flask_admin.contrib.mongoengine.view import ModelView | ||
from .mongoview import MyModelView | ||
from database.models import User, Snippet, Collection, TokenBlocklist | ||
|
||
# https://flask-admin.readthedocs.io/en/latest/api/mod_contrib_mongoengine/ | ||
|
||
|
||
def initialize_views(): | ||
admin.add_view(MyModelView(User)) | ||
admin.add_view(MyModelView(Snippet)) | ||
admin.add_view(MyModelView(Collection)) | ||
admin.add_view(MyModelView(TokenBlocklist)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,49 @@ | ||
aniso8601==9.0.1 | ||
aniso8601==7.0.0 | ||
appdirs==1.4.4 | ||
astroid==2.5.6 | ||
bcrypt==3.2.0 | ||
black==20.8b1 | ||
blinker==1.4 | ||
cffi==1.14.5 | ||
click==7.1.2 | ||
dnspython==2.1.0 | ||
email-validator==1.1.3 | ||
Flask==1.1.2 | ||
Flask-Admin==1.5.8 | ||
Flask-BasicAuth==0.2.0 | ||
Flask-Bcrypt==0.7.1 | ||
Flask-Cors==3.0.10 | ||
Flask-JWT-Extended==4.1.0 | ||
Flask-Mail==0.9.1 | ||
flask-mongoengine==1.0.0 | ||
Flask-RESTful==0.3.8 | ||
Flask-WTF==0.14.3 | ||
idna==3.1 | ||
install==1.3.4 | ||
iso8601==0.1.14 | ||
isort==5.8.0 | ||
itsdangerous==1.1.0 | ||
Jinja2==2.11.3 | ||
lazy-object-proxy==1.6.0 | ||
MarkupSafe==1.1.1 | ||
mccabe==0.6.1 | ||
mongoengine==0.23.0 | ||
mypy-extensions==0.4.3 | ||
pathspec==0.8.1 | ||
promise==2.3 | ||
pycparser==2.20 | ||
PyJWT==2.0.1 | ||
pylint==2.8.3 | ||
pymongo==3.11.3 | ||
pytz==2021.1 | ||
regex==2021.4.4 | ||
Rx==1.6.1 | ||
sentinels==1.0.0 | ||
singledispatch==3.6.1 | ||
six==1.15.0 | ||
toml==0.10.2 | ||
typed-ast==1.4.2 | ||
typing-extensions==3.7.4.3 | ||
Werkzeug==1.0.1 | ||
wrapt==1.12.1 | ||
WTForms==2.3.3 | ||
gunicorn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
from flask import request, render_template | ||
from flask_jwt_extended import create_access_token, decode_token | ||
|
||
from database.models import User | ||
from flask_restful import Resource | ||
from services.mail_service import send_email | ||
|
||
from resources.errors import ( | ||
SchemaValidationError, | ||
InternalServerError, | ||
EmailDoesNotExistError, | ||
BadTokenError, | ||
ExpiredTokenError, | ||
) | ||
from jwt.exceptions import ( | ||
ExpiredSignatureError, | ||
DecodeError, | ||
InvalidTokenError, | ||
) | ||
|
||
import datetime | ||
|
||
|
||
class ForgotPassword(Resource): | ||
def post(self): | ||
url = request.host_url + "reset/" | ||
try: | ||
body = request.get_json() | ||
email = body.get("email") | ||
if not email: | ||
raise SchemaValidationError | ||
|
||
user = User.objects.get(email=email) | ||
if not user: | ||
raise EmailDoesNotExistError | ||
|
||
expires = datetime.timedelta(hours=24) | ||
reset_token = create_access_token(str(user.id), expires_delta=expires) | ||
|
||
return send_email( | ||
"[Cheat-hub] Reset Your Password", | ||
sender="[email protected]", | ||
recipients=[user.email], | ||
text_body=render_template("reset_password.txt", url=url + reset_token), | ||
html_body=render_template("reset_password.html", url=url + reset_token), | ||
) | ||
except SchemaValidationError: | ||
raise SchemaValidationError | ||
except EmailDoesNotExistError: | ||
raise EmailDoesNotExistError | ||
except Exception as e: | ||
raise InternalServerError | ||
|
||
|
||
class ResetPassword(Resource): | ||
def post(self): | ||
url = request.host_url + "reset/" | ||
try: | ||
body = request.get_json() | ||
reset_token = body.get("reset_token") | ||
password = body.get("password") | ||
|
||
if not reset_token or not password: | ||
raise SchemaValidationError | ||
|
||
user_id = decode_token(reset_token)["sub"] | ||
user = User.objects.get(id=user_id) | ||
|
||
user.modify(password=password) | ||
user.hash_password() | ||
user.save() | ||
|
||
return send_email( | ||
"[Cheat-hub] Password reset successful", | ||
sender="[email protected]", | ||
recipients=[user.email], | ||
text_body="Password reset was successful", | ||
html_body="<p>Password reset was successful</p>", | ||
) | ||
|
||
except SchemaValidationError: | ||
raise SchemaValidationError | ||
except ExpiredSignatureError: | ||
raise ExpiredTokenError | ||
except (DecodeError, InvalidTokenError): | ||
raise BadTokenError | ||
except Exception as e: | ||
raise InternalServerError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
15d4ffe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: