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

New POST create entity endpoint - also authentication #67

Merged
merged 94 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
da18a99
New POST endpoints to create entities
CasperWA Dec 21, 2023
6921784
Start to implement authentication
CasperWA Dec 21, 2023
3ff68e5
Further work on authentication
CasperWA Dec 22, 2023
2649275
Finalize auth and admin flows
CasperWA Dec 22, 2023
b927db7
Sort and add pre-commit-hooks hooks
CasperWA Jan 4, 2024
e85c677
Satisfy new name-tests-test hook
CasperWA Jan 4, 2024
f2d0fb2
Fix tests for use with the new workflows
CasperWA Jan 4, 2024
65ab38c
Ignore deprecation warning about 'crypt'
CasperWA Jan 5, 2024
9e0862f
Remove password handling
CasperWA Jan 6, 2024
3a13339
Fix for pytest and pre-commit hooks
CasperWA Jan 6, 2024
dc43b54
Ensure `.env` is not loaded when testing
CasperWA Jan 8, 2024
d17394d
Setup auth usage in tests
CasperWA Jan 8, 2024
a17f62c
Minor log fix
CasperWA Jan 8, 2024
e1248ba
Update README
CasperWA Jan 8, 2024
cbb59f3
Fix Docker CI tests
CasperWA Jan 9, 2024
e49c457
Set ENTITY_SERVICE_DEBUG in Dockerfile
CasperWA Jan 9, 2024
2e55789
Fix logic in if-sentence
CasperWA Jan 9, 2024
1c9098e
Fully test the CLI
CasperWA Jan 9, 2024
3e6a470
Add new marker for skipping tests if using
CasperWA Jan 9, 2024
4749749
Try to make new tests work with a live backend
CasperWA Jan 9, 2024
e7b03ba
Fix tests for live backend
CasperWA Jan 9, 2024
f5c5767
Ensure env vars don't overrule login in tests
CasperWA Jan 9, 2024
715d059
Cache access token for CLI
CasperWA Jan 10, 2024
a7c22cc
Further update tests
CasperWA Jan 10, 2024
1cf7b93
Add 'production' extra to version control gunicorn
CasperWA Jan 15, 2024
82440ae
Fix live-backend testing with TestClient
CasperWA Jan 15, 2024
0f88732
Address comments from review by @DanielMarchand
CasperWA Jan 15, 2024
c08b1b4
Copy in current env for CLI login test
CasperWA Jan 15, 2024
5e7b0a8
Ensure private SSL key env var is set in environment
CasperWA Jan 15, 2024
65da5dd
Revert "Copy in current env for CLI login test"
CasperWA Jan 15, 2024
0936828
Try to add coverage when running docker for live testing
CasperWA Jan 15, 2024
6fc7b56
Ignore long lines in commented out lines
CasperWA Jan 17, 2024
6e3e8ff
Run docker with ASGI app wrapped in coverage API
CasperWA Jan 17, 2024
64e3c1e
Properly point to app in coverage entrypoint
CasperWA Jan 17, 2024
e985fe9
Use --pythonpath
CasperWA Jan 17, 2024
076b7d9
Try forcing a stop for the service
CasperWA Jan 18, 2024
6c30c46
Use a file to detect when to actively stop the service
CasperWA Jan 18, 2024
4c9aa5e
Fix dependency handling when running CI tests
CasperWA Jan 18, 2024
59d23f7
Pass input value to entrypoint properly
CasperWA Jan 18, 2024
5fa69a6
Try installing coverage with sudo
CasperWA Jan 18, 2024
4d3f5c3
Try again
CasperWA Jan 18, 2024
df1fa0a
Avoid using host user
CasperWA Jan 18, 2024
4e4f38b
Optimize test fixtures
CasperWA Jan 18, 2024
064c5c8
Move test fixtures as close as possible to their use
CasperWA Jan 18, 2024
b939960
Add tests for access token cache functions
CasperWA Jan 18, 2024
bb06e3d
Skip new test for the live backend
CasperWA Jan 18, 2024
35e717d
Add tests for the MongoDB backend
CasperWA Jan 22, 2024
83bbeb2
Fix test for soft_entity() error message
CasperWA Jan 22, 2024
c6fc0e8
Add tests for the admin backend
CasperWA Jan 23, 2024
2d42d58
Fix new tests
CasperWA Jan 23, 2024
577ad2a
Add no cover comments where reasonable
CasperWA Jan 23, 2024
24271f8
Merge remote-tracking branch 'origin/main' into cwa/close-63-post-ent…
CasperWA Jan 23, 2024
5b8d7f6
Never "close()" MongoClients
CasperWA Jan 23, 2024
f0ace0b
Close MongoClient if it is the last to be removed
CasperWA Jan 23, 2024
4bac252
Use httpx-auth for CLI authentication
CasperWA Jan 25, 2024
0b7e37e
Merge branch 'main' into cwa/close-63-post-entity-endpoint
CasperWA Jan 25, 2024
3d55209
Successfully implement GitLab Oauth2 for CLI
CasperWA Jan 26, 2024
20b4d92
Update routers with new auth method
CasperWA Jan 26, 2024
c15e65b
Update tests according to new auth flow
CasperWA Jan 27, 2024
2875f6b
Try to set up X509 auth for test live backend
CasperWA Jan 28, 2024
0f9b5d7
Add authSource and authMethod to client if using x509
CasperWA Jan 28, 2024
cf8e38c
Try to setup mongo service in CI
CasperWA Jan 28, 2024
d56e8db
Update bind-ip command
CasperWA Jan 28, 2024
9b9808d
Fix to proper option name
CasperWA Jan 28, 2024
99c4161
Try something else with entrypoint
CasperWA Jan 28, 2024
76b23c5
Try again, now avoiding bind-ip
CasperWA Jan 28, 2024
da67037
No equals, wrap all in quotations
CasperWA Jan 28, 2024
fd0e1fe
Run mongo as a step in the job instead
CasperWA Jan 28, 2024
8b45963
Set new environment variables for security config
CasperWA Jan 29, 2024
9560e43
Try setting up a while loop to check healthy status
CasperWA Jan 29, 2024
e467597
Try again
CasperWA Jan 29, 2024
acdc8d3
Just sleep
CasperWA Jan 29, 2024
58426a5
Let's see the mongo logs
CasperWA Jan 29, 2024
6b0c286
Just run the mongo image and see what it outputs
CasperWA Jan 29, 2024
4d3d36f
Fiddle a bit with things and see
CasperWA Jan 29, 2024
52dc9e4
Use github.workspace
CasperWA Jan 29, 2024
7f0872f
Run cert creation prior to mongo
CasperWA Jan 29, 2024
bf6ed0f
Try to fix if-condition
CasperWA Jan 29, 2024
602fb74
Simplify for testing in CI
CasperWA Jan 29, 2024
060f5d4
Move commented out volume line
CasperWA Jan 29, 2024
7068c78
Add back running in detached mode
CasperWA Jan 29, 2024
c4864c8
Add back root username/password as env var
CasperWA Jan 29, 2024
4dbc958
Add Python3.12 deprecation to ignore list
CasperWA Jan 29, 2024
dd356f1
Check if it can even be remedied
CasperWA Jan 29, 2024
4c39f04
Try to turn back errors
CasperWA Jan 29, 2024
786efe4
Remove unused auth models
CasperWA Jan 29, 2024
a944161
Merge remote-tracking branch 'origin/main' into cwa/close-63-post-ent…
CasperWA Jan 29, 2024
cde29e0
Update README
CasperWA Jan 29, 2024
001aa78
Use local user for entities-service docker container
CasperWA Jan 29, 2024
cfb2036
Fix naming of utility files in CI job
CasperWA Jan 29, 2024
3dad644
Implement fixes after testing on staging.onto-ns.com
CasperWA Jan 30, 2024
97e1032
Make special GitLabUserInfo groups optional
CasperWA Jan 30, 2024
183806c
Add back namespace validators
CasperWA Jan 31, 2024
a172cca
Treat yaml/yml as equals for upload file format
CasperWA Jan 31, 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
28 changes: 28 additions & 0 deletions .github/docker_init/create_x509_user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
db.getSiblingDB("$external").runCommand(
{
createUser: "CN=entities-service,OU=Team4.0 Client,O=SINTEF,L=Trondheim,ST=Trondelag,C=NO",
roles: [
{ role: "readWrite", db: "entities_service" }
],
}
)

db.createUser(
{
user: "root",
pwd: "root",
roles: [
{ role: "root", db: "admin" }
]
}
)

db.createUser(
{
user: "guest",
pwd: "guest",
roles: [
{ role: "read", db: "entities_service" }
]
}
)
221 changes: 221 additions & 0 deletions .github/docker_init/setup_mongo_security.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#!/bin/sh
# Create X.509 certificates for MongoDB for testing purposes
# Created following the appendices of the MongoDB Security Manual:
# https://www.mongodb.com/docs/manual/appendix/security/
set -ex

# Some configuration
DN_server="/C=NO/ST=Trondelag/L=Trondheim/O=SINTEF/OU=Team4.0 CA Server/CN=entities-service"
DN_client="/C=NO/ST=Trondelag/L=Trondheim/O=SINTEF/OU=Team4.0 Client/CN=entities-service"
DNS_server_1="mongodb"
DNS_server_2="localhost"

if [ -z "${HOST_USER}" ]; then
echo "HOST_USER is not set. This means that the script will be run with 'root' user in a Docker container!"
fi

ORIGINAL_DIR=$(pwd)
TARGET_DIR=${ORIGINAL_DIR}
# if [ -z "${IN_DOCKER}" ] || [ -z "${CI}" ]; then
# TARGET_DIR=${ORIGINAL_DIR}
# else
# # Running through Docker Compose
# TARGET_DIR=/mongo_tls
# fi

echo "Generating certificates in ${TARGET_DIR}"
mkdir -p ${TARGET_DIR}

# Run in a temporary directory
mkdir -p /tmp/mongodb-test
cd /tmp/mongodb-test

## 1. Create a CA Certificate
# OpenSSL Configuration File
cat > openssl-test-ca.cnf <<EOF
# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 4096
default_keyfile = myTestCertificateKey.pem ## The default private key file name.
default_md = sha256 ## Use SHA-256 for Signatures
distinguished_name = req_dn
req_extensions = v3_req
x509_extensions = v3_ca # The extensions to add to the self signed cert

[ v3_req ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only. NOT FOR PRODUCTION USE."
extendedKeyUsage = serverAuth, clientAuth

[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default =
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = TestCertificateStateName
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = TestCertificateLocalityName
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = TestCertificateOrgName
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = TestCertificateOrgUnitName
organizationalUnitName_max = 64

commonName = Common Name (eg, YOUR name)
commonName_max = 64

[ v3_ca ]
# Extensions for a typical CA

subjectKeyIdentifier=hash
basicConstraints = critical,CA:true
authorityKeyIdentifier=keyid:always,issuer:always
EOF

# Test CA PEM file
openssl genrsa -out mongodb-test-ca.key 4096
openssl req -new -x509 -days 1826 -key mongodb-test-ca.key -out mongodb-test-ca.crt -config openssl-test-ca.cnf -subj "${DN_server}"

openssl genrsa -out mongodb-test-ia.key 4096
openssl req -new -key mongodb-test-ia.key -out mongodb-test-ia.csr -config openssl-test-ca.cnf -subj "${DN_server}"
openssl x509 -sha256 -req -days 730 -in mongodb-test-ia.csr -CA mongodb-test-ca.crt -CAkey mongodb-test-ca.key -set_serial 01 -out mongodb-test-ia.crt -extfile openssl-test-ca.cnf -extensions v3_ca

cat mongodb-test-ia.crt mongodb-test-ca.crt > test-ca.pem

## 2. Create a Server Certificate
# OpenSSL Configuration File
cat > openssl-test-server.cnf <<EOF
# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.


[ req ]
default_bits = 4096
default_keyfile = myTestServerCertificateKey.pem ## The default private key file name.
default_md = sha256
distinguished_name = req_dn
req_extensions = v3_req

[ v3_req ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only. NOT FOR PRODUCTION USE."
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ${DNS_server_1}
DNS.2 = ${DNS_server_2}

[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default = TestServerCertificateCountry
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = TestServerCertificateState
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = TestServerCertificateLocality
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = TestServerCertificateOrg
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = TestServerCertificateOrgUnit
organizationalUnitName_max = 64

commonName = Common Name (eg, YOUR name)
commonName_max = 64
EOF

# Test PEM file for Server
openssl genrsa -out mongodb-test-server1.key 4096
openssl req -new -key mongodb-test-server1.key -out mongodb-test-server1.csr -config openssl-test-server.cnf -subj "${DN_server}"
openssl x509 -sha256 -req -days 365 -in mongodb-test-server1.csr -CA mongodb-test-ia.crt -CAkey mongodb-test-ia.key -CAcreateserial -out mongodb-test-server1.crt -extfile openssl-test-server.cnf -extensions v3_req
cat mongodb-test-server1.crt mongodb-test-server1.key > test-server1.pem

## 3. Create a Client Certificate
# OpenSSL Configuration File
cat > openssl-test-client.cnf <<EOF
# NOT FOR PRODUCTION USE. OpenSSL configuration file for testing.

[ req ]
default_bits = 4096
default_keyfile = myTestClientCertificateKey.pem ## The default private key file name.
default_md = sha256
distinguished_name = req_dn
req_extensions = v3_req


[ v3_req ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate for TESTING only. NOT FOR PRODUCTION USE."
extendedKeyUsage = serverAuth, clientAuth


[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default =
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = TestClientCertificateState
stateOrProvinceName_max = 64

localityName = Locality Name (eg, city)
localityName_default = TestClientCertificateLocality
localityName_max = 64

organizationName = Organization Name (eg, company)
organizationName_default = TestClientCertificateOrg
organizationName_max = 64

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = TestClientCertificateOrgUnit
organizationalUnitName_max = 64
commonName = Common Name (eg, YOUR name)
commonName_max = 64
EOF

openssl genrsa -out mongodb-test-client.key 4096
openssl req -new -key mongodb-test-client.key -out mongodb-test-client.csr -config openssl-test-client.cnf -subj "${DN_client}"
openssl x509 -sha256 -req -days 365 -in mongodb-test-client.csr -CA mongodb-test-ia.crt -CAkey mongodb-test-ia.key -CAcreateserial -out mongodb-test-client.crt -extfile openssl-test-client.cnf -extensions v3_req
cat mongodb-test-client.crt mongodb-test-client.key > test-client.pem

# Remove temporary files
mv -fZ *.pem ${TARGET_DIR}
cd ${TARGET_DIR}
rm -rf /tmp/mongodb-test

# Update ownership of files
if [ -n "${HOST_USER}" ]; then
chown -R ${HOST_USER}:${HOST_USER} ${TARGET_DIR}
fi
33 changes: 33 additions & 0 deletions .github/utils/coverage_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -mx

# Install coverage
pip install -r .github/utils/requirements.txt

# Run server with coverage as a job
# Redo the Dockerfile entrypoints, but pointing to the run_with_coverage script
# Avoid '--reload' always.
if [ "$1" == "development" ]; then
gunicorn --bind "0.0.0.0:${PORT}" --log-level debug --workers 1 --worker-class entities_service.uvicorn.UvicornWorker --pythonpath ".github/utils" run_with_coverage:APP &
elif [ "$1" == "production" ]; then
gunicorn --bind "0.0.0.0:${PORT}" --workers 1 --worker-class entities_service.uvicorn.UvicornWorker --pythonpath ".github/utils" run_with_coverage:APP &
else
echo "unknown environment"
exit 1
fi

echo "$(jobs -l)"

echo "waiting for signal to kill gunicorn"
SECONDS=0
while [ ! -f "stop_gunicorn" ] && [[ ${SECONDS} -lt ${RUN_TIME:-40} ]]; do
sleep 1
done

echo "stopping gunicorn"
rm -f stop_gunicorn
GUNICORN_PID=$(ps -C gunicorn fch -o pid | head -n 1)
kill -HUP $GUNICORN_PID
sleep ${STOP_TIME:-3}

echo "exited $0"
1 change: 1 addition & 0 deletions .github/utils/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coverage[toml]~=7.4
25 changes: 25 additions & 0 deletions .github/utils/run_with_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Special file to run the application with coverage.

First, import the coverage module and start it.
Then, import the application and register a function to save the coverage at exit.
Finally, run the application.
"""
from __future__ import annotations

import atexit

from coverage import Coverage

cov = Coverage(data_file=".coverage.docker", config_file="pyproject.toml")
cov.start()

from entities_service.main import APP # noqa: F401, E402


def save_coverage():
print("saving coverage", flush=True)
cov.stop()
cov.save()


atexit.register(save_coverage)
4 changes: 2 additions & 2 deletions .github/workflows/cd_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
release:
name: External
uses: SINTEF/ci-cd/.github/workflows/cd_release.yml@v2.7.2
if: github.repository == 'SINTEF/dlite-entities-service' && startsWith(github.ref, 'refs/tags/v')
if: github.repository == 'SINTEF/entities-service' && startsWith(github.ref, 'refs/tags/v')
with:
# General
git_username: "TEAM 4.0[bot]"
Expand All @@ -18,7 +18,7 @@ jobs:

# Python package
python_package: true
package_dirs: dlite_entities_service
package_dirs: entities_service
install_extras: "[dev]"
python_version_build: "3.10"
build_libs: flit
Expand Down
Loading
Loading