feat: 添加IP白名单/黑名单功能 - 支持单IP、CIDR、IP范围
Este cometimento está contido em:
@@ -53,6 +53,16 @@ type OnlineUser struct {
|
||||
CurrentDir string `json:"current_dir"`
|
||||
}
|
||||
|
||||
// IPAccessRule IP访问规则
|
||||
type IPAccessRule struct {
|
||||
ID int64 `json:"id"`
|
||||
IP string `json:"ip"` // 支持单IP (192.168.1.1)、CIDR (192.168.1.0/24)、IP范围 (192.168.1.1-192.168.1.100)
|
||||
Type string `json:"type"` // "whitelist" 或 "blacklist"
|
||||
Note string `json:"note"` // 备注说明
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// Open 打开数据库
|
||||
func Open(dbPath string) (*DB, error) {
|
||||
dir := filepath.Dir(dbPath)
|
||||
@@ -118,6 +128,17 @@ func (db *DB) initTables() error {
|
||||
total_download_bytes INTEGER DEFAULT 0,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS ip_access_rules (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ip TEXT NOT NULL,
|
||||
type TEXT NOT NULL DEFAULT 'blacklist',
|
||||
note TEXT DEFAULT '',
|
||||
enabled INTEGER DEFAULT 1,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_ip_rules_type ON ip_access_rules(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_ip_rules_enabled ON ip_access_rules(enabled);
|
||||
`
|
||||
|
||||
_, err := db.Exec(schema)
|
||||
@@ -328,3 +349,84 @@ func (db *DB) CleanOldLogs(days int) (int64, error) {
|
||||
}
|
||||
return result.RowsAffected()
|
||||
}
|
||||
|
||||
// --- IP访问规则 CRUD ---
|
||||
|
||||
// CreateIPRule 创建IP规则
|
||||
func (db *DB) CreateIPRule(rule *IPAccessRule) error {
|
||||
now := time.Now().Format("2006-01-02 15:04:05")
|
||||
result, err := db.Exec(`
|
||||
INSERT INTO ip_access_rules (ip, type, note, enabled, created_at)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
rule.IP, rule.Type, rule.Note, rule.Enabled, now)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建IP规则失败: %w", err)
|
||||
}
|
||||
rule.ID, _ = result.LastInsertId()
|
||||
rule.CreatedAt = now
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListIPRules 列出所有IP规则
|
||||
func (db *DB) ListIPRules(ruleType string) ([]IPAccessRule, error) {
|
||||
var rows *sql.Rows
|
||||
var err error
|
||||
if ruleType != "" {
|
||||
rows, err = db.Query(`SELECT id, ip, type, note, enabled, created_at
|
||||
FROM ip_access_rules WHERE type=? ORDER BY id`, ruleType)
|
||||
} else {
|
||||
rows, err = db.Query(`SELECT id, ip, type, note, enabled, created_at
|
||||
FROM ip_access_rules ORDER BY id`)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rules []IPAccessRule
|
||||
for rows.Next() {
|
||||
var rule IPAccessRule
|
||||
var enabled int
|
||||
if err := rows.Scan(&rule.ID, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rule.Enabled = enabled == 1
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
// DeleteIPRule 删除IP规则
|
||||
func (db *DB) DeleteIPRule(id int64) error {
|
||||
_, err := db.Exec(`DELETE FROM ip_access_rules WHERE id=?`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateIPRule 更新IP规则
|
||||
func (db *DB) UpdateIPRule(rule *IPAccessRule) error {
|
||||
_, err := db.Exec(`UPDATE ip_access_rules SET ip=?, type=?, note=?, enabled=? WHERE id=?`,
|
||||
rule.IP, rule.Type, rule.Note, rule.Enabled, rule.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetEnabledIPRules 获取所有启用的IP规则
|
||||
func (db *DB) GetEnabledIPRules() ([]IPAccessRule, error) {
|
||||
rows, err := db.Query(`SELECT id, ip, type, note, enabled, created_at
|
||||
FROM ip_access_rules WHERE enabled=1 ORDER BY id`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rules []IPAccessRule
|
||||
for rows.Next() {
|
||||
var rule IPAccessRule
|
||||
var enabled int
|
||||
if err := rows.Scan(&rule.ID, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rule.Enabled = enabled == 1
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
Criar uma nova questão referindo esta
Bloquear um utilizador