mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-14 21:16:54 +01:00
move helper funcs
This commit is contained in:
parent
2a49d34521
commit
03af3b88c4
@ -14,6 +14,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setting is a key value store of user settings
|
// Setting is a key value store of user settings
|
||||||
@ -210,3 +211,17 @@ func upsertUserSettingValue(ctx context.Context, userID int64, key, value string
|
|||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildSignupIPQuery builds a query to find users by their signup IP addresses
|
||||||
|
func BuildSignupIPQuery(ctx context.Context, keyword string) *xorm.Session {
|
||||||
|
query := db.GetEngine(ctx).
|
||||||
|
Table("user_setting").
|
||||||
|
Join("INNER", "user", "user.id = user_setting.user_id").
|
||||||
|
Where("user_setting.setting_key = ?", SignupIP)
|
||||||
|
|
||||||
|
if len(keyword) > 0 {
|
||||||
|
query = query.And("(user.lower_name LIKE ? OR user.full_name LIKE ? OR user_setting.setting_value LIKE ?)",
|
||||||
|
"%"+strings.ToLower(keyword)+"%", "%"+keyword+"%", "%"+keyword+"%")
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|||||||
32
modules/util/network.go
Normal file
32
modules/util/network.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TrimPortFromIP removes the client port from an IP address
|
||||||
|
// Handles both IPv4 and IPv6 addresses with ports
|
||||||
|
func TrimPortFromIP(ip string) string {
|
||||||
|
// Handle IPv6 with brackets: [IPv6]:port
|
||||||
|
if strings.HasPrefix(ip, "[") {
|
||||||
|
// If there's no port, return as is
|
||||||
|
if !strings.Contains(ip, "]:") {
|
||||||
|
return ip
|
||||||
|
}
|
||||||
|
// Remove the port part after ]:
|
||||||
|
return strings.Split(ip, "]:")[0] + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count colons to differentiate between IPv4 and IPv6
|
||||||
|
colonCount := strings.Count(ip, ":")
|
||||||
|
|
||||||
|
// Handle IPv4 with port (single colon)
|
||||||
|
if colonCount == 1 {
|
||||||
|
return strings.Split(ip, ":")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip
|
||||||
|
}
|
||||||
66
modules/util/network_test.go
Normal file
66
modules/util/network_test.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTrimPortFromIP(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "IPv4 without port",
|
||||||
|
input: "192.168.1.1",
|
||||||
|
expected: "192.168.1.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv4 with port",
|
||||||
|
input: "192.168.1.1:8080",
|
||||||
|
expected: "192.168.1.1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6 without port",
|
||||||
|
input: "2001:db8::1",
|
||||||
|
expected: "2001:db8::1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6 with brackets, without port",
|
||||||
|
input: "[2001:db8::1]",
|
||||||
|
expected: "[2001:db8::1]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "IPv6 with brackets and port",
|
||||||
|
input: "[2001:db8::1]:8080",
|
||||||
|
expected: "[2001:db8::1]",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "localhost with port",
|
||||||
|
input: "localhost:8080",
|
||||||
|
expected: "localhost",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty string",
|
||||||
|
input: "",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Not an IP address",
|
||||||
|
input: "abc123",
|
||||||
|
expected: "abc123",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := TrimPortFromIP(tt.input)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,58 +5,18 @@ package admin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/templates"
|
"code.gitea.io/gitea/modules/templates"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/services/context"
|
"code.gitea.io/gitea/services/context"
|
||||||
|
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tplIPs templates.TplName = "admin/ips/list"
|
tplIPs templates.TplName = "admin/ips/list"
|
||||||
)
|
)
|
||||||
|
|
||||||
// trimPortFromIP removes the client port from an IP address
|
|
||||||
// Handles both IPv4 and IPv6 addresses with ports
|
|
||||||
func trimPortFromIP(ip string) string {
|
|
||||||
// Handle IPv6 with brackets: [IPv6]:port
|
|
||||||
if strings.HasPrefix(ip, "[") {
|
|
||||||
// If there's no port, return as is
|
|
||||||
if !strings.Contains(ip, "]:") {
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
// Remove the port part after ]:
|
|
||||||
return strings.Split(ip, "]:")[0] + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count colons to differentiate between IPv4 and IPv6
|
|
||||||
colonCount := strings.Count(ip, ":")
|
|
||||||
|
|
||||||
// Handle IPv4 with port (single colon)
|
|
||||||
if colonCount == 1 {
|
|
||||||
return strings.Split(ip, ":")[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ip
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildIPQuery(ctx *context.Context, keyword string) *xorm.Session {
|
|
||||||
query := db.GetEngine(ctx).
|
|
||||||
Table("user_setting").
|
|
||||||
Join("INNER", "user", "user.id = user_setting.user_id").
|
|
||||||
Where("user_setting.setting_key = ?", user_model.SignupIP)
|
|
||||||
|
|
||||||
if len(keyword) > 0 {
|
|
||||||
query = query.And("(user.lower_name LIKE ? OR user.full_name LIKE ? OR user_setting.setting_value LIKE ?)",
|
|
||||||
"%"+strings.ToLower(keyword)+"%", "%"+keyword+"%", "%"+keyword+"%")
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPs show all user signup IPs
|
// IPs show all user signup IPs
|
||||||
func IPs(ctx *context.Context) {
|
func IPs(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("admin.ips.ip")
|
ctx.Data["Title"] = ctx.Tr("admin.ips.ip")
|
||||||
@ -107,7 +67,7 @@ func IPs(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the count and user IPs for pagination
|
// Get the count and user IPs for pagination
|
||||||
query := buildIPQuery(ctx, keyword)
|
query := user_model.BuildSignupIPQuery(ctx, keyword)
|
||||||
|
|
||||||
count, err = query.Count(new(user_model.Setting))
|
count, err = query.Count(new(user_model.Setting))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -115,7 +75,7 @@ func IPs(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = buildIPQuery(ctx, keyword).
|
err = user_model.BuildSignupIPQuery(ctx, keyword).
|
||||||
Select("user.id as uid, user.name, user.full_name, user_setting.setting_value as ip").
|
Select("user.id as uid, user.name, user.full_name, user_setting.setting_value as ip").
|
||||||
OrderBy(orderBy).
|
OrderBy(orderBy).
|
||||||
Limit(setting.UI.Admin.UserPagingNum, (page-1)*setting.UI.Admin.UserPagingNum).
|
Limit(setting.UI.Admin.UserPagingNum, (page-1)*setting.UI.Admin.UserPagingNum).
|
||||||
@ -128,7 +88,7 @@ func IPs(ctx *context.Context) {
|
|||||||
for i := range userIPs {
|
for i := range userIPs {
|
||||||
// Trim the port from the IP
|
// Trim the port from the IP
|
||||||
// FIXME: Maybe have a different helper for this?
|
// FIXME: Maybe have a different helper for this?
|
||||||
userIPs[i].IP = trimPortFromIP(userIPs[i].IP)
|
userIPs[i].IP = util.TrimPortFromIP(userIPs[i].IP)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["UserIPs"] = userIPs
|
ctx.Data["UserIPs"] = userIPs
|
||||||
|
|||||||
@ -298,7 +298,7 @@ func ViewUser(ctx *context.Context) {
|
|||||||
signupIP, err := user_model.GetUserSetting(ctx, u.ID, user_model.SignupIP)
|
signupIP, err := user_model.GetUserSetting(ctx, u.ID, user_model.SignupIP)
|
||||||
if err == nil && len(signupIP) > 0 {
|
if err == nil && len(signupIP) > 0 {
|
||||||
ctx.Data["HasSignupIP"] = true
|
ctx.Data["HasSignupIP"] = true
|
||||||
ctx.Data["SignupIP"] = trimPortFromIP(signupIP)
|
ctx.Data["SignupIP"] = util.TrimPortFromIP(signupIP)
|
||||||
} else {
|
} else {
|
||||||
ctx.Data["HasSignupIP"] = false
|
ctx.Data["HasSignupIP"] = false
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user