Metadata-Version: 2.4
Name: pyfileserv
Version: 0.11.0
Summary: 带登录认证的安全文件服务器
Project-URL: Homepage, https://github.com/yzutyc/pyfileserv
Project-URL: Repository, https://github.com/yzutyc/pyfileserv
Author-email: yzutyc <yucheng@email.cn>
License-Expression: MIT
Keywords: authentication,bcrypt,http,pyfileserv
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Requires-Python: >=3.8
Requires-Dist: bcrypt>=4.0.0
Provides-Extra: build
Requires-Dist: build; extra == 'build'
Requires-Dist: twine; extra == 'build'
Provides-Extra: cert
Requires-Dist: cryptography>=41.0.0; extra == 'cert'
Provides-Extra: full
Requires-Dist: cryptography>=41.0.0; extra == 'full'
Requires-Dist: markdown>=3.4.0; extra == 'full'
Requires-Dist: openpyxl>=3.1.0; extra == 'full'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'full'
Requires-Dist: pytest>=7.0.0; extra == 'full'
Requires-Dist: python-docx>=1.1.0; extra == 'full'
Requires-Dist: python-pptx>=1.0.0; extra == 'full'
Requires-Dist: pyyaml>=6.0; extra == 'full'
Requires-Dist: redis>=4.0.0; extra == 'full'
Provides-Extra: markdown
Requires-Dist: markdown>=3.4.0; extra == 'markdown'
Provides-Extra: office
Requires-Dist: openpyxl>=3.1.0; extra == 'office'
Requires-Dist: python-docx>=1.1.0; extra == 'office'
Requires-Dist: python-pptx>=1.0.0; extra == 'office'
Provides-Extra: postgres
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgres'
Provides-Extra: redis
Requires-Dist: redis>=4.0.0; extra == 'redis'
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == 'test'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
Description-Content-Type: text/markdown

<p align="center">
  <img src="src/file_server/static/logo.svg" alt="File Server Logo" width="128" height="128">
</p>

<h1 align="center">File Server</h1>

<p align="center">带登录认证的安全文件服务器</p>

---

## 功能特性

- **用户认证系统** - 基于用户名/密码的登录认证，使用 bcrypt 加密存储密码
- **文件分享** - 创建带密码保护、过期时间、下载次数限制的分享链接，支持管理页面
- **HTTPS 支持** - 支持 SSL/TLS 加密传输，可使用自签名证书或正规证书
- **YAML 配置文件** - 支持 YAML 格式配置文件，所有配置项持久化
- **PostgreSQL 数据库** - 支持将用户信息和分享数据存储到 PostgreSQL 数据库
- **会话管理** - 基于 Cookie 的安全会话机制，1小时超时，支持内存和 Redis 存储
- **多级目录浏览** - 支持子目录导航，面包屑路径显示
- **文件分类浏览** - 目录列表按类型分类展示：HTML、XMind、JSON 和其他文件
- **文件下载** - 支持任意文件下载，显示文件大小和修改时间
- **文件上传** - 支持多文件上传，拖拽上传，自动处理文件名冲突
- **文件搜索** - 实时搜索/过滤文件名和目录名
- **文件排序** - 支持按名称、大小或修改时间排序
- **图片预览** - JPG、PNG、GIF、WebP、SVG 等格式在线预览，支持同目录多图导航
- **音频预览** - MP3、WAV、OGG、FLAC 等格式在线播放，支持播放列表
- **视频预览** - MP4、WebM、AVI、MOV、MKV 等格式在线播放
- **文本/代码预览** - 多种编程语言语法高亮显示，带行号
- **Markdown 预览** - 实时渲染 MD 文件，支持效果/源码双视图，一键导出 PDF
- **HTML 预览** - 沙箱 iframe 渲染，支持效果/源码双视图
- **XMind 预览** - 树形结构展示思维导图，支持节点展开/折叠
- **JSON 预览** - 格式化显示，支持效果/源码双视图
- **PDF 预览** - PDF 文件在线预览，内嵌浏览器查看器
- **Word 预览** - DOCX 文档在线预览，支持标题、粗体、斜体、下划线、表格渲染
- **Excel 预览** - XLSX 表格在线预览，支持多工作表标签切换
- **PowerPoint 预览** - PPTX 演示文稿在线预览，卡片式幻灯片内容展示
- **主题切换** - 所有预览页面均支持深色/浅色主题
- **JSON 查看器** - JSON 文件语法高亮显示，支持复制和下载
- **用户管理** - 创建、删除、修改用户密码
- **管理员权限控制** - 基于角色的访问控制，只有管理员可访问用户管理页面
- **证书管理** - 内置自签名证书生成工具

## 安全特性

- **HTTPS 加密** - 支持 SSL/TLS 加密传输，防止数据窃听
- bcrypt 密码加密（rounds=12），用户密码和分享密码均使用 bcrypt 哈希存储
- 安全会话 ID（secrets.token_hex）
- HttpOnly + SameSite Cookie
- 会话超时机制
- 访问控制（未认证用户重定向到登录页）
- 路径遍历防护（防止 `../` 攻击）
- 文件上传安全（文件名清理、大小限制 100MB）
- 用户数据文件权限限制（0o600）
- 服务器路径信息隐藏（防止信息泄露）
- **管理员权限控制** - 前后端双重验证，非管理员无法访问管理功能

## 安装

### 基础安装（推荐）

仅安装核心依赖，适合大多数用户：

```bash
pip install pyfileserv
```

**核心依赖**: 仅需 `bcrypt`（密码加密），其他功能均使用 Python 标准库。

### 完整功能安装

如果需要所有高级功能：

```bash
pip install pyfileserv[full]
```

### 按需安装可选功能

根据需求选择安装：

```bash
# YAML 配置文件支持
pip install pyfileserv[yaml]

# PostgreSQL 数据库支持
pip install pyfileserv[postgres]

# Redis 会话存储支持
pip install pyfileserv[redis]

# Markdown 文件预览支持
pip install pyfileserv[markdown]

# Office 文档预览支持（Word/Excel/PPT）
pip install pyfileserv[office]

# SSL 证书生成工具
pip install pyfileserv[cert]

# 组合安装多个功能
pip install pyfileserv[yaml,postgres,redis]
```

或使用 pipx 安装（推荐）：

```bash
pipx install pyfileserv
```

## 使用方法

### 1. 创建用户

```bash
pyfileserv user create
# 或指定用户名
pyfileserv user create -u admin
```

### 2. 启动服务器

```bash
pyfileserv
# 或指定端口
pyfileserv -p 9000
```

### 命令行参数

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `-p, --port` | 服务器端口 | 8000 |
| `-d, --directory` | 文件服务目录 | 当前目录 |
| `-c, --config-dir` | 配置文件目录 | 脚本目录 |
| `-f, --config-file` | 配置文件路径 | - |
| `-s, --static-dir` | 静态文件目录 | 脚本目录 |
| `--ssl-cert` | SSL 证书文件路径（启用 HTTPS） | - |
| `--ssl-key` | SSL 私钥文件路径（启用 HTTPS） | - |

### 配置文件

pyfileserv 支持 YAML 格式的配置文件，配置优先级：
**命令行参数 > 配置文件 > 环境变量 > 默认值**

#### 生成默认配置文件

```bash
# 生成默认配置文件 config.yml
pyfileserv config init

# 指定输出路径
pyfileserv config init -o myconfig.yml
```

#### 配置文件示例

```yaml
# pyfileserv 配置文件

# 服务器配置
server:
  port: 8000
  host: ""

# 路径配置
paths:
  serve_dir: null
  static_dir: null
  users_file: "users.json"

# SSL/HTTPS 配置
ssl:
  cert_file: null
  key_file: null

# 数据库配置
database:
  # 存储类型: json (文件) 或 postgres
  type: "json"

  # PostgreSQL 配置（仅 type=postgres 时使用）
  host: "localhost"
  port: 5432
  database: "pyfileserv"
  username: null
  password: null

  # 连接池配置
  pool_size: 5
  max_overflow: 10

# 会话配置
session:
  # 会话超时时间（秒），默认 1 小时
  timeout: 3600
  # 会话存储方式: memory (内存) 或 redis
  storage: "memory"

# Redis 配置（仅当 session.storage='redis' 时使用）
redis:
  enabled: true
  host: "localhost"
  port: 6379
  db: 0
  password: null
  key_prefix: "pyfileserv:session:"

# 安全配置
security:
  # bcrypt 加密轮数
  bcrypt_rounds: 12
  # 登录保护：最大失败尝试次数
  login_max_attempts: 5
  # 登录保护：锁定时长（秒），默认 15 分钟
  login_lockout_duration: 900
```

#### 使用配置文件

```bash
# 使用当前目录的 config.yml
pyfileserv

# 指定配置文件路径
pyfileserv -f /path/to/config.yml

# 指定配置文件目录
pyfileserv -c /etc/pyfileserv
```

### 数据库配置

pyfileserv 支持两种用户存储方式：JSON 文件（默认）和 PostgreSQL 数据库。

#### 使用 PostgreSQL

1. 安装依赖：
```bash
pip install psycopg2-binary
# 或安装完整功能包
pip install pyfileserv[postgres]
```

2. 创建数据库和用户：

使用 postgres 超级用户登录：
```bash
sudo -u postgres psql
```

或在 Windows 上：
```bash
psql -U postgres
```

然后执行以下 SQL 命令：
```sql
-- 创建数据库
CREATE DATABASE pyfileserv;

-- 创建用户（请修改密码）
CREATE USER pyfileserv WITH PASSWORD 'your_secure_password';

-- 授权
GRANT ALL PRIVILEGES ON DATABASE pyfileserv TO pyfileserv;

-- 连接到新数据库
\c pyfileserv

-- 授权 schema 权限（PostgreSQL 15+ 需要）
GRANT ALL ON SCHEMA public TO pyfileserv;

-- 退出
\q
```

3. 修改配置文件：
```yaml
database:
  type: "postgres"
  host: "localhost"
  port: 5432
  database: "pyfileserv"
  username: "your_user"
  password: "your_password"
```

4. 表会在首次启动时自动创建。

#### 用户管理命令与数据库

所有用户管理命令（`user create/list/delete/passwd`）都支持通过配置文件使用数据库：

```bash
# 使用配置文件管理数据库用户
pyfileserv -f config.yml user create -u admin
pyfileserv -f config.yml user list
```

### Redis 会话存储配置

pyfileserv 支持将会话数据存储到 Redis，以实现多实例共享会话状态。

#### 使用 Redis 存储会话

1. 安装依赖：
```bash
pip install redis
# 或安装完整功能包
pip install pyfileserv[full]
```

2. 确保 Redis 服务器正在运行：
```bash
# Linux
sudo systemctl start redis

# Windows (如果使用 WSL)
wsl sudo service redis-server start

# macOS
brew services start redis
```

3. 修改配置文件：
```yaml
session:
  timeout: 3600
  storage: "redis"  # 改为 redis

redis:
  enabled: true
  host: "localhost"
  port: 6379
  db: 0
  password: null  # 如果 Redis 设置了密码，在此填写
  key_prefix: "pyfileserv:session:"  # 键前缀，用于隔离不同应用
```

4. 重启服务器即可生效。

#### Redis 配置说明

| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| `enabled` | 是否启用 Redis | `true` |
| `host` | Redis 服务器地址 | `localhost` |
| `port` | Redis 端口 | `6379` |
| `db` | Redis 数据库编号 | `0` |
| `password` | Redis 密码（可选） | `null` |
| `key_prefix` | 键前缀 | `pyfileserv:session:` |

#### 环境变量配置

也可以通过环境变量配置 Redis：

```bash
export PYFILESERV_SESSION_STORAGE=redis
export PYFILESERV_REDIS_ENABLED=true
export PYFILESERV_REDIS_HOST=localhost
export PYFILESERV_REDIS_PORT=6379
export PYFILESERV_REDIS_DB=0
export PYFILESERV_REDIS_PASSWORD=your_redis_password
export PYFILESERV_REDIS_KEY_PREFIX="pyfileserv:session:"
```

#### 使用场景

- **单实例部署**：使用默认的内存存储即可，性能更好
- **多实例/负载均衡**：使用 Redis 存储，实现会话共享
- **容器化部署**：推荐使用 Redis，避免容器重启后会话丢失

### 登录保护配置

pyfileserv 内置登录失败锁定机制，防止暴力破解攻击。

#### 配置说明

```yaml
security:
  # 最大失败尝试次数
  login_max_attempts: 5
  # 锁定时长（秒），900秒 = 15分钟
  login_lockout_duration: 900
```

#### 环境变量配置

```bash
export PYFILESERV_LOGIN_MAX_ATTEMPTS=5
export PYFILESERV_LOGIN_LOCKOUT_DURATION=900
```

#### 推荐配置

| 场景 | 最大尝试次数 | 锁定时长 |
|------|------------|----------|
| 普通系统 | 5次 | 15分钟 |
| 高安全系统 | 3次 | 30分钟 |
| 内部系统 | 10次 | 5分钟 |

#### 工作原理

1. 用户登录失败时，记录失败次数
2. 达到最大尝试次数后，账户被临时锁定
3. 锁定期内无法登录，显示剩余锁定时间
4. 锁定过期后自动解锁
5. 成功登录后清除失败记录

注意：即使用户名不存在也会记录尝试，防止用户名枚举攻击。

### 用户管理命令

```bash
# 创建用户（会询问是否为管理员）
pyfileserv user create [-u 用户名]

# 列出用户（显示 [管理员] 标记）
pyfileserv user list

# 删除用户
pyfileserv user delete [-u 用户名]

# 修改密码
pyfileserv user passwd [-u 用户名]

# 设置/取消管理员状态
pyfileserv user admin [-u 用户名]
```

#### 管理员权限说明

- **管理员用户**：可以访问 `/admin` 页面，管理所有用户
- **普通用户**：只能浏览和下载文件，无法访问管理功能
- **创建管理员**：使用 `user create` 时回答 "yes"，或创建后用 `user admin` 设置
- **权限验证**：前后端双重检查，非管理员访问管理 API 返回 403 Forbidden

### HTTPS 配置

#### 生成自签名证书

```bash
# 生成默认证书（cert.pem 和 key.pem）
pyfileserv cert generate

# 自定义证书路径和参数
pyfileserv cert generate --cert mycert.pem --key mykey.pem --cn mydomain.com --days 365
```

证书生成需要 `cryptography` 库，可通过以下命令安装：
```bash
pip install cryptography
```

#### 启动 HTTPS 服务器

```bash
# 使用自签名证书启动
pyfileserv --ssl-cert cert.pem --ssl-key key.pem

# 同时指定端口
pyfileserv --ssl-cert cert.pem --ssl-key key.pem -p 8443
```

#### 使用正规 CA 证书

如果你有正规 CA 签发的证书，直接使用 `--ssl-cert` 和 `--ssl-key` 参数指定证书和私钥文件路径即可。

### 示例

```bash
# 在端口 9000 启动服务器
pyfileserv -p 9000

# 指定文件服务目录
pyfileserv -d /path/to/files

# 自定义配置和静态文件目录
pyfileserv -c /etc/pyfileserv -s /var/www/files
```

## 访问

- HTTP 模式：访问 `http://localhost:8000` 或局域网 IP 地址
- HTTPS 模式：访问 `https://localhost:8000` 或局域网 IP 地址

注意：使用自签名证书时，浏览器会提示安全警告，这是正常的，可以点击"继续访问"。

## 项目结构

```
pyfileserv/
├── .github/
│   └── workflows/
│       └── python-publish.yml  # PyPI 自动发布工作流
├── src/file_server/
│   ├── __init__.py          # 包入口
│   ├── __main__.py          # CLI 入口
│   ├── config.py            # 配置模块
│   ├── auth.py              # 认证模块
│   ├── share.py             # 分享业务逻辑层
│   ├── share_store.py       # 分享 JSON 存储后端
│   ├── db.py                # PostgreSQL 数据库模块（用户+分享）
│   ├── templates.py         # HTML 模板
│   ├── admin_templates.py   # 管理员页面模板
│   ├── handlers.py          # HTTP 处理器
│   ├── server.py            # 服务器启动
│   ├── cli.py               # 命令行工具
│   └── static/
│       ├── logo.svg         # Logo 图标
│       └── favicon.svg      # Favicon 图标
├── tests/
│   ├── __init__.py          # 测试包入口
│   ├── conftest.py          # pytest 配置
│   ├── test_auth.py         # 认证模块测试
│   ├── test_config.py       # 配置模块测试
│   ├── test_handlers.py     # 处理器测试
│   ├── test_share.py        # 分享业务逻辑测试
│   ├── test_share_store.py  # 分享 JSON 存储测试
│   └── test_share_db.py     # 分享数据库存储测试
├── CHANGELOG.md         # 变更日志
├── pyproject.toml       # 项目配置
├── release.py           # 发布脚本
└── README.md            # 文档
```

## 开发与发布

### 安装开发依赖

```bash
pip install -e ".[test]"
```

### 运行测试

```bash
pytest tests/ -v
```

### 构建

```bash
pip install build
python -m build
```

### 发布到 TestPyPI

```bash
pip install twine
python -m twine upload --repository testpypi dist/*
```

### 发布到 PyPI

```bash
python -m twine upload dist/*
```

## 要求

- Python >= 3.7

### 核心依赖

- **bcrypt >= 4.0.0** - 密码加密（唯一必需的第三方库）

### 可选依赖

| 功能 | 依赖包 | 说明 |
|------|--------|------|
| YAML 配置 | `pyyaml>=6.0` | 使用 YAML 格式配置文件 |
| PostgreSQL | `psycopg2-binary>=2.9.0` | 将用户数据存储到 PostgreSQL |
| Redis | `redis>=4.0.0` | 使用 Redis 存储会话数据 |
| Markdown | `markdown>=3.4.0` | Markdown 文件预览渲染 |
| Office | `python-docx`、`openpyxl`、`python-pptx` | Word/Excel/PPT 文档预览 |
| SSL 证书 | `cryptography>=41.0.0` | 生成自签名 SSL 证书 |

### 安装示例

```bash
# 基础安装（仅核心功能）
pip install pyfileserv

# 安装所有可选功能
pip install pyfileserv[full]

# 按需安装
pip install pyfileserv[yaml,postgres]  # YAML + PostgreSQL
pip install pyfileserv[redis,markdown]  # Redis + Markdown
```

## 许可证

MIT License
