chore: sync: ClausL-MacBook-Pro.local 2026-05-04 17:50
This commit is contained in:
commit
f72f2ac4e2
7 changed files with 1212 additions and 0 deletions
58
.gitignore
vendored
Normal file
58
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Binaries
|
||||||
|
src/server
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
vendor/
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Go build artifacts
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of go build
|
||||||
|
bin/
|
||||||
|
pkg/
|
||||||
|
|
||||||
|
# Coverage files
|
||||||
|
*.out
|
||||||
|
coverage.html
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Local databases
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
authelia-api.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
|
*~
|
||||||
90
README.md
Normal file
90
README.md
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
# Authelia API
|
||||||
|
|
||||||
|
A Go-based REST API and management layer that sits alongside an Authelia LXC on Proxmox. Provides a "Source of Truth" in SQLite, handles bulk user onboarding via JSON, and automates synchronization of the Authelia `users_database.yml` file.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Sovereign Bootstrap**: Automatically imports existing Authelia users on first run
|
||||||
|
- **Bulk User Management**: Create multiple users via JSON API with automatic password generation
|
||||||
|
- **Real-time Sync**: SQLite changes automatically sync to Authelia's YAML configuration
|
||||||
|
- **SMTP Onboarding**: Send welcome emails using Authelia's SMTP configuration
|
||||||
|
- **Secure API**: Bearer token authentication with bcrypt hashing
|
||||||
|
- **Drop-in Deployment**: Runs alongside existing Authelia installation
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Quick Installation (Recommended)
|
||||||
|
|
||||||
|
Download and execute the installation script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://github.com/yourusername/authelia-api/raw/main/install-authelia-api.sh | sudo bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
1. **Download the binary**:
|
||||||
|
```bash
|
||||||
|
# Download the latest authelia-api binary
|
||||||
|
curl -fsSL -o authelia-api https://github.com/yourusername/authelia-api/releases/latest/download/authelia-api
|
||||||
|
chmod +x authelia-api
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Run the installer**:
|
||||||
|
```bash
|
||||||
|
sudo ./install-authelia-api.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Installation
|
||||||
|
|
||||||
|
For building from source, see the [src/README.md](src/README.md) file.
|
||||||
|
|
||||||
|
**Note for local development**: When installing from a cloned repository, set the environment variable to use the local binary:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTHELIA_API_DEVELOPMENT_MODE=true sudo ./install-authelia-api.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Install using the script above**
|
||||||
|
2. **Get your bearer token** (from Authelia configuration):
|
||||||
|
```bash
|
||||||
|
grep -A2 "session:" /opt/authelia/configuration.yml | grep "secret:" | awk '{print $2}'
|
||||||
|
```
|
||||||
|
3. **Test the API**:
|
||||||
|
```bash
|
||||||
|
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" http://127.0.0.1:8080/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Testing with Postman
|
||||||
|
|
||||||
|
Postman collection and environment files are provided for API testing:
|
||||||
|
|
||||||
|
- `authelia-api.postman_collection.json` - Complete API collection
|
||||||
|
- `authelia-api.postman_environment.json` - Environment variables
|
||||||
|
- `POSTMAN_GUIDE.md` - Setup and usage guide
|
||||||
|
|
||||||
|
See [POSTMAN_GUIDE.md](POSTMAN_GUIDE.md) for detailed instructions.
|
||||||
|
|
||||||
|
## Files in This Repository
|
||||||
|
|
||||||
|
- `authelia-api` - Ready-to-use binary (production)
|
||||||
|
- `install-authelia-api.sh` - Installation script
|
||||||
|
- `POSTMAN_GUIDE.md` - API testing guide
|
||||||
|
- `src/` - Source code and build instructions
|
||||||
|
- `authelia-api.postman_collection.json` - Postman collection
|
||||||
|
- `authelia-api.postman_environment.json` - Postman environment
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
The repository provides a ready-to-deploy binary. The installation script handles:
|
||||||
|
- Systemd service creation
|
||||||
|
- Database setup
|
||||||
|
- Configuration generation
|
||||||
|
- User creation
|
||||||
|
- Firewall configuration (if applicable)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
||||||
BIN
authelia-api
Normal file
BIN
authelia-api
Normal file
Binary file not shown.
161
authelia-api.postman_collection.json
Normal file
161
authelia-api.postman_collection.json
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"name": "Authelia API API",
|
||||||
|
"description": "Postman collection for Authelia API REST API\n\nThis API provides a \"Source of Truth\" for Authelia user management with SQLite backend, bulk user onboarding, and automatic synchronization with Authelia's `users_database.yml` file.\n\n## Authentication\n- Use Bearer token authentication\n- Initial token: `session.secret` from Authelia configuration.yml\n- Header: `Authorization: Bearer <token>`\n\n## Base URL\n- Default: `http://127.0.0.1:8080`\n- Can be changed via `--listen` flag\n\n## Quick Start\n1. Install Authelia API using `install.sh`\n2. Start the service: `systemctl start authelia-api`\n3. Get your session.secret from `/opt/authelia/configuration.yml`\n4. Use this collection with the token as environment variable\n\n## Notes\n- All user passwords are auto-generated as secure placeholders\n- Changes trigger automatic sync to Authelia YAML file\n- SMTP onboarding emails available if configured",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Health Check",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{base_url}}/api/health",
|
||||||
|
"host": ["{{base_url}}"],
|
||||||
|
"path": ["api", "health"]
|
||||||
|
},
|
||||||
|
"description": "Health check endpoint to verify API is running. No authentication required."
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bulk Create Users",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Authorization",
|
||||||
|
"value": "Bearer {{bearer_token}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"users\": [\n {\n \"username\": \"john.doe\",\n \"display_name\": \"John Doe\",\n \"email\": \"john.doe@example.com\",\n \"groups\": [\"users\", \"admins\"]\n },\n {\n \"username\": \"jane.smith\",\n \"display_name\": \"Jane Smith\",\n \"email\": \"jane.smith@example.com\",\n \"groups\": [\"users\"]\n }\n ]\n}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "{{base_url}}/api/users/bulk",
|
||||||
|
"host": ["{{base_url}}"],
|
||||||
|
"path": ["api", "users", "bulk"]
|
||||||
|
},
|
||||||
|
"description": "Create multiple users in a single request. Passwords are automatically generated and returned in the response.\n\n**Limits:**\n- Max 1000 users per request\n- Username, display_name, and email are required\n- Email must contain '@' symbol\n\n**Response includes:**\n- `success`: boolean indicating if any users were created\n- `created`: count of successfully created users\n- `users`: array with status and placeholder_password for each user"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "List Users",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Authorization",
|
||||||
|
"value": "Bearer {{bearer_token}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{base_url}}/api/users",
|
||||||
|
"host": ["{{base_url}}"],
|
||||||
|
"path": ["api", "users"]
|
||||||
|
},
|
||||||
|
"description": "List all users in the system with pagination support.\n\n**Query Parameters:**\n- `page`: page number (default: 1)\n- `page_size`: items per page (default: 50)\n\n**Note:** Pagination is implemented but currently returns all users. Future versions will support proper pagination."
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete User",
|
||||||
|
"request": {
|
||||||
|
"method": "DELETE",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Authorization",
|
||||||
|
"value": "Bearer {{bearer_token}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{base_url}}/api/users/:username",
|
||||||
|
"host": ["{{base_url}}"],
|
||||||
|
"path": ["api", "users", ":username"],
|
||||||
|
"variable": [
|
||||||
|
{
|
||||||
|
"key": ":username",
|
||||||
|
"value": "john.doe",
|
||||||
|
"description": "Username to delete"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Delete a user by username. Triggers automatic sync to update Authelia's YAML file.\n\n**Returns:**\n- `success`: boolean\n- `message`: confirmation message"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"variable": [
|
||||||
|
{
|
||||||
|
"key": "base_url",
|
||||||
|
"value": "http://127.0.0.1:8080",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Base URL for API requests"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "bearer_token",
|
||||||
|
"value": "YOUR_SESSION_SECRET_HERE",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Bearer token (session.secret from Authelia config)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "prerequest",
|
||||||
|
"script": {
|
||||||
|
"type": "text/javascript",
|
||||||
|
"exec": [
|
||||||
|
"// Pre-request script can be used to set dynamic variables",
|
||||||
|
"console.log('Request:', pm.request);"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"type": "text/javascript",
|
||||||
|
"exec": [
|
||||||
|
"// Test script to validate responses",
|
||||||
|
"pm.test('Status code is 200 or 201', function () {",
|
||||||
|
" pm.expect(pm.response.code).to.be.oneOf([200, 201, 204]);",
|
||||||
|
"});",
|
||||||
|
"",
|
||||||
|
"// For health check, ensure status is ok",
|
||||||
|
"if (pm.request.url.toString().includes('/health')) {",
|
||||||
|
" pm.test('Health check returns ok', function () {",
|
||||||
|
" var jsonData = pm.response.json();",
|
||||||
|
" pm.expect(jsonData.status).to.equal('ok');",
|
||||||
|
" });",
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"// For bulk create, check response structure",
|
||||||
|
"if (pm.request.url.toString().includes('/bulk')) {",
|
||||||
|
" pm.test('Bulk create returns success field', function () {",
|
||||||
|
" var jsonData = pm.response.json();",
|
||||||
|
" pm.expect(jsonData).to.have.property('success');",
|
||||||
|
" pm.expect(jsonData).to.have.property('created');",
|
||||||
|
" pm.expect(jsonData).to.have.property('users');",
|
||||||
|
" });",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
23
authelia-api.postman_environment.json
Normal file
23
authelia-api.postman_environment.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"id": "authelia-api-environment",
|
||||||
|
"name": "Authelia API",
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"key": "base_url",
|
||||||
|
"value": "http://127.0.0.1:8080",
|
||||||
|
"type": "default",
|
||||||
|
"enabled": true,
|
||||||
|
"description": "Base URL for API requests"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "bearer_token",
|
||||||
|
"value": "",
|
||||||
|
"type": "secret",
|
||||||
|
"enabled": true,
|
||||||
|
"description": "Bearer token (session.secret from Authelia config)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_postman_variable_scope": "environment",
|
||||||
|
"_postman_exported_at": "2026-04-02T00:00:00.000Z",
|
||||||
|
"_postman_exported_using": "Postman/11.0"
|
||||||
|
}
|
||||||
22
example_bulk_request.json
Normal file
22
example_bulk_request.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"username": "john.doe",
|
||||||
|
"display_name": "John Doe",
|
||||||
|
"email": "john.doe@example.com",
|
||||||
|
"groups": ["users", "admins"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "jane.smith",
|
||||||
|
"display_name": "Jane Smith",
|
||||||
|
"email": "jane.smith@example.com",
|
||||||
|
"groups": ["users"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "bob.johnson",
|
||||||
|
"display_name": "Bob Johnson",
|
||||||
|
"email": "bob.johnson@example.com",
|
||||||
|
"groups": ["users", "developers"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
858
install-authelia-api.sh
Normal file
858
install-authelia-api.sh
Normal file
|
|
@ -0,0 +1,858 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Authelia API Installer
|
||||||
|
# Installation script for Authelia API
|
||||||
|
#
|
||||||
|
# Compatible with:
|
||||||
|
# - Debian/Ubuntu
|
||||||
|
# - RHEL/CentOS/Fedora
|
||||||
|
# - Alpine (with adjustments)
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# curl -fsSL https://github.com/yourusername/authelia-api/install.sh | sudo bash
|
||||||
|
#
|
||||||
|
# For development/testing:
|
||||||
|
# cd /home/authelia/dev
|
||||||
|
# sudo ./install-authelia-api.sh
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
MAGENTA='\033[0;35m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
BOLD='\033[1m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
# Update REPO_URL to your actual GitHub repository before distribution
|
||||||
|
REPO_URL="https://github.com/yourusername/authelia-api"
|
||||||
|
DOWNLOAD_URL="${AUTHELIA_API_DOWNLOAD_URL:-${REPO_URL}/releases/latest/download/authelia-api}"
|
||||||
|
INSTALL_DIR="${AUTHELIA_API_INSTALL_DIR:-/opt/authelia/api}"
|
||||||
|
SERVICE_NAME="authelia-api"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||||
|
USER="authelia" # Default Authelia user
|
||||||
|
|
||||||
|
# For development/testing - use local binary (set AUTHELIA_API_DEVELOPMENT_MODE=true for dev)
|
||||||
|
DEVELOPMENT_MODE="${AUTHELIA_API_DEVELOPMENT_MODE:-false}"
|
||||||
|
LOCAL_BINARY_PATH="/home/authelia/dev/authelia-api"
|
||||||
|
LOCAL_SOURCE_PATH="/home/authelia/dev/src"
|
||||||
|
|
||||||
|
# Global variables
|
||||||
|
NEED_SUDO=false
|
||||||
|
IS_ROOT=false
|
||||||
|
DISTRO=""
|
||||||
|
DISTRO_VERSION=""
|
||||||
|
ARCH=""
|
||||||
|
GO_VERSION="1.22"
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Utility Functions
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
print_header() {
|
||||||
|
echo -e "${CYAN}${BOLD}"
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ Authelia API Installer v1.0.0 ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo -e "${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}✓${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}✗${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}ℹ${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}⚠${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_step() {
|
||||||
|
echo -e "\n${MAGENTA}${BOLD}▶${NC} $1\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_command() {
|
||||||
|
local cmd="$1"
|
||||||
|
local desc="$2"
|
||||||
|
|
||||||
|
if [ "$NEED_SUDO" = true ] && [ "$IS_ROOT" = false ]; then
|
||||||
|
cmd="sudo $cmd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "$desc"
|
||||||
|
eval "$cmd"
|
||||||
|
}
|
||||||
|
|
||||||
|
ask_confirm() {
|
||||||
|
local prompt="$1"
|
||||||
|
local default="${2:-y}"
|
||||||
|
|
||||||
|
if [ "$default" = "y" ]; then
|
||||||
|
prompt="$prompt [Y/n]: "
|
||||||
|
else
|
||||||
|
prompt="$prompt [y/N]: "
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r -p "$prompt" response
|
||||||
|
response=${response:-$default}
|
||||||
|
|
||||||
|
if [[ $response =~ ^[Yy]$ ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# System Detection
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
detect_system() {
|
||||||
|
print_step "Detecting system..."
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -eq 0 ]; then
|
||||||
|
IS_ROOT=true
|
||||||
|
print_info "Running as root"
|
||||||
|
else
|
||||||
|
IS_ROOT=false
|
||||||
|
# Check if sudo is available
|
||||||
|
if command -v sudo &> /dev/null; then
|
||||||
|
NEED_SUDO=true
|
||||||
|
print_info "Running as non-root user, will use sudo when needed"
|
||||||
|
else
|
||||||
|
print_error "Not running as root and sudo is not available"
|
||||||
|
print_error "Please run as root or install sudo"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect distribution
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
DISTRO="$ID"
|
||||||
|
DISTRO_VERSION="$VERSION_ID"
|
||||||
|
print_success "Detected: $NAME $VERSION"
|
||||||
|
elif [ -f /etc/debian_version ]; then
|
||||||
|
DISTRO="debian"
|
||||||
|
DISTRO_VERSION=$(cat /etc/debian_version)
|
||||||
|
print_success "Detected: Debian $DISTRO_VERSION"
|
||||||
|
elif [ -f /etc/redhat-release ]; then
|
||||||
|
DISTRO="rhel"
|
||||||
|
DISTRO_VERSION=$(grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release)
|
||||||
|
print_success "Detected: RHEL/CentOS $DISTRO_VERSION"
|
||||||
|
else
|
||||||
|
print_warning "Could not detect distribution, assuming generic Linux"
|
||||||
|
DISTRO="linux"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect architecture
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
case "$ARCH" in
|
||||||
|
x86_64|amd64)
|
||||||
|
ARCH="amd64"
|
||||||
|
;;
|
||||||
|
aarch64|arm64)
|
||||||
|
ARCH="arm64"
|
||||||
|
;;
|
||||||
|
armv7l|armhf)
|
||||||
|
ARCH="armv7"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "Unsupported architecture: $ARCH"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
print_success "Architecture: $ARCH"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dependencies() {
|
||||||
|
print_step "Checking dependencies..."
|
||||||
|
|
||||||
|
local missing_deps=()
|
||||||
|
|
||||||
|
# Check for curl (needed for binary download)
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
missing_deps+=("curl")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for authelia binary
|
||||||
|
if ! command -v authelia &> /dev/null && [ ! -f /opt/authelia/authelia ]; then
|
||||||
|
print_warning "Authelia binary not found in PATH or /opt/authelia/authelia"
|
||||||
|
print_warning "The authelia-api requires Authelia to be installed"
|
||||||
|
if ! ask_confirm "Continue anyway?" "n"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${#missing_deps[@]} -ne 0 ]; then
|
||||||
|
print_error "Missing dependencies: ${missing_deps[*]}"
|
||||||
|
|
||||||
|
if [ "$DISTRO" = "debian" ] || [ "$DISTRO" = "ubuntu" ]; then
|
||||||
|
run_command "apt-get update" "Updating package list"
|
||||||
|
run_command "apt-get install -y ${missing_deps[*]}" "Installing missing dependencies"
|
||||||
|
elif [ "$DISTRO" = "rhel" ] || [ "$DISTRO" = "centos" ] || [ "$DISTRO" = "fedora" ]; then
|
||||||
|
run_command "yum install -y ${missing_deps[*]}" "Installing missing dependencies"
|
||||||
|
elif [ "$DISTRO" = "alpine" ]; then
|
||||||
|
run_command "apk add ${missing_deps[*]}" "Installing missing dependencies"
|
||||||
|
else
|
||||||
|
print_error "Please install manually: ${missing_deps[*]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "All dependencies satisfied"
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Installation Functions
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
create_user() {
|
||||||
|
print_step "Checking service user..."
|
||||||
|
|
||||||
|
# Detect Authelia service user
|
||||||
|
local authelia_service_file="/etc/systemd/system/authelia.service"
|
||||||
|
if [ -f "$authelia_service_file" ]; then
|
||||||
|
# Extract User from service file
|
||||||
|
local service_user=$(grep -E "^User=" "$authelia_service_file" | cut -d'=' -f2)
|
||||||
|
if [ -n "$service_user" ]; then
|
||||||
|
USER="$service_user"
|
||||||
|
print_success "Using Authelia service user: $USER"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Default to authelia user
|
||||||
|
print_info "Authelia service user not found, using default: $USER"
|
||||||
|
|
||||||
|
# Check if user exists
|
||||||
|
if id "$USER" &>/dev/null; then
|
||||||
|
print_success "User '$USER' already exists"
|
||||||
|
else
|
||||||
|
print_info "Creating user '$USER'"
|
||||||
|
|
||||||
|
if [ "$DISTRO" = "alpine" ]; then
|
||||||
|
run_command "adduser -D -s /bin/false $USER" "Creating system user"
|
||||||
|
else
|
||||||
|
run_command "useradd -r -s /bin/false -M $USER" "Creating system user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "User '$USER' created"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_installation_directory() {
|
||||||
|
print_step "Preparing installation directory..."
|
||||||
|
|
||||||
|
# Create installation directory
|
||||||
|
if [ ! -d "$INSTALL_DIR" ]; then
|
||||||
|
run_command "mkdir -p $INSTALL_DIR" "Creating installation directory"
|
||||||
|
else
|
||||||
|
print_info "Installation directory already exists: $INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
run_command "chown -R $USER:$USER $INSTALL_DIR" "Setting ownership"
|
||||||
|
run_command "chmod 755 $INSTALL_DIR" "Setting directory permissions"
|
||||||
|
|
||||||
|
print_success "Installation directory ready: $INSTALL_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
download_binary() {
|
||||||
|
print_step "Downloading Authelia API binary..."
|
||||||
|
|
||||||
|
local binary_dest="$INSTALL_DIR/authelia-api"
|
||||||
|
|
||||||
|
if [ "$DEVELOPMENT_MODE" = true ]; then
|
||||||
|
if [ -f "$LOCAL_BINARY_PATH" ]; then
|
||||||
|
print_info "Development mode: Using local binary"
|
||||||
|
# Only copy if source and destination are different
|
||||||
|
if [ "$LOCAL_BINARY_PATH" != "$binary_dest" ]; then
|
||||||
|
cp "$LOCAL_BINARY_PATH" "$binary_dest"
|
||||||
|
else
|
||||||
|
print_info "Binary already in correct location"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_warning "Development mode enabled but local binary not found: $LOCAL_BINARY_PATH"
|
||||||
|
print_info "Falling back to download"
|
||||||
|
# Continue to download logic
|
||||||
|
DEVELOPMENT_MODE=false
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEVELOPMENT_MODE" = false ]; then
|
||||||
|
# Construct download URL with architecture
|
||||||
|
local download_url="${DOWNLOAD_URL}_linux_${ARCH}"
|
||||||
|
|
||||||
|
print_info "Downloading from: $download_url"
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
run_command "curl -fsSL -o '$binary_dest' '$download_url'" "Downloading binary"
|
||||||
|
else
|
||||||
|
print_error "curl not available for download"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make binary executable
|
||||||
|
run_command "chmod +x '$binary_dest'" "Making binary executable"
|
||||||
|
run_command "chown $USER:$USER '$binary_dest'" "Setting binary ownership"
|
||||||
|
|
||||||
|
# Verify binary
|
||||||
|
if [ -f "$binary_dest" ] && [ -x "$binary_dest" ]; then
|
||||||
|
print_success "Binary downloaded and ready: $binary_dest"
|
||||||
|
|
||||||
|
# Test binary version
|
||||||
|
if "$binary_dest" --version &>/dev/null; then
|
||||||
|
local version=$("$binary_dest" --version 2>/dev/null || echo "unknown")
|
||||||
|
print_success "Binary version: $version"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
print_error "Binary download or verification failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
download_source_files() {
|
||||||
|
print_step "Downloading source files and documentation..."
|
||||||
|
|
||||||
|
local source_dir="$INSTALL_DIR/src"
|
||||||
|
|
||||||
|
# Create source directory
|
||||||
|
if [ ! -d "$source_dir" ]; then
|
||||||
|
run_command "mkdir -p $source_dir" "Creating source directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For development, copy existing source files
|
||||||
|
if [ "$DEVELOPMENT_MODE" = true ]; then
|
||||||
|
print_info "Development mode: Using existing source files"
|
||||||
|
|
||||||
|
# If source directory already exists in install location, skip copying
|
||||||
|
if [ -d "$INSTALL_DIR/src" ] && [ "$INSTALL_DIR/src" != "$source_dir" ]; then
|
||||||
|
print_info "Source directory already exists at installation location"
|
||||||
|
elif [ -d "$LOCAL_SOURCE_PATH" ] && [ "$LOCAL_SOURCE_PATH" != "$source_dir" ]; then
|
||||||
|
print_info "Copying source files from development location"
|
||||||
|
cp -r "$LOCAL_SOURCE_PATH"/* "$source_dir/" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Also copy root README if it exists (from dev directory)
|
||||||
|
if [ -f "/home/authelia/dev/README.md" ] && [ "/home/authelia/dev/README.md" != "$source_dir/ROOT_README.md" ]; then
|
||||||
|
cp "/home/authelia/dev/README.md" "$source_dir/ROOT_README.md"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# In production, download source archive
|
||||||
|
local source_url="${REPO_URL}/archive/refs/heads/main.tar.gz"
|
||||||
|
local temp_file="/tmp/authelia-api-src.tar.gz"
|
||||||
|
|
||||||
|
print_info "Downloading source files from GitHub"
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
run_command "curl -fsSL -o '$temp_file' '$source_url'" "Downloading source archive"
|
||||||
|
run_command "tar -xzf '$temp_file' -C '$source_dir' --strip-components=1" "Extracting source files"
|
||||||
|
run_command "rm -f '$temp_file'" "Cleaning up temp file"
|
||||||
|
else
|
||||||
|
print_warning "curl not available, skipping source download"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set permissions on source directory
|
||||||
|
run_command "chown -R $USER:$USER '$source_dir'" "Setting source directory ownership"
|
||||||
|
run_command "chmod -R 644 '$source_dir'" "Setting source file permissions"
|
||||||
|
|
||||||
|
print_success "Source files downloaded to: $source_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_configuration() {
|
||||||
|
print_step "Creating configuration..."
|
||||||
|
|
||||||
|
local config_file="$INSTALL_DIR/config.yml"
|
||||||
|
|
||||||
|
# Check if configuration already exists
|
||||||
|
if [ -f "$config_file" ]; then
|
||||||
|
print_info "Configuration already exists: $config_file"
|
||||||
|
if ask_confirm "Overwrite existing configuration?" "n"; then
|
||||||
|
print_info "Backing up existing configuration"
|
||||||
|
run_command "cp '$config_file' '${config_file}.backup.$(date +%Y%m%d_%H%M%S)'" "Backing up config"
|
||||||
|
else
|
||||||
|
print_info "Skipping configuration creation"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create basic configuration
|
||||||
|
cat > /tmp/authelia-api-config.yml << EOF
|
||||||
|
# Authelia API Configuration
|
||||||
|
# This file can be used to override default settings
|
||||||
|
|
||||||
|
# Database settings
|
||||||
|
database_path: "$INSTALL_DIR/authelia-api.db"
|
||||||
|
|
||||||
|
# API server settings
|
||||||
|
listen_addr: "127.0.0.1:8080"
|
||||||
|
log_level: "info"
|
||||||
|
|
||||||
|
# Authelia integration (will auto-discover from Authelia config)
|
||||||
|
# authelia_config_path: "/opt/authelia/configuration.yml"
|
||||||
|
# authelia_binary_path: "/opt/authelia/authelia"
|
||||||
|
|
||||||
|
# Uncomment to override environment variables
|
||||||
|
# AUTHELIA_API_DB_PATH: "$INSTALL_DIR/authelia-api.db"
|
||||||
|
# AUTHELIA_API_LISTEN_ADDR: "127.0.0.1:8080"
|
||||||
|
# AUTHELIA_API_LOG_LEVEL: "info"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run_command "mv /tmp/authelia-api-config.yml '$config_file'" "Creating configuration file"
|
||||||
|
run_command "chown $USER:$USER '$config_file'" "Setting configuration ownership"
|
||||||
|
run_command "chmod 600 '$config_file'" "Securing configuration"
|
||||||
|
|
||||||
|
print_success "Configuration created: $config_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_systemd_service() {
|
||||||
|
print_step "Creating systemd service..."
|
||||||
|
|
||||||
|
# Skip service creation for non-standard install directories
|
||||||
|
if [ "$INSTALL_DIR" != "/opt/authelia/api" ]; then
|
||||||
|
print_info "Skipping systemd service creation (non-standard install directory)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if service already exists
|
||||||
|
if [ -f "$SERVICE_FILE" ]; then
|
||||||
|
print_info "Service file already exists: $SERVICE_FILE"
|
||||||
|
if ask_confirm "Overwrite existing service file?" "n"; then
|
||||||
|
print_info "Stopping existing service"
|
||||||
|
run_command "systemctl stop $SERVICE_NAME 2>/dev/null || true" "Stopping service"
|
||||||
|
run_command "systemctl disable $SERVICE_NAME 2>/dev/null || true" "Disabling service"
|
||||||
|
else
|
||||||
|
print_info "Skipping service creation"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create service file
|
||||||
|
local service_content="[Unit]
|
||||||
|
Description=Authelia API
|
||||||
|
Documentation=https://github.com/yourusername/authelia-api
|
||||||
|
After=network.target authelia.service
|
||||||
|
Requires=authelia.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$USER
|
||||||
|
Group=$USER
|
||||||
|
WorkingDirectory=$INSTALL_DIR
|
||||||
|
Environment=\"AUTHELIA_API_DB_PATH=$INSTALL_DIR/authelia-api.db\"
|
||||||
|
Environment=\"AUTHELIA_API_LISTEN_ADDR=127.0.0.1:8080\"
|
||||||
|
Environment=\"AUTHELIA_API_LOG_LEVEL=info\"
|
||||||
|
ExecStart=$INSTALL_DIR/authelia-api --config /opt/authelia/configuration.yml
|
||||||
|
ExecReload=/bin/kill -HUP \$MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
TimeoutStopSec=30
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=authelia-api"
|
||||||
|
|
||||||
|
# Add security hardening only if not running as root
|
||||||
|
if [ "$USER" != "root" ]; then
|
||||||
|
service_content="$service_content
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=$INSTALL_DIR /opt/authelia"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add install section
|
||||||
|
service_content="$service_content
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target"
|
||||||
|
|
||||||
|
# Write service file
|
||||||
|
echo "$service_content" > /tmp/authelia-api.service
|
||||||
|
|
||||||
|
run_command "mv /tmp/authelia-api.service '$SERVICE_FILE'" "Creating service file"
|
||||||
|
run_command "chmod 644 '$SERVICE_FILE'" "Setting service file permissions"
|
||||||
|
|
||||||
|
# Reload systemd
|
||||||
|
run_command "systemctl daemon-reload" "Reloading systemd"
|
||||||
|
|
||||||
|
print_success "Systemd service created: $SERVICE_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_database() {
|
||||||
|
print_step "Setting up database..."
|
||||||
|
|
||||||
|
local db_file="$INSTALL_DIR/authelia-api.db"
|
||||||
|
|
||||||
|
# Check if database already exists
|
||||||
|
if [ -f "$db_file" ]; then
|
||||||
|
print_info "Database already exists: $db_file"
|
||||||
|
if ask_confirm "Initialize new database (old data will be lost)?" "n"; then
|
||||||
|
print_info "Backing up existing database"
|
||||||
|
run_command "cp '$db_file' '${db_file}.backup.$(date +%Y%m%d_%H%M%S)'" "Backing up database"
|
||||||
|
run_command "rm -f '$db_file'" "Removing old database"
|
||||||
|
else
|
||||||
|
print_info "Skipping database setup"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create empty database file
|
||||||
|
run_command "touch '$db_file'" "Creating database file"
|
||||||
|
run_command "chown $USER:$USER '$db_file'" "Setting database ownership"
|
||||||
|
run_command "chmod 600 '$db_file'" "Securing database"
|
||||||
|
|
||||||
|
print_success "Database file created: $db_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_bootstrap() {
|
||||||
|
print_step "Running bootstrap..."
|
||||||
|
|
||||||
|
local binary_path="$INSTALL_DIR/authelia-api"
|
||||||
|
|
||||||
|
if [ ! -f "$binary_path" ]; then
|
||||||
|
print_error "Binary not found: $binary_path"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "Running bootstrap process (first-time setup)"
|
||||||
|
|
||||||
|
# Run bootstrap with proper user
|
||||||
|
if [ "$IS_ROOT" = true ]; then
|
||||||
|
run_command "sudo -u $USER $binary_path --bootstrap" "Running bootstrap"
|
||||||
|
else
|
||||||
|
run_command "$binary_path --bootstrap" "Running bootstrap"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
print_success "Bootstrap completed successfully"
|
||||||
|
else
|
||||||
|
print_warning "Bootstrap encountered issues (this might be expected if already bootstrapped)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_and_start_service() {
|
||||||
|
print_step "Enabling and starting service..."
|
||||||
|
|
||||||
|
# Skip service operations for non-standard install directories
|
||||||
|
if [ "$INSTALL_DIR" != "/opt/authelia/api" ]; then
|
||||||
|
print_info "Skipping service operations (non-standard install directory)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable service
|
||||||
|
run_command "systemctl enable $SERVICE_NAME" "Enabling service"
|
||||||
|
|
||||||
|
# Start service
|
||||||
|
run_command "systemctl start $SERVICE_NAME" "Starting service"
|
||||||
|
|
||||||
|
# Check service status
|
||||||
|
sleep 2
|
||||||
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
|
print_success "Service is running"
|
||||||
|
|
||||||
|
# Show status
|
||||||
|
run_command "systemctl status $SERVICE_NAME --no-pager" "Service status"
|
||||||
|
else
|
||||||
|
print_error "Service failed to start"
|
||||||
|
run_command "journalctl -u $SERVICE_NAME -n 20 --no-pager" "Checking service logs"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_firewall() {
|
||||||
|
print_step "Configuring firewall (if applicable)..."
|
||||||
|
|
||||||
|
# Skip firewall configuration for non-standard install directories
|
||||||
|
if [ "$INSTALL_DIR" != "/opt/authelia/api" ]; then
|
||||||
|
print_info "Skipping firewall configuration (non-standard install directory)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local port="8080"
|
||||||
|
|
||||||
|
# Check if firewall-cmd is available (firewalld)
|
||||||
|
if command -v firewall-cmd &> /dev/null; then
|
||||||
|
if firewall-cmd --state &>/dev/null; then
|
||||||
|
print_info "Configuring firewalld"
|
||||||
|
|
||||||
|
# Add the service/port
|
||||||
|
if ! firewall-cmd --query-port="${port}/tcp" &>/dev/null; then
|
||||||
|
run_command "firewall-cmd --permanent --add-port=${port}/tcp" "Adding firewall rule"
|
||||||
|
run_command "firewall-cmd --reload" "Reloading firewall"
|
||||||
|
print_success "Firewall rule added for port $port"
|
||||||
|
else
|
||||||
|
print_info "Firewall rule already exists for port $port"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Check for ufw
|
||||||
|
elif command -v ufw &> /dev/null; then
|
||||||
|
if ufw status | grep -q "Status: active"; then
|
||||||
|
print_info "Configuring UFW"
|
||||||
|
|
||||||
|
if ! ufw status | grep -q "${port}/tcp"; then
|
||||||
|
run_command "ufw allow ${port}/tcp comment 'Authelia API'" "Adding firewall rule"
|
||||||
|
print_success "Firewall rule added for port $port"
|
||||||
|
else
|
||||||
|
print_info "Firewall rule already exists for port $port"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Check for iptables (direct)
|
||||||
|
elif command -v iptables &> /dev/null; then
|
||||||
|
print_info "Note: Using iptables directly requires manual configuration"
|
||||||
|
print_info "If using iptables, you may need to add:"
|
||||||
|
print_info " iptables -A INPUT -p tcp --dport $port -j ACCEPT"
|
||||||
|
else
|
||||||
|
print_info "No firewall management tool detected"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_backup_script() {
|
||||||
|
print_step "Creating backup script..."
|
||||||
|
|
||||||
|
local backup_script="$INSTALL_DIR/backup.sh"
|
||||||
|
|
||||||
|
cat > "$backup_script" << 'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Authelia API Backup Script
|
||||||
|
# Backups database and configuration
|
||||||
|
|
||||||
|
BACKUP_DIR="/opt/authelia/backups"
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
BACKUP_FILE="$BACKUP_DIR/authelia-api_backup_$TIMESTAMP.tar.gz"
|
||||||
|
|
||||||
|
# Create backup directory if it doesn't exist
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
|
# Stop authelia-api service to ensure consistent backup
|
||||||
|
echo "Stopping authelia-api service..."
|
||||||
|
systemctl stop authelia-api
|
||||||
|
|
||||||
|
# Create backup
|
||||||
|
echo "Creating backup..."
|
||||||
|
tar -czf "$BACKUP_FILE" \
|
||||||
|
/opt/authelia/api/authelia-api.db \
|
||||||
|
/opt/authelia/api/config.yml \
|
||||||
|
/opt/authelia/api/src/ 2>/dev/null || true
|
||||||
|
|
||||||
|
# Restart authelia-api service
|
||||||
|
echo "Starting authelia-api service..."
|
||||||
|
systemctl start authelia-api
|
||||||
|
|
||||||
|
echo "Backup created: $BACKUP_FILE"
|
||||||
|
echo "Size: $(du -h "$BACKUP_FILE" | cut -f1)"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Copy backup script from source if it exists
|
||||||
|
if [ -f "$LOCAL_SOURCE_PATH/backup.sh" ]; then
|
||||||
|
cp "$LOCAL_SOURCE_PATH/backup.sh" "$backup_script"
|
||||||
|
run_command "chmod +x '$backup_script'" "Making backup script executable"
|
||||||
|
run_command "chown $USER:$USER '$backup_script'" "Setting backup script ownership"
|
||||||
|
print_success "Backup script created: $backup_script"
|
||||||
|
else
|
||||||
|
run_command "chmod +x '$backup_script'" "Making backup script executable"
|
||||||
|
run_command "chown $USER:$USER '$backup_script'" "Setting backup script ownership"
|
||||||
|
print_success "Backup script created: $backup_script"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Main Installation Flow
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
main_installation() {
|
||||||
|
print_header
|
||||||
|
|
||||||
|
echo -e "${BOLD}Authelia API Installation${NC}"
|
||||||
|
echo -e "This will install the Authelia API to: ${CYAN}$INSTALL_DIR${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Show what will be installed
|
||||||
|
echo -e "${BOLD}Components to install:${NC}"
|
||||||
|
echo " • Authelia API binary"
|
||||||
|
echo " • Source code and documentation"
|
||||||
|
echo " • Configuration files"
|
||||||
|
echo " • Systemd service"
|
||||||
|
echo " • Backup script"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$IS_ROOT" = false ] && [ "$NEED_SUDO" = true ]; then
|
||||||
|
echo -e "${YELLOW}Note:${NC} Some operations will require sudo privileges"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ask_confirm "Proceed with installation?" "y"; then
|
||||||
|
print_info "Installation cancelled"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run installation steps
|
||||||
|
detect_system
|
||||||
|
check_dependencies
|
||||||
|
create_user
|
||||||
|
prepare_installation_directory
|
||||||
|
download_binary
|
||||||
|
download_source_files
|
||||||
|
create_configuration
|
||||||
|
setup_database
|
||||||
|
create_systemd_service
|
||||||
|
run_bootstrap
|
||||||
|
enable_and_start_service
|
||||||
|
setup_firewall
|
||||||
|
create_backup_script
|
||||||
|
|
||||||
|
print_step "Installation Complete!"
|
||||||
|
|
||||||
|
echo -e "${GREEN}${BOLD}✓ Authelia API has been successfully installed${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Service Information:${NC}"
|
||||||
|
echo " Service: $SERVICE_NAME"
|
||||||
|
echo " Status: $(systemctl is-active $SERVICE_NAME 2>/dev/null || echo 'not installed')"
|
||||||
|
echo " Logs: journalctl -u $SERVICE_NAME"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Files and Directories:${NC}"
|
||||||
|
echo " Binary: $INSTALL_DIR/authelia-api"
|
||||||
|
echo " Database: $INSTALL_DIR/authelia-api.db"
|
||||||
|
echo " Config: $INSTALL_DIR/config.yml"
|
||||||
|
echo " Source: $INSTALL_DIR/src/"
|
||||||
|
echo " Backup: $INSTALL_DIR/backup.sh"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}API Access:${NC}"
|
||||||
|
echo " URL: http://127.0.0.1:8080"
|
||||||
|
echo " Health: http://127.0.0.1:8080/api/health"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Next Steps:${NC}"
|
||||||
|
echo " 1. Review configuration: $INSTALL_DIR/config.yml"
|
||||||
|
echo " 2. Test API with: curl http://127.0.0.1:8080/api/health"
|
||||||
|
echo " 3. Check logs: journalctl -u $SERVICE_NAME -f"
|
||||||
|
echo " 4. Add API admins using the API endpoints"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Documentation:${NC} $REPO_URL"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test API health endpoint
|
||||||
|
print_info "Testing API health endpoint..."
|
||||||
|
sleep 3
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
if curl -fs http://127.0.0.1:8080/api/health &>/dev/null; then
|
||||||
|
print_success "API is responding correctly"
|
||||||
|
else
|
||||||
|
print_warning "API health check failed (service might still be starting)"
|
||||||
|
print_info "Check logs with: journalctl -u $SERVICE_NAME -f"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Uninstallation Functions
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
print_header
|
||||||
|
|
||||||
|
echo -e "${RED}${BOLD}⚠ Uninstall Authelia API${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "This will:"
|
||||||
|
echo " • Stop and disable the service"
|
||||||
|
echo " • Remove systemd service file"
|
||||||
|
echo " • Remove installation directory: ${CYAN}$INSTALL_DIR${NC}"
|
||||||
|
echo " • Remove backup scripts"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}Warning:${NC} This will delete all authelia-api data including the database!"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if ! ask_confirm "Are you sure you want to uninstall?" "n"; then
|
||||||
|
print_info "Uninstall cancelled"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_step "Starting uninstallation..."
|
||||||
|
|
||||||
|
# Stop and disable service
|
||||||
|
if [ -f "$SERVICE_FILE" ]; then
|
||||||
|
run_command "systemctl stop $SERVICE_NAME 2>/dev/null || true" "Stopping service"
|
||||||
|
run_command "systemctl disable $SERVICE_NAME 2>/dev/null || true" "Disabling service"
|
||||||
|
run_command "rm -f '$SERVICE_FILE'" "Removing service file"
|
||||||
|
run_command "systemctl daemon-reload" "Reloading systemd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove installation directory
|
||||||
|
if [ -d "$INSTALL_DIR" ]; then
|
||||||
|
run_command "rm -rf '$INSTALL_DIR'" "Removing installation directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove backup script
|
||||||
|
if [ -f "/usr/local/bin/authelia-api-backup" ]; then
|
||||||
|
run_command "rm -f /usr/local/bin/authelia-api-backup" "Removing backup script"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_success "Uninstallation complete!"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Note:${NC} Authelia configuration and user database were not modified"
|
||||||
|
echo " Backup files in /opt/authelia/backups/ were not removed"
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Main Script Entry Point
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
# Parse command line arguments
|
||||||
|
case "${1:-}" in
|
||||||
|
--help|-h|help)
|
||||||
|
print_header
|
||||||
|
echo "Usage: $0 [OPTION]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " install Install Authelia API (default)"
|
||||||
|
echo " uninstall Remove Authelia API"
|
||||||
|
echo " --help, -h Show this help message"
|
||||||
|
echo " --version, -v Show version"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 # Interactive installation"
|
||||||
|
echo " $0 install # Explicit installation"
|
||||||
|
echo " $0 uninstall # Remove installation"
|
||||||
|
echo ""
|
||||||
|
echo "Install via curl:"
|
||||||
|
echo " curl -fsSL $REPO_URL/install.sh | sudo bash"
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--version|-v)
|
||||||
|
echo "Authelia API Installer v1.0.0"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
uninstall|--uninstall)
|
||||||
|
uninstall
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
install|--install|"")
|
||||||
|
main_installation
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "Unknown option: $1"
|
||||||
|
echo "Use --help for usage information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Reference in a new issue