init
This commit is contained in:
commit
b6f84af6bd
4 changed files with 197 additions and 0 deletions
7
go.mod
Normal file
7
go.mod
Normal file
|
@ -0,0 +1,7 @@
|
|||
module vpn.konfach.ru/controller
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require github.com/carlmjohnson/requests v0.24.2
|
||||
|
||||
require golang.org/x/net v0.27.0 // indirect
|
4
go.sum
Normal file
4
go.sum
Normal file
|
@ -0,0 +1,4 @@
|
|||
github.com/carlmjohnson/requests v0.24.2 h1:JDakhAmTIKL/qL/1P7Kkc2INGBJIkIFP6xUeUmPzLso=
|
||||
github.com/carlmjohnson/requests v0.24.2/go.mod h1:duYA/jDnyZ6f3xbcF5PpZ9N8clgopubP2nK5i6MVMhU=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
5
main.go
Normal file
5
main.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package main
|
||||
|
||||
func main() {
|
||||
|
||||
}
|
181
src/panels/3x/api.go
Normal file
181
src/panels/3x/api.go
Normal file
|
@ -0,0 +1,181 @@
|
|||
package tresx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
|
||||
"github.com/carlmjohnson/requests"
|
||||
)
|
||||
|
||||
type XUIPriovider struct {
|
||||
baseUrl string
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func NewTresXProvider(basePath string) *XUIPriovider {
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &XUIPriovider{
|
||||
baseUrl: basePath,
|
||||
client: &http.Client{
|
||||
Jar: jar,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type basicResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"msg"`
|
||||
Object json.RawMessage `json:"obj"`
|
||||
}
|
||||
|
||||
func (t *XUIPriovider) Login(login, password string) error {
|
||||
params := url.Values{}
|
||||
params.Add("username", login)
|
||||
params.Add("password", password)
|
||||
|
||||
url := fmt.Sprintf("%s/login?%s", t.baseUrl, params.Encode())
|
||||
req, err := http.NewRequest("POST", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := t.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var resp basicResponse
|
||||
err = json.Unmarshal(body, &resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
return fmt.Errorf("login failed: %s", resp.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Inbound struct {
|
||||
ID int64 `json:"id"`
|
||||
Up int64 `json:"up"`
|
||||
Down int64 `json:"down"`
|
||||
Total int64 `json:"total"`
|
||||
Remark string `json:"remark"`
|
||||
Enable bool `json:"enable"`
|
||||
ExpiryTime int64 `json:"expiryTime"`
|
||||
ClientStats []ClientStat `json:"clientStats"`
|
||||
Listen string `json:"listen"`
|
||||
Port int64 `json:"port"`
|
||||
Protocol string `json:"protocol"`
|
||||
Settings string `json:"settings"`
|
||||
StreamSettings string `json:"streamSettings"`
|
||||
Tag string `json:"tag"`
|
||||
Sniffing string `json:"sniffing"`
|
||||
Allocate string `json:"allocate"`
|
||||
}
|
||||
|
||||
type ClientStat struct {
|
||||
ID int64 `json:"id"`
|
||||
InboundID int64 `json:"inboundId"`
|
||||
Enable bool `json:"enable"`
|
||||
Email string `json:"email"`
|
||||
Up int64 `json:"up"`
|
||||
Down int64 `json:"down"`
|
||||
ExpiryTime int64 `json:"expiryTime"`
|
||||
Total int64 `json:"total"`
|
||||
Reset int64 `json:"reset"`
|
||||
}
|
||||
|
||||
func (t *XUIPriovider) Inbounds(ctx context.Context) error {
|
||||
var resp basicResponse
|
||||
err := requests.
|
||||
URL(t.baseUrl).
|
||||
Path("panel/api/inbounds/list").
|
||||
Client(t.client).
|
||||
ToJSON(&resp).
|
||||
Fetch(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
return fmt.Errorf("logout failed: %s", resp.Message)
|
||||
}
|
||||
|
||||
var inbounds []Inbound
|
||||
err = json.Unmarshal(resp.Object, &inbounds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type addClientRequest struct {
|
||||
ID int `json:"id"`
|
||||
Settings json.RawMessage `json:"settings"`
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
Flow string `json:"flow"`
|
||||
Email string `json:"email"`
|
||||
LimitIP int64 `json:"limitIp"`
|
||||
TotalGB int64 `json:"totalGB"`
|
||||
ExpiryTime int64 `json:"expiryTime"`
|
||||
Enable bool `json:"enable"`
|
||||
TgID string `json:"tgId"`
|
||||
SubID string `json:"subId"`
|
||||
Reset int64 `json:"reset"`
|
||||
}
|
||||
|
||||
func (t *XUIPriovider) AddClientToInbound(ctx context.Context, inboundID int, clients []Client) error {
|
||||
addReq := addClientRequest{
|
||||
ID: inboundID,
|
||||
}
|
||||
|
||||
settings := struct {
|
||||
Clients []Client `json:"clients"`
|
||||
}{
|
||||
Clients: clients,
|
||||
}
|
||||
var err error
|
||||
addReq.Settings, err = json.Marshal(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var resp basicResponse
|
||||
err = requests.
|
||||
URL(t.baseUrl).
|
||||
Path("panel/api/inbounds/addClient").
|
||||
Post().
|
||||
BodyJSON(addReq).
|
||||
Client(t.client).
|
||||
ToJSON(&resp).
|
||||
Fetch(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
return fmt.Errorf("logout failed: %s", resp.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in a new issue