|
@@ -5,6 +5,7 @@ import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"os"
|
|
"os"
|
|
|
"path/filepath"
|
|
"path/filepath"
|
|
|
|
|
+ "strings"
|
|
|
"time"
|
|
"time"
|
|
|
|
|
|
|
|
_ "modernc.org/sqlite"
|
|
_ "modernc.org/sqlite"
|
|
@@ -56,9 +57,10 @@ type OnlineUser struct {
|
|
|
// IPAccessRule IP访问规则
|
|
// IPAccessRule IP访问规则
|
|
|
type IPAccessRule struct {
|
|
type IPAccessRule struct {
|
|
|
ID int64 `json:"id"`
|
|
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"` // 备注说明
|
|
|
|
|
|
|
+ Username string `json:"username"` // 为空表示全局规则,有值表示用户专属规则
|
|
|
|
|
+ IP string `json:"ip"` // 支持单IP、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"`
|
|
Enabled bool `json:"enabled"`
|
|
|
CreatedAt string `json:"created_at"`
|
|
CreatedAt string `json:"created_at"`
|
|
|
}
|
|
}
|
|
@@ -130,6 +132,7 @@ func (db *DB) initTables() error {
|
|
|
);
|
|
);
|
|
|
CREATE TABLE IF NOT EXISTS ip_access_rules (
|
|
CREATE TABLE IF NOT EXISTS ip_access_rules (
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
|
|
+ username TEXT DEFAULT '',
|
|
|
ip TEXT NOT NULL,
|
|
ip TEXT NOT NULL,
|
|
|
type TEXT NOT NULL DEFAULT 'blacklist',
|
|
type TEXT NOT NULL DEFAULT 'blacklist',
|
|
|
note TEXT DEFAULT '',
|
|
note TEXT DEFAULT '',
|
|
@@ -139,6 +142,7 @@ func (db *DB) initTables() error {
|
|
|
|
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_ip_rules_type ON ip_access_rules(type);
|
|
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);
|
|
CREATE INDEX IF NOT EXISTS idx_ip_rules_enabled ON ip_access_rules(enabled);
|
|
|
|
|
+ CREATE INDEX IF NOT EXISTS idx_ip_rules_username ON ip_access_rules(username);
|
|
|
`
|
|
`
|
|
|
|
|
|
|
|
_, err := db.Exec(schema)
|
|
_, err := db.Exec(schema)
|
|
@@ -356,9 +360,9 @@ func (db *DB) CleanOldLogs(days int) (int64, error) {
|
|
|
func (db *DB) CreateIPRule(rule *IPAccessRule) error {
|
|
func (db *DB) CreateIPRule(rule *IPAccessRule) error {
|
|
|
now := time.Now().Format("2006-01-02 15:04:05")
|
|
now := time.Now().Format("2006-01-02 15:04:05")
|
|
|
result, err := db.Exec(`
|
|
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)
|
|
|
|
|
|
|
+ INSERT INTO ip_access_rules (username, ip, type, note, enabled, created_at)
|
|
|
|
|
+ VALUES (?, ?, ?, ?, ?, ?)`,
|
|
|
|
|
+ rule.Username, rule.IP, rule.Type, rule.Note, rule.Enabled, now)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return fmt.Errorf("创建IP规则失败: %w", err)
|
|
return fmt.Errorf("创建IP规则失败: %w", err)
|
|
|
}
|
|
}
|
|
@@ -367,17 +371,32 @@ func (db *DB) CreateIPRule(rule *IPAccessRule) error {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// ListIPRules 列出所有IP规则
|
|
|
|
|
-func (db *DB) ListIPRules(ruleType string) ([]IPAccessRule, error) {
|
|
|
|
|
- var rows *sql.Rows
|
|
|
|
|
- var err error
|
|
|
|
|
|
|
+// ListIPRules 列出IP规则,ruleType和username为空时列出全部
|
|
|
|
|
+func (db *DB) ListIPRules(ruleType, username string) ([]IPAccessRule, error) {
|
|
|
|
|
+ query := `SELECT id, username, ip, type, note, enabled, created_at FROM ip_access_rules`
|
|
|
|
|
+ var conditions []string
|
|
|
|
|
+ var args []interface{}
|
|
|
|
|
+
|
|
|
if ruleType != "" {
|
|
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`)
|
|
|
|
|
|
|
+ conditions = append(conditions, "type=?")
|
|
|
|
|
+ args = append(args, ruleType)
|
|
|
}
|
|
}
|
|
|
|
|
+ if username != "" {
|
|
|
|
|
+ if username == "__empty__" {
|
|
|
|
|
+ conditions = append(conditions, "username='')")
|
|
|
|
|
+ } else if username == "__has__" {
|
|
|
|
|
+ conditions = append(conditions, "username!='')")
|
|
|
|
|
+ } else {
|
|
|
|
|
+ conditions = append(conditions, "username=?")
|
|
|
|
|
+ args = append(args, username)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if len(conditions) > 0 {
|
|
|
|
|
+ query += " WHERE " + strings.Join(conditions, " AND ")
|
|
|
|
|
+ }
|
|
|
|
|
+ query += " ORDER BY id"
|
|
|
|
|
+
|
|
|
|
|
+ rows, err := db.Query(query, args...)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -387,7 +406,7 @@ func (db *DB) ListIPRules(ruleType string) ([]IPAccessRule, error) {
|
|
|
for rows.Next() {
|
|
for rows.Next() {
|
|
|
var rule IPAccessRule
|
|
var rule IPAccessRule
|
|
|
var enabled int
|
|
var enabled int
|
|
|
- if err := rows.Scan(&rule.ID, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
|
|
|
|
|
|
+ if err := rows.Scan(&rule.ID, &rule.Username, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
|
rule.Enabled = enabled == 1
|
|
rule.Enabled = enabled == 1
|
|
@@ -404,15 +423,15 @@ func (db *DB) DeleteIPRule(id int64) error {
|
|
|
|
|
|
|
|
// UpdateIPRule 更新IP规则
|
|
// UpdateIPRule 更新IP规则
|
|
|
func (db *DB) UpdateIPRule(rule *IPAccessRule) error {
|
|
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)
|
|
|
|
|
|
|
+ _, err := db.Exec(`UPDATE ip_access_rules SET username=?, ip=?, type=?, note=?, enabled=? WHERE id=?`,
|
|
|
|
|
+ rule.Username, rule.IP, rule.Type, rule.Note, rule.Enabled, rule.ID)
|
|
|
return err
|
|
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`)
|
|
|
|
|
|
|
+// GetEnabledIPRules 获取所有启用的IP规则(全局+指定用户)
|
|
|
|
|
+func (db *DB) GetEnabledIPRules(username string) ([]IPAccessRule, error) {
|
|
|
|
|
+ rows, err := db.Query(`SELECT id, username, ip, type, note, enabled, created_at
|
|
|
|
|
+ FROM ip_access_rules WHERE enabled=1 AND (username='' OR username=?) ORDER BY id`, username)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
@@ -422,7 +441,7 @@ func (db *DB) GetEnabledIPRules() ([]IPAccessRule, error) {
|
|
|
for rows.Next() {
|
|
for rows.Next() {
|
|
|
var rule IPAccessRule
|
|
var rule IPAccessRule
|
|
|
var enabled int
|
|
var enabled int
|
|
|
- if err := rows.Scan(&rule.ID, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
|
|
|
|
|
|
+ if err := rows.Scan(&rule.ID, &rule.Username, &rule.IP, &rule.Type, &rule.Note, &enabled, &rule.CreatedAt); err != nil {
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
|
rule.Enabled = enabled == 1
|
|
rule.Enabled = enabled == 1
|