wip
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
# DAV Server
|
||||
|
||||
A self-hosted **CalDAV**, **CardDAV**, and **WebDAV** server written in Go.
|
||||
|
||||
## Features
|
||||
|
||||
| Protocol | Use case |
|
||||
|----------|----------|
|
||||
| CalDAV | Calendars — sync with Apple Calendar, Thunderbird, GNOME Calendar, … |
|
||||
| CardDAV | Contacts — sync with Apple Contacts, GNOME Contacts, … |
|
||||
| WebDAV | General file access via Finder, Windows Explorer, Nautilus, … |
|
||||
|
||||
- HTTP Basic Auth with **bcrypt** password storage
|
||||
- Per-user isolated collections
|
||||
- Auto-discovery via `/.well-known/caldav` and `/.well-known/carddav`
|
||||
- Optional **TLS** (or use a reverse proxy)
|
||||
- Structured logging (text or JSON)
|
||||
- Graceful shutdown
|
||||
- Docker & Docker Compose support
|
||||
|
||||
## Quick start
|
||||
|
||||
### 1. Install dependencies
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
### 2. Generate password hashes
|
||||
|
||||
```bash
|
||||
go run ./tools/hashpwd mysecretpassword
|
||||
# Outputs: $2b$12$...
|
||||
```
|
||||
|
||||
### 3. Edit `config.yaml`
|
||||
|
||||
Replace the placeholder hashes with your real bcrypt hashes:
|
||||
|
||||
```yaml
|
||||
users:
|
||||
alice:
|
||||
password: "$2b$12$<hash generated above>"
|
||||
display_name: "Alice Smith"
|
||||
email: "alice@example.com"
|
||||
calendars:
|
||||
- personal
|
||||
- work
|
||||
address_books:
|
||||
- contacts
|
||||
```
|
||||
|
||||
### 4. Run the server
|
||||
|
||||
```bash
|
||||
make run
|
||||
# or
|
||||
go run ./cmd/server -config config.yaml
|
||||
```
|
||||
|
||||
The server starts at **http://localhost:8080**.
|
||||
|
||||
---
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
# Build and start
|
||||
docker compose up --build
|
||||
|
||||
# Or build manually
|
||||
docker build -t davserver .
|
||||
docker run -p 8080:8080 \
|
||||
-v ./config.yaml:/app/config.yaml:ro \
|
||||
-v dav-data:/app/data \
|
||||
davserver
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Client configuration
|
||||
|
||||
### Apple Calendar / Contacts (macOS / iOS)
|
||||
|
||||
1. Go to **Settings → Calendar → Accounts → Add Account → Other → Add CalDAV Account**
|
||||
2. Enter:
|
||||
- **Server**: `http://yourserver:8080`
|
||||
- **Username**: `alice`
|
||||
- **Password**: your plaintext password
|
||||
3. The app will auto-discover calendars at `/cal/alice/`.
|
||||
|
||||
Same flow for **CardDAV** with Contacts app.
|
||||
|
||||
### Thunderbird
|
||||
|
||||
1. Install the **TbSync** add-on + **CalDAV & CardDAV** provider
|
||||
2. Add a new account and point it at `http://yourserver:8080/.well-known/caldav`
|
||||
|
||||
### GNOME Calendar / Evolution
|
||||
|
||||
Use the GNOME Online Accounts panel:
|
||||
- **Server**: `http://yourserver:8080`
|
||||
- Check *CalDAV* / *CardDAV* as appropriate
|
||||
|
||||
---
|
||||
|
||||
## API endpoints
|
||||
|
||||
| Path | Description |
|
||||
|------|-------------|
|
||||
| `/.well-known/caldav` | Redirects to `/cal/` |
|
||||
| `/.well-known/carddav` | Redirects to `/card/` |
|
||||
| `/cal/<user>/` | CalDAV home |
|
||||
| `/cal/<user>/<calendar>/` | Calendar collection |
|
||||
| `/card/<user>/` | CardDAV home |
|
||||
| `/card/<user>/<book>/` | Address book collection |
|
||||
| `/files/<user>/` | WebDAV file storage |
|
||||
| `/healthz` | Health check (unauthenticated) |
|
||||
|
||||
---
|
||||
|
||||
## TLS / Reverse proxy
|
||||
|
||||
### Self-signed certificate (development)
|
||||
|
||||
```bash
|
||||
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
|
||||
```
|
||||
|
||||
Update `config.yaml`:
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enabled: true
|
||||
cert_file: cert.pem
|
||||
key_file: key.pem
|
||||
```
|
||||
|
||||
### Caddy reverse proxy (recommended for production)
|
||||
|
||||
```
|
||||
dav.example.com {
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration reference
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
base_url: "https://dav.example.com" # used in DAV responses
|
||||
|
||||
auth:
|
||||
realm: "My DAV Server"
|
||||
|
||||
storage:
|
||||
data_dir: "./data" # all user data lives here
|
||||
|
||||
logging:
|
||||
level: "info" # debug | info | warn | error
|
||||
format: "text" # text | json
|
||||
|
||||
tls:
|
||||
enabled: false
|
||||
cert_file: ""
|
||||
key_file: ""
|
||||
|
||||
users:
|
||||
<username>:
|
||||
password: "<bcrypt hash>"
|
||||
display_name: "Full Name"
|
||||
email: "user@example.com"
|
||||
calendars: # pre-created calendar names
|
||||
- personal
|
||||
address_books: # pre-created address book names
|
||||
- contacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project layout
|
||||
|
||||
```
|
||||
caldav-server/
|
||||
├── cmd/server/ # main entrypoint
|
||||
├── internal/
|
||||
│ ├── auth/ # HTTP Basic Auth middleware
|
||||
│ ├── caldav/ # CalDAV backend
|
||||
│ ├── carddav/ # CardDAV backend
|
||||
│ ├── config/ # YAML config loader
|
||||
│ ├── store/ # filesystem storage layer
|
||||
│ └── webdav/ # WebDAV file handler
|
||||
├── tools/hashpwd/ # bcrypt password hasher CLI
|
||||
├── config.yaml # sample configuration
|
||||
├── Dockerfile
|
||||
├── docker-compose.yaml
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running tests
|
||||
|
||||
```bash
|
||||
make test
|
||||
# or
|
||||
go test ./... -race
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Package | Purpose |
|
||||
|---------|---------|
|
||||
| `github.com/emersion/go-webdav` | WebDAV/CalDAV/CardDAV protocol layer |
|
||||
| `github.com/emersion/go-ical` | iCalendar parsing/serialisation |
|
||||
| `github.com/emersion/go-vcard` | vCard parsing/serialisation |
|
||||
| `golang.org/x/crypto` | bcrypt |
|
||||
| `golang.org/x/net` | `golang.org/x/net/webdav` |
|
||||
| `gopkg.in/yaml.v3` | YAML config parsing |
|
||||
Reference in New Issue
Block a user