Skip to content

Commit

Permalink
Fix quickstart to show how to properly handle connections. (#863)
Browse files Browse the repository at this point in the history
This is for the SQLAlchemy scoped session example which doesn't use Flask-SQLAlchemy
  • Loading branch information
jwag956 authored Oct 21, 2023
1 parent d848340 commit 346a41c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/psf/black
rev: 23.9.1
rev: 23.10.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
Expand Down
10 changes: 10 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ Flask-Security Changelog

Here you can see the full list of changes between each Flask-Security release.

Version 5.3.2
-------------

Released xxx

Fixes
++++++

- (:issue:`859`) Update Quickstart to show how to properly handle SQLAlchemy connections

Version 5.3.1
-------------

Expand Down
7 changes: 5 additions & 2 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ SQLAlchemy Install requirements
$ . pymyenv/bin/activate
$ pip install flask-security-too[common] sqlalchemy

SQLAlchemy Application
~~~~~~~~~~~~~~~~~~~~~~
SQLAlchemy Application (w/o Flask-SQLAlchemy)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following code sample illustrates how to get started as quickly as
possible using `SQLAlchemy in a declarative way
Expand Down Expand Up @@ -173,6 +173,9 @@ and models.py.
# Don't worry if email has findable domain
app.config["SECURITY_EMAIL_VALIDATOR_ARGS"] = {"check_deliverability": False}

# manage sessions per request - make sure connections are closed and returned
app.teardown_appcontext(lambda exc: db_session.close())

# Setup Flask-Security
user_datastore = SQLAlchemySessionUserDatastore(db_session, User, Role)
app.security = Security(app, user_datastore)
Expand Down
1 change: 1 addition & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ filterwarnings =
ignore::DeprecationWarning:mongoengine:
ignore::DeprecationWarning:flask_login:0
ignore::DeprecationWarning:pydantic_core:0
ignore::UserWarning:cbor2:0
ignore:.*passwordless feature.*:DeprecationWarning:flask_security:0
ignore::DeprecationWarning:passlib:0
ignore:.*'sms' was enabled in SECURITY_US_ENABLED_METHODS;.*:UserWarning:flask_security:0
Expand Down
5 changes: 3 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ def sqlalchemy_session_datastore(request, app, tmpdir, realdburl):
return sqlalchemy_session_setup(request, app, tmpdir, realdburl)


def sqlalchemy_session_setup(request, app, tmpdir, realdburl):
def sqlalchemy_session_setup(request, app, tmpdir, realdburl, **engine_kwargs):
"""
Note that we test having a different user id column name here.
"""
Expand Down Expand Up @@ -501,10 +501,11 @@ def sqlalchemy_session_setup(request, app, tmpdir, realdburl):

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + path

engine = create_engine(app.config["SQLALCHEMY_DATABASE_URI"])
engine = create_engine(app.config["SQLALCHEMY_DATABASE_URI"], **engine_kwargs)
db_session = scoped_session(
sessionmaker(autocommit=False, autoflush=False, bind=engine)
)
app.teardown_appcontext(lambda exc: db_session.close())
Base = declarative_base()
Base.query = db_session.query_property()

Expand Down
20 changes: 17 additions & 3 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from unittest import mock
import re
import os.path
import sys
import time
import typing as t

Expand Down Expand Up @@ -809,7 +808,6 @@ def __init__(self, email):
"""


@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires python3 or higher")
@pytest.mark.settings(password_check_breached="strict")
def test_breached(app, sqlalchemy_datastore):
# partial response from: https://api.pwnedpasswords.com/range/07003
Expand All @@ -833,7 +831,6 @@ def test_breached(app, sqlalchemy_datastore):
assert app.config["SECURITY_MSG_PASSWORD_BREACHED"][0] in pbad[0]


@pytest.mark.skipif(sys.version_info < (3, 0), reason="requires python3 or higher")
@pytest.mark.settings(
password_check_breached="strict",
password_breached_count=16,
Expand Down Expand Up @@ -1444,3 +1441,20 @@ def test_login_email_whatever(app, client, get_message):
)
assert response.status_code == 302
assert "/" in response.location


@pytest.mark.skip
def test_sqlalchemy_session_conn(request, app, tmpdir, realdburl):
# test harness for checking connection mgmt by logging all connections
from .conftest import sqlalchemy_session_setup

ds = sqlalchemy_session_setup(
request, app, tmpdir, realdburl, echo_pool="debug", echo="debug"
)
init_app_with_options(app, ds)
client = app.test_client()

client.post("/login", data=dict(email="[email protected]", password="password"))

client.post("/login", json=dict(noemail="[email protected]", password="password"))
time.sleep(5)

0 comments on commit 346a41c

Please sign in to comment.