mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-11-08 17:53:41 +08:00
Compare commits
4 Commits
v0.6.5-alp
...
v0.6.5-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
348adc2b02 | ||
|
|
dcf24b98dc | ||
|
|
af679e04f4 | ||
|
|
93cbca6a9f |
@@ -5,9 +5,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/songquanpeng/one-api/common/logger"
|
"github.com/songquanpeng/one-api/common/logger"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IsValidSubnet(subnet string) error {
|
func splitSubnets(subnets string) []string {
|
||||||
|
res := strings.Split(subnets, ",")
|
||||||
|
for i := 0; i < len(res); i++ {
|
||||||
|
res[i] = strings.TrimSpace(res[i])
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidSubnet(subnet string) error {
|
||||||
_, _, err := net.ParseCIDR(subnet)
|
_, _, err := net.ParseCIDR(subnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse subnet: %w", err)
|
return fmt.Errorf("failed to parse subnet: %w", err)
|
||||||
@@ -15,7 +24,7 @@ func IsValidSubnet(subnet string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsIpInSubnet(ctx context.Context, ip string, subnet string) bool {
|
func isIpInSubnet(ctx context.Context, ip string, subnet string) bool {
|
||||||
_, ipNet, err := net.ParseCIDR(subnet)
|
_, ipNet, err := net.ParseCIDR(subnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf(ctx, "failed to parse subnet: %s", err.Error())
|
logger.Errorf(ctx, "failed to parse subnet: %s", err.Error())
|
||||||
@@ -23,3 +32,21 @@ func IsIpInSubnet(ctx context.Context, ip string, subnet string) bool {
|
|||||||
}
|
}
|
||||||
return ipNet.Contains(net.ParseIP(ip))
|
return ipNet.Contains(net.ParseIP(ip))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsValidSubnets(subnets string) error {
|
||||||
|
for _, subnet := range splitSubnets(subnets) {
|
||||||
|
if err := isValidSubnet(subnet); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsIpInSubnets(ctx context.Context, ip string, subnets string) bool {
|
||||||
|
for _, subnet := range splitSubnets(subnets) {
|
||||||
|
if isIpInSubnet(ctx, ip, subnet) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func TestIsIpInSubnet(t *testing.T) {
|
|||||||
ip2 := "125.216.250.89"
|
ip2 := "125.216.250.89"
|
||||||
subnet := "192.168.0.0/24"
|
subnet := "192.168.0.0/24"
|
||||||
Convey("TestIsIpInSubnet", t, func() {
|
Convey("TestIsIpInSubnet", t, func() {
|
||||||
So(IsIpInSubnet(ctx, ip1, subnet), ShouldBeTrue)
|
So(isIpInSubnet(ctx, ip1, subnet), ShouldBeTrue)
|
||||||
So(IsIpInSubnet(ctx, ip2, subnet), ShouldBeFalse)
|
So(isIpInSubnet(ctx, ip2, subnet), ShouldBeFalse)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func validateToken(c *gin.Context, token model.Token) error {
|
|||||||
return fmt.Errorf("令牌名称过长")
|
return fmt.Errorf("令牌名称过长")
|
||||||
}
|
}
|
||||||
if token.Subnet != nil && *token.Subnet != "" {
|
if token.Subnet != nil && *token.Subnet != "" {
|
||||||
err := network.IsValidSubnet(*token.Subnet)
|
err := network.IsValidSubnets(*token.Subnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("无效的网段:%s", err.Error())
|
return fmt.Errorf("无效的网段:%s", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func TokenAuth() func(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if token.Subnet != nil && *token.Subnet != "" {
|
if token.Subnet != nil && *token.Subnet != "" {
|
||||||
if !network.IsIpInSubnet(ctx, c.ClientIP(), *token.Subnet) {
|
if !network.IsIpInSubnets(ctx, c.ClientIP(), *token.Subnet) {
|
||||||
abortWithMessage(c, http.StatusForbidden, fmt.Sprintf("该令牌只能在指定网段使用:%s,当前 ip:%s", *token.Subnet, c.ClientIP()))
|
abortWithMessage(c, http.StatusForbidden, fmt.Sprintf("该令牌只能在指定网段使用:%s,当前 ip:%s", *token.Subnet, c.ClientIP()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const snackbarConstants = {
|
|||||||
},
|
},
|
||||||
NOTICE: {
|
NOTICE: {
|
||||||
variant: 'info',
|
variant: 'info',
|
||||||
autoHideDuration: 20000
|
autoHideDuration: 7000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Mobile: {
|
Mobile: {
|
||||||
|
|||||||
@@ -51,9 +51,9 @@ export function showError(error) {
|
|||||||
|
|
||||||
export function showNotice(message, isHTML = false) {
|
export function showNotice(message, isHTML = false) {
|
||||||
if (isHTML) {
|
if (isHTML) {
|
||||||
enqueueSnackbar(<SnackbarHTMLContent htmlContent={message} />, getSnackbarOptions('INFO'));
|
enqueueSnackbar(<SnackbarHTMLContent htmlContent={message} />, getSnackbarOptions('NOTICE'));
|
||||||
} else {
|
} else {
|
||||||
enqueueSnackbar(message, getSnackbarOptions('INFO'));
|
enqueueSnackbar(message, getSnackbarOptions('NOTICE'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -340,7 +340,9 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.values(CHANNEL_OPTIONS).map((option) => {
|
{Object.values(CHANNEL_OPTIONS).sort((a, b) => {
|
||||||
|
return a.text.localeCompare(b.text)
|
||||||
|
}).map((option) => {
|
||||||
return (
|
return (
|
||||||
<MenuItem key={option.value} value={option.value}>
|
<MenuItem key={option.value} value={option.value}>
|
||||||
{option.text}
|
{option.text}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ const EditModal = ({ open, tokenId, onCancel, onOk }) => {
|
|||||||
fontSize: "1.125rem",
|
fontSize: "1.125rem",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tokenId ? "编辑Token" : "新建Token"}
|
{tokenId ? "编辑令牌" : "新建令牌"}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<Divider />
|
<Divider />
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const EditToken = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
label='IP 限制'
|
label='IP 限制'
|
||||||
name='subnet'
|
name='subnet'
|
||||||
placeholder={'请输入允许访问的网段,例如:192.168.0.0/24'}
|
placeholder={'请输入允许访问的网段,例如:192.168.0.0/24,请使用英文逗号分隔多个网段'}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
value={inputs.subnet}
|
value={inputs.subnet}
|
||||||
autoComplete='new-password'
|
autoComplete='new-password'
|
||||||
|
|||||||
Reference in New Issue
Block a user