mirror of
https://github.com/yhl452493373/frps-panel.git
synced 2026-04-04 06:16:59 +08:00
completely save config with toml format
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
"Other error": "Other error",
|
"Other error": "Other error",
|
||||||
"Param error": "Param error",
|
"Param error": "Param error",
|
||||||
"User exist": "User exist",
|
"User exist": "User exist",
|
||||||
|
"User not exist": "User not exist",
|
||||||
"User format error": "User cannot be empty or include space char. It only allowed alphanumeric and underline.",
|
"User format error": "User cannot be empty or include space char. It only allowed alphanumeric and underline.",
|
||||||
"Token format error": "Token cannot be empty or include space char. It allow include those special char: _!@#$%^&*()",
|
"Token format error": "Token cannot be empty or include space char. It allow include those special char: _!@#$%^&*()",
|
||||||
"Please check at least one user": "Please Check at least one user",
|
"Please check at least one user": "Please Check at least one user",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
"Other error": "其他异常",
|
"Other error": "其他异常",
|
||||||
"Param error": "参数异常",
|
"Param error": "参数异常",
|
||||||
"User exist": "用户已经存在",
|
"User exist": "用户已经存在",
|
||||||
|
"User not exist": "用户不存在",
|
||||||
"User format error": "用户不能为空或包含空格。只允许英文数字、字母、下划线",
|
"User format error": "用户不能为空或包含空格。只允许英文数字、字母、下划线",
|
||||||
"Token format error": "Token不能为空或包含空格。允许的特殊符号:_!@#$%^&*()",
|
"Token format error": "Token不能为空或包含空格。允许的特殊符号:_!@#$%^&*()",
|
||||||
"Please check at least one user": "请选中需要操作的用户",
|
"Please check at least one user": "请选中需要操作的用户",
|
||||||
|
|||||||
@@ -46,6 +46,14 @@
|
|||||||
border-color: #79bbff;
|
border-color: #79bbff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-form-checkbox[lay-skin=primary] > .layui-icon-indeterminate:before {
|
||||||
|
background-color: #79bbff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-checkbox[lay-skin=primary]>.layui-icon-indeterminate{
|
||||||
|
border-color: #79bbff;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-form-checked[lay-skin=primary] > i {
|
.layui-form-checked[lay-skin=primary] > i {
|
||||||
background-color: #409eff;
|
background-color: #409eff;
|
||||||
border-color: #409eff !important;
|
border-color: #409eff !important;
|
||||||
@@ -173,6 +181,14 @@ section.proxy-list .proxy-info .layui-row .layui-row > div:first-child {
|
|||||||
border-color: #5f5f60;
|
border-color: #5f5f60;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layui-form-checkbox[lay-skin=primary] > .layui-icon-indeterminate:before {
|
||||||
|
background-color: #5f5f60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-checkbox[lay-skin=primary]>.layui-icon-indeterminate{
|
||||||
|
border-color: #5f5f60;
|
||||||
|
}
|
||||||
|
|
||||||
.layui-form-checked[lay-skin=primary] > i {
|
.layui-form-checked[lay-skin=primary] > i {
|
||||||
background-color: #484849;
|
background-color: #484849;
|
||||||
border-color: #484849 !important;
|
border-color: #484849 !important;
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ var loadUserList = (function ($) {
|
|||||||
if (domains.trim() !== '') {
|
if (domains.trim() !== '') {
|
||||||
try {
|
try {
|
||||||
domains.split(',').forEach(function (domain) {
|
domains.split(',').forEach(function (domain) {
|
||||||
if (!/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}){1,3}$/.test(domain.trim())) {
|
if (!/^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,}$/.test(domain.trim())) {
|
||||||
valid = false;
|
valid = false;
|
||||||
throw 'break';
|
throw 'break';
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ var loadUserList = (function ($) {
|
|||||||
if (subdomains.trim() !== '') {
|
if (subdomains.trim() !== '') {
|
||||||
try {
|
try {
|
||||||
subdomains.split(',').forEach(function (subdomain) {
|
subdomains.split(',').forEach(function (subdomain) {
|
||||||
if (!/^[a-zA-z0-9][a-zA-Z0-9-]{0,19}$/.test(subdomain.trim())) {
|
if (!/^[a-zA-z0-9][a-zA-z0-9-]{0,19}$/.test(subdomain.trim())) {
|
||||||
valid = false;
|
valid = false;
|
||||||
throw 'break';
|
throw 'break';
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ var loadUserList = (function ($) {
|
|||||||
* set verify rule of layui.form
|
* set verify rule of layui.form
|
||||||
*/
|
*/
|
||||||
(function setFormVerifyRule() {
|
(function setFormVerifyRule() {
|
||||||
layui.form.verify(verifyRules);
|
// layui.form.verify(verifyRules);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,7 +251,9 @@ var loadUserList = (function ($) {
|
|||||||
where: {},
|
where: {},
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
editTrigger: 'dblclick',
|
editTrigger: 'dblclick',
|
||||||
page: navigator.language.indexOf("zh") !== -1,
|
page: {
|
||||||
|
layout: navigator.language.indexOf("zh") === -1 ? ['first', 'prev', 'next', 'last'] : ['prev', 'page', 'next', 'skip', 'count', 'limit']
|
||||||
|
},
|
||||||
toolbar: '#userListToolbarTemplate',
|
toolbar: '#userListToolbarTemplate',
|
||||||
defaultToolbar: false,
|
defaultToolbar: false,
|
||||||
cols: [[
|
cols: [[
|
||||||
@@ -270,7 +272,14 @@ var loadUserList = (function ($) {
|
|||||||
sort: true
|
sort: true
|
||||||
},
|
},
|
||||||
{title: i18n['Operation'], width: 150, toolbar: '#userListOperationTemplate'}
|
{title: i18n['Operation'], width: 150, toolbar: '#userListOperationTemplate'}
|
||||||
]]
|
]],
|
||||||
|
parseData: function (res) {
|
||||||
|
res.data.forEach(function (data) {
|
||||||
|
data.ports = data.ports.join(',');
|
||||||
|
data.domains = data.domains.join(',');
|
||||||
|
data.subdomains = data.subdomains.join(',');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bindFormEvent();
|
bindFormEvent();
|
||||||
@@ -348,7 +357,6 @@ var loadUserList = (function ($) {
|
|||||||
before.ports = before.ports.split(',')
|
before.ports = before.ports.split(',')
|
||||||
before.domains = before.domains.split(',')
|
before.domains = before.domains.split(',')
|
||||||
before.subdomains = before.subdomains.split(',')
|
before.subdomains = before.subdomains.split(',')
|
||||||
|
|
||||||
after.ports = after.ports.split(',')
|
after.ports = after.ports.split(',')
|
||||||
after.domains = after.domains.split(',')
|
after.domains = after.domains.split(',')
|
||||||
after.subdomains = after.subdomains.split(',')
|
after.subdomains = after.subdomains.split(',')
|
||||||
@@ -359,8 +367,14 @@ var loadUserList = (function ($) {
|
|||||||
layui.table.on('toolbar(tokenTable)', function (obj) {
|
layui.table.on('toolbar(tokenTable)', function (obj) {
|
||||||
var id = obj.config.id;
|
var id = obj.config.id;
|
||||||
var checkStatus = layui.table.checkStatus(id);
|
var checkStatus = layui.table.checkStatus(id);
|
||||||
|
|
||||||
var data = checkStatus.data;
|
var data = checkStatus.data;
|
||||||
|
|
||||||
|
data.forEach(function (temp) {
|
||||||
|
temp.ports = temp.ports.split(',')
|
||||||
|
temp.domains = temp.domains.split(',')
|
||||||
|
temp.subdomains = temp.subdomains.split(',')
|
||||||
|
});
|
||||||
|
|
||||||
switch (obj.event) {
|
switch (obj.event) {
|
||||||
case 'add':
|
case 'add':
|
||||||
addPopup();
|
addPopup();
|
||||||
@@ -379,6 +393,10 @@ var loadUserList = (function ($) {
|
|||||||
|
|
||||||
layui.table.on('tool(tokenTable)', function (obj) {
|
layui.table.on('tool(tokenTable)', function (obj) {
|
||||||
var data = obj.data;
|
var data = obj.data;
|
||||||
|
|
||||||
|
data.ports = data.ports.split(',')
|
||||||
|
data.domains = data.domains.split(',')
|
||||||
|
data.subdomains = data.subdomains.split(',')
|
||||||
switch (obj.event) {
|
switch (obj.event) {
|
||||||
case 'remove':
|
case 'remove':
|
||||||
removePopup(data);
|
removePopup(data);
|
||||||
@@ -418,9 +436,15 @@ var loadUserList = (function ($) {
|
|||||||
btn1: function (index) {
|
btn1: function (index) {
|
||||||
if (layui.form.validate('#addUserForm')) {
|
if (layui.form.validate('#addUserForm')) {
|
||||||
var formData = layui.form.val('addUserForm');
|
var formData = layui.form.val('addUserForm');
|
||||||
formData.ports = formData.ports.split(',')
|
if (formData.ports != null) {
|
||||||
formData.domains = formData.domains.split(',')
|
formData.ports = formData.ports.split(',')
|
||||||
formData.subdomains = formData.subdomains.split(',')
|
}
|
||||||
|
if (formData.domains != null) {
|
||||||
|
formData.domains = formData.domains.split(',')
|
||||||
|
}
|
||||||
|
if (formData.subdomains != null) {
|
||||||
|
formData.subdomains = formData.subdomains.split(',')
|
||||||
|
}
|
||||||
add(formData, index);
|
add(formData, index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -638,17 +662,27 @@ var loadUserList = (function ($) {
|
|||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
function errorMsg(result) {
|
function errorMsg(result) {
|
||||||
var reason = i18n['Other Error'];
|
var reason = i18n['OtherError'];
|
||||||
if (result.code === 1)
|
if (result.code === 1)
|
||||||
reason = i18n['ParamError'];
|
reason = i18n['ParamError'];
|
||||||
else if (result.code === 2)
|
else if (result.code === 2)
|
||||||
reason = i18n['UserExist'];
|
reason = i18n['UserExist'];
|
||||||
else if (result.code === 3)
|
else if (result.code === 3)
|
||||||
reason = i18n['ParamError'];
|
reason = i18n['UserNotExist'];
|
||||||
else if (result.code === 4)
|
else if (result.code === 4)
|
||||||
reason = i18n['UserFormatError'];
|
reason = i18n['ParamError'];
|
||||||
else if (result.code === 5)
|
else if (result.code === 5)
|
||||||
|
reason = i18n['UserFormatError'];
|
||||||
|
else if (result.code === 6)
|
||||||
reason = i18n['TokenFormatError'];
|
reason = i18n['TokenFormatError'];
|
||||||
|
else if (result.code === 7)
|
||||||
|
reason = i18n['CommentInvalid'];
|
||||||
|
else if (result.code === 8)
|
||||||
|
reason = i18n['PortsInvalid'];
|
||||||
|
else if (result.code === 9)
|
||||||
|
reason = i18n['DomainsInvalid'];
|
||||||
|
else if (result.code === 10)
|
||||||
|
reason = i18n['SubdomainsInvalid'];
|
||||||
layui.layer.msg(i18n['OperateFailed'] + ',' + reason)
|
layui.layer.msg(i18n['OperateFailed'] + ',' + reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>${ .FrpsPanel }</title>
|
<title>${ .FrpsPanel }</title>
|
||||||
<link rel="stylesheet" href="./static/lib/layui/css/layui.css">
|
<link rel="stylesheet" href="./static/lib/layui/css/layui.css">
|
||||||
|
|||||||
@@ -70,34 +70,22 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseConfigFile(configFile, tokensFile string) (controller.HandleController, server.TLS, error) {
|
func parseConfigFile(configFile, tokensFile string) (controller.HandleController, server.TLS, error) {
|
||||||
var config controller.Config
|
var common controller.Common
|
||||||
_, err := toml.DecodeFile(configFile, &config)
|
var tokens controller.Tokens
|
||||||
|
_, err := toml.DecodeFile(configFile, &common)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("decode config file %v error: %v", configFile, err)
|
log.Fatalf("decode config file %v error: %v", configFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = toml.DecodeFile(tokensFile, &config)
|
_, err = toml.DecodeFile(tokensFile, &tokens)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("decode token file %v error: %v", tokensFile, err)
|
log.Fatalf("decode token file %v error: %v", tokensFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Common.DashboardTls = strings.HasPrefix("https://", strings.ToLower(config.Common.DashboardAddr))
|
common.Common.DashboardTls = strings.HasPrefix("https://", strings.ToLower(common.Common.DashboardAddr))
|
||||||
|
|
||||||
//f, err := os.Create("/Volumes/Work/Git Sources/frps-panel/config/frps-panel-new.toml")
|
|
||||||
//if err != nil {
|
|
||||||
// log.Fatal(err)
|
|
||||||
//}
|
|
||||||
//if err := toml.NewEncoder(f).Encode(config); err != nil {
|
|
||||||
// // failed to encode
|
|
||||||
// log.Fatal(err)
|
|
||||||
//}
|
|
||||||
//if err := f.Close(); err != nil {
|
|
||||||
// // failed to close the file
|
|
||||||
// log.Fatal(err)
|
|
||||||
//}
|
|
||||||
|
|
||||||
tls := server.TLS{
|
tls := server.TLS{
|
||||||
Enable: config.Common.TlsMode,
|
Enable: common.Common.TlsMode,
|
||||||
Protocol: "HTTP",
|
Protocol: "HTTP",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,8 +100,8 @@ func parseConfigFile(configFile, tokensFile string) (controller.HandleController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return controller.HandleController{
|
return controller.HandleController{
|
||||||
CommonInfo: config.Common,
|
CommonInfo: common.Common,
|
||||||
Tokens: config.Tokens.Tokens,
|
Tokens: tokens.Tokens,
|
||||||
Version: version,
|
Version: version,
|
||||||
ConfigFile: configFile,
|
ConfigFile: configFile,
|
||||||
TokensFile: tokensFile,
|
TokensFile: tokensFile,
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
; basic options
|
|
||||||
[common]
|
|
||||||
; frps panel config info
|
|
||||||
plugin_addr = 127.0.0.1
|
|
||||||
plugin_port = 7200
|
|
||||||
admin_user = admin
|
|
||||||
admin_pwd = admin
|
|
||||||
; specified login state keep time
|
|
||||||
admin_keep_time = 0
|
|
||||||
|
|
||||||
; enable tls
|
|
||||||
tls_mode = false
|
|
||||||
; tls_cert_file = cert.crt
|
|
||||||
; tls_key_file = cert.key
|
|
||||||
|
|
||||||
; frp dashboard info
|
|
||||||
dashboard_addr = 127.0.0.1
|
|
||||||
dashboard_port = 7500
|
|
||||||
dashboard_user = admin
|
|
||||||
dashboard_pwd = admin
|
|
||||||
|
|
||||||
; user tokens
|
|
||||||
[users]
|
|
||||||
user1 = token1
|
|
||||||
|
|
||||||
; user been disabled
|
|
||||||
[disabled]
|
|
||||||
|
|
||||||
; user allowed ports. it will be used when a new proxy connect on
|
|
||||||
[ports]
|
|
||||||
|
|
||||||
; user allowed domains. it will be used when a new proxy connect on
|
|
||||||
[domains]
|
|
||||||
|
|
||||||
; user allowed subdomains. it will be used when a new proxy connect on
|
|
||||||
[subdomains]
|
|
||||||
@@ -3,15 +3,15 @@
|
|||||||
user = "user1"
|
user = "user1"
|
||||||
token = "token1"
|
token = "token1"
|
||||||
comment = "张三"
|
comment = "张三"
|
||||||
ports = ["1", "2", "3", "10-100"]
|
ports = [""]
|
||||||
domains = ["aaa.com", "bbb.com"]
|
domains = [""]
|
||||||
subdomains = ["a", "b"]
|
subdomains = [""]
|
||||||
status = true
|
status = true
|
||||||
[tokens.user2]
|
[tokens.user2]
|
||||||
user = "user2"
|
user = "user2"
|
||||||
token = "token2"
|
token = "token2"
|
||||||
comment = "李四"
|
comment = "李四"
|
||||||
ports = ["11", "22", "33", "110-200"]
|
ports = [""]
|
||||||
domains = ["ccc.com", "ddd.com"]
|
domains = [""]
|
||||||
subdomains = ["c", "d"]
|
subdomains = [""]
|
||||||
status = true
|
status = true
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func (c *HandleController) BasicAuth() gin.HandlerFunc {
|
func (c *HandleController) BasicAuth() gin.HandlerFunc {
|
||||||
return func(context *gin.Context) {
|
return func(context *gin.Context) {
|
||||||
if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" {
|
if trimString(c.CommonInfo.AdminUser) == "" || trimString(c.CommonInfo.AdminPwd) == "" {
|
||||||
if context.Request.RequestURI == LoginUrl {
|
if context.Request.RequestURI == LoginUrl {
|
||||||
context.Redirect(http.StatusTemporaryRedirect, LoginSuccessUrl)
|
context.Redirect(http.StatusTemporaryRedirect, LoginSuccessUrl)
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ func (c *HandleController) BasicAuth() gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *HandleController) LoginAuth(username, password string, context *gin.Context) bool {
|
func (c *HandleController) LoginAuth(username, password string, context *gin.Context) bool {
|
||||||
if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" {
|
if trimString(c.CommonInfo.AdminUser) == "" || trimString(c.CommonInfo.AdminPwd) == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
plugin "github.com/fatedier/frp/pkg/plugin/server"
|
plugin "github.com/fatedier/frp/pkg/plugin/server"
|
||||||
ginI18n "github.com/gin-contrib/i18n"
|
ginI18n "github.com/gin-contrib/i18n"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -123,7 +121,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
|||||||
return func(context *gin.Context) {
|
return func(context *gin.Context) {
|
||||||
context.HTML(http.StatusOK, "index.html", gin.H{
|
context.HTML(http.StatusOK, "index.html", gin.H{
|
||||||
"version": c.Version,
|
"version": c.Version,
|
||||||
"showExit": strings.TrimSpace(c.CommonInfo.AdminUser) != "" && strings.TrimSpace(c.CommonInfo.AdminPwd) != "",
|
"showExit": trimString(c.CommonInfo.AdminUser) != "" && trimString(c.CommonInfo.AdminPwd) != "",
|
||||||
"FrpsPanel": ginI18n.MustGetMessage(context, "Frps Panel"),
|
"FrpsPanel": ginI18n.MustGetMessage(context, "Frps Panel"),
|
||||||
"User": ginI18n.MustGetMessage(context, "User"),
|
"User": ginI18n.MustGetMessage(context, "User"),
|
||||||
"Token": ginI18n.MustGetMessage(context, "Token"),
|
"Token": ginI18n.MustGetMessage(context, "Token"),
|
||||||
@@ -206,6 +204,7 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
|||||||
"OperateError": ginI18n.MustGetMessage(context, "Operate error"),
|
"OperateError": ginI18n.MustGetMessage(context, "Operate error"),
|
||||||
"OperateFailed": ginI18n.MustGetMessage(context, "Operate failed"),
|
"OperateFailed": ginI18n.MustGetMessage(context, "Operate failed"),
|
||||||
"UserExist": ginI18n.MustGetMessage(context, "User exist"),
|
"UserExist": ginI18n.MustGetMessage(context, "User exist"),
|
||||||
|
"UserNotExist": ginI18n.MustGetMessage(context, "User not exist"),
|
||||||
"UserFormatError": ginI18n.MustGetMessage(context, "User format error"),
|
"UserFormatError": ginI18n.MustGetMessage(context, "User format error"),
|
||||||
"TokenFormatError": ginI18n.MustGetMessage(context, "Token format error"),
|
"TokenFormatError": ginI18n.MustGetMessage(context, "Token format error"),
|
||||||
"ShouldCheckUser": ginI18n.MustGetMessage(context, "Please check at least one user"),
|
"ShouldCheckUser": ginI18n.MustGetMessage(context, "Please check at least one user"),
|
||||||
@@ -220,6 +219,7 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
|||||||
"SubdomainsInvalid": ginI18n.MustGetMessage(context, "Subdomains is invalid"),
|
"SubdomainsInvalid": ginI18n.MustGetMessage(context, "Subdomains is invalid"),
|
||||||
"CommentInvalid": ginI18n.MustGetMessage(context, "Comment is invalid"),
|
"CommentInvalid": ginI18n.MustGetMessage(context, "Comment is invalid"),
|
||||||
"ParamError": ginI18n.MustGetMessage(context, "Param error"),
|
"ParamError": ginI18n.MustGetMessage(context, "Param error"),
|
||||||
|
"OtherError": ginI18n.MustGetMessage(context, "Other error"),
|
||||||
"Name": ginI18n.MustGetMessage(context, "Name"),
|
"Name": ginI18n.MustGetMessage(context, "Name"),
|
||||||
"Port": ginI18n.MustGetMessage(context, "Port"),
|
"Port": ginI18n.MustGetMessage(context, "Port"),
|
||||||
"Connections": ginI18n.MustGetMessage(context, "Connections"),
|
"Connections": ginI18n.MustGetMessage(context, "Connections"),
|
||||||
@@ -287,52 +287,6 @@ func (c *HandleController) MakeQueryTokensFunc() func(context *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func filter(main TokenInfo, sub TokenInfo) bool {
|
|
||||||
replaceSpaceUser := TrimAllSpaceReg.ReplaceAllString(sub.User, "")
|
|
||||||
if len(replaceSpaceUser) != 0 {
|
|
||||||
if !strings.Contains(main.User, replaceSpaceUser) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceSpaceToken := TrimAllSpaceReg.ReplaceAllString(sub.Token, "")
|
|
||||||
if len(replaceSpaceToken) != 0 {
|
|
||||||
if !strings.Contains(main.Token, replaceSpaceToken) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceSpaceComment := TrimAllSpaceReg.ReplaceAllString(sub.Comment, "")
|
|
||||||
if len(replaceSpaceComment) != 0 {
|
|
||||||
if !strings.Contains(main.Comment, replaceSpaceComment) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func TokensList(tokens map[string]TokenInfo) Tokens {
|
|
||||||
return Tokens{
|
|
||||||
tokens,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *HandleController) SaveToken() error {
|
|
||||||
tokenFile, err := os.Create(c.TokensFile)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("error to crate file %v: %v", c.TokensFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = toml.NewEncoder(tokenFile).Encode(TokensList(c.Tokens)); err != nil {
|
|
||||||
log.Printf("error to encode tokens: %v", err)
|
|
||||||
}
|
|
||||||
if err = tokenFile.Close(); err != nil {
|
|
||||||
log.Printf("error to close file %v: %v", c.TokensFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *HandleController) MakeAddTokenFunc() func(context *gin.Context) {
|
func (c *HandleController) MakeAddTokenFunc() func(context *gin.Context) {
|
||||||
return func(context *gin.Context) {
|
return func(context *gin.Context) {
|
||||||
info := TokenInfo{
|
info := TokenInfo{
|
||||||
@@ -345,46 +299,34 @@ func (c *HandleController) MakeAddTokenFunc() func(context *gin.Context) {
|
|||||||
}
|
}
|
||||||
err := context.BindJSON(&info)
|
err := context.BindJSON(&info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("user add failed, param error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "user add failed, param error "
|
response.Message = fmt.Sprintf("user add failed, param error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !UserFormatReg.MatchString(info.User) {
|
|
||||||
log.Printf("user add failed, user format error")
|
result := c.verifyToken(info, TOKEN_ADD)
|
||||||
response.Success = false
|
|
||||||
response.Code = UserFormatError
|
if !result.Success {
|
||||||
response.Message = fmt.Sprintf("user add failed, user format error")
|
context.JSON(http.StatusOK, &result)
|
||||||
context.JSON(http.StatusOK, &response)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, exist := c.Tokens[info.User]; exist {
|
|
||||||
log.Printf("user add failed, user [%v] exist", info.User)
|
|
||||||
response.Success = false
|
|
||||||
response.Code = UserExist
|
|
||||||
response.Message = fmt.Sprintf("user add failed, user [%s] exist ", info.User)
|
|
||||||
context.JSON(http.StatusOK, &response)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !TokenFormatReg.MatchString(info.Token) {
|
|
||||||
log.Printf("user add failed, token format error")
|
|
||||||
response.Success = false
|
|
||||||
response.Code = TokenFormatError
|
|
||||||
response.Message = fmt.Sprintf("user add failed, token format error")
|
|
||||||
context.JSON(http.StatusOK, &response)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.Comment = cleanString(info.Comment)
|
||||||
|
info.Ports = cleanStrings(info.Ports)
|
||||||
|
info.Domains = cleanStrings(info.Domains)
|
||||||
|
info.Subdomains = cleanStrings(info.Subdomains)
|
||||||
|
|
||||||
c.Tokens[info.User] = info
|
c.Tokens[info.User] = info
|
||||||
|
|
||||||
err = c.SaveToken()
|
err = c.saveToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("add failed, error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = SaveError
|
response.Code = SaveError
|
||||||
response.Message = "user add failed"
|
response.Message = fmt.Sprintf("add failed, error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -403,10 +345,10 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) {
|
|||||||
update := TokenUpdate{}
|
update := TokenUpdate{}
|
||||||
err := context.BindJSON(&update)
|
err := context.BindJSON(&update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("update failed, param error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "user update failed, param error"
|
response.Message = fmt.Sprintf("update failed, param error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -414,32 +356,35 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) {
|
|||||||
before := update.Before
|
before := update.Before
|
||||||
after := update.After
|
after := update.After
|
||||||
|
|
||||||
if after.User != before.User {
|
if before.User != after.User {
|
||||||
log.Printf("update failed, user not match")
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "update failed, user not match"
|
response.Message = fmt.Sprintf("update failed, user should be same : before -> %v, after -> %v", before.User, after.User)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !TokenFormatReg.MatchString(after.Token) {
|
result := c.verifyToken(after, TOKEN_UPDATE)
|
||||||
log.Printf("update failed, token format error")
|
|
||||||
response.Success = false
|
if !result.Success {
|
||||||
response.Code = TokenFormatError
|
context.JSON(http.StatusOK, &result)
|
||||||
response.Message = "user update failed, token format error"
|
|
||||||
context.JSON(http.StatusOK, &response)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
after.Comment = cleanString(after.Comment)
|
||||||
|
after.Ports = cleanStrings(after.Ports)
|
||||||
|
after.Domains = cleanStrings(after.Domains)
|
||||||
|
after.Subdomains = cleanStrings(after.Subdomains)
|
||||||
|
|
||||||
c.Tokens[after.User] = after
|
c.Tokens[after.User] = after
|
||||||
|
|
||||||
err = c.SaveToken()
|
err = c.saveToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("user update failed, error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = SaveError
|
response.Code = SaveError
|
||||||
response.Message = "user update failed"
|
response.Message = fmt.Sprintf("user update failed, error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -458,24 +403,33 @@ func (c *HandleController) MakeRemoveTokensFunc() func(context *gin.Context) {
|
|||||||
remove := TokenRemove{}
|
remove := TokenRemove{}
|
||||||
err := context.BindJSON(&remove)
|
err := context.BindJSON(&remove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("user remove failed, param error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "user remove failed, param error "
|
response.Message = fmt.Sprintf("user remove failed, param error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, user := range remove.Users {
|
||||||
|
result := c.verifyToken(user, TOKEN_REMOVE)
|
||||||
|
|
||||||
|
if !result.Success {
|
||||||
|
context.JSON(http.StatusOK, &result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, user := range remove.Users {
|
for _, user := range remove.Users {
|
||||||
delete(c.Tokens, user.User)
|
delete(c.Tokens, user.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.SaveToken()
|
err = c.saveToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("user update failed, error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = SaveError
|
response.Code = SaveError
|
||||||
response.Message = "user update failed"
|
response.Message = fmt.Sprintf("user update failed, error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -494,27 +448,36 @@ func (c *HandleController) MakeDisableTokensFunc() func(context *gin.Context) {
|
|||||||
disable := TokenDisable{}
|
disable := TokenDisable{}
|
||||||
err := context.BindJSON(&disable)
|
err := context.BindJSON(&disable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("disable failed, param error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "disable failed, param error "
|
response.Message = fmt.Sprintf("disable failed, param error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, user := range disable.Users {
|
||||||
|
result := c.verifyToken(user, TOKEN_DISABLE)
|
||||||
|
|
||||||
|
if !result.Success {
|
||||||
|
context.JSON(http.StatusOK, &result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, user := range disable.Users {
|
for _, user := range disable.Users {
|
||||||
token := c.Tokens[user.User]
|
token := c.Tokens[user.User]
|
||||||
token.Status = false
|
token.Status = false
|
||||||
c.Tokens[user.User] = token
|
c.Tokens[user.User] = token
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.SaveToken()
|
err = c.saveToken()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("disable failed, error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = SaveError
|
response.Code = SaveError
|
||||||
response.Message = "disable failed"
|
response.Message = fmt.Sprintf("disable failed, error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -533,21 +496,30 @@ func (c *HandleController) MakeEnableTokensFunc() func(context *gin.Context) {
|
|||||||
enable := TokenEnable{}
|
enable := TokenEnable{}
|
||||||
err := context.BindJSON(&enable)
|
err := context.BindJSON(&enable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("enable failed, param error : %v", err)
|
|
||||||
response.Success = false
|
response.Success = false
|
||||||
response.Code = ParamError
|
response.Code = ParamError
|
||||||
response.Message = "enable failed, param error "
|
response.Message = fmt.Sprintf("enable failed, param error : %v", err)
|
||||||
|
log.Printf(response.Message)
|
||||||
context.JSON(http.StatusOK, &response)
|
context.JSON(http.StatusOK, &response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, user := range enable.Users {
|
||||||
|
result := c.verifyToken(user, TOKEN_ENABLE)
|
||||||
|
|
||||||
|
if !result.Success {
|
||||||
|
context.JSON(http.StatusOK, &result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, user := range enable.Users {
|
for _, user := range enable.Users {
|
||||||
token := c.Tokens[user.User]
|
token := c.Tokens[user.User]
|
||||||
token.Status = true
|
token.Status = true
|
||||||
c.Tokens[user.User] = token
|
c.Tokens[user.User] = token
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.SaveToken()
|
err = c.saveToken()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("enable failed, error : %v", err)
|
log.Printf("enable failed, error : %v", err)
|
||||||
@@ -588,7 +560,7 @@ func (c *HandleController) MakeProxyFunc() func(context *gin.Context) {
|
|||||||
request, _ := http.NewRequest("GET", requestUrl, nil)
|
request, _ := http.NewRequest("GET", requestUrl, nil)
|
||||||
username := c.CommonInfo.DashboardUser
|
username := c.CommonInfo.DashboardUser
|
||||||
password := c.CommonInfo.DashboardPwd
|
password := c.CommonInfo.DashboardPwd
|
||||||
if len(strings.TrimSpace(username)) != 0 && len(strings.TrimSpace(password)) != 0 {
|
if trimString(username) != "" && trimString(password) != "" {
|
||||||
request.SetBasicAuth(username, password)
|
request.SetBasicAuth(username, password)
|
||||||
log.Printf("Proxy to %s", requestUrl)
|
log.Printf("Proxy to %s", requestUrl)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
|
|||||||
}
|
}
|
||||||
proxyType := content.ProxyType
|
proxyType := content.ProxyType
|
||||||
|
|
||||||
if StringIndexOf(proxyType, supportProxyTypes) == -1 {
|
if stringContains(proxyType, supportProxyTypes) {
|
||||||
log.Printf("proxy type [%v] not support, plugin do nothing", proxyType)
|
log.Printf("proxy type [%v] not support, plugin do nothing", proxyType)
|
||||||
res.Unchange = true
|
res.Unchange = true
|
||||||
return res
|
return res
|
||||||
@@ -100,12 +100,12 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
|
|||||||
portErr = fmt.Errorf("user [%v] port range [%v] format error", user, port)
|
portErr = fmt.Errorf("user [%v] port range [%v] format error", user, port)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
start, err := strconv.Atoi(strings.TrimSpace(allowedRanges[0]))
|
start, err := strconv.Atoi(trimString(allowedRanges[0]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
portErr = fmt.Errorf("user [%v] port rang [%v] start port [%v] is not a number", user, port, allowedRanges[0])
|
portErr = fmt.Errorf("user [%v] port rang [%v] start port [%v] is not a number", user, port, allowedRanges[0])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
end, err := strconv.Atoi(strings.TrimSpace(allowedRanges[1]))
|
end, err := strconv.Atoi(trimString(allowedRanges[1]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
portErr = fmt.Errorf("user [%v] port rang [%v] end port [%v] is not a number", user, port, allowedRanges[0])
|
portErr = fmt.Errorf("user [%v] port rang [%v] end port [%v] is not a number", user, port, allowedRanges[0])
|
||||||
break
|
break
|
||||||
@@ -141,7 +141,7 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
|
|||||||
if portAllowed {
|
if portAllowed {
|
||||||
if token, exist := c.Tokens[user]; exist {
|
if token, exist := c.Tokens[user]; exist {
|
||||||
for _, userDomain := range userDomains {
|
for _, userDomain := range userDomains {
|
||||||
if StringIndexOf(userDomain, token.Domains) == -1 {
|
if stringContains(userDomain, token.Domains) {
|
||||||
domainAllowed = false
|
domainAllowed = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -183,12 +183,3 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func StringIndexOf(element string, data []string) int {
|
|
||||||
for k, v := range data {
|
|
||||||
if element == v {
|
|
||||||
return k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|||||||
205
pkg/server/controller/utils.go
Normal file
205
pkg/server/controller/utils.go
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func filter(main TokenInfo, sub TokenInfo) bool {
|
||||||
|
replaceSpaceUser := trimAllSpace.ReplaceAllString(sub.User, "")
|
||||||
|
if len(replaceSpaceUser) != 0 {
|
||||||
|
if !strings.Contains(main.User, replaceSpaceUser) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceSpaceToken := trimAllSpace.ReplaceAllString(sub.Token, "")
|
||||||
|
if len(replaceSpaceToken) != 0 {
|
||||||
|
if !strings.Contains(main.Token, replaceSpaceToken) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceSpaceComment := trimAllSpace.ReplaceAllString(sub.Comment, "")
|
||||||
|
if len(replaceSpaceComment) != 0 {
|
||||||
|
if !strings.Contains(main.Comment, replaceSpaceComment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimString(str string) string {
|
||||||
|
return strings.TrimSpace(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandleController) verifyToken(token TokenInfo, operate int) OperationResponse {
|
||||||
|
response := OperationResponse{
|
||||||
|
Success: true,
|
||||||
|
Code: Success,
|
||||||
|
Message: "operate success",
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
validateExist = false
|
||||||
|
validateNotExist = false
|
||||||
|
validateUser = false
|
||||||
|
validateToken = false
|
||||||
|
validateComment = false
|
||||||
|
validatePorts = false
|
||||||
|
validateDomains = false
|
||||||
|
validateSubdomains = false
|
||||||
|
)
|
||||||
|
|
||||||
|
if operate == TOKEN_ADD {
|
||||||
|
validateExist = true
|
||||||
|
validateUser = true
|
||||||
|
validateToken = true
|
||||||
|
validateComment = true
|
||||||
|
validatePorts = true
|
||||||
|
validateDomains = true
|
||||||
|
validateSubdomains = true
|
||||||
|
} else if operate == TOKEN_UPDATE {
|
||||||
|
validateNotExist = true
|
||||||
|
validateUser = true
|
||||||
|
validateToken = true
|
||||||
|
validateComment = true
|
||||||
|
validatePorts = true
|
||||||
|
validateDomains = true
|
||||||
|
validateSubdomains = true
|
||||||
|
} else if operate == TOKEN_ENABLE || operate == TOKEN_DISABLE || operate == TOKEN_REMOVE {
|
||||||
|
validateNotExist = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateUser && !userFormat.MatchString(token.User) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = UserFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, user [%s] format error", token.User)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateExist {
|
||||||
|
if _, exist := c.Tokens[token.User]; exist {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = UserExist
|
||||||
|
response.Message = fmt.Sprintf("operate failed, user [%s] exist ", token.User)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateNotExist {
|
||||||
|
if _, exist := c.Tokens[token.User]; !exist {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = UserNotExist
|
||||||
|
response.Message = fmt.Sprintf("operate failed, user [%s] not exist ", token.User)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateToken && !tokenFormat.MatchString(token.Token) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = TokenFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, token [%s] format error", token.Token)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
trimmedComment := trimString(token.Comment)
|
||||||
|
if validateComment && trimmedComment != "" && commentFormat.MatchString(trimmedComment) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = CommentFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, comment [%s] format error", token.Comment)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
if validatePorts {
|
||||||
|
for _, port := range token.Ports {
|
||||||
|
trimmedPort := trimString(port)
|
||||||
|
if trimmedPort != "" && !portsFormatSingle.MatchString(trimmedPort) && !portsFormatRange.MatchString(trimmedPort) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = PortsFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, ports [%v] format error", token.Ports)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateDomains {
|
||||||
|
for _, domain := range token.Domains {
|
||||||
|
trimmedDomain := trimString(domain)
|
||||||
|
if trimmedDomain != "" && !domainFormat.MatchString(trimmedDomain) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = DomainsFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, domains [%v] format error", token.Domains)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if validateSubdomains {
|
||||||
|
for _, subdomain := range token.Subdomains {
|
||||||
|
trimmedSubdomain := trimString(subdomain)
|
||||||
|
if trimmedSubdomain != "" && !subdomainFormat.MatchString(trimmedSubdomain) {
|
||||||
|
response.Success = false
|
||||||
|
response.Code = SubdomainsFormatError
|
||||||
|
response.Message = fmt.Sprintf("operate failed, subdomains [%v] format error", token.Subdomains)
|
||||||
|
log.Printf(response.Message)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanStrings(originalStrings []string) []string {
|
||||||
|
cleanedStrings := make([]string, len(originalStrings))
|
||||||
|
for i, str := range originalStrings {
|
||||||
|
cleanedStrings[i] = cleanString(str)
|
||||||
|
}
|
||||||
|
return cleanedStrings
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanString(originalString string) string {
|
||||||
|
return trimAllSpace.ReplaceAllString(originalString, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringContains(element string, data []string) bool {
|
||||||
|
for _, v := range data {
|
||||||
|
if element == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func tokensList(tokens map[string]TokenInfo) Tokens {
|
||||||
|
return Tokens{
|
||||||
|
tokens,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HandleController) saveToken() error {
|
||||||
|
tokenFile, err := os.Create(c.TokensFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error to crate file %v: %v", c.TokensFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = toml.NewEncoder(tokenFile).Encode(tokensList(c.Tokens)); err != nil {
|
||||||
|
log.Printf("error to encode tokens: %v", err)
|
||||||
|
}
|
||||||
|
if err = tokenFile.Close(); err != nil {
|
||||||
|
log.Printf("error to close file %v: %v", c.TokensFile, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -5,14 +5,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Success = 0
|
Success int = iota
|
||||||
ParamError = 1
|
ParamError
|
||||||
UserExist = 2
|
UserExist
|
||||||
SaveError = 3
|
UserNotExist
|
||||||
UserFormatError = 4
|
SaveError
|
||||||
TokenFormatError = 5
|
UserFormatError
|
||||||
FrpServerError = 6
|
TokenFormatError
|
||||||
|
CommentFormatError
|
||||||
|
PortsFormatError
|
||||||
|
DomainsFormatError
|
||||||
|
SubdomainsFormatError
|
||||||
|
FrpServerError
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TOKEN_ADD int = iota
|
||||||
|
TOKEN_UPDATE
|
||||||
|
TOKEN_REMOVE
|
||||||
|
TOKEN_ENABLE
|
||||||
|
TOKEN_DISABLE
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
SessionName = "GOSESSION"
|
SessionName = "GOSESSION"
|
||||||
AuthName = "_PANEL_AUTH"
|
AuthName = "_PANEL_AUTH"
|
||||||
LoginUrl = "/login"
|
LoginUrl = "/login"
|
||||||
@@ -22,9 +37,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
UserFormatReg = regexp.MustCompile("^\\w+$")
|
userFormat = regexp.MustCompile("^\\w+$")
|
||||||
TokenFormatReg = regexp.MustCompile("^[\\w!@#$%^&*()]+$")
|
tokenFormat = regexp.MustCompile("^[\\w!@#$%^&*()]+$")
|
||||||
TrimAllSpaceReg = regexp.MustCompile("[\\n\\t\\r\\s]")
|
commentFormat = regexp.MustCompile("[\\n\\t\\r]")
|
||||||
|
portsFormatSingle = regexp.MustCompile("^\\s*\\d{1,5}\\s*$")
|
||||||
|
portsFormatRange = regexp.MustCompile("^\\s*\\d{1,5}\\s*-\\s*\\d{1,5}\\s*$")
|
||||||
|
domainFormat = regexp.MustCompile("^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+[a-zA-Z]{2,}$")
|
||||||
|
subdomainFormat = regexp.MustCompile("^[a-zA-z0-9-]{1,20}$")
|
||||||
|
trimAllSpace = regexp.MustCompile("[\\n\\t\\r\\s]")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@@ -36,9 +56,8 @@ type HTTPError struct {
|
|||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Common struct {
|
||||||
Common CommonInfo
|
Common CommonInfo
|
||||||
Tokens
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommonInfo struct {
|
type CommonInfo struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user