158 lines
3.2 KiB
Go
158 lines
3.2 KiB
Go
package srun
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/Mmx233/tool"
|
|
log "github.com/sirupsen/logrus"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Api struct {
|
|
BaseUrl string
|
|
Client *http.Client
|
|
// 禁用自动重定向
|
|
NoDirect *http.Client
|
|
}
|
|
|
|
func (a *Api) Init(https bool, domain string, client *http.Client) {
|
|
a.BaseUrl = "http"
|
|
if https {
|
|
a.BaseUrl += "s"
|
|
}
|
|
a.BaseUrl = a.BaseUrl + "://" + domain + "/"
|
|
|
|
// 初始化 http client
|
|
a.Client = client
|
|
copyClient := *client
|
|
a.NoDirect = ©Client
|
|
a.NoDirect.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {
|
|
return http.ErrUseLastResponse
|
|
}
|
|
}
|
|
|
|
func (a *Api) request(path string, query map[string]interface{}) (map[string]interface{}, error) {
|
|
log.Debugln("HTTP GET ", a.BaseUrl+path)
|
|
timestamp := fmt.Sprint(time.Now().UnixNano())
|
|
callback := "jQuery" + timestamp
|
|
if query == nil {
|
|
query = make(map[string]interface{}, 2)
|
|
}
|
|
query["callback"] = callback
|
|
query["_"] = timestamp
|
|
httpTool := tool.NewHttpTool(a.Client)
|
|
req, err := httpTool.GenReq("GET", &tool.DoHttpReq{
|
|
Url: a.BaseUrl + path,
|
|
Query: query,
|
|
})
|
|
if err != nil {
|
|
log.Debugln(err)
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := httpTool.Client.Do(req)
|
|
if err != nil {
|
|
log.Debugln(err)
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Debugln(err)
|
|
return nil, err
|
|
}
|
|
res := string(data)
|
|
|
|
log.Debugln(res)
|
|
res = strings.TrimPrefix(res, callback+"(")
|
|
res = strings.TrimSuffix(res, ")")
|
|
|
|
var r map[string]interface{}
|
|
return r, json.Unmarshal([]byte(res), &r)
|
|
}
|
|
|
|
func (a *Api) GetUserInfo() (map[string]interface{}, error) {
|
|
return a.request("cgi-bin/rad_user_info", nil)
|
|
}
|
|
|
|
func (a *Api) DetectAcid() (string, error) {
|
|
addr := a.BaseUrl
|
|
for {
|
|
log.Debugln("HTTP GET ", addr)
|
|
res, err := a.NoDirect.Get(addr)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
_ = res.Body.Close()
|
|
loc := res.Header.Get("location")
|
|
if res.StatusCode == 302 && loc != "" {
|
|
if strings.HasPrefix(loc, "/") {
|
|
addr = a.BaseUrl + strings.TrimPrefix(loc, "/")
|
|
} else {
|
|
addr = loc
|
|
}
|
|
|
|
var u *url.URL
|
|
u, err = url.Parse(addr)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
acid := u.Query().Get(`ac_id`)
|
|
if acid != "" {
|
|
return acid, nil
|
|
}
|
|
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
return "", ErrAcidCannotFound
|
|
}
|
|
|
|
type LoginRequest struct {
|
|
Username string
|
|
Password string
|
|
AcID string
|
|
IP string
|
|
Info string
|
|
ChkSum string
|
|
N string
|
|
Type string
|
|
OS string
|
|
Name string
|
|
DoubleStack string
|
|
}
|
|
|
|
func (a *Api) Login(req *LoginRequest) (map[string]interface{}, error) {
|
|
return a.request(
|
|
"cgi-bin/srun_portal",
|
|
map[string]interface{}{
|
|
"action": "login",
|
|
"username": req.Username,
|
|
"password": req.Password,
|
|
"ac_id": req.AcID,
|
|
"ip": req.IP,
|
|
"info": req.Info,
|
|
"chksum": req.ChkSum,
|
|
"n": req.N,
|
|
"type": req.Type,
|
|
"os": req.OS,
|
|
"name": req.Name,
|
|
"double_stack": req.DoubleStack,
|
|
})
|
|
}
|
|
|
|
func (a *Api) GetChallenge(username, ip string) (map[string]interface{}, error) {
|
|
return a.request(
|
|
"cgi-bin/get_challenge",
|
|
map[string]interface{}{
|
|
"username": username,
|
|
"ip": ip,
|
|
})
|
|
}
|