Build [v1.9.12] (Secure Seal & LDAP Sync: Custom Caddy & Config Volume)
This commit is contained in:
@@ -73,6 +73,11 @@ def authenticate_ldap(username, password):
|
||||
return None
|
||||
|
||||
real_user_dn = conn.entries[0].entry_dn
|
||||
user_groups = []
|
||||
if hasattr(conn.entries[0], 'memberOf'):
|
||||
user_groups = [str(g).lower() for g in conn.entries[0].memberOf.values]
|
||||
log.debug(f"LDAP: Found memberOf groups on user: {user_groups}")
|
||||
|
||||
log.debug(f"LDAP: Canonical DN found: {real_user_dn}")
|
||||
|
||||
# Check roles based on group membership
|
||||
@@ -87,27 +92,39 @@ def authenticate_ldap(username, password):
|
||||
groups_dn = config.get("groups_dn", "ou=groups")
|
||||
|
||||
# Iterate through mappings to find the highest role
|
||||
# Priority: admin > user
|
||||
potential_roles = []
|
||||
|
||||
for mapping in role_mappings:
|
||||
group_name = mapping["group"]
|
||||
target_role = mapping["role"]
|
||||
|
||||
# Construct group DN if it's just a common name, else use as is
|
||||
# Construct group DN if it's just a common name
|
||||
if "=" not in group_name:
|
||||
full_group_dn = f"cn={group_name},{groups_dn},{base_dn}"
|
||||
else:
|
||||
full_group_dn = group_name
|
||||
|
||||
|
||||
full_group_dn_lower = full_group_dn.lower()
|
||||
|
||||
log.debug(f"LDAP: Checking membership in group: {full_group_dn}")
|
||||
conn.search(full_group_dn, '(objectClass=*)', attributes=['member'])
|
||||
|
||||
# Method 1: Check memberOf if available (AD/LLDAP)
|
||||
if full_group_dn_lower in user_groups:
|
||||
log.debug(f"LDAP: Match found via memberOf for {target_role}")
|
||||
potential_roles.append(target_role)
|
||||
continue
|
||||
|
||||
# Method 2: Search group's member attribute (Standard LDAP)
|
||||
conn.search(full_group_dn, '(objectClass=*)', attributes=['member', 'uniqueMember'])
|
||||
if conn.entries:
|
||||
members = conn.entries[0].member.values
|
||||
if real_user_dn in members or user_dn in members or \
|
||||
any(m.lower().replace(" ", "") == real_user_dn.lower().replace(" ", "") for m in members):
|
||||
log.debug(f"LDAP: User is in group {group_name}, assigning role: {target_role}")
|
||||
members = []
|
||||
if hasattr(conn.entries[0], 'member'):
|
||||
members = [str(m).lower() for m in conn.entries[0].member.values]
|
||||
elif hasattr(conn.entries[0], 'uniqueMember'):
|
||||
members = [str(m).lower() for m in conn.entries[0].uniqueMember.values]
|
||||
|
||||
if real_user_dn.lower() in members or user_dn.lower() in members:
|
||||
log.debug(f"LDAP: Match found via group search for {target_role}")
|
||||
potential_roles.append(target_role)
|
||||
|
||||
if "admin" in potential_roles:
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
# TFM aInventory - Caddy Explicit IP Configuration
|
||||
# Version 1.9.10 - Focused on resolving Protocol Errors on private IPs.
|
||||
# TFM aInventory - Caddy Patched IP Configuration
|
||||
# Version 1.9.12 - Secure Seal & IP Stability
|
||||
{
|
||||
admin off
|
||||
admin off
|
||||
auto_https disable_redirects
|
||||
auto_https disable_redirects
|
||||
|
||||
# Trust local CA for internal certificate issuance
|
||||
local_certs
|
||||
}
|
||||
|
||||
# Frontend SSL Proxy (8919 -> 443)
|
||||
https://{$SERVER_IP:192.168.84.113}:443 {
|
||||
https://{$SERVER_IP:192.168.84.113}:443 {
|
||||
tls internal {
|
||||
reverse_proxy frontend:3000
|
||||
on_demand
|
||||
}
|
||||
reverse_proxy frontend:3000
|
||||
|
||||
# Security Headers for PWA
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
X-XSS-Protection "1; mode=block"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "SAMEORIGIN"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
}
|
||||
}
|
||||
|
||||
# Backend SSL Proxy (8918 -> 444)
|
||||
https://{$SERVER_IP:192.168.84.113}:444 {
|
||||
https://{$SERVER_IP:192.168.84.113}:444 {
|
||||
tls internal {
|
||||
reverse_proxy backend:8000
|
||||
on_demand
|
||||
}
|
||||
reverse_proxy backend:8000
|
||||
}
|
||||
}
|
||||
|
||||
8
config/proxy/Dockerfile
Normal file
8
config/proxy/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM caddy:2-alpine
|
||||
|
||||
# Install nss-tools to allow Caddy to manage its internal trust store (fixes certutil warning)
|
||||
# Install ca-certificates to ensure Caddy can trust external sites if needed
|
||||
RUN apk add --no-cache nss-tools ca-certificates
|
||||
|
||||
# Expose the internal proxy ports
|
||||
EXPOSE 80 443 444
|
||||
29
deploy.sh
29
deploy.sh
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# TFM aInventory - Bulletproof Deployment Script (v1.9.10)
|
||||
# TFM aInventory - Bulletproof Deployment Script (v1.9.12)
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
@@ -30,7 +30,7 @@ for arg in "$@"; do
|
||||
--help)
|
||||
echo "Usage: ./deploy.sh [options]"
|
||||
echo "Options:"
|
||||
echo " --reset-ssl Clear Caddy storage and reset certificates"
|
||||
echo " --reset-ssl Clear Caddy storage and reset certificates (Aggressive)"
|
||||
echo " --reset-admin Force reset Admin password to 'Admin123!'"
|
||||
echo " --help Show this help message"
|
||||
exit 0
|
||||
@@ -39,19 +39,25 @@ for arg in "$@"; do
|
||||
done
|
||||
|
||||
if [ "$RESET_SSL" = true ]; then
|
||||
echo "🧹 Resetting SSL certificates..."
|
||||
echo "🧹 Aggressive SSL Reset in progress..."
|
||||
docker compose down
|
||||
# Clear internal docker volumes
|
||||
docker volume rm -f inventory_caddy_data 2>/dev/null || true
|
||||
echo "✅ SSL data cleared."
|
||||
docker volume rm -f inventory_caddy_config 2>/dev/null || true
|
||||
# Clear persistent host volumes if they exist
|
||||
rm -rf ./data/caddy_data/* 2>/dev/null || true
|
||||
rm -rf ./data/caddy_config/* 2>/dev/null || true
|
||||
echo "✅ SSL storage completely cleared."
|
||||
fi
|
||||
|
||||
echo "🚀 Starting TFM aInventory Services..."
|
||||
# Use --build to ensure the custom Caddy image is built
|
||||
docker compose --env-file inventory.env up -d --build --remove-orphans
|
||||
|
||||
if [ "$RESET_ADMIN" = true ]; then
|
||||
echo "🔐 Resetting Admin credentials..."
|
||||
# Wait for container to be ready
|
||||
sleep 2
|
||||
sleep 3
|
||||
docker compose exec backend python3 -m backend.scripts.reset_admin
|
||||
fi
|
||||
|
||||
@@ -60,17 +66,18 @@ echo "🔍 Verifying port mapping..."
|
||||
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
|
||||
|
||||
echo ""
|
||||
echo "🚀 DIAGNOSTIC LOGS (Proxy SSL Handshake):"
|
||||
echo "🚀 DIAGNOSTIC LOGS (Proxy Status):"
|
||||
docker compose logs proxy --tail 20
|
||||
|
||||
echo ""
|
||||
echo "✅ Deployment complete."
|
||||
echo "✅ Deployment complete (v1.9.12)."
|
||||
echo " ------------------------------------------------------------"
|
||||
echo " DEFAULT CREDENTIALS:"
|
||||
echo " ACCESS COORDINATES:"
|
||||
echo " 1. SECURE: https://${SERVER_IP:-localhost}:${FRONTEND_SSL_PORT:-8919}"
|
||||
echo " 2. DIRECT: http://${SERVER_IP:-localhost}:${FRONTEND_PORT:-8917}"
|
||||
echo " ------------------------------------------------------------"
|
||||
echo " CREDENTIALS (if first run or reset):"
|
||||
echo " User: Admin"
|
||||
echo " Pass: Admin123!"
|
||||
echo " ------------------------------------------------------------"
|
||||
echo " 1. SECURE ACCESS: https://${SERVER_IP:-localhost}:${FRONTEND_SSL_PORT:-8919}"
|
||||
echo " 2. DIRECT ACCESS: http://${SERVER_IP:-localhost}:${FRONTEND_PORT:-8917}"
|
||||
echo " ------------------------------------------------------------"
|
||||
echo ""
|
||||
|
||||
@@ -12,6 +12,7 @@ services:
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./logs:/app/logs
|
||||
- ./config:/app/config
|
||||
- ./scripts:/app/scripts:ro
|
||||
environment:
|
||||
- DATA_DIR=/app/data
|
||||
@@ -36,7 +37,9 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
proxy:
|
||||
image: caddy:alpine
|
||||
build:
|
||||
context: .
|
||||
dockerfile: config/proxy/Dockerfile
|
||||
networks:
|
||||
- inventory_net
|
||||
ports:
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version": "1.9.10", "last_build": "2026-04-13-2207", "codename": "AccessRecovery", "commit": "bdf6d605"}
|
||||
{"version": "1.9.11", "last_build": "2026-04-13-2215", "codename": "Convergence", "commit": "9d7e4f0c"}
|
||||
|
||||
Reference in New Issue
Block a user