Skip to content
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

SSO, test additions, database work, ASGI middleware, and more #58

Merged
merged 82 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
c708a80
Add new project `BL_Python.identity`.
aholmes Apr 8, 2024
69e20a8
Add SAML2 type stubs.
aholmes Apr 8, 2024
9316cd6
Fix some type errors in pysaml2 type stubs.
aholmes Apr 9, 2024
b478378
Add SAML2 client.
aholmes Apr 9, 2024
b0fb457
Add Identity tables to Platform lib.
aholmes Apr 9, 2024
c527a44
Update userloader to handle calling back into the application that's …
aholmes Apr 10, 2024
6bdba94
Fix pyright informational message.
aholmes Apr 10, 2024
c3a981e
Fix variable format.
aholmes Apr 10, 2024
9730134
Add flask-login dependency and type stubs.
aholmes Apr 10, 2024
4cf7bba
Additional flask-login type stub updates.
aholmes Apr 10, 2024
d53fdf5
Make UserLoader work in Identity.
aholmes Apr 10, 2024
80cb056
Add `login_required` decorator.
aholmes Apr 10, 2024
0f297c6
Rename class to avoid possible conflict.
aholmes Apr 10, 2024
f1e77d4
Fix error in bl-alembic that suppressed exceptions from alembic.
aholmes Apr 13, 2024
7ba99eb
Additional classes for Identity/SSO.
aholmes Apr 13, 2024
0d5874d
Fix incorrectly named foreign key ref.
aholmes Apr 15, 2024
7c74945
Correct types for Identity classes.
aholmes Apr 15, 2024
8f17d98
Move Identity DI into Platform lib.
aholmes Apr 16, 2024
277131e
Rework DI module for user loader.
aholmes Apr 16, 2024
206da3f
Fix problem with manually-added blueprints in a Connexion app.
aholmes Apr 16, 2024
2a47a6f
Resolve type error and possible runtime type bug in database initiali…
aholmes Apr 16, 2024
6e10231
Fix some type issues.
aholmes Apr 16, 2024
dfaf79d
Fix issues with types for migrations and user auth.
aholmes Apr 17, 2024
66b145b
Fix types in SSO decorator.
aholmes Apr 17, 2024
ab26ff2
Fix pyright error.
aholmes Apr 17, 2024
38e0db4
Fix problems with authenticated test request context.
aholmes Apr 17, 2024
5a3562d
Fix type issues preventing Roles from being used without errors.
aholmes Apr 19, 2024
9b7c499
Make it possible to use a custom application bootstrap method with th…
aholmes Apr 19, 2024
a8ba402
Refactor test client files to resolve type issues.
aholmes Apr 19, 2024
c7de695
Resolve invariance error.
aholmes Apr 19, 2024
03d310e
Don't use LocalProxy to get user from flask-login.
aholmes Apr 19, 2024
f1c42c8
Add missing `platform` dependencies to BL_Python.web.
aholmes Apr 22, 2024
557ef99
Update scaffold template to fit new test client creation.
aholmes Apr 22, 2024
7230e5b
Automatically use the in-memory database during testing.
aholmes Apr 22, 2024
bceeff1
Handle missing psycopg2.
aholmes Apr 22, 2024
801211c
Fixtures to mock database.
aholmes Apr 22, 2024
d77d9e7
Resolve errors with test client initialization when working with in-m…
aholmes Apr 23, 2024
8c84fdd
Add a type alias.
aholmes Apr 23, 2024
49d72ae
Add tests for feature flags.
aholmes Apr 24, 2024
ae39008
Fix problems with unauthenticated requests coming from testclient.
aholmes Apr 24, 2024
5e23cd2
Add fixtures to make it easier to set up the test database from non-w…
aholmes Apr 25, 2024
ba5144f
Fix more type errors.
aholmes Apr 25, 2024
8b02981
Fix some type errors.
aholmes Apr 25, 2024
405a285
Change where default cookies are set so they are set regardless of au…
aholmes Apr 25, 2024
9016c67
Add SAML2 handlers.
aholmes Apr 26, 2024
31a7019
Enable the ability to bind middleware after the application has been …
aholmes Apr 26, 2024
c818994
Add SSO endpoints for SAML2.
aholmes Apr 27, 2024
972bcba
Fix some type issues.
aholmes Apr 29, 2024
e5765d2
Fix double-load issue and LoginManager registration with SSO blueprint.
aholmes Apr 29, 2024
17ef9c0
Make it possible to register middleware before application binding.
aholmes Apr 29, 2024
5600f28
Fix issue with not being able to alter routing information.
aholmes Apr 30, 2024
d854a5a
Adjustments to SSO routes.
aholmes Apr 30, 2024
b934f0c
Fix problems with SSO.
aholmes Apr 30, 2024
c98e922
Add typings for flask_injector.
aholmes Apr 30, 2024
8825b91
Fix type errors.
aholmes Apr 30, 2024
de30d1a
Fix problems with config and SSO preventing login.
aholmes Apr 30, 2024
5516319
Remove obsolete comment.
aholmes Apr 30, 2024
17be3d6
Fix a bunch of issues involving whether a "current_app" is set from F…
aholmes May 1, 2024
14be5a9
Fix issue with storing table name with schema "None" when no schema i…
aholmes May 2, 2024
52db17e
Fix issues with loading user.
aholmes May 2, 2024
1f2c0f1
Fix problem with assuming port 5000 for test client.
aholmes May 2, 2024
6ce2661
Resolve pyright errors.
aholmes May 2, 2024
f024378
Fix issue with using unbound types for DI modules.
aholmes May 2, 2024
18f10ee
Fix type errors.
aholmes May 2, 2024
d55bbbb
Fix type errors.
aholmes May 2, 2024
7b71a8e
Resolve jankiness with session middleware.
aholmes May 2, 2024
1e73150
Add SSM parameter loading to BL_Python.AWS.
aholmes May 3, 2024
5e6d109
Load SSM parameters in web application startup.
aholmes May 3, 2024
b021986
Fix tests broken by SSM change.
aholmes May 3, 2024
bc70a10
Add SSM parameter loading to DB migrations.
aholmes May 3, 2024
d88db56
Be more forgiving of SSM load failures because not every app needs SSM.
aholmes May 4, 2024
104414c
Remove old comment.
aholmes May 4, 2024
362a9cf
Merge branch 'main' into aholmes-identity-sso
aholmes May 8, 2024
44d3a39
Adjust Makefile to be compatible with `make` 3.81 for MacOS users.
aholmes May 13, 2024
b570bad
Fix problems with venv activate and ignoring command exit statuses in…
aholmes May 13, 2024
a3f481d
Fix additional problems with ordering of shell commands when not usin…
aholmes May 13, 2024
4ae20bc
One more MacOS fix.
aholmes May 13, 2024
fe005be
Add missing dependencies to BL_Python.web.
aholmes May 13, 2024
c88f4cc
Fix envvar issue in Makefile.
aholmes May 13, 2024
89a7898
Minor CICD output changes to debug on GitHub.
aholmes May 13, 2024
a91fecd
Fix issue with `make` rebuilding venv for every job.
aholmes May 14, 2024
36ee95a
Further reduce build time by making use of sentinels for phony target…
aholmes May 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 97 additions & 123 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
.ONESHELL:

# Can be overridden to use a different directory name.
VENV ?= .venv

Expand Down Expand Up @@ -39,15 +37,13 @@ PYTEST_REPORT := pytest
# This variable is reassigned to whichever of the dev/cicd
# targets actually runs.
DEFAULT_TARGET ?= dev
.DEFAULT_GOAL = $(DEFAULT_TARGET)
.DEFAULT_GOAL := $(DEFAULT_TARGET)


ifeq ($(DEFAULT_TARGET),dev)
CONFIGURE_TARGET := _dev_configure
BUILD_TARGET := _dev_build
BUILD_TARGET := $(SETUP_DEV_SENTINEL)
else ifeq ($(DEFAULT_TARGET),cicd)
CONFIGURE_TARGET := _cicd_configure
BUILD_TARGET := _cicd_build
BUILD_TARGET := $(SETUP_CICD_SENTINEL)
else
$(error DEFAULT_TARGET must be one of "dev" or "cicd")
endif
Expand All @@ -61,167 +57,147 @@ PACKAGE_INSTALL_DIR := $(VENV)/lib/python*/site-packages/BL_Python
# used to suppress outputs of targets (see `test` and `clean-test`)
CMD_PREFIX=

define package_to_dist
$(VENV)/lib/python$(PYTHON_VERSION)/site-packages/BL_Python.$(1)-*.dist-info
endef

define package_to_inst
$(VENV)/lib/python$(PYTHON_VERSION)/site-packages/BL_Python/$(1)/__init__.py
endef

define dep_to_venv_path
$(VENV)/lib/python$(PYTHON_VERSION)/site-packages/$(1)
endef

PYPROJECT_FILES=./pyproject.toml $(wildcard src/*/pyproject.toml)
PACKAGE_PATHS=$(subst /pyproject.toml,,$(PYPROJECT_FILES))
PACKAGES=$(subst /pyproject.toml,,$(subst src/,BL_Python.,$(wildcard src/*/pyproject.toml)))


MAKE_ARTIFACT_DIRECTORY = .make
$(MAKE_ARTIFACT_DIRECTORY):
mkdir -p $(MAKE_ARTIFACT_DIRECTORY)

SETUP_DEPENDENCIES_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/dependencies_sentinel
SETUP_DEV_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/setup_dev_sentinel
SETUP_CICD_SENTINEL = $(MAKE_ARTIFACT_DIRECTORY)/setup_cicd_sentinel

PYPROJECT_FILES_SENTINEL = ./.pyproject_sentinel
$(PYPROJECT_FILES_SENTINEL): $(VENV)
$(MAKE) $(PYPROJECT_FILES)
touch $@

.PHONY: dev
dev : $(VENV) $(SETUP_DEPENDENCIES)
$(MAKE) _dev_build DEFAULT_TARGET=dev
_dev_configure : $(VENV) $(PYPROJECT_FILES)
_dev_build : _dev_configure
@if [ -d $(call package_to_dist,all) ]; then
echo "Package $@ is already built, skipping..."
else
$(ACTIVATE_VENV)

pip install -e .[dev-dependencies]
# By default, psycopg2 is not installed
# but it should be for development
pip install -e src/database[postgres-binary]

rm -rf $(PACKAGE_INSTALL_DIR)
dev :
$(MAKE) $(SETUP_DEV_SENTINEL) DEFAULT_TARGET=dev
# By default, psycopg2 is not installed
# but it should be for development
$(SETUP_DEV_SENTINEL): $(VENV) $(SETUP_DEPENDENCIES_SENTINEL) $(PYPROJECT_FILES_SENTINEL) | $(MAKE_ARTIFACT_DIRECTORY)
# `pip list` is multiple seconds faster than `pip show` ...
$(ACTIVATE_VENV) && \
if pip list -l --no-index | grep '^BL_Python\.all\s'; then \
echo "Package BL_Python.all is already built, skipping..."; \
else \
pip install -e .[dev-dependencies] && \
pip install -e src/database[postgres-binary] && \
rm -rf $(PACKAGE_INSTALL_DIR); \
fi

touch $@
@$(REPORT_VENV_USAGE)

cicd : $(VENV) $(SETUP_DEPENDENCIES)
$(MAKE) _cicd_build DEFAULT_TARGET=cicd
_cicd_configure : $(VENV) $(PYPROJECT_FILES)
_cicd_build : _cicd_configure
@if [ -f $(call package_to_inst,) ]; then
echo "Package is already built, skipping..."
else
$(ACTIVATE_VENV)

pip install .[dev-dependencies]
# By default, psycopg2 is not installed
# but it should be for CI/CD
pip install src/database[postgres-binary]
.PHONY: cicd
cicd :
$(MAKE) $(SETUP_CICD_SENTINEL) DEFAULT_TARGET=cicd
$(SETUP_CICD_SENTINEL): $(VENV) $(SETUP_DEPENDENCIES_SENTINEL) $(PYPROJECT_FILES_SENTINEL) | $(MAKE_ARTIFACT_DIRECTORY)
# `pip list` is multiple seconds faster than `pip show` ...
$(ACTIVATE_VENV) && \
if pip list -l --no-index | grep '^BL_Python\.all\s'; then \
echo "Package BL_Python.all is already built, skipping..."; \
else \
pip install .[dev-dependencies] && \
pip install src/database[postgres-binary]; \
fi

touch $@
@$(REPORT_VENV_USAGE)

.PHONY: BL_Python.all $(PACKAGES)
BL_Python.all: $(DEFAULT_TARGET)
$(PACKAGES) : BL_Python.%: src/%/pyproject.toml $(VENV) $(CONFIGURE_TARGET) $(PYPROJECT_FILES)
@if [ -d $(call package_to_dist,$*) ]; then
@echo "Package $@ is already built, skipping..."
else
$(ACTIVATE_VENV)

if [ "$@" = "BL_Python.database" ]; then
pip install -e $(dir $<)[postgres-binary]
else
pip install -e $(dir $<)
fi

rm -rf $(PACKAGE_INSTALL_DIR)
$(PACKAGES) : BL_Python.%: src/%/pyproject.toml $(VENV) $(PYPROJECT_FILES_SENTINEL) | $(MAKE_ARTIFACT_DIRECTORY)
# `pip list` is multiple seconds faster than `pip show` ...
$(ACTIVATE_VENV) && \
if pip list -l --no-index | grep '^BL_Python\.$*\s'; then \
echo "Package $* is already built, skipping..."; \
else \
if [ "$@" = "BL_Python.database" ]; then \
pip install -e $(dir $<)[postgres-binary]; \
else \
pip install -e $(dir $<); \
fi; \
rm -rf $(PACKAGE_INSTALL_DIR); \
fi

@$(REPORT_VENV_USAGE)

$(SETUP_DEPENDENCIES_SENTINEL): $(VENV) | $(MAKE_ARTIFACT_DIRECTORY)
$(ACTIVATE_VENV) && \
if ! pip list -l --no-index | grep '^toml$*\s'; then \
pip install toml; \
fi

SETUP_DEPENDENCIES=$(call dep_to_venv_path,toml/__init__.py) $(call dep_to_venv_path,typing_extensions.py)
$(call dep_to_venv_path,toml/__init__.py): $(VENV)
$(ACTIVATE_VENV)

pip install toml

$(call dep_to_venv_path,typing_extensions.py): $(VENV)
$(ACTIVATE_VENV)

pip install typing_extensions
$(ACTIVATE_VENV) && \
if ! pip list -l --no-index | grep '^typing_extensions$*\s'; then \
pip install typing_extensions; \
fi

$(PACKAGE_PATHS) : $(VENV) $(SETUP_DEPENDENCIES)
$(PYPROJECT_FILES) : $(VENV) $(SETUP_DEPENDENCIES)
$(ACTIVATE_VENV)
touch $@

$(PACKAGE_PATHS) : $(VENV) $(SETUP_DEPENDENCIES_SENTINEL)
$(PYPROJECT_FILES) : $(VENV) $(SETUP_DEPENDENCIES_SENTINEL)
$(ACTIVATE_VENV) && \
REWRITE_DEPENDENCIES=$(REWRITE_DEPENDENCIES) \
GITHUB_REF=$(GITHUB_REF) \
GITHUB_WORKSPACE=$(GITHUB_WORKSPACE) \
./.github/workflows/CICD-scripts/pyproject_dependency_rewrite.py -c $@


$(VENV) :
test -d $(VENV) || env python$(PYTHON_VERSION) -m venv $(VENV)

$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
pip install -U pip


format-isort : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
isort src

format-ruff : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
ruff format --preview --respect-gitignore

.PHONY: format format-ruff format-isort
format : $(VENV) $(BUILD_TARGET) format-isort format-ruff


test-isort : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
isort --check-only src

test-ruff : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
ruff format --preview --respect-gitignore --check

test-pyright : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

ifeq "$(PYRIGHT_MODE)" "pip"
ifeq ($(PYRIGHT_MODE),pip)
$(ACTIVATE_VENV) && \
pyright
else
ifeq "$(PYRIGHT_MODE)" "npm"
# this isn't the real install path everywhere,
# but this is used for CI/CD
else ifeq ($(PYRIGHT_MODE),npm)
# this isn't the real install path everywhere,
# but this is used for CI/CD
$(ACTIVATE_VENV) && \
./node_modules/bin/pyright
else
@echo "Invalid PYRIGHT_MODE '$(PYRIGHT_MODE)'"
@exit 1
endif
endif
else
@echo "Invalid PYRIGHT_MODE '$(PYRIGHT_MODE)'"; \
exit 1
endif

# don't exit with an error
# while testing bandit.
test-bandit : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

# don't exit with an error
# while testing bandit.
-bandit -c pyproject.toml \
-$(ACTIVATE_VENV) && \
bandit -c pyproject.toml \
--format sarif \
--output $(REPORTS_DIR)/$(BANDIT_REPORT) \
-r .

test-pytest : $(VENV) $(BUILD_TARGET)
$(ACTIVATE_VENV)

pytest $(PYTEST_FLAGS) \
&& PYTEST_EXIT_CODE=0 \
|| PYTEST_EXIT_CODE=$$?

-coverage html --data-file=$(REPORTS_DIR)/$(PYTEST_REPORT)/.coverage
-junit2html $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.xml $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.html

-$(ACTIVATE_VENV) && \
pytest $(PYTEST_FLAGS) && PYTEST_EXIT_CODE=0 || PYTEST_EXIT_CODE=$$?; \
coverage html --data-file=$(REPORTS_DIR)/$(PYTEST_REPORT)/.coverage; \
junit2html $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.xml $(REPORTS_DIR)/$(PYTEST_REPORT)/pytest.html; \
exit $$PYTEST_EXIT_CODE

.PHONY: test test-pytest test-bandit test-pyright test-ruff test-isort
Expand All @@ -230,17 +206,14 @@ test : CMD_PREFIX=@
test : clean-test
$(MAKE) -j --keep-going _test


.PHONY: publish-all
# Publishing should use a real install, which `cicd` fulfills
publish-all : REWRITE_DEPENDENCIES=false
# Publishing should use a real install. Reset the build env.
publish-all : reset $(VENV)
$(ACTIVATE_VENV)

$(ACTIVATE_VENV) && \
./publish_all.sh $(PYPI_REPO)


clean-build :
find . -type d \
\( \
Expand All @@ -253,7 +226,7 @@ clean-build :
-o -name __pycache__ \
-o -name \*.egg-info \
-o -name .pytest-cache \
\) -prune -exec rm -rf {} \;
\) -prune -exec rm -rf {} +

clean-test :
$(CMD_PREFIX)rm -rf \
Expand All @@ -263,7 +236,7 @@ clean-test :
.PHONY: clean clean-test clean-build
clean : clean-build clean-test
rm -rf $(VENV)

rm -rf $(MAKE_ARTIFACT_DIRECTORY)
@echo '\nDeactivate your venv with `deactivate`'

.PHONY: remake
Expand All @@ -272,10 +245,11 @@ remake :
$(MAKE)

reset-check:
# https://stackoverflow.com/a/47839479
# https://stackoverflow.com/a/47839479
@echo -n "This will make destructive changes! Considering stashing changes first.\n"
@( read -p "Are you sure? [y/N]: " response && case "$$response" in [yY]) true;; *) false;; esac )

.PHONY: reset reset-check
reset : reset-check clean
git checkout -- $(PYPROJECT_FILES)

4 changes: 3 additions & 1 deletion publish_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
src/database \
src/development \
src/GitHub\
src/identity \
src/platform \
src/programming \
src/testing \
Expand All @@ -91,14 +92,15 @@

initialize

for package in ${packages[@]}; do

Check warning on line 95 in publish_all.sh

View workflow job for this annotation

GitHub Actions / CICD-base

Double quote array expansions to avoid re-splitting elements. [SC2068]
build $package

Check warning on line 96 in publish_all.sh

View workflow job for this annotation

GitHub Actions / CICD-base

Double quote to prevent globbing and word splitting. [SC2086]
done

# default to testpypi
[ -n "$1" ] && repository="$1" || repository="testpypi"

tput init 2> /dev/null
for package in ${packages[@]}; do

Check warning on line 103 in publish_all.sh

View workflow job for this annotation

GitHub Actions / CICD-base

Double quote array expansions to avoid re-splitting elements. [SC2068]
publish $package $repository

Check warning on line 104 in publish_all.sh

View workflow job for this annotation

GitHub Actions / CICD-base

Double quote to prevent globbing and word splitting. [SC2086]

Check warning on line 104 in publish_all.sh

View workflow job for this annotation

GitHub Actions / CICD-base

Double quote to prevent globbing and word splitting. [SC2086]
done
done

6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies = [
"BL_Python.database",
"BL_Python.development",
"BL_Python.GitHub",
"BL_Python.identity",
"BL_Python.platform",
"BL_Python.programming",
"BL_Python.testing",
Expand All @@ -55,6 +56,7 @@ readme = {file = ["README.md"], content-type = "text/markdown"}
"BL_Python.database" = "src/database/BL_Python/database"
"BL_Python.development" = "src/development/BL_Python/development"
"BL_Python.GitHub" = "src/GitHub/BL_Python/GitHub"
"BL_Python.identity" = "src/identity/BL_Python/identity"
"BL_Python.platform" = "src/platform/BL_Python/platform"
"BL_Python.programming" = "src/programming/BL_Python/programming"
"BL_Python.testing" = "src/testing/BL_Python/testing"
Expand All @@ -67,6 +69,7 @@ packages = [
"BL_Python.database",
"BL_Python.development",
"BL_Python.GitHub",
"BL_Python.identity",
"BL_Python.platform",
"BL_Python.programming",
"BL_Python.testing",
Expand Down Expand Up @@ -117,6 +120,7 @@ extraPaths = [
"src/database",
"src/development",
"src/GitHub",
"src/identity",
"src/platform",
"src/programming",
"src/testing",
Expand Down Expand Up @@ -149,6 +153,7 @@ pythonpath = [
"src/database",
"src/development",
"src/GitHub",
"src/identity",
"src/platform",
"src/programming",
"src/testing",
Expand All @@ -161,6 +166,7 @@ testpaths = [
"src/database/test",
"src/development/test",
"src/GitHub/test",
"src/identity/test",
"src/platform/test",
"src/programming/test",
"src/testing/test",
Expand Down
Loading
Loading