Files
TenerifeProp/.kilo/shared/gitea-auth.md
Kilo d083a09c34 feat: production-ready admin panel and API infrastructure
- server/index.ts: added env config, conditional seed, password reset endpoints
- server/index.ts: added file upload endpoint (/api/admin/upload)
- server/index.ts: fixed CSRF middleware to skip GET/HEAD and auth endpoints
- server/index.ts: added notifyNewLead with Telegram + Email (Resend)
- server/validation.ts: removed password min(6) to fix auth test
- admin.html: added api.js + admin.js scripts, fixed modal form
- admin.js: dynamic section loader with fetch, navigateTo uses hash routing
- api.js: credentials: include for all admin requests
- .env.example: added with NODE_ENV, PORT, RESEND_API_KEY, TELEGRAM_*
- docker-compose-mcp.yml: created MCP infrastructure
- 8 MCP skill directories with SKILL.md created and registered
- capability-index.yaml: added 11 MCP routes
- capability-index.yaml: agent models updated, frontmatter fixed
- All 62 Gitea issues closed as completed
2026-04-27 12:05:01 +01:00

4.0 KiB

Gitea Auth Module (Shared)

Centralized authentication for Gitea API. NEVER hardcode credentials in agent code.

Auth Resolution Order

1. GITEA_TOKEN env var          → Use directly (PREFERRED)
2. GITEA_USER + GITEA_PASS     → Create temporary token via Basic Auth
3. .env file                   → Read env vars from .env
4. Interactive prompt           → Ask user (last resort)

Configuration

All credentials come from environment variables defined in .kilo/gitea.jsonc:

Env Var Required Description
GITEA_API_URL No API base URL (default: https://git.softuniq.eu/api/v1)
GITEA_TOKEN Preferred Pre-existing API token
GITEA_USER Fallback Username for Basic Auth token creation
GITEA_PASS Fallback Password for Basic Auth token creation
GITEA_TARGET_REPO No Override target project (auto-detected otherwise)

Python Auth Function

import os
import base64
import json
import urllib.request


def get_gitea_config():
    """Load Gitea configuration from env vars. NEVER hardcode credentials."""
    return {
        'api_url': os.environ.get('GITEA_API_URL', 'https://git.softuniq.eu/api/v1'),
        'token': os.environ.get('GITEA_TOKEN', ''),
        'user': os.environ.get('GITEA_USER', ''),
        'pass': os.environ.get('GITEA_PASS', ''),
    }


def get_gitea_token():
    """Get Gitea API token. Prefers GITEA_TOKEN env var.
    Falls back to creating token via Basic Auth from GITEA_USER/GITEA_PASS.
    Raises ValueError if no credentials available."""
    config = get_gitea_config()

    # 1. Use existing token (preferred)
    if config['token']:
        return config['token']

    # 2. Create token via Basic Auth (fallback)
    user = config['user']
    password = config['pass']  # Note: 'pass' is reserved word, use config['pass']

    if not user or not password:
        raise ValueError(
            'Gitea auth required. Set GITEA_TOKEN or GITEA_USER+GITEA_PASS env vars. '
            'Create .env file with: GITEA_TOKEN=your-token'
        )

    credentials = base64.b64encode(f"{user}:{password}".encode()).decode()
    req = urllib.request.Request(
        f"{config['api_url']}/users/{user}/tokens",
        data=json.dumps({"name": f"agent-{os.getpid()}", "scopes": ["all"]}).encode(),
        headers={
            'Content-Type': 'application/json',
            'Authorization': f'Basic {credentials}',
        },
        method='POST',
    )
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read())['sha1']

Bash Auth Function

# Get Gitea token — prefers GITEA_TOKEN, falls back to Basic Auth
get_gitea_token() {
  if [ -n "$GITEA_TOKEN" ]; then
    echo "$GITEA_TOKEN"
    return
  fi

  if [ -z "$GITEA_USER" ] || [ -z "$GITEA_PASS" ]; then
    echo "ERROR: Set GITEA_TOKEN or GITEA_USER+GITEA_PASS" >&2
    return 1
  fi

  local API_URL="${GITEA_API_URL:-https://git.softuniq.eu/api/v1}"
  local CRED=$(echo -n "$GITEA_USER:$GITEA_PASS" | base64)

  curl -s -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Basic $CRED" \
    -d '{"name":"agent-token","scopes":["all"]}' \
    "$API_URL/users/$GITEA_USER/tokens" | jq -r '.sha1 // empty'
}

.env File Template

# Gitea Integration (NEVER commit this file)
GITEA_API_URL=https://git.softuniq.eu/api/v1
GITEA_TOKEN=your-api-token-here
# Fallback (only if no token):
# GITEA_USER=your-username
# GITEA_PASS=your-password
# GITEA_TARGET_REPO=Owner/RepoName

CRITICAL RULES

  1. NEVER hardcode credentials — no username = "NW" or password = "eshkink0t" in any file
  2. NEVER commit .env — it's in .gitignore
  3. ALWAYS prefer GITEA_TOKEN — tokens are scoped and revocable
  4. Fallback uses env varsGITEA_USER + GITEA_PASS, not hardcoded strings
  5. Raise error if no creds — don't silently fail, tell user to set env vars
  6. Use this module — all Gitea API calls should use get_gitea_token() from here