2020-11-07 19:40:24 +08:00
package models
import (
2022-03-27 12:22:47 +08:00
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
2020-11-07 19:40:24 +08:00
"github.com/TeaOSLab/EdgeAPI/internal/errors"
2022-02-14 08:52:27 +08:00
"github.com/TeaOSLab/EdgeAPI/internal/goman"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
2024-04-06 10:21:52 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
2021-08-08 15:47:48 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
2021-11-17 19:51:00 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
2020-11-07 19:40:24 +08:00
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
2021-01-17 16:48:00 +08:00
"github.com/iwind/TeaGo/lists"
2020-11-07 19:40:24 +08:00
"github.com/iwind/TeaGo/types"
2023-07-25 12:26:12 +08:00
"net"
2024-04-13 16:48:24 +08:00
"strings"
2020-11-09 10:44:00 +08:00
"time"
2020-11-07 19:40:24 +08:00
)
const (
IPItemStateEnabled = 1 // 已启用
IPItemStateDisabled = 0 // 已禁用
)
2022-02-14 08:52:27 +08:00
func init ( ) {
dbs . OnReadyDone ( func ( ) {
goman . New ( func ( ) {
var ticker = time . NewTicker ( 1 * time . Minute )
for range ticker . C {
err := SharedIPItemDAO . CleanExpiredIPItems ( nil )
if err != nil {
remotelogs . Error ( "IPItemDAO" , "clean expired ip items failed: " + err . Error ( ) )
}
}
} )
} )
}
2021-02-02 15:25:40 +08:00
type IPItemType = string
const (
IPItemTypeIPv4 IPItemType = "ipv4" // IPv4
IPItemTypeIPv6 IPItemType = "ipv6" // IPv6
IPItemTypeAll IPItemType = "all" // 所有IP
)
2020-11-07 19:40:24 +08:00
type IPItemDAO dbs . DAO
func NewIPItemDAO ( ) * IPItemDAO {
return dbs . NewDAO ( & IPItemDAO {
DAOObject : dbs . DAOObject {
DB : Tea . Env ,
Table : "edgeIPItems" ,
Model : new ( IPItem ) ,
PkName : "id" ,
} ,
} ) . ( * IPItemDAO )
}
var SharedIPItemDAO * IPItemDAO
func init ( ) {
dbs . OnReady ( func ( ) {
SharedIPItemDAO = NewIPItemDAO ( )
} )
}
2021-06-23 13:12:54 +08:00
// EnableIPItem 启用条目
2021-01-01 23:31:30 +08:00
func ( this * IPItemDAO ) EnableIPItem ( tx * dbs . Tx , id int64 ) error {
_ , err := this . Query ( tx ) .
2020-11-07 19:40:24 +08:00
Pk ( id ) .
Set ( "state" , IPItemStateEnabled ) .
Update ( )
return err
}
2021-06-23 13:12:54 +08:00
// DisableIPItem 禁用条目
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) DisableIPItem ( tx * dbs . Tx , id int64 , sourceUserId int64 ) error {
2021-01-01 23:31:30 +08:00
version , err := SharedIPListDAO . IncreaseVersion ( tx )
2020-11-10 09:22:10 +08:00
if err != nil {
return err
}
2023-04-03 10:02:17 +08:00
var query = this . Query ( tx )
2023-04-25 11:28:04 +08:00
// 检查权限
2023-04-03 10:02:17 +08:00
if sourceUserId > 0 {
2023-04-25 11:28:04 +08:00
query . Where ( "(sourceUserId=:sourceUserId OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE userId=:sourceUserId AND state=1))" )
query . Param ( "sourceUserId" , sourceUserId )
2023-04-03 10:02:17 +08:00
}
_ , err = query .
2020-11-07 19:40:24 +08:00
Pk ( id ) .
Set ( "state" , IPItemStateDisabled ) .
2020-11-10 09:22:10 +08:00
Set ( "version" , version ) .
2020-11-07 19:40:24 +08:00
Update ( )
2021-02-02 15:25:40 +08:00
if err != nil {
return err
}
return this . NotifyUpdate ( tx , id )
2020-11-07 19:40:24 +08:00
}
2022-05-10 15:11:48 +08:00
// DisableIPItemsWithIP 禁用某个IP相关条目
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) DisableIPItemsWithIP ( tx * dbs . Tx , ipFrom string , ipTo string , sourceUserId int64 , listId int64 ) error {
2022-05-10 15:11:48 +08:00
if len ( ipFrom ) == 0 {
return errors . New ( "invalid 'ipFrom'" )
}
var query = this . Query ( tx ) .
Result ( "id" , "listId" ) .
Attr ( "ipFrom" , ipFrom ) .
Attr ( "ipTo" , ipTo ) .
State ( IPItemStateEnabled )
if listId > 0 {
query . Attr ( "listId" , listId )
}
2023-04-03 10:02:17 +08:00
if sourceUserId > 0 {
query . Attr ( "sourceUserId" , sourceUserId )
}
2022-05-10 15:11:48 +08:00
ones , err := query . FindAll ( )
if err != nil {
return err
}
var itemIds = [ ] int64 { }
for _ , one := range ones {
var item = one . ( * IPItem )
var itemId = int64 ( item . Id )
itemIds = append ( itemIds , itemId )
}
for _ , itemId := range itemIds {
version , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
_ , err = this . Query ( tx ) .
Pk ( itemId ) .
Set ( "state" , IPItemStateDisabled ) .
Set ( "version" , version ) .
Update ( )
if err != nil {
return err
}
}
if len ( itemIds ) > 0 {
return this . NotifyUpdate ( tx , itemIds [ len ( itemIds ) - 1 ] )
}
return nil
}
2024-04-13 16:48:24 +08:00
// DisableIPItemsWithIPValue 禁用某个IP相关条目
func ( this * IPItemDAO ) DisableIPItemsWithIPValue ( tx * dbs . Tx , value string , sourceUserId int64 , listId int64 ) error {
if len ( value ) == 0 {
return errors . New ( "invalid 'value'" )
}
var query = this . Query ( tx ) .
Result ( "id" , "listId" ) .
Attr ( "value" , value ) .
State ( IPItemStateEnabled )
if listId > 0 {
query . Attr ( "listId" , listId )
}
if sourceUserId > 0 {
query . Attr ( "sourceUserId" , sourceUserId )
}
ones , err := query . FindAll ( )
if err != nil {
return err
}
var itemIds = [ ] int64 { }
for _ , one := range ones {
var item = one . ( * IPItem )
var itemId = int64 ( item . Id )
itemIds = append ( itemIds , itemId )
}
for _ , itemId := range itemIds {
version , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
_ , err = this . Query ( tx ) .
Pk ( itemId ) .
Set ( "state" , IPItemStateDisabled ) .
Set ( "version" , version ) .
Update ( )
if err != nil {
return err
}
}
if len ( itemIds ) > 0 {
return this . NotifyUpdate ( tx , itemIds [ len ( itemIds ) - 1 ] )
}
return nil
}
2021-11-16 17:50:52 +08:00
// DisableIPItemsWithListId 禁用某个IP名单内的所有IP
func ( this * IPItemDAO ) DisableIPItemsWithListId ( tx * dbs . Tx , listId int64 ) error {
2021-11-17 16:14:55 +08:00
for {
ones , err := this . Query ( tx ) .
ResultPk ( ) .
Attr ( "listId" , listId ) .
State ( IPItemStateEnabled ) .
Limit ( 1000 ) .
FindAll ( )
if err != nil {
return err
}
if len ( ones ) == 0 {
break
}
for _ , one := range ones {
var itemId = one . ( * IPItem ) . Id
version , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
err = this . Query ( tx ) .
Pk ( itemId ) .
State ( IPItemStateEnabled ) .
Set ( "version" , version ) .
Set ( "state" , IPItemStateDisabled ) .
UpdateQuickly ( )
if err != nil {
return err
}
}
2021-11-16 17:50:52 +08:00
}
2021-11-17 16:14:55 +08:00
return nil
2021-11-16 17:50:52 +08:00
}
2021-06-23 13:12:54 +08:00
// FindEnabledIPItem 查找启用中的条目
2021-01-01 23:31:30 +08:00
func ( this * IPItemDAO ) FindEnabledIPItem ( tx * dbs . Tx , id int64 ) ( * IPItem , error ) {
result , err := this . Query ( tx ) .
2020-11-07 19:40:24 +08:00
Pk ( id ) .
Attr ( "state" , IPItemStateEnabled ) .
Find ( )
if result == nil {
return nil , err
}
return result . ( * IPItem ) , err
}
2021-12-10 11:12:34 +08:00
// DeleteOldItem 根据IP删除以前的旧记录
func ( this * IPItemDAO ) DeleteOldItem ( tx * dbs . Tx , listId int64 , ipFrom string , ipTo string ) error {
2022-06-22 18:59:27 +08:00
ones , err := this . Query ( tx ) .
ResultPk ( ) .
2021-12-10 11:12:34 +08:00
UseIndex ( "ipFrom" ) .
2021-07-18 15:52:34 +08:00
Attr ( "listId" , listId ) .
Attr ( "ipFrom" , ipFrom ) .
Attr ( "ipTo" , ipTo ) .
2023-04-01 20:48:47 +08:00
Attr ( "state" , IPItemStateEnabled ) .
2022-06-22 18:59:27 +08:00
FindAll ( )
if err != nil {
return err
}
2023-04-01 20:48:47 +08:00
2022-06-22 18:59:27 +08:00
for _ , one := range ones {
var itemId = int64 ( one . ( * IPItem ) . Id )
version , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
err = this . Query ( tx ) .
Pk ( itemId ) .
Set ( "version" , version ) .
Set ( "state" , IPItemStateDisabled ) .
UpdateQuickly ( )
if err != nil {
return err
}
}
return nil
2021-07-18 15:52:34 +08:00
}
2024-04-13 16:48:24 +08:00
// DeleteOldItemWithValue 根据IP删除以前的旧记录
func ( this * IPItemDAO ) DeleteOldItemWithValue ( tx * dbs . Tx , listId int64 , value string ) error {
if len ( value ) == 0 {
return nil
}
ones , err := this . Query ( tx ) .
ResultPk ( ) .
UseIndex ( "ipFrom" ) .
Attr ( "listId" , listId ) .
Attr ( "value" , value ) .
Attr ( "state" , IPItemStateEnabled ) .
FindAll ( )
if err != nil {
return err
}
for _ , one := range ones {
var itemId = int64 ( one . ( * IPItem ) . Id )
version , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
err = this . Query ( tx ) .
Pk ( itemId ) .
Set ( "version" , version ) .
Set ( "state" , IPItemStateDisabled ) .
UpdateQuickly ( )
if err != nil {
return err
}
}
return nil
}
2021-06-23 13:12:54 +08:00
// CreateIPItem 创建IP
2021-11-16 16:10:48 +08:00
func ( this * IPItemDAO ) CreateIPItem ( tx * dbs . Tx ,
listId int64 ,
2024-04-13 16:48:24 +08:00
value string ,
2021-11-16 16:10:48 +08:00
ipFrom string ,
ipTo string ,
expiredAt int64 ,
reason string ,
itemType IPItemType ,
eventLevel string ,
nodeId int64 ,
serverId int64 ,
sourceNodeId int64 ,
sourceServerId int64 ,
sourceHTTPFirewallPolicyId int64 ,
sourceHTTPFirewallRuleGroupId int64 ,
2023-03-31 21:42:15 +08:00
sourceHTTPFirewallRuleSetId int64 ,
shouldNotify bool ) ( int64 , error ) {
2024-04-13 16:48:24 +08:00
// generate 'itemType'
if itemType != IPItemTypeAll && len ( ipFrom ) > 0 {
if iputils . IsIPv4 ( ipFrom ) {
itemType = IPItemTypeIPv4
} else if iputils . IsIPv6 ( ipFrom ) {
itemType = IPItemTypeIPv6
}
}
2021-01-01 23:31:30 +08:00
version , err := SharedIPListDAO . IncreaseVersion ( tx )
2020-11-07 19:40:24 +08:00
if err != nil {
return 0 , err
}
2022-01-08 16:48:17 +08:00
var op = NewIPItemOperator ( )
2020-11-07 19:40:24 +08:00
op . ListId = listId
2024-04-13 16:48:24 +08:00
op . Value = value
2020-11-07 19:40:24 +08:00
op . IpFrom = ipFrom
op . IpTo = ipTo
2024-04-06 10:21:52 +08:00
2020-11-07 19:40:24 +08:00
op . Reason = reason
2021-02-02 15:25:40 +08:00
op . Type = itemType
2021-02-06 17:38:04 +08:00
op . EventLevel = eventLevel
2020-11-07 19:40:24 +08:00
op . Version = version
if expiredAt < 0 {
expiredAt = 0
}
op . ExpiredAt = expiredAt
2021-11-16 16:10:48 +08:00
op . NodeId = nodeId
op . ServerId = serverId
op . SourceNodeId = sourceNodeId
op . SourceServerId = sourceServerId
op . SourceHTTPFirewallPolicyId = sourceHTTPFirewallPolicyId
op . SourceHTTPFirewallRuleGroupId = sourceHTTPFirewallRuleGroupId
op . SourceHTTPFirewallRuleSetId = sourceHTTPFirewallRuleSetId
2023-03-31 21:42:15 +08:00
// 服务所属用户
if sourceServerId > 0 {
userId , err := SharedServerDAO . FindServerUserId ( tx , sourceServerId )
if err != nil {
return 0 , err
}
op . SourceUserId = userId
}
2022-01-08 16:48:17 +08:00
var autoAdded = listId == firewallconfigs . GlobalListId || sourceNodeId > 0 || sourceServerId > 0 || sourceHTTPFirewallPolicyId > 0
if autoAdded {
op . IsRead = 0
}
2020-11-07 19:40:24 +08:00
op . State = IPItemStateEnabled
2022-06-22 18:59:27 +08:00
op . UpdatedAt = time . Now ( ) . Unix ( )
2021-01-01 23:31:30 +08:00
err = this . Save ( tx , op )
2020-11-07 19:40:24 +08:00
if err != nil {
return 0 , err
}
2021-02-02 15:25:40 +08:00
itemId := types . Int64 ( op . Id )
2022-01-08 15:24:51 +08:00
// 自动加入名单不需要即时更新,防止数量过多而导致性能问题
2022-01-08 16:48:17 +08:00
if autoAdded {
2021-12-12 14:38:57 +08:00
return itemId , nil
}
2023-03-31 21:42:15 +08:00
if shouldNotify {
err = this . NotifyUpdate ( tx , itemId )
if err != nil {
return 0 , err
}
2021-02-02 15:25:40 +08:00
}
return itemId , nil
2020-11-07 19:40:24 +08:00
}
2021-06-23 13:12:54 +08:00
// UpdateIPItem 修改IP
2024-04-13 16:48:24 +08:00
func ( this * IPItemDAO ) UpdateIPItem ( tx * dbs . Tx , itemId int64 , value string , ipFrom string , ipTo string , expiredAt int64 , reason string , itemType IPItemType , eventLevel string ) error {
2020-11-07 19:40:24 +08:00
if itemId <= 0 {
return errors . New ( "invalid itemId" )
}
2024-04-13 16:48:24 +08:00
// generate 'itemType'
if itemType != IPItemTypeAll && len ( ipFrom ) > 0 {
if iputils . IsIPv4 ( ipFrom ) {
itemType = IPItemTypeIPv4
} else if iputils . IsIPv6 ( ipFrom ) {
itemType = IPItemTypeIPv6
}
}
2021-01-01 23:31:30 +08:00
listId , err := this . Query ( tx ) .
2020-11-07 19:40:24 +08:00
Pk ( itemId ) .
Result ( "listId" ) .
FindInt64Col ( 0 )
if err != nil {
return err
}
if listId == 0 {
return errors . New ( "not found" )
}
2021-01-01 23:31:30 +08:00
version , err := SharedIPListDAO . IncreaseVersion ( tx )
2020-11-07 19:40:24 +08:00
if err != nil {
return err
}
2022-07-24 09:56:27 +08:00
var op = NewIPItemOperator ( )
2020-11-07 19:40:24 +08:00
op . Id = itemId
2024-04-13 16:48:24 +08:00
op . Value = value
2020-11-07 19:40:24 +08:00
op . IpFrom = ipFrom
op . IpTo = ipTo
2024-04-06 10:21:52 +08:00
2020-11-07 19:40:24 +08:00
op . Reason = reason
2021-02-02 15:25:40 +08:00
op . Type = itemType
2021-02-06 17:38:04 +08:00
op . EventLevel = eventLevel
2020-11-07 19:40:24 +08:00
if expiredAt < 0 {
expiredAt = 0
}
op . ExpiredAt = expiredAt
op . Version = version
2021-01-01 23:31:30 +08:00
err = this . Save ( tx , op )
2021-02-02 15:25:40 +08:00
if err != nil {
return err
}
return this . NotifyUpdate ( tx , itemId )
2020-11-07 19:40:24 +08:00
}
2021-06-23 13:12:54 +08:00
// CountIPItemsWithListId 计算IP数量
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) CountIPItemsWithListId ( tx * dbs . Tx , listId int64 , sourceUserId int64 , keyword string , ipFrom string , ipTo string , eventLevel string ) ( int64 , error ) {
2021-10-22 12:18:53 +08:00
var query = this . Query ( tx ) .
2020-11-07 19:40:24 +08:00
State ( IPItemStateEnabled ) .
2021-10-22 12:18:53 +08:00
Attr ( "listId" , listId )
2023-04-03 10:02:17 +08:00
if sourceUserId > 0 {
2023-04-25 11:18:09 +08:00
if listId <= 0 || listId == firewallconfigs . GlobalListId {
query . Attr ( "sourceUserId" , sourceUserId )
}
2023-04-03 10:02:17 +08:00
}
2021-10-22 12:18:53 +08:00
if len ( keyword ) > 0 {
query . Where ( "(ipFrom LIKE :keyword OR ipTo LIKE :keyword)" ) .
2022-03-27 12:22:47 +08:00
Param ( "keyword" , dbutils . QuoteLike ( keyword ) )
2021-10-22 12:18:53 +08:00
}
2021-10-26 09:17:33 +08:00
if len ( ipFrom ) > 0 {
query . Attr ( "ipFrom" , ipFrom )
}
if len ( ipTo ) > 0 {
query . Attr ( "ipTo" , ipTo )
}
2022-03-30 09:39:43 +08:00
if len ( eventLevel ) > 0 {
query . Attr ( "eventLevel" , eventLevel )
}
2021-10-22 12:18:53 +08:00
return query . Count ( )
2020-11-07 19:40:24 +08:00
}
2021-06-23 13:12:54 +08:00
// ListIPItemsWithListId 查找IP列表
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) ListIPItemsWithListId ( tx * dbs . Tx , listId int64 , sourceUserId int64 , keyword string , ipFrom string , ipTo string , eventLevel string , offset int64 , size int64 ) ( result [ ] * IPItem , err error ) {
2021-10-22 12:18:53 +08:00
var query = this . Query ( tx ) .
2020-11-07 19:40:24 +08:00
State ( IPItemStateEnabled ) .
2021-10-22 12:18:53 +08:00
Attr ( "listId" , listId )
2023-04-03 10:02:17 +08:00
if sourceUserId > 0 {
2023-04-25 11:18:09 +08:00
if listId <= 0 || listId == firewallconfigs . GlobalListId {
query . Attr ( "sourceUserId" , sourceUserId )
}
2023-04-03 10:02:17 +08:00
}
2021-10-22 12:18:53 +08:00
if len ( keyword ) > 0 {
query . Where ( "(ipFrom LIKE :keyword OR ipTo LIKE :keyword)" ) .
2022-03-27 12:22:47 +08:00
Param ( "keyword" , dbutils . QuoteLike ( keyword ) )
2021-10-22 12:18:53 +08:00
}
2021-10-26 09:17:33 +08:00
if len ( ipFrom ) > 0 {
query . Attr ( "ipFrom" , ipFrom )
}
if len ( ipTo ) > 0 {
query . Attr ( "ipTo" , ipTo )
}
2022-03-30 09:39:43 +08:00
if len ( eventLevel ) > 0 {
query . Attr ( "eventLevel" , eventLevel )
}
2021-10-22 12:18:53 +08:00
_ , err = query .
2020-11-07 19:40:24 +08:00
DescPk ( ) .
Slice ( & result ) .
Offset ( offset ) .
Limit ( size ) .
FindAll ( )
return
}
2020-11-09 10:44:00 +08:00
2021-06-23 13:12:54 +08:00
// ListIPItemsAfterVersion 根据版本号查找IP列表
2021-01-01 23:31:30 +08:00
func ( this * IPItemDAO ) ListIPItemsAfterVersion ( tx * dbs . Tx , version int64 , size int64 ) ( result [ ] * IPItem , err error ) {
_ , err = this . Query ( tx ) .
2023-04-23 09:44:06 +08:00
UseIndex ( "version" ) .
2020-11-09 10:44:00 +08:00
// 这里不要设置状态参数,因为我们要知道哪些是删除的
Gt ( "version" , version ) .
Asc ( "version" ) .
Limit ( size ) .
Slice ( & result ) .
FindAll ( )
return
}
2021-01-03 20:18:07 +08:00
2021-06-23 13:12:54 +08:00
// FindItemListId 查找IPItem对应的列表ID
2021-01-03 20:18:07 +08:00
func ( this * IPItemDAO ) FindItemListId ( tx * dbs . Tx , itemId int64 ) ( int64 , error ) {
return this . Query ( tx ) .
Pk ( itemId ) .
Result ( "listId" ) .
FindInt64Col ( 0 )
}
2021-01-17 16:48:00 +08:00
2021-06-23 13:12:54 +08:00
// FindEnabledItemContainsIP 查找包含某个IP的Item
2024-04-06 15:15:33 +08:00
func ( this * IPItemDAO ) FindEnabledItemContainsIP ( tx * dbs . Tx , listId int64 , ip string ) ( * IPItem , error ) {
var query = this . Query ( tx ) .
2021-02-02 19:29:36 +08:00
Attr ( "listId" , listId ) .
State ( IPItemStateEnabled )
2024-04-06 15:15:33 +08:00
if iputils . IsIPv4 ( ip ) {
query . Where ( "(type='all' OR ipFrom =:ip OR INET_ATON(:ip) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))" ) .
Param ( "ip" , ip )
} else if iputils . IsIPv6 ( ip ) {
query . Where ( "(type='all' OR ipFrom =:ip OR HEX(INET6_ATON(:ip)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))" ) .
2021-02-02 19:29:36 +08:00
Param ( "ip" , ip )
2024-04-06 15:15:33 +08:00
} else {
return nil , nil
2021-02-02 19:29:36 +08:00
}
2024-04-06 15:15:33 +08:00
2021-02-02 19:29:36 +08:00
one , err := query . Find ( )
if err != nil {
return nil , err
}
if one == nil {
return nil , nil
}
return one . ( * IPItem ) , nil
}
2021-08-15 15:42:32 +08:00
// FindEnabledItemsWithIP 根据IP查找Item
func ( this * IPItemDAO ) FindEnabledItemsWithIP ( tx * dbs . Tx , ip string ) ( result [ ] * IPItem , err error ) {
_ , err = this . Query ( tx ) .
2021-12-02 17:12:13 +08:00
State ( IPItemStateEnabled ) .
2021-08-15 15:42:32 +08:00
Attr ( "ipFrom" , ip ) .
Attr ( "ipTo" , "" ) .
Where ( "(expiredAt=0 OR expiredAt>:nowTime)" ) .
Param ( "nowTime" , time . Now ( ) . Unix ( ) ) .
Where ( "listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1)" ) .
AscPk ( ) .
Slice ( & result ) .
FindAll ( )
return
}
2021-06-23 13:12:54 +08:00
// ExistsEnabledItem 检查IP是否存在
func ( this * IPItemDAO ) ExistsEnabledItem ( tx * dbs . Tx , itemId int64 ) ( bool , error ) {
return this . Query ( tx ) .
Pk ( itemId ) .
State ( IPItemStateEnabled ) .
Exist ( )
}
2021-11-17 19:51:00 +08:00
// CountAllEnabledIPItems 计算数量
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) CountAllEnabledIPItems ( tx * dbs . Tx , sourceUserId int64 , keyword string , ip string , listId int64 , unread bool , eventLevel string , listType string ) ( int64 , error ) {
2021-11-17 19:51:00 +08:00
var query = this . Query ( tx )
2023-04-25 11:28:04 +08:00
if sourceUserId > 0 {
2023-04-25 11:18:09 +08:00
if listId <= 0 {
2023-04-25 11:28:04 +08:00
query . Where ( "((listId=" + types . String ( firewallconfigs . GlobalListId ) + " AND sourceUserId=:sourceUserId) OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE userId=:sourceUserId AND state=1))" )
2023-04-25 11:18:09 +08:00
query . Param ( "sourceUserId" , sourceUserId )
} else if listId == firewallconfigs . GlobalListId {
query . Attr ( "sourceUserId" , sourceUserId )
query . UseIndex ( "sourceUserId" )
}
2023-04-03 10:02:17 +08:00
}
2022-10-25 10:15:32 +08:00
if len ( keyword ) > 0 {
2023-07-25 12:26:12 +08:00
if net . ParseIP ( keyword ) != nil { // 是一个IP地址
2024-04-06 14:55:51 +08:00
if iputils . IsIPv4 ( keyword ) {
2024-04-21 10:48:25 +08:00
query . Where ( "(type='all' OR ipFrom =:ipKeyword OR INET_ATON(:ipKeyword) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))" ) .
2024-04-06 14:55:51 +08:00
Param ( "ipKeyword" , keyword )
} else if iputils . IsIPv6 ( keyword ) {
2024-04-21 10:48:25 +08:00
query . Where ( "(type='all' OR ipFrom =:ipKeyword OR HEX(INET6_ATON(:ipKeyword)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))" ) .
2024-04-06 14:55:51 +08:00
Param ( "ipKeyword" , keyword )
}
2023-07-25 12:26:12 +08:00
} else {
query . Like ( "ipFrom" , dbutils . QuoteLike ( keyword ) )
}
2022-10-25 10:15:32 +08:00
}
2021-11-17 19:51:00 +08:00
if len ( ip ) > 0 {
2024-04-06 14:55:51 +08:00
query . Attr ( "ipFrom" , ip )
2021-11-17 19:51:00 +08:00
}
2021-11-17 20:25:36 +08:00
if listId > 0 {
query . Attr ( "listId" , listId )
} else {
2022-04-21 15:09:18 +08:00
if len ( listType ) > 0 {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1 AND type=:listType))" )
query . Param ( "listType" , listType )
} else {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1))" )
}
2021-11-17 20:25:36 +08:00
}
2022-01-08 16:48:17 +08:00
if unread {
query . Attr ( "isRead" , 0 )
}
2022-03-30 09:39:43 +08:00
if len ( eventLevel ) > 0 {
query . Attr ( "eventLevel" , eventLevel )
}
2022-04-21 15:09:18 +08:00
2021-11-17 19:51:00 +08:00
return query .
State ( IPItemStateEnabled ) .
2021-11-21 08:43:26 +08:00
Where ( "(expiredAt=0 OR expiredAt>:expiredAt)" ) .
Param ( "expiredAt" , time . Now ( ) . Unix ( ) ) .
2021-11-17 19:51:00 +08:00
Count ( )
}
// ListAllEnabledIPItems 搜索所有IP
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) ListAllEnabledIPItems ( tx * dbs . Tx , sourceUserId int64 , keyword string , ip string , listId int64 , unread bool , eventLevel string , listType string , offset int64 , size int64 ) ( result [ ] * IPItem , err error ) {
2021-11-17 19:51:00 +08:00
var query = this . Query ( tx )
2023-04-25 11:28:04 +08:00
if sourceUserId > 0 {
2023-04-25 11:18:09 +08:00
if listId <= 0 {
2023-04-25 11:28:04 +08:00
query . Where ( "((listId=" + types . String ( firewallconfigs . GlobalListId ) + " AND sourceUserId=:sourceUserId) OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE userId=:sourceUserId AND state=1))" )
2023-04-25 11:18:09 +08:00
query . Param ( "sourceUserId" , sourceUserId )
} else if listId == firewallconfigs . GlobalListId {
query . Attr ( "sourceUserId" , sourceUserId )
query . UseIndex ( "sourceUserId" )
}
2023-04-03 10:02:17 +08:00
}
2022-10-25 10:15:32 +08:00
if len ( keyword ) > 0 {
2023-07-25 12:26:12 +08:00
if net . ParseIP ( keyword ) != nil { // 是一个IP地址
2024-04-06 14:55:51 +08:00
if iputils . IsIPv4 ( keyword ) {
2024-04-21 10:48:25 +08:00
query . Where ( "(type='all' OR ipFrom =:ipKeyword OR INET_ATON(:ipKeyword) BETWEEN INET_ATON(ipFrom) AND INET_ATON(ipTo))" ) .
2024-04-06 14:55:51 +08:00
Param ( "ipKeyword" , keyword )
} else if iputils . IsIPv6 ( keyword ) {
2024-04-21 10:48:25 +08:00
query . Where ( "(type='all' OR ipFrom =:ipKeyword OR HEX(INET6_ATON(:ipKeyword)) BETWEEN HEX(INET6_ATON(ipFrom)) AND HEX(INET6_ATON(ipTo)))" ) .
2024-04-06 14:55:51 +08:00
Param ( "ipKeyword" , keyword )
}
2023-07-25 12:26:12 +08:00
} else {
query . Like ( "ipFrom" , dbutils . QuoteLike ( keyword ) )
}
2022-10-25 10:15:32 +08:00
}
2021-11-17 19:51:00 +08:00
if len ( ip ) > 0 {
2024-04-06 14:55:51 +08:00
query . Attr ( "ipFrom" , ip )
2021-11-17 19:51:00 +08:00
}
2021-11-17 20:25:36 +08:00
if listId > 0 {
query . Attr ( "listId" , listId )
} else {
2022-04-21 15:09:18 +08:00
if len ( listType ) > 0 {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1 AND type=:listType))" )
query . Param ( "listType" , listType )
} else {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1))" )
}
2021-11-17 20:25:36 +08:00
}
2022-01-08 16:48:17 +08:00
if unread {
query . Attr ( "isRead" , 0 )
2022-03-30 09:39:43 +08:00
}
if len ( eventLevel ) > 0 {
query . Attr ( "eventLevel" , eventLevel )
2022-01-08 16:48:17 +08:00
}
2021-11-17 19:51:00 +08:00
_ , err = query .
State ( IPItemStateEnabled ) .
2021-11-21 08:43:26 +08:00
Where ( "(expiredAt=0 OR expiredAt>:expiredAt)" ) .
Param ( "expiredAt" , time . Now ( ) . Unix ( ) ) .
2021-11-17 19:51:00 +08:00
DescPk ( ) .
Offset ( offset ) .
Size ( size ) .
Slice ( & result ) .
FindAll ( )
return
2023-12-24 10:51:29 +08:00
}
// ListAllIPItemIds 搜索所有IP Id列表
func ( this * IPItemDAO ) ListAllIPItemIds ( tx * dbs . Tx , sourceUserId int64 , keyword string , ip string , listId int64 , unread bool , eventLevel string , listType string , offset int64 , size int64 ) ( itemIds [ ] int64 , err error ) {
var query = this . Query ( tx )
if sourceUserId > 0 {
if listId <= 0 {
query . Where ( "((listId=" + types . String ( firewallconfigs . GlobalListId ) + " AND sourceUserId=:sourceUserId) OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE userId=:sourceUserId AND state=1))" )
query . Param ( "sourceUserId" , sourceUserId )
} else if listId == firewallconfigs . GlobalListId {
query . Attr ( "sourceUserId" , sourceUserId )
query . UseIndex ( "sourceUserId" )
}
}
if len ( keyword ) > 0 {
if net . ParseIP ( keyword ) != nil { // 是一个IP地址
query . Attr ( "ipFrom" , keyword )
} else {
query . Like ( "ipFrom" , dbutils . QuoteLike ( keyword ) )
}
}
if len ( ip ) > 0 {
query . Attr ( "ipFrom" , ip )
}
if listId > 0 {
query . Attr ( "listId" , listId )
} else {
if len ( listType ) > 0 {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1 AND type=:listType))" )
query . Param ( "listType" , listType )
} else {
query . Where ( "(listId=" + types . String ( firewallconfigs . GlobalListId ) + " OR listId IN (SELECT id FROM " + SharedIPListDAO . Table + " WHERE state=1))" )
}
}
if unread {
query . Attr ( "isRead" , 0 )
}
if len ( eventLevel ) > 0 {
query . Attr ( "eventLevel" , eventLevel )
}
result , err := query .
ResultPk ( ) .
State ( IPItemStateEnabled ) .
Where ( "(expiredAt=0 OR expiredAt>:expiredAt)" ) .
Param ( "expiredAt" , time . Now ( ) . Unix ( ) ) .
DescPk ( ) .
Offset ( offset ) .
Size ( size ) .
FindAll ( )
if err != nil {
return nil , err
}
for _ , itemOne := range result {
itemIds = append ( itemIds , int64 ( itemOne . ( * IPItem ) . Id ) )
}
return
2021-11-17 19:51:00 +08:00
}
2022-01-08 16:48:17 +08:00
// UpdateItemsRead 设置所有未已读
2023-04-03 10:02:17 +08:00
func ( this * IPItemDAO ) UpdateItemsRead ( tx * dbs . Tx , sourceUserId int64 ) error {
var query = this . Query ( tx ) .
2022-01-08 16:48:17 +08:00
Attr ( "isRead" , 0 ) .
2023-04-03 10:02:17 +08:00
Set ( "isRead" , 1 )
if sourceUserId > 0 {
query . Attr ( "sourceUserId" , sourceUserId )
query . UseIndex ( "sourceUserId" )
}
return query . UpdateQuickly ( )
2022-01-08 16:48:17 +08:00
}
2022-02-14 08:52:27 +08:00
// CleanExpiredIPItems 清除过期数据
func ( this * IPItemDAO ) CleanExpiredIPItems ( tx * dbs . Tx ) error {
// 删除 N 天之前过期的数据
_ , err := this . Query ( tx ) .
2022-05-21 22:06:04 +08:00
Where ( "(createdAt<=:timestamp AND updatedAt<=:timestamp)" ) .
2022-02-14 08:52:27 +08:00
State ( IPItemStateDisabled ) .
Param ( "timestamp" , time . Now ( ) . Unix ( ) - 7 * 86400 ) . // N 天之前过期的
Limit ( 10000 ) . // 限制条数,防止数量过多导致超时
Delete ( )
if err != nil {
return err
}
// 将过期的设置为已删除,这样是为了在 expiredAt<UNIX_TIMESTAMP()边缘节点让过期的IP有一个执行删除的机会
ones , _ , err := this . Query ( tx ) .
ResultPk ( ) .
Where ( "(expiredAt>0 AND expiredAt<=:timestamp)" ) .
Param ( "timestamp" , time . Now ( ) . Unix ( ) ) .
State ( IPItemStateEnabled ) .
2022-02-14 09:00:24 +08:00
Limit ( 500 ) .
2022-02-14 08:52:27 +08:00
FindOnes ( )
if err != nil {
return err
}
for _ , one := range ones {
var expiredId = one . GetInt64 ( "id" )
newVersion , err := SharedIPListDAO . IncreaseVersion ( tx )
if err != nil {
return err
}
2022-02-17 19:37:22 +08:00
// 这里不重置过期时间用于清理
2022-02-14 08:52:27 +08:00
_ , err = this . Query ( tx ) .
Pk ( expiredId ) .
Set ( "state" , IPItemStateDisabled ) .
Set ( "version" , newVersion ) .
Update ( )
if err != nil {
return err
}
}
return nil
}
2024-04-13 16:48:24 +08:00
// ParseIPValue 解析IP值
func ( this * IPItemDAO ) ParseIPValue ( value string ) ( newValue string , ipFrom string , ipTo string , ok bool ) {
if len ( value ) == 0 {
return
}
newValue = value
// ip1-ip2
if strings . Contains ( value , "-" ) {
var pieces = strings . Split ( value , "-" )
if len ( pieces ) != 2 {
return
}
ipFrom = strings . TrimSpace ( pieces [ 0 ] )
ipTo = strings . TrimSpace ( pieces [ 1 ] )
if ! iputils . IsValid ( ipFrom ) || ! iputils . IsValid ( ipTo ) {
return
}
if ! iputils . IsSameVersion ( ipFrom , ipTo ) {
return
}
if iputils . CompareIP ( ipFrom , ipTo ) > 0 {
ipFrom , ipTo = ipTo , ipFrom
newValue = ipFrom + "-" + ipTo
}
ok = true
return
}
// ip/mask
if strings . Contains ( value , "/" ) {
cidr , err := iputils . ParseCIDR ( value )
if err != nil {
return
}
return newValue , cidr . From ( ) . String ( ) , cidr . To ( ) . String ( ) , true
}
// single value
if iputils . IsValid ( value ) {
ipFrom = value
ok = true
return
}
return
}
2021-06-23 13:12:54 +08:00
// NotifyUpdate 通知更新
2021-02-02 15:25:40 +08:00
func ( this * IPItemDAO ) NotifyUpdate ( tx * dbs . Tx , itemId int64 ) error {
2021-01-17 16:48:00 +08:00
// 获取ListId
listId , err := this . FindItemListId ( tx , itemId )
if err != nil {
return err
}
if listId == 0 {
return nil
}
2021-11-26 10:39:50 +08:00
if listId == firewallconfigs . GlobalListId {
sourceNodeId , err := this . Query ( tx ) .
Pk ( itemId ) .
Result ( "sourceNodeId" ) .
FindInt64Col ( 0 )
if err != nil {
return err
}
if sourceNodeId > 0 {
clusterIds , err := SharedNodeDAO . FindEnabledNodeClusterIds ( tx , sourceNodeId )
if err != nil {
return err
}
for _ , clusterId := range clusterIds {
2022-10-23 16:22:20 +08:00
err = SharedNodeTaskDAO . CreateClusterTask ( tx , nodeconfigs . NodeRoleNode , clusterId , 0 , 0 , NodeTaskTypeIPItemChanged )
2021-11-26 10:39:50 +08:00
if err != nil {
return err
}
}
} else {
clusterIds , err := SharedNodeClusterDAO . FindAllEnabledNodeClusterIds ( tx )
2023-08-08 16:46:17 +08:00
if err != nil {
return err
}
2021-11-26 10:39:50 +08:00
for _ , clusterId := range clusterIds {
2022-10-23 16:22:20 +08:00
err = SharedNodeTaskDAO . CreateClusterTask ( tx , nodeconfigs . NodeRoleNode , clusterId , 0 , 0 , NodeTaskTypeIPItemChanged )
2021-11-26 10:39:50 +08:00
if err != nil {
return err
}
}
}
return nil
}
2021-01-17 16:48:00 +08:00
httpFirewallPolicyIds , err := SharedHTTPFirewallPolicyDAO . FindEnabledFirewallPolicyIdsWithIPListId ( tx , listId )
if err != nil {
return err
}
resultClusterIds := [ ] int64 { }
for _ , policyId := range httpFirewallPolicyIds {
// 集群
clusterIds , err := SharedNodeClusterDAO . FindAllEnabledNodeClusterIdsWithHTTPFirewallPolicyId ( tx , policyId )
if err != nil {
return err
}
for _ , clusterId := range clusterIds {
if ! lists . ContainsInt64 ( resultClusterIds , clusterId ) {
resultClusterIds = append ( resultClusterIds , clusterId )
}
}
// 服务
webIds , err := SharedHTTPWebDAO . FindAllWebIdsWithHTTPFirewallPolicyId ( tx , policyId )
if err != nil {
return err
}
if len ( webIds ) > 0 {
for _ , webId := range webIds {
serverId , err := SharedServerDAO . FindEnabledServerIdWithWebId ( tx , webId )
if err != nil {
return err
}
if serverId > 0 {
clusterId , err := SharedServerDAO . FindServerClusterId ( tx , serverId )
if err != nil {
return err
}
if ! lists . ContainsInt64 ( resultClusterIds , clusterId ) {
resultClusterIds = append ( resultClusterIds , clusterId )
}
}
}
}
}
if len ( resultClusterIds ) > 0 {
for _ , clusterId := range resultClusterIds {
2022-10-23 16:22:20 +08:00
err = SharedNodeTaskDAO . CreateClusterTask ( tx , nodeconfigs . NodeRoleNode , clusterId , 0 , 0 , NodeTaskTypeIPItemChanged )
2021-01-17 16:48:00 +08:00
if err != nil {
return err
}
}
}
return nil
}