✨(all) add organizations, resources, channels, and infra migration (#34)
Add multi-tenant organization model populated from OIDC claims with org-scoped user discovery, CalDAV principal filtering, and cross-org isolation at the SabreDAV layer. Add bookable resource principals (rooms, equipment) with CalDAV auto-scheduling that handles conflict detection, auto-accept/decline, and org-scoped booking enforcement. Fixes #14. Replace CalendarSubscriptionToken with a unified Channel model supporting CalDAV integration tokens and iCal feed URLs, with encrypted token storage and role-based access control. Fixes #16. Migrate task queue from Celery to Dramatiq with async ICS import, progress tracking, and task status polling endpoint. Replace nginx with Caddy for both the reverse proxy and frontend static serving. Switch frontend package manager from yarn/pnpm to npm and upgrade Node to 24, Next.js to 16, TypeScript to 5.9. Harden security with fail-closed entitlements, RSVP rate limiting and token expiry, CalDAV proxy path validation blocking internal API routes, channel path scope enforcement, and ETag-based conflict prevention. Add frontend pages for resource management and integration channel CRUD, with resource booking in the event modal. Restructure CalDAV paths to /calendars/users/ and /calendars/resources/ with nested principal collections in SabreDAV.
This commit is contained in:
38
bin/pylint
38
bin/pylint
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck source=bin/_config.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/_config.sh"
|
||||
|
||||
declare diff_from
|
||||
declare -a paths
|
||||
declare -a args
|
||||
|
||||
# Parse options
|
||||
for arg in "$@"
|
||||
do
|
||||
case $arg in
|
||||
--diff-only=*)
|
||||
diff_from="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
args+=("$arg")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
paths+=("$arg")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -n "${diff_from}" ]]; then
|
||||
# Run pylint only on modified files located in src/backend
|
||||
# (excluding deleted files and migration files)
|
||||
# shellcheck disable=SC2207
|
||||
paths=($(git diff "${diff_from}" --name-only --diff-filter=d -- src/backend ':!**/migrations/*.py' | grep -E '^src/backend/.*\.py$'))
|
||||
fi
|
||||
|
||||
# Fix docker vs local path when project sources are mounted as a volume
|
||||
read -ra paths <<< "$(echo "${paths[@]}" | sed "s|src/backend/||g")"
|
||||
_dc_run --no-deps backend-dev pylint "${paths[@]}" "${args[@]}"
|
||||
@@ -5,14 +5,27 @@ set -o pipefail # don't ignore exit codes when piping output
|
||||
|
||||
echo "-----> Running post-frontend script"
|
||||
|
||||
# Move the frontend build to the nginx root and clean up
|
||||
# Move the frontend build to the app root and clean up
|
||||
mkdir -p build/
|
||||
mv src/frontend/apps/calendars/out build/frontend-out
|
||||
|
||||
cp src/frontend/apps/calendars/src/features/i18n/translations.json translations.json
|
||||
|
||||
mv src/backend/* ./
|
||||
mv src/nginx/* ./
|
||||
|
||||
# Download Caddy binary with checksum verification
|
||||
CADDY_VERSION="2.11.2"
|
||||
CADDY_SHA256="94391dfefe1f278ac8f387ab86162f0e88d87ff97df367f360e51e3cda3df56f"
|
||||
CADDY_TAR="/tmp/caddy.tar.gz"
|
||||
curl -fsSL -o "$CADDY_TAR" \
|
||||
"https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_linux_amd64.tar.gz"
|
||||
echo "${CADDY_SHA256} ${CADDY_TAR}" | sha256sum -c -
|
||||
tar -xz -C bin/ caddy < "$CADDY_TAR"
|
||||
rm "$CADDY_TAR"
|
||||
chmod +x bin/caddy
|
||||
|
||||
# Copy Caddyfile (uses {$ENV} vars natively, no ERB needed)
|
||||
cp src/proxy/Caddyfile ./Caddyfile
|
||||
|
||||
echo "3.13" > .python-version
|
||||
|
||||
@@ -25,22 +38,25 @@ mkdir -p "$DEB_DIR" "$PHP_PREFIX"
|
||||
|
||||
# Hardcoded Launchpad URLs for PHP 8.3.6-0maysync1 (Ubuntu Noble amd64)
|
||||
# Source: https://launchpad.net/ubuntu/noble/amd64/php8.3-fpm/8.3.6-0maysync1
|
||||
declare -A PHP_DEBS=(
|
||||
[php8.3-cli]="http://launchpadlibrarian.net/724872605/php8.3-cli_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-fpm]="http://launchpadlibrarian.net/724872610/php8.3-fpm_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-common]="http://launchpadlibrarian.net/724872606/php8.3-common_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-opcache]="http://launchpadlibrarian.net/724872623/php8.3-opcache_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-readline]="http://launchpadlibrarian.net/724872627/php8.3-readline_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-pgsql]="http://launchpadlibrarian.net/724872624/php8.3-pgsql_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-xml]="http://launchpadlibrarian.net/724872633/php8.3-xml_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-mbstring]="http://launchpadlibrarian.net/724872617/php8.3-mbstring_8.3.6-0maysync1_amd64.deb"
|
||||
[php8.3-curl]="http://launchpadlibrarian.net/724872607/php8.3-curl_8.3.6-0maysync1_amd64.deb"
|
||||
[php-common]="http://launchpadlibrarian.net/710804987/php-common_93ubuntu2_all.deb"
|
||||
# Format: "package_name url sha256"
|
||||
PHP_DEBS=(
|
||||
"php8.3-cli http://launchpadlibrarian.net/724872605/php8.3-cli_8.3.6-0maysync1_amd64.deb 8cb7461dd06fb214b30c060b80b1c6f95d1ff5e2656fdadf215e50b9f299f196"
|
||||
"php8.3-fpm http://launchpadlibrarian.net/724872610/php8.3-fpm_8.3.6-0maysync1_amd64.deb b3a9435025766bcbf6c16199c06481c5196098c084933dfabf8867c982edc2b2"
|
||||
"php8.3-common http://launchpadlibrarian.net/724872606/php8.3-common_8.3.6-0maysync1_amd64.deb 0e0d0ad9c17add5fb2afcc14c6fffb81c2beb99114108b8ebd0461d910a79dfc"
|
||||
"php8.3-opcache http://launchpadlibrarian.net/724872623/php8.3-opcache_8.3.6-0maysync1_amd64.deb 13b2662201c57904c1eda9b048b1349acaf3609c7d9e8df5b2d93833a059bdb0"
|
||||
"php8.3-readline http://launchpadlibrarian.net/724872627/php8.3-readline_8.3.6-0maysync1_amd64.deb 380f8ed79196914ee2eebb68bf518a752204826af1fdb8a0d5c9609c76086b90"
|
||||
"php8.3-pgsql http://launchpadlibrarian.net/724872624/php8.3-pgsql_8.3.6-0maysync1_amd64.deb b1ed204c980c348d1870cfa88c1b40257621ae5696a2a7f44f861a9d00eb7477"
|
||||
"php8.3-xml http://launchpadlibrarian.net/724872633/php8.3-xml_8.3.6-0maysync1_amd64.deb 6c6ded219d1966a50108d032b7a522e641765a8a6aa48747483313fa7dafd533"
|
||||
"php8.3-mbstring http://launchpadlibrarian.net/724872617/php8.3-mbstring_8.3.6-0maysync1_amd64.deb 42c89945eb105c2232ab208b893ef65e9abc8af5c95aa10c507498655ef812c4"
|
||||
"php8.3-curl http://launchpadlibrarian.net/724872607/php8.3-curl_8.3.6-0maysync1_amd64.deb 95d46a22e6b493ba0b6256cf036a2a37d4b9b5f438968073709845af1c17df4c"
|
||||
"php-common http://launchpadlibrarian.net/710804987/php-common_93ubuntu2_all.deb 39b15c407700e81ddd62580736feba31b187ffff56f6835dac5fa8f847c42529"
|
||||
)
|
||||
|
||||
for pkg in "${!PHP_DEBS[@]}"; do
|
||||
for entry in "${PHP_DEBS[@]}"; do
|
||||
read -r pkg url sha256 <<< "$entry"
|
||||
echo " Downloading ${pkg}"
|
||||
curl -fsSL -o "$DEB_DIR/${pkg}.deb" "${PHP_DEBS[$pkg]}"
|
||||
curl -fsSL -o "$DEB_DIR/${pkg}.deb" "$url"
|
||||
echo "${sha256} ${DEB_DIR}/${pkg}.deb" | sha256sum -c -
|
||||
done
|
||||
|
||||
for deb in "$DEB_DIR"/*.deb; do
|
||||
@@ -90,11 +106,14 @@ chmod +x bin/php
|
||||
echo "-----> PHP version: $("$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" -v | head -1)"
|
||||
echo "-----> PHP modules: $("$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" -m | tr '\n' ' ')"
|
||||
|
||||
# Download Composer and install SabreDAV dependencies
|
||||
# Download Composer with integrity verification and install SabreDAV dependencies
|
||||
echo "-----> Installing SabreDAV dependencies"
|
||||
COMPOSER_VERSION="2.9.5"
|
||||
COMPOSER_SHA256="c86ce603fe836bf0861a38c93ac566c8f1e69ac44b2445d9b7a6a17ea2e9972a"
|
||||
curl -fsSL -o bin/composer.phar \
|
||||
https://getcomposer.org/download/latest-stable/composer.phar
|
||||
cp -r docker/sabredav sabredav
|
||||
"https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar"
|
||||
echo "${COMPOSER_SHA256} bin/composer.phar" | sha256sum -c -
|
||||
cp -r src/caldav sabredav
|
||||
cd sabredav
|
||||
"../$PHP_PREFIX/usr/bin/php8.3" -n -c "$BUILD_INI" ../bin/composer.phar install \
|
||||
--no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
# Parse DATABASE_URL into PG* vars for PHP and psql
|
||||
source bin/export_pg_vars.sh
|
||||
|
||||
# Set defaults for Caddy env vars
|
||||
export CALENDARS_FRONTEND_ROOT="${CALENDARS_FRONTEND_ROOT:-/app/build/frontend-out}"
|
||||
export CALENDARS_FRONTEND_BACKEND_SERVER="${CALENDARS_FRONTEND_BACKEND_SERVER:-localhost:8000}"
|
||||
export DJANGO_ADMIN_URL="${DJANGO_ADMIN_URL:-admin}"
|
||||
|
||||
# Start PHP-FPM for SabreDAV (CalDAV server)
|
||||
.php/usr/sbin/php-fpm8.3 \
|
||||
-n -c /app/.php/php.ini \
|
||||
@@ -12,11 +17,11 @@ source bin/export_pg_vars.sh
|
||||
# Start the Django backend
|
||||
gunicorn -b :8000 calendars.wsgi:application --log-file - &
|
||||
|
||||
# Start the Nginx server
|
||||
bin/run &
|
||||
# Start the Caddy server
|
||||
bin/caddy run --config Caddyfile --adapter caddyfile &
|
||||
|
||||
# if the current shell is killed, also terminate all its children
|
||||
trap "pkill SIGTERM -P $$" SIGTERM
|
||||
trap "pkill -SIGTERM -P $$" SIGTERM
|
||||
|
||||
# wait for a single child to finish,
|
||||
wait -n
|
||||
|
||||
Reference in New Issue
Block a user