2025-12-29 21:24:24 +00:00
2025-12-29 21:24:24 +00:00

CalSpot

A lightweight, self-hosted calendar server providing WebDAV access for calendar management and public HTTP endpoints for sharing calendars. Built with Go and SQLite.

Features

  • WebDAV Interface: Upload and sync .ics calendar files using any CalDAV-compatible client
  • Public Calendar Sharing: Share calendars via simple HTTP URLs with security-through-obscurity
  • Authentication: HTTP Basic Auth protection for WebDAV endpoints
  • User Management: Interactive REPL for managing users
  • Secure Storage: bcrypt password hashing and SQLite backend
  • Lightweight: Single binary with no external dependencies
  • Docker Support: Production-ready containerized deployment

Architecture

  • Language: Go 1.25.5
  • Database: SQLite3 (file-based)
  • Authentication: HTTP Basic Auth with bcrypt password hashing
  • Calendar Format: iCalendar (.ics) files
  • Storage: Single calendar per user with automatic versioning

Quick Start

Local Development

# Clone the repository
git clone <repository-url>
cd calspot

# Build the server
go build -o calspot main.go

# Run the server
./calspot

The server will start on port 8000 with an interactive REPL for user management.

Docker Deployment

# Build the Docker image
docker build -t calspot .

# Run the container
docker run -it -p 8000:8000 -v $(pwd)/data:/home/appuser/data calspot

User Management (REPL)

The server includes an interactive command-line interface for managing users:

Commands

Add User

add [username] [password]
  • If no username provided: generates a UUID username
  • If no password provided: generates a secure 16-character password
  • Displays the public calendar ID (UUID) for sharing

Example:

> add alice MySecurePass123
User alice created. Public ID: 01933b2c-8f5e-7890-a234-567890abcdef

Delete User

del <username>

Removes user and their associated calendar data.

List Users

list

Shows all registered users with their public IDs.

Reset Password

resetpassword <username> [newpassword]

Updates user password. Generates secure password if not provided.

API Endpoints

WebDAV (Authenticated)

Endpoint: /webdav/
Authentication: HTTP Basic Auth
Methods: GET, PUT, DELETE, PROPFIND, etc.

Upload a calendar:

curl -u username:password \
  -T calendar.ics \
  http://localhost:8000/webdav/calendar.ics

Download via WebDAV:

curl -u username:password \
  http://localhost:8000/webdav/calendar.ics

Public Calendar Access (No Authentication)

Endpoint: /<user-id>/calendar.ics
Authentication: None (security via obscure UUID)
Method: GET

Access public calendar:

curl http://localhost:8000/01933b2c-8f5e-7890-a234-567890abcdef/calendar.ics

Subscribe in calendar apps:

http://localhost:8000/01933b2c-8f5e-7890-a234-567890abcdef/calendar.ics

Configuration

Environment Variables

Variable Default Description
DB_PATH ./data/cal.db Path to SQLite database file

Example:

DB_PATH=/var/lib/calspot/calendar.db ./calspot

Technical Details

Database Schema

CREATE TABLE users (
    id TEXT PRIMARY KEY,           -- UUIDv7 for public calendar access
    username TEXT UNIQUE,          -- Login username
    password_hash TEXT             -- bcrypt hash
);

CREATE TABLE calendars (
    user_id TEXT PRIMARY KEY,      -- Foreign key to users.id
    filename TEXT,                 -- Original filename (e.g., calendar.ics)
    content BLOB,                  -- iCalendar file content
    mod_time DATETIME              -- Last modification time
);

Dependencies

  • github.com/google/uuid - UUID generation (v1.6.0)
  • github.com/mattn/go-sqlite3 - SQLite driver (v1.14.32)
  • golang.org/x/crypto - bcrypt hashing (v0.46.0)
  • golang.org/x/net/webdav - WebDAV implementation (v0.48.0)

Build Requirements

  • Go 1.25.5 or later
  • GCC (for CGO/SQLite3 compilation)
Description
Upload a calendar via WebDAV, access over HTTP(S)
Readme 44 KiB
Languages
Go 95.8%
Dockerfile 4.2%