mirror of
https://github.com/fumiama/tienyik.git
synced 2026-06-04 23:10:26 +08:00
feat: add more apis & cmd tyaliv
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -33,3 +33,9 @@ go.work.sum
|
||||
|
||||
# MacOS
|
||||
.DS_Store
|
||||
|
||||
# WASM
|
||||
*.wasm
|
||||
|
||||
# configs
|
||||
*.yaml
|
||||
|
||||
@@ -94,11 +94,11 @@ type RequestLogin struct {
|
||||
ChallengeID string `form:"challengeId"`
|
||||
DeviceCode string `form:"deviceCode"`
|
||||
DeviceName string `form:"deviceName"`
|
||||
DeviceType string `form:"deviceType"`
|
||||
DeviceType uint64 `form:"deviceType"`
|
||||
DeviceModel string `form:"deviceModel"`
|
||||
AppVersion string `form:"appVersion"`
|
||||
SysVersion string `form:"sysVersion"`
|
||||
ClientVersion string `form:"clientVersion"`
|
||||
ClientVersion uint64 `form:"clientVersion"`
|
||||
}
|
||||
|
||||
type ResponseLogin struct {
|
||||
@@ -135,6 +135,8 @@ type ResponseLogin struct {
|
||||
func (r *ResponseLogin) SetClient(cli *hcli.Client) {
|
||||
cli.Tenantid = strconv.FormatInt(r.TenantID, 10)
|
||||
cli.Usereid = r.UserEid
|
||||
cli.SetSecretKey(r.SecretKey)
|
||||
cli.SetTimestamp(r.Timestamp)
|
||||
}
|
||||
|
||||
func Login(tya *tienyik.AES, cli *hcli.Client, r *RequestLogin) (*ResponseLogin, error) {
|
||||
@@ -148,3 +150,10 @@ func Login(tya *tienyik.AES, cli *hcli.Client, r *RequestLogin) (*ResponseLogin,
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[*ResponseLogin](tya, resp.Body)
|
||||
}
|
||||
|
||||
func Logout(tya *tienyik.AES, cli *hcli.Client) error {
|
||||
_, err := cli.Post(
|
||||
textio.API(), "", nil,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ package auth
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/fumiama/tienyik"
|
||||
"github.com/fumiama/tienyik/api/cdserv"
|
||||
"github.com/fumiama/tienyik/hcli"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -36,3 +39,39 @@ func TestNegotiationEncKey(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogin(t *testing.T) {
|
||||
cli := hcli.NewClient()
|
||||
sd, err := cdserv.GetServData()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("get serv data:", sd)
|
||||
x, err := GenChallengeData(nil, cli)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sd.SetClient(cli)
|
||||
rsp, err := Login(nil, cli, &RequestLogin{
|
||||
UserAccount: os.Getenv("TYUSR"),
|
||||
Password: tienyik.ChallengePassword(os.Getenv("TYPWD"), x.ChallengeCode),
|
||||
SHA256Password: tienyik.ChallengeSHA256Password(os.Getenv("TYPWD"), x.ChallengeCode),
|
||||
ChallengeID: x.ChallengeID,
|
||||
DeviceCode: cli.Devicecode,
|
||||
DeviceName: tienyik.DeviceNameEdge,
|
||||
DeviceType: cli.Devicetype,
|
||||
DeviceModel: tienyik.DeviceModelMacOS,
|
||||
AppVersion: tienyik.AppVersion,
|
||||
SysVersion: tienyik.DeviceModelMacOS,
|
||||
ClientVersion: cli.Version,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(rsp)
|
||||
rsp.SetClient(cli)
|
||||
err = Logout(nil, cli)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
323
api/desktop/client.go
Normal file
323
api/desktop/client.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package desktop
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/fumiama/tienyik"
|
||||
"github.com/fumiama/tienyik/hcli"
|
||||
"github.com/fumiama/tienyik/internal/horm"
|
||||
"github.com/fumiama/tienyik/internal/hson"
|
||||
"github.com/fumiama/tienyik/internal/textio"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultRequestPageDesktopSortType = "createTimeV1"
|
||||
)
|
||||
|
||||
type RequestPageDesktop struct {
|
||||
GetCnt int `json:"getCnt"`
|
||||
DesktopTypes []string `json:"desktopTypes"`
|
||||
SortType string `json:"sortType"`
|
||||
}
|
||||
|
||||
type ResponsePageDesktop struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
SortList []struct {
|
||||
ObjID string `json:"objId"`
|
||||
ObjType int `json:"objType"`
|
||||
ObjValue string `json:"objValue"`
|
||||
DesktopTypes []string `json:"desktopTypes"`
|
||||
} `json:"sortList"`
|
||||
DesktopPoolList []any `json:"desktopPoolList"`
|
||||
DesktopList []struct {
|
||||
ObjType int `json:"objType"`
|
||||
TenantID int `json:"tenantId"`
|
||||
ObjID string `json:"objId"`
|
||||
ConnectURL []string `json:"connectUrl"`
|
||||
ObjName string `json:"objName"`
|
||||
Backupurl []string `json:"backupurl"`
|
||||
OsType string `json:"osType"`
|
||||
OsName string `json:"osName"`
|
||||
ConnectMaster int `json:"connectMaster"`
|
||||
NeedLineUp bool `json:"needLineUp"`
|
||||
UserDesktopGroupID any `json:"userDesktopGroupId"`
|
||||
Strategy struct {
|
||||
ReconnectMsg any `json:"reconnectMsg"`
|
||||
RebootMsg any `json:"rebootMsg"`
|
||||
ShutoffMsg any `json:"shutoffMsg"`
|
||||
ShutdownStrategy any `json:"shutdownStrategy"`
|
||||
RebootStrategy any `json:"rebootStrategy"`
|
||||
ModifyComputerAllas string `json:"modifyComputerAllas"`
|
||||
CheckBeforeConnect any `json:"checkBeforeConnect"`
|
||||
} `json:"strategy"`
|
||||
CloudMobileType any `json:"cloudMobileType"`
|
||||
DesktopID string `json:"desktopId"`
|
||||
DesktopName string `json:"desktopName"`
|
||||
FlavorName any `json:"flavorName"`
|
||||
ImageName string `json:"imageName"`
|
||||
OsBit string `json:"osBit"`
|
||||
CPUCore any `json:"cpuCore"`
|
||||
MemoryGB any `json:"memoryGB"`
|
||||
RootDiskGB any `json:"rootDiskGB"`
|
||||
DataDiskGB any `json:"dataDiskGB"`
|
||||
Status string `json:"status"`
|
||||
Summary any `json:"summary"`
|
||||
TanentCode string `json:"tanentCode"`
|
||||
TanentName string `json:"tanentName"`
|
||||
UseStatus string `json:"useStatus"`
|
||||
DesktopCode string `json:"desktopCode"`
|
||||
ForeignDesktopID string `json:"foreignDesktopId"`
|
||||
ForbiddenConnect bool `json:"forbiddenConnect"`
|
||||
GpuType bool `json:"gpuType"`
|
||||
GpuVirtualMethod any `json:"gpuVirtualMethod"`
|
||||
UserMode int `json:"userMode"`
|
||||
DefaultDesktop bool `json:"defaultDesktop"`
|
||||
ExpireDate any `json:"expireDate"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
NowDate any `json:"nowDate"`
|
||||
NoticeInterval int `json:"noticeInterval"`
|
||||
BandExpireDate any `json:"bandExpireDate"`
|
||||
BandNoticeInterval int `json:"bandNoticeInterval"`
|
||||
UpperResolution any `json:"upperResolution"`
|
||||
ProdType string `json:"prodType"`
|
||||
ProdGroupType int `json:"prodGroupType"`
|
||||
ProdInstID string `json:"prodInstId"`
|
||||
ProdGroupName string `json:"prodGroupName"`
|
||||
DesktopMirrorTagSet []any `json:"desktopMirrorTagSet"`
|
||||
LicenseExpireDate int64 `json:"licenseExpireDate"`
|
||||
LicenseNoticeInterval int `json:"licenseNoticeInterval"`
|
||||
AllowConnStartTime any `json:"allowConnStartTime"`
|
||||
AllowConnEndTime any `json:"allowConnEndTime"`
|
||||
OperationAuditSupported bool `json:"operationAuditSupported"`
|
||||
ProjectionScreenState any `json:"projectionScreenState"`
|
||||
NickName string `json:"nickName"`
|
||||
VMType int `json:"vmType"`
|
||||
PayType string `json:"payType"`
|
||||
ProdSubType any `json:"prodSubType"`
|
||||
InstStatus int `json:"instStatus"`
|
||||
UseTimeVO any `json:"useTimeVO"`
|
||||
UseStatusShowActions any `json:"useStatusShowActions"`
|
||||
UseStatusText string `json:"useStatusText"`
|
||||
UseStatusColor string `json:"useStatusColor"`
|
||||
ModifyComputerAllas any `json:"modifyComputerAllas"`
|
||||
UsePrivateImageFile bool `json:"usePrivateImageFile"`
|
||||
ImageID int `json:"imageId"`
|
||||
ImageCategoryID int `json:"imageCategoryId"`
|
||||
HaProdType int `json:"haProdType"`
|
||||
CtrlTypes []any `json:"ctrlTypes"`
|
||||
OrderProductData struct {
|
||||
TimeLimitTotal any `json:"timeLimitTotal"`
|
||||
TimeLimitUsed any `json:"timeLimitUsed"`
|
||||
NextAcctTime any `json:"nextAcctTime"`
|
||||
BusiChannelType any `json:"busiChannelType"`
|
||||
ManageData any `json:"manageData"`
|
||||
ActiveDate any `json:"activeDate"`
|
||||
KeepTime any `json:"keepTime"`
|
||||
} `json:"orderProductData"`
|
||||
LicenseID int `json:"licenseId"`
|
||||
RegionID int `json:"regionId"`
|
||||
TenantCode string `json:"tenantCode"`
|
||||
ConnectAPIURL struct {
|
||||
ConnectPath string `json:"connectPath"`
|
||||
StatusPath string `json:"statusPath"`
|
||||
StatePath string `json:"statePath"`
|
||||
AppendData any `json:"appendData"`
|
||||
} `json:"connectApiUrl"`
|
||||
} `json:"desktopList"`
|
||||
PreemptionDesktopList []any `json:"preemptionDesktopList"`
|
||||
}
|
||||
|
||||
func PageDesktop(tya *tienyik.AES, cli *hcli.Client, r *RequestPageDesktop) (*ResponsePageDesktop, error) {
|
||||
resp, err := cli.Post(
|
||||
textio.API(), textio.ContenTypeJSON,
|
||||
bytes.NewReader(hson.Marshal(tya, r)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[*ResponsePageDesktop](tya, resp.Body)
|
||||
}
|
||||
|
||||
type ResponseFeature struct {
|
||||
CPUCore int `json:"cpuCore"`
|
||||
MemoryGB int `json:"memoryGB"`
|
||||
SystemDiskGB int `json:"systemDiskGB"`
|
||||
DataDiskGB any `json:"dataDiskGB"`
|
||||
TotalDiskGB int `json:"totalDiskGB"`
|
||||
SysDisk struct {
|
||||
Size int `json:"size"`
|
||||
Path string `json:"path"`
|
||||
Code string `json:"code"`
|
||||
} `json:"sysDisk"`
|
||||
DataDiskList []any `json:"dataDiskList"`
|
||||
MirrorVersion string `json:"mirrorVersion"`
|
||||
MirrorCategoryName string `json:"mirrorCategoryName"`
|
||||
DesktopName string `json:"desktopName"`
|
||||
GpuSliceRAM any `json:"gpuSliceRam"`
|
||||
GpuSliceRAMDesc any `json:"gpuSliceRamDesc"`
|
||||
ExpireDate any `json:"expireDate"`
|
||||
CreateDate int64 `json:"createDate"`
|
||||
NowDate int64 `json:"nowDate"`
|
||||
LinkInfo any `json:"linkInfo"`
|
||||
OrderProduct struct {
|
||||
TimeLimitTotal any `json:"timeLimitTotal"`
|
||||
TimeLimitUsed any `json:"timeLimitUsed"`
|
||||
NextAcctTime any `json:"nextAcctTime"`
|
||||
BusiChannelType string `json:"busiChannelType"`
|
||||
ManageData any `json:"manageData"`
|
||||
ActiveDate any `json:"activeDate"`
|
||||
KeepTime any `json:"keepTime"`
|
||||
} `json:"orderProduct"`
|
||||
MirrorID int `json:"mirrorId"`
|
||||
MirrorCategoryID int `json:"mirrorCategoryId"`
|
||||
ProductName string `json:"productName"`
|
||||
PayType string `json:"payType"`
|
||||
ProdType string `json:"prodType"`
|
||||
ProdSubType any `json:"prodSubType"`
|
||||
TimePkgVOS []any `json:"timePkgVOS"`
|
||||
Os string `json:"os"`
|
||||
MirrorType string `json:"mirrorType"`
|
||||
}
|
||||
|
||||
func Feature(tya *tienyik.AES, cli *hcli.Client, desktopId string, objType int, objId string) (*ResponseFeature, error) {
|
||||
u, err := url.Parse(textio.API())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q := u.Query()
|
||||
q.Set("desktopId", desktopId)
|
||||
q.Set("objType", strconv.Itoa(objType))
|
||||
q.Set("objId", objId)
|
||||
u.RawQuery = tya.EUrlParams(q)
|
||||
|
||||
resp, err := cli.Get(u.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[*ResponseFeature](tya, resp.Body)
|
||||
}
|
||||
|
||||
type ResponseGetDesktopExtraInfo struct {
|
||||
Strategy struct {
|
||||
ReconnectMsg any `json:"reconnectMsg"`
|
||||
RebootMsg any `json:"rebootMsg"`
|
||||
ShutoffMsg any `json:"shutoffMsg"`
|
||||
ShutdownStrategy string `json:"shutdownStrategy"`
|
||||
RebootStrategy string `json:"rebootStrategy"`
|
||||
ModifyComputerAllas any `json:"modifyComputerAllas"`
|
||||
CheckBeforeConnect any `json:"checkBeforeConnect"`
|
||||
} `json:"strategy"`
|
||||
UpperResolution string `json:"upperResolution"`
|
||||
TimeLimitProductData any `json:"timeLimitProductData"`
|
||||
HaProdType int `json:"haProdType"`
|
||||
}
|
||||
|
||||
func GetDesktopExtraInfo(tya *tienyik.AES, cli *hcli.Client, objId string, objType int) (*ResponseGetDesktopExtraInfo, error) {
|
||||
u, err := url.Parse(textio.API())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q := u.Query()
|
||||
q.Set("objId", objId)
|
||||
q.Set("objType", strconv.Itoa(objType))
|
||||
u.RawQuery = tya.EUrlParams(q)
|
||||
|
||||
resp, err := cli.Get(u.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[*ResponseGetDesktopExtraInfo](tya, resp.Body)
|
||||
}
|
||||
|
||||
type RequestConnect struct {
|
||||
ObjID string `form:"objId"`
|
||||
ObjType int `form:"objType"`
|
||||
OsType string `form:"osType"`
|
||||
DeviceID int `form:"deviceId"`
|
||||
DeviceCode string `form:"deviceCode"`
|
||||
DeviceName string `form:"deviceName"`
|
||||
SysVersion string `form:"sysVersion"`
|
||||
AppVersion string `form:"appVersion"`
|
||||
HostName string `form:"hostName"`
|
||||
VdCommand string `form:"vdCommand"`
|
||||
IPAddress string `form:"ipAddress"`
|
||||
MacAddress string `form:"macAddress"`
|
||||
HardwareFeatureCode string `form:"hardwareFeatureCode"`
|
||||
SpecifiedCertCategory int `form:"specifiedCertCategory"`
|
||||
}
|
||||
|
||||
type ResponseConnect struct {
|
||||
GoingRetry bool `json:"goingRetry"`
|
||||
DesktopInfo any `json:"desktopInfo"`
|
||||
ShadowDesktopInfo struct {
|
||||
InHaMode int `json:"inHaMode"`
|
||||
HaDesktopID any `json:"haDesktopId"`
|
||||
HaConnectingTips any `json:"haConnectingTips"`
|
||||
HaConnectSucTips any `json:"haConnectSucTips"`
|
||||
} `json:"shadowDesktopInfo"`
|
||||
DesktopAnywhereInfo struct {
|
||||
AnywhereStatus int `json:"anywhereStatus"`
|
||||
MigrateStatus any `json:"migrateStatus"`
|
||||
AnywhereDesktopID any `json:"anywhereDesktopId"`
|
||||
SrcResPoolName any `json:"srcResPoolName"`
|
||||
TargetResPoolName any `json:"targetResPoolName"`
|
||||
EstimatedTime int `json:"estimatedTime"`
|
||||
ReminderDays any `json:"reminderDays"`
|
||||
RoamingDays any `json:"roamingDays"`
|
||||
NeedReserveRemind int `json:"needReserveRemind"`
|
||||
ShadowInfoDTO any `json:"shadowInfoDTO"`
|
||||
AnywhereOpen bool `json:"anywhereOpen"`
|
||||
ConnectTargetDesktop bool `json:"connectTargetDesktop"`
|
||||
} `json:"desktopAnywhereInfo"`
|
||||
DesktopID string `json:"desktopId"`
|
||||
PollingKey string `json:"pollingKey"`
|
||||
AuthInfo any `json:"authInfo"`
|
||||
}
|
||||
|
||||
func Connect(tya *tienyik.AES, cli *hcli.Client, r *RequestConnect) (*ResponseConnect, error) {
|
||||
resp, err := cli.Post(
|
||||
textio.API(), textio.ContenTypeForm,
|
||||
bytes.NewReader(horm.Marshal(tya, r)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[*ResponseConnect](tya, resp.Body)
|
||||
}
|
||||
|
||||
type RequestState struct {
|
||||
ObjID string `json:"objId"`
|
||||
ObjType int `json:"objType"`
|
||||
}
|
||||
|
||||
type ResponseState struct {
|
||||
ObjType int `json:"objType"`
|
||||
ObjID string `json:"objId"`
|
||||
DesktopID int `json:"desktopId"`
|
||||
DesktopState string `json:"desktopState"`
|
||||
RunningTask int `json:"runningTask"`
|
||||
RunningTaskName string `json:"runningTaskName"`
|
||||
TaskStartTime int64 `json:"taskStartTime"`
|
||||
MirrorReady any `json:"mirrorReady"`
|
||||
UseStatus string `json:"useStatus"`
|
||||
UseStatusText string `json:"useStatusText"`
|
||||
UseStatusColor string `json:"useStatusColor"`
|
||||
}
|
||||
|
||||
func State(tya *tienyik.AES, cli *hcli.Client, r []RequestState) ([]ResponseState, error) {
|
||||
resp, err := cli.Post(
|
||||
textio.API(), textio.ContenTypeJSON,
|
||||
bytes.NewReader(hson.Marshal(tya, &r)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return hson.Unmarshal[[]ResponseState](tya, resp.Body)
|
||||
}
|
||||
101
api/desktop/client_test.go
Normal file
101
api/desktop/client_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package desktop
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/fumiama/tienyik"
|
||||
"github.com/fumiama/tienyik/api/auth"
|
||||
"github.com/fumiama/tienyik/api/cdserv"
|
||||
"github.com/fumiama/tienyik/hcli"
|
||||
)
|
||||
|
||||
func TestDesktop(t *testing.T) {
|
||||
cli := hcli.NewClient()
|
||||
sd, err := cdserv.GetServData()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("get serv data:", sd)
|
||||
x, err := auth.GenChallengeData(nil, cli)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sd.SetClient(cli)
|
||||
rsp, err := auth.Login(nil, cli, &auth.RequestLogin{
|
||||
UserAccount: os.Getenv("TYUSR"),
|
||||
Password: tienyik.ChallengePassword(os.Getenv("TYPWD"), x.ChallengeCode),
|
||||
SHA256Password: tienyik.ChallengeSHA256Password(os.Getenv("TYPWD"), x.ChallengeCode),
|
||||
ChallengeID: x.ChallengeID,
|
||||
DeviceCode: cli.Devicecode,
|
||||
DeviceName: tienyik.DeviceNameEdge,
|
||||
DeviceType: cli.Devicetype,
|
||||
DeviceModel: tienyik.DeviceModelMacOS,
|
||||
AppVersion: tienyik.AppVersion,
|
||||
SysVersion: tienyik.DeviceModelMacOS,
|
||||
ClientVersion: cli.Version,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(rsp)
|
||||
rsp.SetClient(cli)
|
||||
pd, err := PageDesktop(nil, cli, &RequestPageDesktop{
|
||||
GetCnt: 1,
|
||||
DesktopTypes: []string{"1", tienyik.ArchX86, tienyik.ArchARM, tienyik.ArchHW},
|
||||
SortType: DefaultRequestPageDesktopSortType,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(pd)
|
||||
for _, x := range pd.DesktopList {
|
||||
feat, err := Feature(nil, cli, x.DesktopID, x.ObjType, x.ObjID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("feat:", feat)
|
||||
ext, err := GetDesktopExtraInfo(nil, cli, x.ObjID, x.ObjType)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("ext:", ext)
|
||||
s, err := State(nil, cli, []RequestState{{
|
||||
ObjID: x.ObjID,
|
||||
ObjType: x.ObjType,
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("s1:", s)
|
||||
con, err := Connect(nil, cli, &RequestConnect{
|
||||
ObjID: x.ObjID,
|
||||
ObjType: x.ObjType,
|
||||
OsType: x.OsType,
|
||||
DeviceID: int(cli.Devicetype),
|
||||
DeviceCode: cli.Devicecode,
|
||||
DeviceName: tienyik.DeviceNameEdge,
|
||||
SysVersion: tienyik.DeviceModelMacOS,
|
||||
AppVersion: tienyik.AppVersion,
|
||||
HostName: tienyik.DeviceNameEdge,
|
||||
HardwareFeatureCode: cli.Devicecode,
|
||||
SpecifiedCertCategory: 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("con:", con)
|
||||
s, err = State(nil, cli, []RequestState{{
|
||||
ObjID: x.ObjID,
|
||||
ObjType: x.ObjType,
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("s2:", s)
|
||||
}
|
||||
err = auth.Logout(nil, cli)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
26
cfg.go
26
cfg.go
@@ -7,12 +7,15 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const Version = "103010001"
|
||||
const (
|
||||
Version = 103010001
|
||||
AppVersion = "3.1.0"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceTypePC = "25"
|
||||
DeviceTypeMAC = "45"
|
||||
DeviceTypeWEB = "60"
|
||||
DeviceTypePC = 25
|
||||
DeviceTypeMAC = 45
|
||||
DeviceTypeWEB = 60
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,6 +24,21 @@ const (
|
||||
AppModelPHONE = "3"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceNameEdge = "Edge浏览器"
|
||||
)
|
||||
|
||||
// alos sysVersion
|
||||
const (
|
||||
DeviceModelMacOS = "Macintosh; Intel Mac OS X 10_15_7"
|
||||
)
|
||||
|
||||
const (
|
||||
ArchX86 = "2001"
|
||||
ArchARM = "2002"
|
||||
ArchHW = "2003"
|
||||
)
|
||||
|
||||
func NewDeviceCode() string {
|
||||
sb := &strings.Builder{}
|
||||
sb.WriteString("web_")
|
||||
|
||||
198
cmd/tyaliv/main.go
Normal file
198
cmd/tyaliv/main.go
Normal file
@@ -0,0 +1,198 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
base14 "github.com/fumiama/go-base16384"
|
||||
"github.com/fumiama/tienyik"
|
||||
"github.com/fumiama/tienyik/api/auth"
|
||||
"github.com/fumiama/tienyik/api/cdserv"
|
||||
"github.com/fumiama/tienyik/api/desktop"
|
||||
"github.com/fumiama/tienyik/hcli"
|
||||
"github.com/fumiama/tienyik/internal/log"
|
||||
"github.com/fumiama/tienyik/internal/textio"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
UserAccount string `yaml:"UserAccount"`
|
||||
PasswordB14 string `yaml:"PasswordB14"` // PasswordB14 is a little bit more secure
|
||||
CheckIntervalSec int `yaml:"CheckIntervalSec"` // CheckIntervalSec default 60
|
||||
GetDeviceCount int `yaml:"GetDeviceCount"` // GetDeviceCount default 20
|
||||
}
|
||||
|
||||
func main() {
|
||||
c := flag.String("c", "config.yaml", "load config file")
|
||||
s := flag.String("s", "", "save config file template")
|
||||
flag.Parse()
|
||||
|
||||
cfg := config{}
|
||||
|
||||
if *s != "" {
|
||||
fmt.Print("UserAccount: ")
|
||||
fmt.Scanln(&cfg.UserAccount)
|
||||
pwd := ""
|
||||
fmt.Print("Password: ")
|
||||
textio.NoEchoScanln(&pwd)
|
||||
cfg.PasswordB14 = base14.EncodeString(pwd)
|
||||
cfg.CheckIntervalSec = 60
|
||||
cfg.GetDeviceCount = 20
|
||||
data, err := yaml.Marshal(&cfg)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = os.WriteFile(*s, data, 0644)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Open(*c)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = yaml.NewDecoder(f).Decode(&cfg)
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if cfg.UserAccount == "" {
|
||||
log.Fatalln("user account must be set")
|
||||
}
|
||||
if cfg.PasswordB14 == "" {
|
||||
log.Fatalln("password must be set (in b14 format)")
|
||||
}
|
||||
if cfg.CheckIntervalSec <= 0 {
|
||||
cfg.CheckIntervalSec = 60
|
||||
}
|
||||
if cfg.GetDeviceCount <= 0 {
|
||||
cfg.GetDeviceCount = 20
|
||||
}
|
||||
|
||||
RECONN:
|
||||
cli := hcli.NewClient()
|
||||
sd, err := cdserv.GetServData()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
x, err := auth.GenChallengeData(nil, cli)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
sd.SetClient(cli)
|
||||
pwd := base14.DecodeString(cfg.PasswordB14)
|
||||
rsp, err := auth.Login(nil, cli, &auth.RequestLogin{
|
||||
UserAccount: cfg.UserAccount,
|
||||
Password: tienyik.ChallengePassword(pwd, x.ChallengeCode),
|
||||
SHA256Password: tienyik.ChallengeSHA256Password(pwd, x.ChallengeCode),
|
||||
ChallengeID: x.ChallengeID,
|
||||
DeviceCode: cli.Devicecode,
|
||||
DeviceName: tienyik.DeviceNameEdge,
|
||||
DeviceType: cli.Devicetype,
|
||||
DeviceModel: tienyik.DeviceModelMacOS,
|
||||
AppVersion: tienyik.AppVersion,
|
||||
SysVersion: tienyik.DeviceModelMacOS,
|
||||
ClientVersion: cli.Version,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
rsp.SetClient(cli)
|
||||
defer auth.Logout(nil, cli)
|
||||
|
||||
pd, err := desktop.PageDesktop(nil, cli, &desktop.RequestPageDesktop{
|
||||
GetCnt: 20,
|
||||
DesktopTypes: []string{"1", tienyik.ArchX86},
|
||||
SortType: desktop.DefaultRequestPageDesktopSortType,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
mp := make(map[string][2]string, len(pd.DesktopList)*4)
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("available desktops:")
|
||||
for _, x := range pd.DesktopList {
|
||||
if x.UseStatusText == "运行中" {
|
||||
sb.WriteString(" |●")
|
||||
} else {
|
||||
sb.WriteString(" |○")
|
||||
}
|
||||
sb.WriteString("[")
|
||||
sb.WriteString(x.ObjID)
|
||||
sb.WriteString("]")
|
||||
sb.WriteString(x.ObjName)
|
||||
sb.WriteString("(")
|
||||
sb.WriteString(x.OsName)
|
||||
sb.WriteString(")|")
|
||||
mp[x.ObjID] = [2]string{x.ObjName, x.OsType}
|
||||
}
|
||||
log.Infoln(&sb)
|
||||
|
||||
t := time.NewTicker(time.Second * time.Duration(cfg.CheckIntervalSec))
|
||||
defer t.Stop()
|
||||
|
||||
mainStopCh := make(chan struct{})
|
||||
mc := make(chan os.Signal, 4)
|
||||
signal.Notify(mc, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM)
|
||||
go func() {
|
||||
for {
|
||||
<-mc
|
||||
close(mainStopCh)
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
log.Infoln("start refreshing...")
|
||||
|
||||
reqs := make([]desktop.RequestState, len(pd.DesktopList))
|
||||
for i, x := range pd.DesktopList {
|
||||
reqs[i].ObjID = x.ObjID
|
||||
reqs[i].ObjType = x.ObjType
|
||||
}
|
||||
s, err := desktop.State(nil, cli, reqs)
|
||||
if err != nil {
|
||||
log.Warnln("get state err:", err)
|
||||
goto RECONN
|
||||
}
|
||||
for _, x := range s {
|
||||
log.Infof("%s [%s]%s status is %s", x.ObjID, mp[x.ObjID][0], x.DesktopState)
|
||||
if x.DesktopState == "ACTIVE" {
|
||||
continue
|
||||
}
|
||||
log.Infof("%s [%s]%s do refresh", x.ObjID, mp[x.ObjID][0])
|
||||
_, err = desktop.Connect(nil, cli, &desktop.RequestConnect{
|
||||
ObjID: x.ObjID,
|
||||
ObjType: x.ObjType,
|
||||
OsType: mp[x.ObjID][1],
|
||||
DeviceID: int(cli.Devicetype),
|
||||
DeviceCode: cli.Devicecode,
|
||||
DeviceName: tienyik.DeviceNameEdge,
|
||||
SysVersion: tienyik.DeviceModelMacOS,
|
||||
AppVersion: tienyik.AppVersion,
|
||||
HostName: tienyik.DeviceNameEdge,
|
||||
HardwareFeatureCode: cli.Devicecode,
|
||||
SpecifiedCertCategory: 1,
|
||||
})
|
||||
if err != nil {
|
||||
log.Warnln("connect err:", err)
|
||||
goto RECONN
|
||||
}
|
||||
}
|
||||
case <-mainStopCh:
|
||||
log.Warnln("quit loop")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
3
go.mod
3
go.mod
@@ -5,7 +5,10 @@ go 1.24.4
|
||||
require (
|
||||
github.com/fumiama/go-base16384 v1.7.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/tetratelabs/wazero v1.9.0
|
||||
golang.org/x/net v0.28.0
|
||||
golang.org/x/term v0.23.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
5
go.sum
5
go.sum
@@ -13,15 +13,20 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
53
hcli/cli.go
53
hcli/cli.go
@@ -1,6 +1,7 @@
|
||||
package hcli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -21,17 +22,22 @@ var DefaultClient = http.Client{
|
||||
|
||||
type Client struct {
|
||||
rcnt uintptr
|
||||
sg tienyik.Signer
|
||||
secretKey string
|
||||
offsetTime int64
|
||||
|
||||
Appmodel string
|
||||
Devicecode string
|
||||
Devicetype string
|
||||
Devicetype uint64
|
||||
Servernode string
|
||||
Tenantid string
|
||||
Usereid string
|
||||
Version string
|
||||
Version uint64
|
||||
}
|
||||
|
||||
func NewClient() *Client {
|
||||
return &Client{
|
||||
sg: tienyik.NewSigner(context.TODO()),
|
||||
Appmodel: tienyik.AppModelTOB,
|
||||
Devicecode: tienyik.NewDeviceCode(),
|
||||
Devicetype: tienyik.DeviceTypeWEB,
|
||||
@@ -39,6 +45,15 @@ func NewClient() *Client {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) SetSecretKey(k string) {
|
||||
c.secretKey = k
|
||||
}
|
||||
|
||||
func (c *Client) SetTimestamp(ts int64) {
|
||||
n := time.Now().UnixMilli()
|
||||
c.offsetTime = n - ts
|
||||
}
|
||||
|
||||
func (c *Client) setHeaders(req *http.Request) {
|
||||
if c == nil {
|
||||
return
|
||||
@@ -54,27 +69,39 @@ func (c *Client) setHeaders(req *http.Request) {
|
||||
}
|
||||
|
||||
fieldValue := v.Field(i)
|
||||
if fieldValue.IsZero() {
|
||||
continue
|
||||
}
|
||||
k := base14.DecodeString("廝呲舀㴄") + field.Name
|
||||
|
||||
if fieldValue.Kind() == reflect.String {
|
||||
req.Header.Set(
|
||||
base14.DecodeString("廝呲舀㴄")+field.Name,
|
||||
fieldValue.String(),
|
||||
)
|
||||
switch fieldValue.Kind() {
|
||||
case reflect.String:
|
||||
req.Header.Set(k, fieldValue.String())
|
||||
case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint, reflect.Uintptr:
|
||||
req.Header.Set(k, strconv.FormatUint(fieldValue.Uint(), 10))
|
||||
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
|
||||
req.Header.Set(k, strconv.FormatInt(fieldValue.Int(), 10))
|
||||
default:
|
||||
panic("unsupported field " + field.Name + " value type " + fieldValue.Type().String())
|
||||
}
|
||||
}
|
||||
|
||||
if c.Appmodel != "" {
|
||||
ts := time.Now().UnixMilli()
|
||||
rid := uint64(atomic.AddUintptr(&c.rcnt, 1)) + uint64(ts)
|
||||
requestid := strconv.FormatUint(rid, 10)
|
||||
|
||||
ts -= c.offsetTime
|
||||
timestamp := strconv.FormatInt(ts, 10)
|
||||
requestid := strconv.FormatUint(
|
||||
uint64(atomic.AddUintptr(&c.rcnt, 1))+uint64(ts), 10,
|
||||
)
|
||||
|
||||
req.Header.Set(base14.DecodeString("廝呲草獱歙攷徥爀㴆"), requestid)
|
||||
req.Header.Set(base14.DecodeString("廝呲荑睭杜蕆厵縀㴆"), timestamp)
|
||||
}
|
||||
|
||||
if c.Servernode != "" {
|
||||
//TODO: gensign
|
||||
if c.secretKey != "" {
|
||||
req.Header.Set(base14.DecodeString("廝呲荍睧榘敇揉獳欜渀㴂"), c.sg.GenKeyNew(
|
||||
context.TODO(), c.Devicetype, uint64(ts), rid, c.secretKey,
|
||||
c.Usereid, req.URL.EscapedPath(), c.Servernode, c.Version,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package horm
|
||||
import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/fumiama/tienyik"
|
||||
"github.com/fumiama/tienyik/internal/textio"
|
||||
@@ -22,8 +23,13 @@ func Marshal(tya *tienyik.AES, x any) []byte {
|
||||
continue
|
||||
}
|
||||
|
||||
if field.Kind() == reflect.String {
|
||||
switch field.Kind() {
|
||||
case reflect.String:
|
||||
q.Set(formTag, field.String())
|
||||
case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint, reflect.Uintptr:
|
||||
q.Set(formTag, strconv.FormatUint(field.Uint(), 10))
|
||||
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int:
|
||||
q.Set(formTag, strconv.FormatInt(field.Int(), 10))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
17
internal/textio/interact.go
Normal file
17
internal/textio/interact.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package textio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
func NoEchoScanln(a ...any) (n int, err error) {
|
||||
fd := int(os.Stdin.Fd())
|
||||
bytePassword, err := term.ReadPassword(fd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return fmt.Sscanln(string(bytePassword)+"\n", a...)
|
||||
}
|
||||
198
wasm.go
Normal file
198
wasm.go
Normal file
@@ -0,0 +1,198 @@
|
||||
package tienyik
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"github.com/fumiama/tienyik/internal/op"
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
)
|
||||
|
||||
//go:embed main.1755740488270.wasm
|
||||
var wasmdata []byte
|
||||
|
||||
type Signer struct {
|
||||
rt wazero.Runtime
|
||||
md api.Module
|
||||
genKey api.Function
|
||||
genKeyNew api.Function
|
||||
genKeyWithoutURI api.Function
|
||||
_malloc api.Function
|
||||
_free api.Function
|
||||
}
|
||||
|
||||
func NewSigner(ctx context.Context) (sg Signer) {
|
||||
rt := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
|
||||
_, err := rt.NewHostModuleBuilder("a").
|
||||
// ___cxa_throw
|
||||
NewFunctionBuilder().WithFunc(func(ctx context.Context, e, n, t uint32) {
|
||||
panic(fmt.Sprintf("___cxa_throw: ptr(e)=%08x, type(n)=%08x, destructor(t)=%08x", e, n, t))
|
||||
}).Export("c").
|
||||
// __abort_js
|
||||
NewFunctionBuilder().WithFunc(func(ctx context.Context) {
|
||||
panic("wasm aborted")
|
||||
}).Export("a").
|
||||
// _emscripten_resize_heap
|
||||
NewFunctionBuilder().WithFunc(func(ctx context.Context, _ uint32) uint32 {
|
||||
panic("wasm oom")
|
||||
}).Export("b").
|
||||
Instantiate(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
md, err := rt.InstantiateWithConfig(ctx, wasmdata,
|
||||
wazero.NewModuleConfig())
|
||||
if err != nil {
|
||||
_ = rt.Close(ctx)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sg.rt = rt
|
||||
sg.md = md
|
||||
|
||||
sg.genKey = md.ExportedFunction("f")
|
||||
sg.genKeyNew = md.ExportedFunction("g")
|
||||
sg.genKeyWithoutURI = md.ExportedFunction("h")
|
||||
sg._malloc = md.ExportedFunction("i")
|
||||
sg._free = md.ExportedFunction("j")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GenKey is the go repr of js func
|
||||
//
|
||||
// generatorSign(e) {
|
||||
// const t = Module.lengthBytesUTF8(e.secretKey) + 1
|
||||
// , n = Module._malloc(t);
|
||||
// Module.stringToUTF8(e.secretKey, n, t);
|
||||
// const r = Module._gen_key(e.deviceType, BigInt(e.timestamp), BigInt(e.requestId), n, e.tenantId, e.userId, e.version)
|
||||
// , o = Module.UTF8ToString(r);
|
||||
// return Module._free(n),
|
||||
// Module._free(r),
|
||||
// o
|
||||
// }
|
||||
func (sg *Signer) GenKey(
|
||||
ctx context.Context, deviceType, timestamp, requestID uint64,
|
||||
secretKey string, tenantID, userID, version uint64,
|
||||
) string {
|
||||
t := len(secretKey) + 1
|
||||
n := sg.malloc(ctx, uint64(t))
|
||||
if !sg.md.Memory().WriteString(uint32(n), secretKey+"\x00") {
|
||||
panic("write out-of-bound")
|
||||
}
|
||||
defer sg.free(ctx, n)
|
||||
|
||||
return sg.string(op.Must(sg.genKey.Call(
|
||||
ctx, deviceType, timestamp, requestID,
|
||||
n, tenantID, userID, version),
|
||||
)[0])
|
||||
}
|
||||
|
||||
// GenKeyNew is the go repr of js func
|
||||
//
|
||||
// generatorSignNew(e) {
|
||||
// const t = Module.lengthBytesUTF8(e.secretKey) + 1
|
||||
// , n = Module._malloc(t);
|
||||
// Module.stringToUTF8(e.secretKey, n, t);
|
||||
// const r = Module.lengthBytesUTF8(e.userEid) + 1
|
||||
// , o = Module._malloc(r);
|
||||
// Module.stringToUTF8(e.userEid, o, r);
|
||||
// const i = Module.lengthBytesUTF8(e.requestUri) + 1
|
||||
// , a = Module._malloc(i);
|
||||
// Module.stringToUTF8(e.requestUri, a, i);
|
||||
// const s = Module.lengthBytesUTF8(this.serverNode) + 1
|
||||
// , l = Module._malloc(s);
|
||||
// Module.stringToUTF8(this.serverNode, l, s);
|
||||
// const c = Module._gen_key_new(e.deviceType, BigInt(e.timestamp), BigInt(e.requestId), n, o, a, l, e.version)
|
||||
// , u = Module.UTF8ToString(c);
|
||||
// return Module._free(n),
|
||||
// Module._free(o),
|
||||
// Module._free(a),
|
||||
// Module._free(l),
|
||||
// Module._free(c),
|
||||
// u
|
||||
// }
|
||||
func (sg *Signer) GenKeyNew(
|
||||
ctx context.Context, deviceType, timestamp, requestID uint64,
|
||||
secretKey, userEID, requestURI, serverNode string, version uint64,
|
||||
) string {
|
||||
t := len(secretKey) + 1
|
||||
n := sg.malloc(ctx, uint64(t))
|
||||
if !sg.md.Memory().WriteString(uint32(n), secretKey+"\x00") {
|
||||
panic("write out-of-bound")
|
||||
}
|
||||
defer sg.free(ctx, n)
|
||||
|
||||
r := len(userEID) + 1
|
||||
o := sg.malloc(ctx, uint64(r))
|
||||
if !sg.md.Memory().WriteString(uint32(o), userEID+"\x00") {
|
||||
panic("write out-of-bound")
|
||||
}
|
||||
defer sg.free(ctx, o)
|
||||
|
||||
i := len(requestURI) + 1
|
||||
a := sg.malloc(ctx, uint64(i))
|
||||
if !sg.md.Memory().WriteString(uint32(a), requestURI+"\x00") {
|
||||
panic("write out-of-bound")
|
||||
}
|
||||
defer sg.free(ctx, a)
|
||||
|
||||
s := len(serverNode) + 1
|
||||
l := sg.malloc(ctx, uint64(s))
|
||||
if !sg.md.Memory().WriteString(uint32(l), serverNode+"\x00") {
|
||||
panic("write out-of-bound")
|
||||
}
|
||||
defer sg.free(ctx, l)
|
||||
|
||||
return sg.string(op.Must(sg.genKeyNew.Call(
|
||||
ctx, deviceType, timestamp, requestID,
|
||||
n, o, a, l, version),
|
||||
)[0])
|
||||
}
|
||||
|
||||
func (sg *Signer) malloc(ctx context.Context, n uint64) uint64 {
|
||||
return op.Must(sg._malloc.Call(ctx, n))[0]
|
||||
}
|
||||
|
||||
func (sg *Signer) free(ctx context.Context, n uint64) {
|
||||
op.Must(sg._free.Call(ctx, n))
|
||||
}
|
||||
|
||||
func (sg *Signer) string(ptr uint64) string {
|
||||
buf := strings.Builder{}
|
||||
x := uint32(ptr)
|
||||
for {
|
||||
b, ok := sg.md.Memory().ReadByte(x)
|
||||
x++
|
||||
if !ok {
|
||||
panic("read out-of-bound")
|
||||
}
|
||||
if b == 0 {
|
||||
break
|
||||
}
|
||||
buf.WriteByte(b)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (sg *Signer) IsClosed() bool {
|
||||
return sg.md == nil || sg.rt == nil || sg.md.IsClosed() ||
|
||||
sg.genKey == nil || sg.genKeyNew == nil || sg.genKeyWithoutURI == nil ||
|
||||
sg._malloc == nil || sg._free == nil
|
||||
}
|
||||
|
||||
func (sg *Signer) Close(ctx context.Context) {
|
||||
if sg.md != nil && !sg.md.IsClosed() {
|
||||
sg.md.Close(ctx)
|
||||
sg.md = nil
|
||||
}
|
||||
if sg.rt != nil {
|
||||
sg.rt.Close(ctx)
|
||||
sg.rt = nil
|
||||
}
|
||||
}
|
||||
20
wasm_test.go
Normal file
20
wasm_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package tienyik
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSigner(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
sg := NewSigner(ctx)
|
||||
sigstr := sg.GenKeyNew(
|
||||
ctx, 60, 1763891935806, 1763891937568, "9c047f01dfab388a3ef7c4ae34855e3a",
|
||||
"6806caebc2cdaef5f10987a94d21cf1f", "/api/cdserv/client/msgcenter/page",
|
||||
"8aff800b3c96e620043bb7deb4a0258d", 103010001,
|
||||
)
|
||||
if sigstr != "66443F2BF714E1D2B4AC8D3B3CBC3913" {
|
||||
t.Fatal("got", sigstr)
|
||||
}
|
||||
t.Fail()
|
||||
}
|
||||
Reference in New Issue
Block a user