Modern ERP Reports Application with microservices architecture Tech Stack: - Backend: FastAPI + python-oracledb (Oracle DB integration) - Frontend: Vue.js 3 + PrimeVue + Vite - Telegram Bot: python-telegram-bot + SQLite - Infrastructure: Shared database pool, JWT authentication, SSH tunnel Features: - FastAPI backend with async Oracle connection pool - Vue.js 3 responsive frontend with PrimeVue components - Telegram bot alternative interface - Microservices architecture with shared components - Complete deployment support (Linux Docker + Windows IIS) - Comprehensive testing (Playwright E2E + pytest) Repository Structure: - reports-app/ - Main application (backend, frontend, telegram-bot) - shared/ - Shared components (database pool, auth, utils) - deployment/ - Deployment scripts (Linux & Windows) - docs/ - Project documentation - security/ - Security scanning and git hooks
383 lines
13 KiB
PowerShell
383 lines
13 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Enable HTTPS for ROA2WEB on IIS
|
|
|
|
.DESCRIPTION
|
|
This script configures HTTPS for ROA2WEB by:
|
|
- Creating a self-signed SSL certificate (or using existing certificate)
|
|
- Configuring HTTPS binding on IIS site
|
|
- Enabling HTTP to HTTPS redirect
|
|
|
|
.PARAMETER IISSiteName
|
|
IIS Site name (default: Default Web Site)
|
|
|
|
.PARAMETER CertificateDnsName
|
|
DNS name for certificate (default: server IP or hostname)
|
|
|
|
.PARAMETER UseExistingCert
|
|
Use existing certificate by thumbprint
|
|
|
|
.PARAMETER CertThumbprint
|
|
Thumbprint of existing certificate to use
|
|
|
|
.PARAMETER Port
|
|
HTTPS port (default: 443)
|
|
|
|
.EXAMPLE
|
|
.\Enable-HTTPS.ps1
|
|
Create self-signed certificate and enable HTTPS
|
|
|
|
.EXAMPLE
|
|
.\Enable-HTTPS.ps1 -IISSiteName "ROA2WEB" -CertificateDnsName "roa2web.company.com"
|
|
Create certificate with custom DNS name
|
|
|
|
.EXAMPLE
|
|
.\Enable-HTTPS.ps1 -UseExistingCert -CertThumbprint "ABC123..."
|
|
Use existing certificate
|
|
|
|
.NOTES
|
|
Author: ROA2WEB Team
|
|
Requires: PowerShell 5.1+, Administrator privileges
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$IISSiteName = "Default Web Site",
|
|
[string]$CertificateDnsName = "",
|
|
[switch]$UseExistingCert,
|
|
[string]$CertThumbprint = "",
|
|
[int]$Port = 443,
|
|
[string]$IPAddress = "*"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# =============================================================================
|
|
# HELPER FUNCTIONS
|
|
# =============================================================================
|
|
|
|
function Write-Step {
|
|
param([string]$Message)
|
|
Write-Host "`n[*] $Message" -ForegroundColor Cyan
|
|
}
|
|
|
|
function Write-Success {
|
|
param([string]$Message)
|
|
Write-Host " [OK] $Message" -ForegroundColor Green
|
|
}
|
|
|
|
function Write-Error {
|
|
param([string]$Message)
|
|
Write-Host " [ERROR] $Message" -ForegroundColor Red
|
|
}
|
|
|
|
function Write-Warning {
|
|
param([string]$Message)
|
|
Write-Host " [WARN] $Message" -ForegroundColor Yellow
|
|
}
|
|
|
|
function Test-Administrator {
|
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = [Security.Principal.WindowsPrincipal]$identity
|
|
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN SCRIPT
|
|
# =============================================================================
|
|
|
|
Write-Host @"
|
|
|
|
====================================================================
|
|
ROA2WEB - Enable HTTPS on IIS
|
|
====================================================================
|
|
|
|
"@ -ForegroundColor Cyan
|
|
|
|
# Check administrator privileges
|
|
if (-not (Test-Administrator)) {
|
|
Write-Error "This script must be run as Administrator"
|
|
Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
Write-Success "Running as Administrator"
|
|
|
|
# Import required modules
|
|
Write-Step "Loading IIS module..."
|
|
Import-Module WebAdministration -ErrorAction Stop
|
|
Write-Success "IIS module loaded"
|
|
|
|
# Verify IIS site exists
|
|
Write-Step "Verifying IIS site '$IISSiteName'..."
|
|
$site = Get-Website -Name $IISSiteName -ErrorAction SilentlyContinue
|
|
if (-not $site) {
|
|
Write-Error "IIS site '$IISSiteName' not found"
|
|
Write-Host "`nAvailable sites:" -ForegroundColor Yellow
|
|
Get-Website | Format-Table Name, State, PhysicalPath
|
|
exit 1
|
|
}
|
|
Write-Success "IIS site found: $IISSiteName (State: $($site.State))"
|
|
|
|
# Get or create certificate
|
|
if ($UseExistingCert) {
|
|
Write-Step "Using existing certificate..."
|
|
|
|
if ([string]::IsNullOrEmpty($CertThumbprint)) {
|
|
Write-Host "`nAvailable certificates in LocalMachine\My:" -ForegroundColor Yellow
|
|
Get-ChildItem -Path "cert:\LocalMachine\My" |
|
|
Select-Object Thumbprint, Subject, FriendlyName, NotAfter |
|
|
Format-Table -AutoSize
|
|
|
|
$CertThumbprint = Read-Host "Enter certificate thumbprint"
|
|
}
|
|
|
|
$cert = Get-ChildItem -Path "cert:\LocalMachine\My\$CertThumbprint" -ErrorAction SilentlyContinue
|
|
if (-not $cert) {
|
|
Write-Error "Certificate with thumbprint '$CertThumbprint' not found"
|
|
exit 1
|
|
}
|
|
|
|
Write-Success "Certificate found: $($cert.Subject)"
|
|
|
|
} else {
|
|
Write-Step "Creating self-signed SSL certificate..."
|
|
|
|
# Auto-detect DNS name if not provided
|
|
if ([string]::IsNullOrEmpty($CertificateDnsName)) {
|
|
$serverName = $env:COMPUTERNAME
|
|
$ipAddress = (Get-NetIPAddress -AddressFamily IPv4 |
|
|
Where-Object {$_.IPAddress -notlike "127.*" -and $_.IPAddress -notlike "169.*"} |
|
|
Select-Object -First 1).IPAddress
|
|
|
|
Write-Host " Detected hostname: $serverName" -ForegroundColor Yellow
|
|
Write-Host " Detected IP: $ipAddress" -ForegroundColor Yellow
|
|
|
|
$response = Read-Host "Use hostname for certificate? (Y/n)"
|
|
if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") {
|
|
$CertificateDnsName = $serverName
|
|
} else {
|
|
$CertificateDnsName = $ipAddress
|
|
}
|
|
}
|
|
|
|
# Check if certificate already exists
|
|
$existingCert = Get-ChildItem -Path "cert:\LocalMachine\My" |
|
|
Where-Object {$_.DnsNameList -contains $CertificateDnsName} |
|
|
Select-Object -First 1
|
|
|
|
if ($existingCert) {
|
|
Write-Warning "Certificate for '$CertificateDnsName' already exists"
|
|
$response = Read-Host "Use existing certificate? (Y/n)"
|
|
if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") {
|
|
$cert = $existingCert
|
|
Write-Success "Using existing certificate"
|
|
} else {
|
|
Write-Warning "Removing existing certificate..."
|
|
Remove-Item -Path "cert:\LocalMachine\My\$($existingCert.Thumbprint)" -Force
|
|
}
|
|
}
|
|
|
|
if (-not $cert) {
|
|
# Create new certificate
|
|
$cert = New-SelfSignedCertificate `
|
|
-DnsName $CertificateDnsName `
|
|
-CertStoreLocation "cert:\LocalMachine\My" `
|
|
-NotAfter (Get-Date).AddYears(5) `
|
|
-FriendlyName "ROA2WEB SSL Certificate" `
|
|
-KeyUsage DigitalSignature, KeyEncipherment `
|
|
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
|
|
|
|
Write-Success "Certificate created successfully"
|
|
Write-Host " DNS Name: $CertificateDnsName" -ForegroundColor Yellow
|
|
Write-Host " Thumbprint: $($cert.Thumbprint)" -ForegroundColor Yellow
|
|
Write-Host " Valid Until: $($cert.NotAfter)" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
# Configure HTTPS binding
|
|
Write-Step "Configuring HTTPS binding..."
|
|
|
|
# Check if HTTPS binding already exists
|
|
$existingBinding = Get-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -ErrorAction SilentlyContinue
|
|
|
|
if ($existingBinding) {
|
|
Write-Warning "HTTPS binding already exists on port $Port"
|
|
$response = Read-Host "Remove and recreate binding? (Y/n)"
|
|
if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") {
|
|
Remove-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -ErrorAction SilentlyContinue
|
|
Write-Success "Existing binding removed"
|
|
} else {
|
|
Write-Warning "Skipping binding creation"
|
|
$existingBinding = $null
|
|
}
|
|
}
|
|
|
|
if (-not $existingBinding) {
|
|
# Create HTTPS binding
|
|
try {
|
|
New-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -IPAddress $IPAddress
|
|
Write-Success "HTTPS binding created on port $Port"
|
|
} catch {
|
|
Write-Error "Failed to create HTTPS binding: $_"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Attach certificate to binding
|
|
Write-Step "Attaching certificate to HTTPS binding..."
|
|
|
|
try {
|
|
# Method 1: Using IIS PowerShell Provider (IIS 8+)
|
|
Push-Location
|
|
Set-Location IIS:\SslBindings
|
|
|
|
# Remove existing binding if present
|
|
$sslBinding = "${IPAddress}!${Port}"
|
|
if ($IPAddress -eq "*") {
|
|
$sslBinding = "0.0.0.0!${Port}"
|
|
}
|
|
|
|
if (Test-Path $sslBinding) {
|
|
Remove-Item $sslBinding -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# Create new SSL binding
|
|
$cert | New-Item $sslBinding
|
|
Pop-Location
|
|
|
|
Write-Success "Certificate attached to HTTPS binding"
|
|
|
|
} catch {
|
|
Write-Warning "Method 1 failed, trying alternative method..."
|
|
|
|
try {
|
|
# Method 2: Using netsh (more compatible)
|
|
$certHash = $cert.Thumbprint
|
|
$appId = "{4dc3e181-e14b-4a21-b022-59fc669b0914}"
|
|
|
|
# Remove existing binding
|
|
netsh http delete sslcert ipport=0.0.0.0:$Port 2>&1 | Out-Null
|
|
|
|
# Add new binding
|
|
$result = netsh http add sslcert ipport=0.0.0.0:$Port certhash=$certHash appid=$appId
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Success "Certificate attached using netsh"
|
|
} else {
|
|
Write-Error "Failed to attach certificate: $result"
|
|
exit 1
|
|
}
|
|
|
|
} catch {
|
|
Write-Error "Failed to attach certificate: $_"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Update web.config for HTTP to HTTPS redirect
|
|
Write-Step "Checking web.config for HTTPS redirect..."
|
|
|
|
$webConfigPath = Join-Path $site.PhysicalPath "web.config"
|
|
|
|
if (Test-Path $webConfigPath) {
|
|
$webConfig = Get-Content $webConfigPath -Raw
|
|
|
|
if ($webConfig -match "Force HTTPS") {
|
|
Write-Success "HTTPS redirect rule already exists in web.config"
|
|
} else {
|
|
Write-Warning "HTTPS redirect rule not found in web.config"
|
|
Write-Host "`nTo enable automatic HTTP to HTTPS redirect, add this rule to web.config:" -ForegroundColor Yellow
|
|
Write-Host @"
|
|
|
|
<rule name="Force HTTPS" stopProcessing="true">
|
|
<match url="(.*)" />
|
|
<conditions>
|
|
<add input="{HTTPS}" pattern="off" />
|
|
</conditions>
|
|
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
|
|
</rule>
|
|
|
|
"@ -ForegroundColor Gray
|
|
|
|
$response = Read-Host "`nAdd this rule automatically? (Y/n)"
|
|
if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") {
|
|
# Backup web.config
|
|
$backupPath = "$webConfigPath.backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
Copy-Item -Path $webConfigPath -Destination $backupPath
|
|
Write-Success "web.config backed up to: $backupPath"
|
|
|
|
# Add redirect rule
|
|
$redirectRule = @"
|
|
<!-- Rule: Force HTTPS (redirect HTTP to HTTPS) -->
|
|
<rule name="Force HTTPS" stopProcessing="true">
|
|
<match url="(.*)" />
|
|
<conditions>
|
|
<add input="{HTTPS}" pattern="off" />
|
|
</conditions>
|
|
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
|
|
</rule>
|
|
|
|
"@
|
|
|
|
$webConfig = $webConfig -replace '(<rules>)', "`$1`r`n$redirectRule"
|
|
Set-Content -Path $webConfigPath -Value $webConfig
|
|
Write-Success "HTTPS redirect rule added to web.config"
|
|
}
|
|
}
|
|
} else {
|
|
Write-Warning "web.config not found at: $webConfigPath"
|
|
Write-Host " Please ensure web.config exists and contains proper rewrite rules" -ForegroundColor Yellow
|
|
}
|
|
|
|
# Test configuration
|
|
Write-Step "Testing configuration..."
|
|
|
|
# Restart IIS site to apply changes
|
|
try {
|
|
Stop-Website -Name $IISSiteName -ErrorAction SilentlyContinue
|
|
Start-Sleep -Seconds 2
|
|
Start-Website -Name $IISSiteName
|
|
Write-Success "IIS site restarted"
|
|
} catch {
|
|
Write-Warning "Could not restart IIS site: $_"
|
|
}
|
|
|
|
# Display summary
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host " HTTPS CONFIGURATION COMPLETED" -ForegroundColor Green
|
|
Write-Host ("=" * 70) -ForegroundColor Cyan
|
|
|
|
Write-Host "`nConfiguration Summary:" -ForegroundColor Yellow
|
|
Write-Host " IIS Site: $IISSiteName"
|
|
Write-Host " HTTPS Port: $Port"
|
|
Write-Host " Certificate: $($cert.Subject)"
|
|
Write-Host " Thumbprint: $($cert.Thumbprint)"
|
|
Write-Host " Valid Until: $($cert.NotAfter)"
|
|
|
|
Write-Host "`nAccess Points:" -ForegroundColor Yellow
|
|
Write-Host " HTTPS URL: https://$CertificateDnsName"
|
|
if ($site.Bindings.Collection | Where-Object {$_.protocol -eq "http"}) {
|
|
Write-Host " HTTP URL: http://$CertificateDnsName (will redirect to HTTPS)"
|
|
}
|
|
|
|
Write-Host "`nNext Steps:" -ForegroundColor Yellow
|
|
|
|
if ($cert.Subject -match "CN=[\d\.]+") {
|
|
Write-Host " 1. [RECOMMENDED] Replace self-signed certificate with CA-issued certificate"
|
|
Write-Host " - Browsers will show security warnings for self-signed certificates"
|
|
Write-Host " - Use Let's Encrypt, DigiCert, or another CA for production"
|
|
}
|
|
|
|
Write-Host " 2. Test HTTPS access: https://$CertificateDnsName"
|
|
Write-Host " 3. Verify HTTP to HTTPS redirect is working"
|
|
Write-Host " 4. Check browser console for mixed content warnings"
|
|
|
|
Write-Host "`nTroubleshooting:" -ForegroundColor Yellow
|
|
Write-Host " View IIS bindings: Get-WebBinding -Name '$IISSiteName'"
|
|
Write-Host " View certificates: Get-ChildItem cert:\LocalMachine\My"
|
|
Write-Host " Test HTTPS locally: Invoke-WebRequest https://localhost:$Port -SkipCertificateCheck"
|
|
Write-Host " IIS Manager: inetmgr"
|
|
|
|
Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
|
|
Write-Host ""
|