-
-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds flask admin as a feature. Bumps flask admin to 1.6.0 #551
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,7 @@ FLASK_DEBUG=1 | |
ALGOLIA_APP_ID=search_id | ||
ALGOLIA_API_KEY=search_key | ||
INDEX_NAME=resources_api | ||
SECRET_KEY=sammy | ||
SECURITY_PASSWORD_SALT=saltedpop | ||
[email protected] | ||
ADMIN_PASSWORD=1234 | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ RUN apt-get update \ | |
&& pip install poetry \ | ||
&& poetry config virtualenvs.create false | ||
|
||
RUN poetry lock | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I manually added the dependency versions to the pyproject.toml file. Below link to solution for resolving the "....which doesn't match any versions, version solving failed." error [Known issue]python-poetry/poetry#1281 (comment) |
||
|
||
RUN poetry install --no-dev --no-interaction --no-ansi | ||
|
||
COPY . /src | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -37,6 +37,13 @@ def get_sys_exec_root_or_drive(): | |||||
if not all([algolia_app_id, algolia_api_key]): | ||||||
print("Application requires 'ALGOLIA_APP_ID' and 'ALGOLIA_API_KEY' for search") | ||||||
|
||||||
secret_key = os.environ.get('SECRET_KEY', None) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uses bracket notation instead of .get() |
||||||
security_password_hash = 'pbkdf2_sha512' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make this an environment variable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SECURITY_PASSWORD_HASH added to .env |
||||||
security_password_salt = os.environ.get('SECURITY_PASSWORD_SALT', None) | ||||||
|
||||||
if not all([secret_key, security_password_salt]): | ||||||
print('Application requires "SECRET_KEY" and "SECURITY_HASH"') | ||||||
Comment on lines
+44
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can remove this if we use the bracket syntax instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uses bracket notation instead of .get() |
||||||
|
||||||
index_name = os.environ.get("INDEX_NAME") | ||||||
|
||||||
|
||||||
|
@@ -49,6 +56,16 @@ class Config: | |||||
ALGOLIA_API_KEY = algolia_api_key | ||||||
INDEX_NAME = index_name | ||||||
|
||||||
SECRET_KEY = secret_key | ||||||
SECURITY_URL_PREFIX = "/admin" | ||||||
SECURITY_PASSWORD_HASH = security_password_hash | ||||||
SECURITY_PASSWORD_SALT = security_password_salt | ||||||
SECURITY_LOGIN_URL = "/login/" | ||||||
SECURITY_LOGOUT_URL = "/logout/" | ||||||
SECURITY_POST_LOGIN_VIEW = "/admin/" | ||||||
SECURITY_POST_LOGOUT_VIEW = "/admin/" | ||||||
SECURITY_REGISTERABLE = False | ||||||
SECURITY_SEND_REGISTER_EMAIL = False | ||||||
# Can pass in changes to defaults, such as PaginatorConfig(per_page=40) | ||||||
RESOURCE_PAGINATOR = PaginatorConfig() | ||||||
LANGUAGE_PAGINATOR = PaginatorConfig() | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,18 @@ | ||
from app import app, cli | ||
from app.models import Category, Language, Resource, db | ||
from app.admin import run_flask_admin | ||
from app.models import Category, Language, Resource, db, Role, User | ||
import os | ||
from flask_security import Security, SQLAlchemyUserDatastore, utils | ||
from flask import url_for | ||
from flask_admin import helpers as admin_helpers | ||
from werkzeug.middleware.dispatcher import DispatcherMiddleware | ||
from prometheus_client import make_wsgi_app | ||
from sqlalchemy import event | ||
|
||
admin = run_flask_admin(app) | ||
|
||
user_datastore = SQLAlchemyUserDatastore(db, User, Role) | ||
security = Security(app, user_datastore) | ||
|
||
if __name__ == "__main__": | ||
app.run() | ||
|
@@ -15,6 +25,49 @@ | |
}) | ||
|
||
|
||
# @event.listens_for(User.password, 'set', retval=True) | ||
# def hash_user_password(target, value, oldvalue, initiator): | ||
# """Encrypts password when new admin created in User View""" | ||
# if value != oldvalue: | ||
# return utils.encrypt_password(value) | ||
# return value | ||
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This listens for when a new admin password is added in the admin view and encrypts with same method as before_first_request(). Removed. |
||
|
||
|
||
@security.context_processor | ||
def security_context_processor(): | ||
return dict( | ||
admin_base_template=admin.base_template, | ||
admin_view=admin.index_view, | ||
h=admin_helpers, | ||
get_url=url_for | ||
) | ||
|
||
|
||
@app.shell_context_processor | ||
def make_shell_context(): | ||
return {'db': db, 'Resource': Resource, 'Category': Category, 'Language': Language} | ||
return {'db': db, 'Resource': Resource, 'Category': Category, 'Language': Language, | ||
'User': User, 'Role': Role} | ||
|
||
|
||
@app.before_first_request | ||
def before_first_request(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please rename this so we don't accidentally shadow or get confused. Choose a name that is descriptive of what the function is doing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed to add_admin_role
Comment on lines
+52
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the admin user already exists when this function runs, what happens? Are there side effects? |
||
""" Adds admin/user roles and default admin account and password if none exists""" | ||
db.create_all() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this idempotent? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only way to check would be to delete the table from the database I think? May need help with this. |
||
user_datastore.find_or_create_role(name='admin', description='Administrator') | ||
user_datastore.find_or_create_role(name='user', description='End User') | ||
|
||
admin_email = os.environ.get('ADMIN_EMAIL', "[email protected]") | ||
admin_password = os.environ.get('ADMIN_PASSWORD', 'password') | ||
Comment on lines
+59
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want this to blow up. Please use bracket syntax here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to bracket from |
||
|
||
encrypted_password = utils.encrypt_password(admin_password) | ||
|
||
if not user_datastore.get_user(admin_email): | ||
user_datastore.create_user(email=admin_email, password=encrypted_password) | ||
db.session.commit() | ||
|
||
user_datastore.add_role_to_user(admin_email, 'admin') | ||
db.session.commit() | ||
|
||
|
||
if __name__ == "__main__": | ||
app.run() |
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.
Can we please add a newline to the end of this file?
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.
Added