change config from ini to toml (processing)

This commit is contained in:
杨黄林
2023-09-14 23:29:42 +08:00
parent e2d276c4fc
commit 7e09934024
11 changed files with 168 additions and 412 deletions

View File

@@ -12,7 +12,7 @@ import (
func (c *HandleController) BasicAuth() gin.HandlerFunc {
return func(context *gin.Context) {
if strings.TrimSpace(c.CommonInfo.User) == "" || strings.TrimSpace(c.CommonInfo.Pwd) == "" {
if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" {
if context.Request.RequestURI == LoginUrl {
context.Redirect(http.StatusTemporaryRedirect, LoginSuccessUrl)
}
@@ -23,19 +23,19 @@ func (c *HandleController) BasicAuth() gin.HandlerFunc {
auth := session.Get(AuthName)
if auth != nil {
if c.CommonInfo.KeepTime > 0 {
if c.CommonInfo.AdminKeepTime > 0 {
cookie, _ := context.Request.Cookie(SessionName)
if cookie != nil {
//important thx https://blog.csdn.net/zhanghongxia8285/article/details/107321838/
cookie.Expires = time.Now().Add(time.Second * time.Duration(c.CommonInfo.KeepTime))
cookie.Expires = time.Now().Add(time.Second * time.Duration(c.CommonInfo.AdminKeepTime))
http.SetCookie(context.Writer, cookie)
}
}
username, password, _ := parseBasicAuth(fmt.Sprintf("%v", auth))
usernameMatch := username == c.CommonInfo.User
passwordMatch := password == c.CommonInfo.Pwd
usernameMatch := username == c.CommonInfo.AdminUser
passwordMatch := password == c.CommonInfo.AdminPwd
if usernameMatch && passwordMatch {
context.Next()
@@ -54,14 +54,14 @@ func (c *HandleController) BasicAuth() gin.HandlerFunc {
}
func (c *HandleController) LoginAuth(username, password string, context *gin.Context) bool {
if strings.TrimSpace(c.CommonInfo.User) == "" || strings.TrimSpace(c.CommonInfo.Pwd) == "" {
if strings.TrimSpace(c.CommonInfo.AdminUser) == "" || strings.TrimSpace(c.CommonInfo.AdminPwd) == "" {
return true
}
session := sessions.Default(context)
sessionAuth := session.Get(AuthName)
internalAuth := encodeBasicAuth(c.CommonInfo.User, c.CommonInfo.Pwd)
internalAuth := encodeBasicAuth(c.CommonInfo.AdminUser, c.CommonInfo.AdminPwd)
if sessionAuth == internalAuth {
return true

View File

@@ -5,12 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/BurntSushi/toml"
plugin "github.com/fatedier/frp/pkg/plugin/server"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
"io"
"log"
"net/http"
"os"
"sort"
"strconv"
"strings"
@@ -121,7 +123,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
return func(context *gin.Context) {
context.HTML(http.StatusOK, "index.html", gin.H{
"version": c.Version,
"showExit": strings.TrimSpace(c.CommonInfo.User) != "" && strings.TrimSpace(c.CommonInfo.Pwd) != "",
"showExit": strings.TrimSpace(c.CommonInfo.AdminUser) != "" && strings.TrimSpace(c.CommonInfo.AdminPwd) != "",
"FrpsPanel": ginI18n.MustGetMessage(context, "Frps Panel"),
"User": ginI18n.MustGetMessage(context, "User"),
"Token": ginI18n.MustGetMessage(context, "Token"),
@@ -352,36 +354,18 @@ func (c *HandleController) MakeAddTokenFunc() func(context *gin.Context) {
context.JSON(http.StatusOK, &response)
return
}
replaceSpaceToken := TrimAllSpaceReg.ReplaceAllString(info.Token, "")
info.Token = replaceSpaceToken
c.Tokens[info.User] = info
usersSection, _ := c.IniFile.GetSection("users")
key, err := usersSection.NewKey(info.User, info.Token)
key.Comment = info.Comment
replaceSpacePorts := TrimAllSpaceReg.ReplaceAllString(info.Ports, "")
if len(replaceSpacePorts) != 0 {
portsSection, _ := c.IniFile.GetSection("ports")
key, err = portsSection.NewKey(info.User, replaceSpacePorts)
key.Comment = fmt.Sprintf("user %s allowed ports", info.User)
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(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)
}
replaceSpaceDomains := TrimAllSpaceReg.ReplaceAllString(info.Domains, "")
if len(replaceSpaceDomains) != 0 {
domainsSection, _ := c.IniFile.GetSection("domains")
key, err = domainsSection.NewKey(info.User, replaceSpaceDomains)
key.Comment = fmt.Sprintf("user %s allowed domains", info.User)
}
replaceSpaceSubdomains := TrimAllSpaceReg.ReplaceAllString(info.Subdomains, "")
if len(replaceSpaceSubdomains) != 0 {
subdomainsSection, _ := c.IniFile.GetSection("subdomains")
key, err = subdomainsSection.NewKey(info.User, replaceSpaceSubdomains)
key.Comment = fmt.Sprintf("user %s allowed subdomains", info.User)
}
err = c.IniFile.SaveTo(c.ConfigFile)
if err != nil {
log.Printf("add failed, error : %v", err)
response.Success = false
@@ -414,13 +398,7 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) {
}
after := update.After
before := update.Before
usersSection, _ := c.IniFile.GetSection("users")
key, err := usersSection.GetKey(before.User)
comment := TrimBreakLineReg.ReplaceAllString(after.Comment, "")
after.Comment = comment
key.Comment = comment
_ = update.Before
if !TokenFormatReg.MatchString(after.Token) {
log.Printf("update failed, token format error")
@@ -430,58 +408,20 @@ func (c *HandleController) MakeUpdateTokensFunc() func(context *gin.Context) {
context.JSON(http.StatusOK, &response)
return
}
replaceSpaceToken := TrimAllSpaceReg.ReplaceAllString(after.Token, "")
after.Token = replaceSpaceToken
key.SetValue(replaceSpaceToken)
if before.Ports != after.Ports {
portsSection, _ := c.IniFile.GetSection("ports")
replaceSpacePorts := TrimAllSpaceReg.ReplaceAllString(after.Ports, "")
after.Ports = replaceSpacePorts
ports := strings.Split(replaceSpacePorts, ",")
if len(replaceSpacePorts) != 0 {
key, err = portsSection.NewKey(after.User, replaceSpacePorts)
key.Comment = fmt.Sprintf("user %s allowed ports", after.User)
c.Ports[after.User] = ports
} else {
portsSection.DeleteKey(after.User)
delete(c.Ports, after.User)
}
}
if before.Domains != after.Domains {
domainsSection, _ := c.IniFile.GetSection("domains")
replaceSpaceDomains := TrimAllSpaceReg.ReplaceAllString(after.Domains, "")
after.Domains = replaceSpaceDomains
domains := strings.Split(replaceSpaceDomains, ",")
if len(replaceSpaceDomains) != 0 {
key, err = domainsSection.NewKey(after.User, replaceSpaceDomains)
key.Comment = fmt.Sprintf("user %s allowed domains", after.User)
c.Domains[after.User] = domains
} else {
domainsSection.DeleteKey(after.User)
delete(c.Domains, after.User)
}
}
if before.Subdomains != after.Subdomains {
subdomainsSection, _ := c.IniFile.GetSection("subdomains")
replaceSpaceSubdomains := TrimAllSpaceReg.ReplaceAllString(after.Subdomains, "")
after.Subdomains = replaceSpaceSubdomains
subdomains := strings.Split(replaceSpaceSubdomains, ",")
if len(replaceSpaceSubdomains) != 0 {
key, err = subdomainsSection.NewKey(after.User, replaceSpaceSubdomains)
key.Comment = fmt.Sprintf("user %s allowed subdomains", after.User)
c.Subdomains[after.User] = subdomains
} else {
subdomainsSection.DeleteKey(after.User)
delete(c.Subdomains, after.User)
}
}
c.Tokens[after.User] = after
err = c.IniFile.SaveTo(c.ConfigFile)
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(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)
}
if err != nil {
log.Printf("user update failed, error : %v", err)
response.Success = false
@@ -513,36 +453,26 @@ func (c *HandleController) MakeRemoveTokensFunc() func(context *gin.Context) {
return
}
usersSection, _ := c.IniFile.GetSection("users")
for _, user := range remove.Users {
delete(c.Tokens, user.User)
usersSection.DeleteKey(user.User)
}
portsSection, _ := c.IniFile.GetSection("ports")
for _, user := range remove.Users {
delete(c.Ports, user.User)
portsSection.DeleteKey(user.User)
}
domainsSection, _ := c.IniFile.GetSection("domains")
for _, user := range remove.Users {
delete(c.Domains, user.User)
domainsSection.DeleteKey(user.User)
}
subdomainsSection, _ := c.IniFile.GetSection("subdomains")
for _, user := range remove.Users {
delete(c.Subdomains, user.User)
subdomainsSection.DeleteKey(user.User)
}
err = c.IniFile.SaveTo(c.ConfigFile)
tokenFile, err := os.Create(c.TokensFile)
if err != nil {
log.Printf("user remove failed, error : %v", err)
log.Printf("error to crate file %v: %v", c.TokensFile, err)
}
if err = toml.NewEncoder(tokenFile).Encode(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)
}
if err != nil {
log.Printf("user update failed, error : %v", err)
response.Success = false
response.Code = SaveError
response.Message = "user remove failed"
response.Message = "user update failed"
context.JSON(http.StatusOK, &response)
return
}
@@ -569,25 +499,22 @@ func (c *HandleController) MakeDisableTokensFunc() func(context *gin.Context) {
return
}
section, _ := c.IniFile.GetSection("disabled")
for _, user := range disable.Users {
section.DeleteKey(user.User)
token := c.Tokens[user.User]
token.Status = false
c.Tokens[user.User] = token
key, err := section.NewKey(user.User, "disable")
if err != nil {
log.Printf("disable failed, error : %v", err)
response.Success = false
response.Code = SaveError
response.Message = "disable failed"
context.JSON(http.StatusOK, &response)
return
}
key.Comment = fmt.Sprintf("disable user '%s'", user.User)
}
err = c.IniFile.SaveTo(c.ConfigFile)
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(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)
}
if err != nil {
log.Printf("disable failed, error : %v", err)
response.Success = false
@@ -619,15 +546,22 @@ func (c *HandleController) MakeEnableTokensFunc() func(context *gin.Context) {
return
}
section, _ := c.IniFile.GetSection("disabled")
for _, user := range enable.Users {
section.DeleteKey(user.User)
token := c.Tokens[user.User]
token.Status = true
c.Tokens[user.User] = token
}
err = c.IniFile.SaveTo(c.ConfigFile)
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(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)
}
if err != nil {
log.Printf("enable failed, error : %v", err)
response.Success = false
@@ -646,7 +580,7 @@ func (c *HandleController) MakeProxyFunc() func(context *gin.Context) {
var client *http.Client
var protocol string
if c.CommonInfo.DashboardTLS {
if c.CommonInfo.DashboardTls {
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{

View File

@@ -92,8 +92,8 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
portAllowed := true
if proxyType == "tcp" || proxyType == "udp" {
portAllowed = false
if _, exist := c.Ports[user]; exist {
for _, port := range c.Ports[user] {
if token, exist := c.Tokens[user]; exist {
for _, port := range token.Ports {
if strings.Contains(port, "-") {
allowedRanges := strings.Split(port, "-")
if len(allowedRanges) != 2 {
@@ -139,9 +139,9 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
domainAllowed := true
if proxyType == "http" || proxyType == "https" || proxyType == "tcpmux" {
if portAllowed {
if _, exist := c.Domains[user]; exist {
if token, exist := c.Tokens[user]; exist {
for _, userDomain := range userDomains {
if StringIndexOf(userDomain, c.Domains[user]) == -1 {
if StringIndexOf(userDomain, token.Domains) == -1 {
domainAllowed = false
break
}
@@ -158,8 +158,8 @@ func (c *HandleController) JudgePort(content *plugin.NewProxyContent) plugin.Res
if proxyType == "http" || proxyType == "https" {
subdomainAllowed = false
if portAllowed && domainAllowed {
if _, exist := c.Subdomains[user]; exist {
for _, subdomain := range c.Subdomains[user] {
if token, exist := c.Tokens[user]; exist {
for _, subdomain := range token.Subdomains {
if subdomain == userSubdomain {
subdomainAllowed = true
break

View File

@@ -2,7 +2,6 @@ package controller
import (
"github.com/gin-gonic/gin"
"gopkg.in/ini.v1"
"os"
"path/filepath"
)
@@ -10,12 +9,9 @@ import (
type HandleController struct {
CommonInfo CommonInfo
Tokens map[string]TokenInfo
Ports map[string][]string
Domains map[string][]string
Subdomains map[string][]string
ConfigFile string
IniFile *ini.File
Version string
ConfigFile string
TokensFile string
}
func NewHandleController(config *HandleController) *HandleController {
@@ -39,7 +35,7 @@ func (c *HandleController) Register(rootDir string, engine *gin.Engine) {
engine.GET(LogoutUrl, c.MakeLogoutFunc())
var group *gin.RouterGroup
if len(c.CommonInfo.User) != 0 {
if len(c.CommonInfo.AdminUser) != 0 {
//group = engine.Group("/", gin.BasicAuthForRealm(gin.Accounts{
// c.CommonInfo.User: c.CommonInfo.Pwd,
//}, "Restricted"))

View File

@@ -37,27 +37,35 @@ type HTTPError struct {
Err error
}
type Config struct {
Common CommonInfo
Tokens []TokenInfo
}
type CommonInfo struct {
PluginAddr string
PluginPort int
User string
Pwd string
KeepTime int
DashboardTLS bool
DashboardAddr string
DashboardPort int
DashboardUser string
DashboardPwd string
PluginAddr string `toml:"plugin_addr"`
PluginPort int `toml:"plugin_port"`
AdminUser string `toml:"admin_user"`
AdminPwd string `toml:"admin_pwd"`
AdminKeepTime int `toml:"admin_keep_time"`
TlsMode bool `toml:"tls_mode"`
TlsCertFile string `toml:"tls_cert_file"`
TlsKeyFile string `toml:"tls_key_file"`
DashboardAddr string `toml:"dashboard_addr"`
DashboardPort int `toml:"dashboard_port"`
DashboardUser string `toml:"dashboard_user"`
DashboardPwd string `toml:"dashboard_pwd"`
DashboardTls bool
}
type TokenInfo struct {
User string `json:"user" form:"user"`
Token string `json:"token" form:"token"`
Comment string `json:"comment" form:"comment"`
Ports string `json:"ports" from:"ports"`
Domains string `json:"domains" from:"domains"`
Subdomains string `json:"subdomains" from:"subdomains"`
Status bool `json:"status" form:"status"`
User string `toml:"user" json:"user" form:"user"`
Token string `toml:"token" json:"token" form:"token"`
Comment string `toml:"comment" json:"comment" form:"comment"`
Ports []string `toml:"ports" json:"ports" from:"ports"`
Domains []string `toml:"domains" json:"domains" from:"domains"`
Subdomains []string `toml:"subdomains" json:"subdomains" from:"subdomains"`
Status bool `toml:"status" json:"status" form:"status"`
}
type TokenResponse struct {

View File

@@ -179,7 +179,7 @@ func (s *Server) initHTTPServer() error {
HttpOnly: false,
SameSite: 4,
Path: "/",
MaxAge: s.cfg.CommonInfo.KeepTime,
MaxAge: s.cfg.CommonInfo.AdminKeepTime,
})
engine.Use(sessions.Sessions(controller.SessionName, authStore))
engine.Use(GinI18nLocalize(s.rootDir))