ugh damn ssl shit
This commit is contained in:
1 parent
2da85c4d84
commit
cca9d94b36
3 files changed
+235
-9
No files matched your search
+125
@@ -0,0 +1,125 @@
|
||||
# HTTPS Webhook Setup Guide
|
||||
|
||||
## Quick Start (Self-Signed Certificate for Testing)
|
||||
|
||||
### 1. Generate Certificate
|
||||
```powershell
|
||||
python generate_cert.py
|
||||
```
|
||||
|
||||
This creates `cert.pem` and `key.pem` files.
|
||||
|
||||
### 2. Run Server with HTTPS
|
||||
|
||||
#### Option A: HTTPS for webhook only (recommended for development)
|
||||
```powershell
|
||||
python src/test_server.py --ssl-cert cert.pem --ssl-key key.pem --hook-port 8443 --hook-ssl-only
|
||||
```
|
||||
- Main server: `http://localhost:7432/` (HTTP)
|
||||
- Webhook: `https://localhost:8443/hook` (HTTPS)
|
||||
|
||||
#### Option B: HTTPS for everything
|
||||
```powershell
|
||||
python src/test_server.py --ssl-cert cert.pem --ssl-key key.pem --hook-port 8443
|
||||
```
|
||||
- Main server: `https://localhost:7432/` (HTTPS)
|
||||
- Webhook: `https://localhost:8443/hook` (HTTPS)
|
||||
|
||||
#### Option C: Single port with HTTPS
|
||||
```powershell
|
||||
python src/test_server.py --ssl-cert cert.pem --ssl-key key.pem
|
||||
```
|
||||
- Everything on: `https://localhost:7432/`
|
||||
|
||||
### 3. Test the Webhook
|
||||
|
||||
Update `src/test_webhook.py` to use HTTPS:
|
||||
```python
|
||||
url = "https://localhost:8443/hook"
|
||||
```
|
||||
|
||||
Then run:
|
||||
```powershell
|
||||
python src/test_webhook.py
|
||||
```
|
||||
|
||||
## Production Setup (with Real Certificate)
|
||||
|
||||
### Option 1: Let's Encrypt (Free, Recommended)
|
||||
|
||||
On Linux/WSL:
|
||||
```bash
|
||||
# Install certbot
|
||||
sudo apt-get install certbot
|
||||
|
||||
# Generate certificate (replace yourdomain.com)
|
||||
sudo certbot certonly --standalone -d yourdomain.com
|
||||
|
||||
# Certificates will be at:
|
||||
# /etc/letsencrypt/live/yourdomain.com/fullchain.pem
|
||||
# /etc/letsencrypt/live/yourdomain.com/privkey.pem
|
||||
|
||||
# Run server
|
||||
python src/test_server.py \
|
||||
--ssl-cert /etc/letsencrypt/live/yourdomain.com/fullchain.pem \
|
||||
--ssl-key /etc/letsencrypt/live/yourdomain.com/privkey.pem \
|
||||
--host 0.0.0.0 \
|
||||
--hook-port 443 \
|
||||
--hook-ssl-only
|
||||
```
|
||||
|
||||
### Option 2: Reverse Proxy (nginx/Caddy)
|
||||
|
||||
Run studspider on HTTP internally, use nginx/Caddy for HTTPS:
|
||||
|
||||
```nginx
|
||||
# nginx config
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name yourdomain.com;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location /hook {
|
||||
proxy_pass http://localhost:7432/hook;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then run studspider normally:
|
||||
```powershell
|
||||
python src/test_server.py
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "OpenSSL not found" Error
|
||||
- **Windows**: Install from https://slproweb.com/products/Win32OpenSSL.html
|
||||
- **Alternative**: Use Git Bash or WSL which include OpenSSL
|
||||
|
||||
### Self-Signed Certificate Warnings
|
||||
- Normal for development
|
||||
- Use `--insecure` flag with curl/tools for testing
|
||||
- For production, get a proper certificate from Let's Encrypt
|
||||
|
||||
### Port 443 Already in Use
|
||||
- Use a different port like 8443
|
||||
- Or stop the service using port 443
|
||||
|
||||
### Certificate File Not Found
|
||||
- Use absolute paths: `--ssl-cert C:\path\to\cert.pem`
|
||||
- Or run from the directory containing the certificates
|
||||
|
||||
## Square Webhook Configuration
|
||||
|
||||
When setting up webhooks in Square Dashboard:
|
||||
1. Use your HTTPS URL: `https://yourdomain.com:8443/hook`
|
||||
2. Square requires valid SSL (not self-signed)
|
||||
3. Consider using ngrok for local testing:
|
||||
```powershell
|
||||
ngrok http 8443
|
||||
```
|
||||
Then use the ngrok HTTPS URL in Square Dashboard
|
||||
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Generate self-signed SSL certificate for testing HTTPS webhooks
|
||||
Run this script to create cert.pem and key.pem files
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
def generate_certificate():
|
||||
"""Generate self-signed certificate using OpenSSL"""
|
||||
|
||||
cert_file = "cert.pem"
|
||||
key_file = "key.pem"
|
||||
|
||||
# Check if OpenSSL is available
|
||||
try:
|
||||
subprocess.run(["openssl", "version"],
|
||||
capture_output=True, check=True)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
print("ERROR: OpenSSL not found!")
|
||||
print("\nFor Windows, you can:")
|
||||
print("1. Install OpenSSL from: https://slproweb.com/products/Win32OpenSSL.html")
|
||||
print("2. Or use Git Bash which includes OpenSSL")
|
||||
print("3. Or use WSL (Windows Subsystem for Linux)")
|
||||
return False
|
||||
|
||||
print("Generating self-signed certificate...")
|
||||
print("This will create cert.pem and key.pem files")
|
||||
print()
|
||||
|
||||
# Generate certificate valid for 365 days
|
||||
cmd = [
|
||||
"openssl", "req", "-x509",
|
||||
"-newkey", "rsa:4096",
|
||||
"-keyout", key_file,
|
||||
"-out", cert_file,
|
||||
"-days", "365",
|
||||
"-nodes", # No passphrase
|
||||
"-subj", "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
||||
]
|
||||
|
||||
try:
|
||||
subprocess.run(cmd, check=True)
|
||||
print(f"\n✓ Certificate created: {os.path.abspath(cert_file)}")
|
||||
print(f"✓ Private key created: {os.path.abspath(key_file)}")
|
||||
print("\nYou can now run the server with HTTPS:")
|
||||
print(f" python src/test_server.py --ssl-cert {cert_file} --ssl-key {key_file} --hook-port 8443")
|
||||
print("\nOr webhook-only HTTPS:")
|
||||
print(f" python src/test_server.py --ssl-cert {cert_file} --ssl-key {key_file} --hook-port 8443 --hook-ssl-only")
|
||||
print("\nNote: Self-signed certificates will show security warnings in browsers.")
|
||||
print("For production, use certificates from a trusted CA like Let's Encrypt.")
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"ERROR: Failed to generate certificate: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not generate_certificate():
|
||||
sys.exit(1)
|
||||
+50
-9
@@ -1,6 +1,7 @@
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import ssl
|
||||
from aiohttp import web
|
||||
from base64 import b64decode
|
||||
from typing import Dict, Any
|
||||
@@ -240,16 +241,48 @@ parser.add_argument(
|
||||
default=8080,
|
||||
help="Optional separate port for webhook endpoint. default: 8080",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ssl-cert",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Path to SSL certificate file for HTTPS (PEM format)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ssl-key",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Path to SSL private key file for HTTPS (PEM format)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--hook-ssl-only",
|
||||
action="store_true",
|
||||
help="Enable HTTPS only for webhook endpoint (main server stays HTTP)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(banner.generate("studspider v0.1"))
|
||||
print("Built for PLAY-WELL TEKNOLOGIES by contact@traps.moe\n\n")
|
||||
|
||||
# Setup SSL context if certificates provided
|
||||
ssl_context = None
|
||||
if args.ssl_cert and args.ssl_key:
|
||||
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
ssl_context.load_cert_chain(args.ssl_cert, args.ssl_key)
|
||||
print(f"SSL enabled with cert: {args.ssl_cert}")
|
||||
elif args.ssl_cert or args.ssl_key:
|
||||
print("ERROR: Both --ssl-cert and --ssl-key must be provided together")
|
||||
exit(1)
|
||||
|
||||
# If hook-port is specified, run a separate server for webhooks
|
||||
if args.hook_port:
|
||||
print(f"Starting main server on {args.host}:{args.port}")
|
||||
print(f"Starting webhook server on {args.host}:{args.hook_port}")
|
||||
protocol_main = "https" if (ssl_context and not args.hook_ssl_only) else "http"
|
||||
protocol_hook = "https" if ssl_context else "http"
|
||||
|
||||
print(f"Starting main server on {args.host}:{args.port} ({protocol_main})")
|
||||
print(
|
||||
f"Starting webhook server on {args.host}:{args.hook_port} ({protocol_hook})"
|
||||
)
|
||||
|
||||
# Create separate app for webhook
|
||||
hook_app = web.Application()
|
||||
@@ -259,23 +292,31 @@ if __name__ == "__main__":
|
||||
async def run_servers():
|
||||
runner1 = web.AppRunner(app)
|
||||
await runner1.setup()
|
||||
site1 = web.TCPSite(runner1, args.host, args.port)
|
||||
# Main server uses SSL only if not hook-ssl-only mode
|
||||
main_ssl = None if args.hook_ssl_only else ssl_context
|
||||
site1 = web.TCPSite(runner1, args.host, args.port, ssl_context=main_ssl)
|
||||
|
||||
runner2 = web.AppRunner(hook_app)
|
||||
await runner2.setup()
|
||||
site2 = web.TCPSite(runner2, args.host, args.hook_port)
|
||||
# Webhook server always uses SSL if certificates provided
|
||||
site2 = web.TCPSite(
|
||||
runner2, args.host, args.hook_port, ssl_context=ssl_context
|
||||
)
|
||||
|
||||
await site1.start()
|
||||
await site2.start()
|
||||
|
||||
print(f"Main server running on http://{args.host}:{args.port}")
|
||||
print(f"Webhook server running on http://{args.host}:{args.hook_port}/hook")
|
||||
print(f"Main server running on {protocol_main}://{args.host}:{args.port}")
|
||||
print(
|
||||
f"Webhook server running on {protocol_hook}://{args.host}:{args.hook_port}/hook"
|
||||
)
|
||||
|
||||
# Keep running
|
||||
await asyncio.Event().wait()
|
||||
|
||||
asyncio.run(run_servers())
|
||||
else:
|
||||
print(f"Server running on {args.host}:{args.port}")
|
||||
print(f"Webhook endpoint: http://{args.host}:{args.port}/hook")
|
||||
web.run_app(app, host=args.host, port=args.port)
|
||||
protocol = "https" if ssl_context else "http"
|
||||
print(f"Server running on {args.host}:{args.port} ({protocol})")
|
||||
print(f"Webhook endpoint: {protocol}://{args.host}:{args.port}/hook")
|
||||
web.run_app(app, host=args.host, port=args.port, ssl_context=ssl_context)
|
||||
Reference in new issue
Block a user