1
0
mirror of https://github.com/fumiama/tienyik.git synced 2026-06-10 18:10:26 +08:00

feat: add more apis & cmd tyaliv

This commit is contained in:
源文雨
2025-11-24 17:35:20 +08:00
parent da1de770ad
commit eaf6d29fd8
14 changed files with 990 additions and 20 deletions

View File

@@ -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
}

View File

@@ -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
View 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
View 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)
}
}