Termcloud

A simple file storage service with user buckets and usage limits.

Setup

  1. Set up PostgreSQL database and run the schema:
psql -d termcloud -f internal/db/schema.sql
  1. Configure environment variables (copy .env.example to .env and customize):
cp .env.example .env
# Edit .env with your settings

Configuration Options

Variable Default Description
DATABASE_URL - PostgreSQL connection string
PORT 8080 Server port
STORAGE_DIR storage Directory for file storage
MAX_FILE_SIZE_MB 100 Maximum file size in MB
RATE_LIMIT 20.0 Requests per second limit
CORS_ORIGINS * Allowed CORS origins
GZIP_LEVEL 5 Gzip compression level (1-9)
DB_MAX_CONNECTIONS 100 Maximum database connections
DB_MIN_CONNECTIONS 10 Minimum database connections
DB_CONN_LIFETIME 1h Connection lifetime
DB_CONN_IDLE_TIME 1m Connection idle timeout
DB_HEALTH_CHECK_PERIOD 5s Health check interval
DEFAULT_STORAGE_LIMIT_GB 1 Default user storage limit
  1. Build and run:
make build
make run

Usage

Create a user and get API key:

make admin ARGS="create-user mai sakurajima@waifu.club 5"

API Endpoints

All API endpoints require X-API-Key header.

Buckets:

  • GET /api/v1/buckets - List user buckets
  • POST /api/v1/buckets - Create bucket {"name": "my-bucket"}
  • DELETE /api/v1/buckets/:bucket - Delete bucket

Objects:

  • GET /api/v1/buckets/:bucket/objects - List objects in bucket
  • PUT /api/v1/buckets/:bucket/objects/* - Upload file (multipart form with "file" field)
  • GET /api/v1/buckets/:bucket/objects/* - Download file
  • DELETE /api/v1/buckets/:bucket/objects/* - Delete file

User Info:

  • GET /api/v1/user - Get user info and usage stats

Bucket Policies:

  • PUT /api/v1/buckets/:bucket/policy - Set bucket policy {"policy": "json-policy-string"}
  • GET /api/v1/buckets/:bucket/policy - Get bucket policy
  • DELETE /api/v1/buckets/:bucket/policy - Delete bucket policy

Bucket Policies

Bucket policies use JSON format similar to AWS S3 IAM policies to control access to buckets and objects.

Policy Structure

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "StatementId",
      "Effect": "Allow|Deny",
      "Principal": {
        "User": ["username1", "username2"]
      },
      "Action": [
        "termcloud:GetObject",
        "termcloud:PutObject",
        "termcloud:DeleteObject",
        "termcloud:ListObjects"
      ],
      "Resource": [
        "arn:termcloud:s3:::bucket-name/*"
      ]
    }
  ]
}

Supported Actions

  • termcloud:GetObject - Download files
  • termcloud:PutObject - Upload files
  • termcloud:DeleteObject - Delete files
  • termcloud:ListObjects - List files in bucket
  • termcloud:GetBucket - Get bucket info
  • termcloud:DeleteBucket - Delete bucket
  • * - All actions

Policy Examples

Read-only access:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"User": ["john"]},
      "Action": ["termcloud:GetObject", "termcloud:ListObjects"],
      "Resource": ["arn:termcloud:s3:::my-bucket/*"]
    }
  ]
}

Deny delete operations:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": {"User": ["*"]},
      "Action": ["termcloud:DeleteObject"],
      "Resource": ["arn:termcloud:s3:::my-bucket/*"]
    }
  ]
}

Example Usage

# Create bucket
curl -X POST http://localhost:8080/api/v1/buckets \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-files"}'

# Upload file
curl -X PUT http://localhost:8080/api/v1/buckets/my-files/objects/test.txt \
  -H "X-API-Key: your-api-key" \
  -F "file=@test.txt"

# Download file
curl http://localhost:8080/api/v1/buckets/my-files/objects/test.txt \
  -H "X-API-Key: your-api-key" \
  -o downloaded.txt
Description
No description provided
Readme 139 KiB
Languages
Go 94.7%
PLpgSQL 4.5%
Makefile 0.8%