From 63645d248c765244488cd34dbc1bb6528ca6b7c7 Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@smartai.com> Date: 星期二, 05 九月 2023 09:58:13 +0800 Subject: [PATCH] 修复编译 --- version-control/service/upgrade.go | 1882 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 941 insertions(+), 941 deletions(-) diff --git a/version-control/service/upgrade.go b/version-control/service/upgrade.go index 5e6b4fd..d26bdf6 100644 --- a/version-control/service/upgrade.go +++ b/version-control/service/upgrade.go @@ -1,941 +1,941 @@ -package service - -import ( - "basic.com/valib/bhomeclient.git" - "basic.com/valib/bhomedbapi.git" - "basic.com/valib/c_bhomebus.git/proto/source/bhome_msg" - "basic.com/valib/licence.git" - "basic.com/valib/logger.git" - "basic.com/valib/version.git" - "context" - "crypto/md5" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "github.com/skip2/go-qrcode" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "path" - "runtime" - "strings" - "sync" - "time" - "vamicro/config" - "vamicro/extend/util" - "vamicro/version-control/models" - "vamicro/version-control/response" - "vamicro/version-control/utils" -) - -const ( - uriVersion string = "/data/api-u/upgrade/findUpgradeVersion" - uriDownload string = "/data/api-p/download" - uriAuth string = "/data/api-s/authorization" - uriMobile string = "/data/api-s/fromQrcode" -) - -type ( - Payload struct { - Arch string `json:"arch"` - Programs []*models.Program `json:"programs"` - Version string `json:"version"` - Intro string `json:"intro"` - PatchUrl string `json:"patchUrl"` - } - - UpdateInfo struct { - response.ResponseHead - Data []Payload `json:"data"` - } - - VersionInfo struct { - Build string `json:"build"` - Commit string `json:"commit"` - Name string `json:"name"` - Version string `json:"version"` - } - - UpdateNotice struct { - NoticeUser map[string]int - HaveNewVersion int64 //鏄惁鏈夋柊鐗堟湰锛�1鏈夛紝0娌℃湁 - PkgDownloaded int64 //鏄惁涓嬭浇瀹屾垚锛�1鏈夛紝0娌℃湁 - LastNoticeTime int64 - NewVersionProgram []*models.Program - NoticeStatus bool - } -) - -var ( - updateNotice UpdateNotice - updateNoticeLock sync.Mutex - LastDownFile []string - LastDownLock sync.RWMutex -) - -func Init() { - backUpPath := GetBackupPath() - if _, err := os.Stat(backUpPath); os.IsNotExist(err) { - _ = os.MkdirAll(backUpPath, 0777) - } - preDownPath := GetPreDownPath() - if _, err := os.Stat(preDownPath); os.IsNotExist(err) { - _ = os.MkdirAll(preDownPath, 0777) - } - updateNotice.NoticeUser = make(map[string]int) - LastDownFile = make([]string, 0) -} - -func OnlineUpgrade() ([]*models.Program, error) { - - programMap := make(map[string]*models.Program) - - LastDownLock.Lock() - defer LastDownLock.Unlock() - //鏌ユ壘棰勪笅杞藉崌绾у寘 - preDowns := GetLastDownFile() - logger.Info("绯荤粺寮�濮嬪崌绾э紒") - for _, preDown := range preDowns { - logger.Info(preDowns) - ps, err := UpgradeViaZip(preDown) - if err != nil { - return []*models.Program{}, err - } - for _, p := range ps { - programMap[p.Name] = p - } - } - logger.Info("绯荤粺鍗囩骇瀹屾垚锛侊紒") - - if len(programMap) > 0 { //浣跨敤棰勪笅杞藉崌绾у畬鎴� - programs := make([]*models.Program, 0, len(programMap)) - for _, v := range programMap { - programs = append(programs, v) - } - return programs, nil - } - - info, err := getUpdateInfo() - if nil != err { - return []*models.Program{}, errors.New("绯荤粺娌℃湁鏇存柊鍙敤") - } - - logger.Info("绯荤粺鍗囩骇寮�濮嬶紒") - //寰幆涓嬭浇锛岃В鍘嬶紝瑕嗙洊鍗囩骇鍖� - for _, payload := range info.Data { - ps, err := HandlerPatchPkg(payload) - if err != nil { - return []*models.Program{}, err - } - for _, p := range ps { - programMap[p.Name] = p - } - } - logger.Info("绯荤粺鍗囩骇瀹屾垚锛侊紒") - - if len(programMap) > 0 { // - programs := make([]*models.Program, 0, len(programMap)) - for _, v := range programMap { - programs = append(programs, v) - } - return programs, nil - } - - return []*models.Program{}, err -} - -//寰幆涓嬭浇锛岃В鍘嬶紝瑕嗙洊鍗囩骇鍖� -func HandlerPatchPkg(payload Payload) ([]*models.Program, error) { - if payload.PatchUrl == "" { - return []*models.Program{}, errors.New("No dist file get") - } - - //u, err := url.Parse("http://" + util.GetShopUrl() + uriDownload) - u, err := url.Parse(payload.PatchUrl) - if err != nil { - logger.Error("parse url failed, url:", payload.PatchUrl, ", err:", err.Error()) - return []*models.Program{}, err - } - upgradePath := GetPreDownPath() - upfile := upgradePath + "/" + GetMd5(payload.Version) + ".tgz" - //tmpFile, err := ioutil.TempFile("", "dist-*.zip") - tmpFile, err := os.OpenFile(upfile, os.O_CREATE|os.O_WRONLY, 0666) - if nil != err { - logger.Error("OnlineUpgrade create temp file failed, err:", err.Error()) - return []*models.Program{}, err - } - fmt.Println("OnlineUpgrade tmpFile.Name: ", tmpFile.Name()) - defer func() { - tmpFile.Close() - backupPath := GetBackupPath() - //鏂囦欢浠巙pgrade鐩綍绉诲姩鍒癰ackup鐩綍 - os.Rename(tmpFile.Name(), backupPath+"/"+tmpFile.Name()) - //os.Remove(tmpFile.Name()) - }() - - //query := u.Query() - //query.Set("filename", info.Data.Archive) - //u.RawQuery = query.Encode() - resp, err := http.Get(u.String()) - if err != nil { - logger.Error("OnlineUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) - return []*models.Program{}, err - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - logger.Error("OnlineUpgrade incorrect status, url:", u.String(), ", status:", resp.StatusCode) - return []*models.Program{}, errors.New("Status code not 200") - } - - _, err = io.Copy(tmpFile, resp.Body) - if err != nil { - logger.Error("OnlineUpgrade save upgrade file failed, url:", u.String(), ", err:", err.Error()) - return []*models.Program{}, err - } - - return UpgradeViaZip(tmpFile.Name()) -} - -//寰幆涓嬭浇鍗囩骇鍖� -func DownloadPatchPkg(payload Payload) (string, error) { - if payload.PatchUrl == "" { - return "", errors.New("no dist file get") - } - - //u, err := url.Parse("http://" + util.GetShopUrl() + uriDownload) - u, err := url.Parse(payload.PatchUrl) - if err != nil { - logger.Error("parse url failed, url:", payload.PatchUrl, ", err:", err.Error()) - return "", err - } - - upgradePath := GetPreDownPath() - upfile := upgradePath + "/" + GetMd5(payload.Version) + ".tgz" - _, err = os.Stat(upfile) - if nil == err { - //宸蹭笅杞借繃 - logger.Info("PreDownUpgrade predown upgrade file have down:", upfile) - return upfile, nil - } - - tmpFile, err := os.OpenFile(upfile, os.O_CREATE|os.O_WRONLY, 0666) - if nil != err { - logger.Error("OnlineUpgrade create temp file failed, err:", err.Error()) - return "", err - } - - fmt.Println("OnlineUpgrade tmpFile.Name: ", tmpFile.Name()) - defer func() { - tmpFile.Close() - }() - - resp, err := http.Get(u.String()) - if err != nil { - logger.Error("OnlineUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) - return "", err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - logger.Error("OnlineUpgrade incorrect status, url:", u.String(), ", status:", resp.StatusCode) - return "", errors.New("status code not 200") - } - - _, err = io.Copy(tmpFile, resp.Body) - if err != nil { - logger.Error("PreDownUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) - tmpFile.Close() - - os.Remove(upfile) - return "", err - } - - return upfile, nil -} - -//妫�鏌ユ槸鍚﹂渶瑕佹洿鏂扮増鏈� -func CheckVersion() (string, string, string) { - //鑾峰彇鏈嶅姟绔墍鏈夌▼搴忔渶鏂扮増鏈俊鎭�� - info, err := getUpdateInfo() - if nil != err { - return "", "", "" - } - - if len(info.Data) <= 0 { - logger.Error("checkVersion no programs get") - return "", "", "" - } - - //鑾峰彇闇�瑕佹洿鏂扮増鏈殑绋嬪簭鍒楄〃 - //programs := needUpgrade(info.Data.Programs) - last := len(info.Data) - 1 - return info.Data[last].PatchUrl, info.Data[last].Version, info.Data[last].Intro -} - -func GetCurVersion() string { - curEnv, err := GetRunVersionEnv() - if err != nil { - return "" - } - return curEnv -} - -//鑾峰彇鏈嶅姟绔渶鏂扮▼搴忓強鍏剁増鏈� -func getUpdateInfo() (*UpdateInfo, error) { - //const PrtSize = 32 << uintptr(^uintptr(0)>>63) - //wordSize := strconv.Itoa(PrtSize) - - u, err := url.Parse("http://" + util.GetShopUrl() + uriVersion) - if err != nil { - logger.Error("parse url failed, url:", "http://"+util.GetShopUrl()+uriVersion, ", err:", err.Error()) - return nil, err - } - - query := u.Query() - //query.Set("os", runtime.GOOS) - query.Set("arch", runtime.GOARCH) - query.Set("versionNum", GetCurVersion()) - //query.Set("wordSize", wordSize) - - u.RawQuery = query.Encode() - resp, err := http.Get(u.String()) - if err != nil { - logger.Error("checkVersion parse url failed, url:", u.String(), ", err:", err.Error()) - return nil, err - } - - if resp.StatusCode != 200 { - logger.Error("checkVersion incorrect status, url:", u.String(), ", status:", resp.StatusCode) - return nil, errors.New("Status code not 200") - } - - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Error("checkVersion read body failed, url:", u.String(), ", err:", err.Error()) - return nil, err - } - - logger.Info("checkVersion dump body:", string(body)) - var info UpdateInfo - err = json.Unmarshal(body, &info) - if err != nil { - logger.Error("checkVersion json.Unmarshal failed, url:", u.String(), ", err:", err.Error()) - return nil, err - } - - //b, err := json.Marshal(&info) - //if err != nil { - // logger.Error("checkVersion json.Marshal failed, url:", u.String(), ", err:", err.Error()) - //} else { - // logger.Info("checkVersion get response, url:", u.String(), ", response:", string(b)) - //} - - return &info, nil -} - -//闇�瑕佸崌绾х殑绋嬪簭 -func needUpgrade(programs []*models.Program) []*models.Program { - //鑾峰彇褰撳墠杩愯鐗堟湰鐩綍 - //dir := utils.GetExePath() - dir := util.GetVamicroPath() - - newPrograms := []*models.Program{} - for _, p := range programs { - exe := path.Join(dir, p.Name) - if !utils.PathExists(exe) { - newPrograms = append(newPrograms, p) - continue - } - - lVersion, err := dynamicGetVersion(dir, exe) - if err != nil { - logger.Error("exe:", exe, "get local version failed, err:", err.Error()) - continue - } - - //鐗堟湰鍚嶇О杞崲涓虹増鏈彿 - rVersion, err := vaversion.VersionName2VaVersion(p.Version) - if err != nil { - logger.Error("exe:", exe, "get remote version failed:", p.Version, ", err:", err.Error()) - continue - } - - c, err := lVersion.Compare(rVersion) - if err != nil { - logger.Error("exe:", exe, "version compare failed, remote:", p.Version, ", err:", err.Error()) - continue - } - - if c > 0 { - logger.Error("exe:", exe, "local version greater, local:", lVersion, "remote:", p.Version) - continue - } - - if c < 0 { - newPrograms = append(newPrograms, p) - } - } - - return newPrograms -} - -func NoticeTick(c context.Context) { - // tick := time.Tick(1 * time.Second) - tick := time.Tick(24 * time.Hour) - for { - select { - case <-c.Done(): - logger.Info("proc close, self update exit") - return - case <-tick: - //logger.Info("NoticeTick !!!") - updateNoticeLock.Lock() - for key, _ := range updateNotice.NoticeUser { - if 0 < updateNotice.NoticeUser[key] { - updateNotice.NoticeUser[key]-- - } - } - updateNoticeLock.Unlock() - } - } -} - -//鍗囩骇閰嶇疆澶勭悊 -func SelfUpdateStart(c context.Context, ms *bhomeclient.MicroNode) { - //涓夊崄绉掓鏌ヤ竴娆¢厤缃苟鏇存柊 - // tick := time.Tick(30 * time.Second) - tick := time.Tick(24 * time.Hour) - - var setting models.SysSetting - for { - select { - case <-c.Done(): - logger.Info("proc close, self update exit") - return - case <-tick: - settings, err := setting.GetAllSetting() - if nil != err { - logger.Error("fetch setting failed") - continue - } - - for _, set := range settings { - data, _ := json.Marshal(set) - var nodes []bhome_msg.BHAddress - nodes = append(nodes, bhome_msg.BHAddress{}) - - go ms.PublishNetTimeout(nodes, SysUpdateConfigTopic, data, 10) - - switch set.Name { - case "sys_auto_clean": - if "1" == set.Value { - err := os.RemoveAll(GetBackupPath()) - if nil != err { - logger.Error("clean update package failed:", err.Error()) - } - _ = os.MkdirAll(GetBackupPath(), 0777) - } - case "sys_update_notice": - { - // 鍒ゆ柇鏈夋柊鐗堟湰, 涓嶅啀閲嶅妫�娴� - if updateNotice.HaveNewVersion == 1 { - continue - } - - // 璁惧鏇存柊鎻愰啋 - updateNoticeLock.Lock() - - //鑾峰彇闇�瑕佹洿鏂扮増鏈殑绋嬪簭鍒楄〃 - _, version, _ := CheckVersion() - curVersion := GetCurVersion() - IsLastUpdate := true - if version != curVersion { - // 璁剧疆鏇存柊鎻愰啋, 閲嶆柊涓嬭浇鍗囩骇鍖� - updateNotice.HaveNewVersion = 1 - updateNotice.PkgDownloaded = 0 - IsLastUpdate = true - } else { - IsLastUpdate = false - } - - if !IsLastUpdate { //濡傛灉娌℃湁鏇存柊锛岃缃敤鎴峰欢杩熸椂闂翠负0 - for key, _ := range updateNotice.NoticeUser { - if 0 > updateNotice.NoticeUser[key] { - updateNotice.NoticeUser[key] = 0 - } - } - } - - if "1" == set.Value { - updateNotice.NoticeStatus = true - } else { - updateNotice.NoticeStatus = false - } - - updateNoticeLock.Unlock() - } - case "sys_auto_update": - { - if "1" == set.Value && updateNotice.HaveNewVersion > 0 && updateNotice.PkgDownloaded == 0 { - err := PreDownUpdateFile() - if nil != err { - logger.Error("pre download update file failed:", err.Error()) - } else { - updateNotice.PkgDownloaded = 1 - } - } - } - } - } - } - } -} - -//妫�鏌ユ槸鍚﹁窛涓婃姣旇緝鏈夋洿鏂� -func IsLastUpdate(programs []*models.Program, NewVersionProgram []*models.Program) bool { - for _, program := range programs { - for _, program2 := range NewVersionProgram { - if program.Name == program2.Name { - if program.Version != program2.Version { - return true - } - } - } - } - return true -} - -//鑾峰彇鏇存柊鎻愰啋 -func GetUpdateNotice() UpdateNotice { - return updateNotice -} - -//寤惰繜鎻愰啋 -func DelayNotice(uid string, second int) UpdateNotice { - updateNoticeLock.Lock() - updateNotice.NoticeUser[uid] = second - updateNoticeLock.Unlock() - return updateNotice -} - -//鑾峰彇浠g爜澶囦唤浣嶇疆 -func GetBackupPath() string { - dir := util.GetVamicroPath() + "/backup" - _, err := os.Stat(dir) - if nil != err { - if os.IsNotExist(err) { - os.Mkdir(dir, 0744) - } else { - return "./backup" - } - } - - return dir -} - -//鑾峰彇瑙e帇鍚庣殑琛ヤ竵鍖呬綅缃� -func GetPatchPath() string { - dir := util.GetVamicroPath() + "/patch" - _, err := os.Stat(dir) - if nil != err { - if os.IsNotExist(err) { - os.Mkdir(dir, 0744) - } else { - return "./patch" - } - } - - return dir -} - -//鑾峰彇棰勪笅杞藉崌绾у寘鐩綍 -func GetPreDownPath() string { - dir := util.GetVamicroPath() + "/upgrade" - _, err := os.Stat(dir) - if nil != err { - if os.IsNotExist(err) { - os.Mkdir(dir, 0744) - } else { - return "./upgrade" - } - } - - return dir -} - -//鑾峰彇涓婁紶鍗囩骇鍖呯洰褰� -func GetPreUploadPath() string { - dir := util.GetVamicroPath() + "/upgrade_manual" - _, err := os.Stat(dir) - if nil != err { - if os.IsNotExist(err) { - os.Mkdir(dir, 0744) - } else { - return "./upgrade_manual" - } - } - - return dir -} - -func GetMd5(in string) string { - data := md5.Sum([]byte(in)) - return fmt.Sprintf("%x", data) -} - -//棰勪笅杞藉崌绾ф枃浠� -func PreDownUpdateFile() error { - info, err := getUpdateInfo() - if nil != err { - return err - } - - LastDownLock.Lock() - defer LastDownLock.Unlock() - - LastDownFile = make([]string, 0) - - //寰幆涓嬭浇鍗囩骇鍖� - for _, payload := range info.Data { - logger.Info("姝e湪涓嬭浇鐗堟湰琛ヤ竵銆�" + payload.Version + "銆�") - upfile, err := DownloadPatchPkg(payload) - logger.Info("涓嬭浇鐗堟湰琛ヤ竵瀹屾垚銆�" + payload.Version + "銆�") - if err != nil { - return err - } - - LastDownFile = append(LastDownFile, upfile) - } - - return nil -} - -//鑾峰彇棰勪笅杞藉崌绾у寘 -func GetLastDownFile() []string { - var res = make([]string, 0) - if len(LastDownFile) > 0 { - for _, file := range LastDownFile { - _, err := os.Stat(file) - if nil == err { - res = append(res, file) - } - } - } - return res -} - -//鍥炴粴鐗堟湰 -func Rollback(version string) error { - dir := util.GetVamicroPath() + "/" + version - _, err := os.Stat(dir) - if nil != err { - return err - } - SetRunVersionEnv(version) - versionEnv = version - return nil -} - -type RegUserInfo struct { - UserType string `json:"userType"` //涓汉:personal 鍏徃: company - PhoneNum string `json:"phoneNum"` //鎵嬫満鍙风爜 - Name string `json:"name"` //濮撳悕鎴栧叕鍙稿悕绉� - ProvinceId string `json:"provinceId"` //鐪� - CityId string `json:"cityId"` //甯� - CountyId string `json:"countyId"` //鍘� - Email string `json:"email"` //閭 -} - -//鑾峰彇鎺堟潈 -func Authorization(code string, isManual bool) (authinfo util.AuthorizationInfo, err error) { - sn := util.GetVamicroPath() + "/sn.txt" - authorization := util.GetVamicroPath() + "/auth.txt" - - activateCode := "" - if len(code) == 29 && code[5:6] == "-" { //25浣嶆縺娲荤爜婵�娲� - activateCode = code - } - - if "" != code && len(code) != 29 && code[5:6] != "-" { - authinfo, err := util.GetAuthorizationInfo(code) - if nil == err { - activateCode = authinfo.ActivateCode - logger.Debug("code found:" + code) - if isManual { //鎵嬪姩鎿嶄綔鏇存柊鎺堟潈鏂囦欢锛屽垯绔嬪嵆杩斿洖锛屼笉鐢ㄥ啀娆¤闂晢鍩� - ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) - ioutil.WriteFile(authorization, []byte(code), os.ModePerm) - return authinfo, nil - } else { - //鍚﹀垯浠ュ晢鍩庝负鍑� - defer func() { - if nil != err { - //ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) - //ioutil.WriteFile(authorization, []byte(code), os.ModePerm) - } - }() - } - } else { - return authinfo, errors.New("闈炴硶鐨勬巿鏉�!!") - } - } - devId := config.Server.AnalyServerId - machineCode := licence.GetMachineCode() - - authinfo, authcode, err := postAuthReq(util.GetSn(), activateCode, devId, machineCode, "") - if nil != err { - logger.Error("Authorization err:", err.Error(), authcode) - //ioutil.WriteFile(authorization, []byte(authcode), os.ModePerm) //bug:灞�鍩熺綉浼氭妸鎺堟潈娓呴櫎 - return authinfo, err - } - - if authinfo.MachineCode != machineCode { - logger.Error("GetAuthorization machineCode not match, local:", machineCode, " remote:", authinfo.MachineCode) - return authinfo, errors.New("鎺堟潈涓嶅尮閰�") - } - - ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) - ioutil.WriteFile(authorization, []byte(authcode), os.ModePerm) - - return authinfo, nil -} - -func postAuthReq(sn string, activateCode string, deviceId string, machineCode string, oldDeviceId string) (authinfo util.AuthorizationInfo, authcode string, err error) { - u, err := url.Parse("http://" + util.GetShopUrl() + uriAuth) - if err != nil { - logger.Error("parse url failed, url:", "http://"+util.GetShopUrl()+uriAuth, ", err:", err.Error()) - return authinfo, "", err - } - query := u.Query() - query.Set("sn", sn) - query.Set("activateCode", activateCode) - query.Set("deviceId", deviceId) - query.Set("machineCode", machineCode) - query.Set("oldDeviceId", oldDeviceId) - query.Set("deviceType", config.Server.DeviceType) - query.Set("deviceMode", config.Server.DeviceModel) - query.Set("vGpu", util.GetVGpu()) - - var sysInitApi bhomedbapi.SysInitApi - b, rInfo := sysInitApi.GetRegInfo() - if b { - rbd, e := json.Marshal(rInfo) - if e == nil { - var sysRI RegUserInfo - if e = json.Unmarshal(rbd, &sysRI); e == nil { - query.Set("userType", sysRI.UserType) - query.Set("name", sysRI.Name) - query.Set("phoneNum", sysRI.PhoneNum) - query.Set("provinceId", sysRI.ProvinceId) - query.Set("cityId", sysRI.CityId) - query.Set("countyId", sysRI.CountyId) - query.Set("email", sysRI.Email) - } else { - logger.Error("json.Unmarshal sysRI e:", e) - } - } else { - logger.Error("json.Marshal rInfo e:", e) - } - } - - u.RawQuery = query.Encode() - resp, err := http.Get(u.String()) - if err != nil { - logger.Error("GetAuthorization parse url failed, url:", u.String(), ", err:", err.Error()) - return authinfo, "", err - } - - if resp.StatusCode != 200 { - logger.Error("GetAuthorization incorrect status, url:", u.String(), ", status:", resp.StatusCode) - return authinfo, "", errors.New("Status code not 200") - } - - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - logger.Error("GetAuthorization read body failed, url:", u.String(), ", err:", err.Error()) - return authinfo, "", err - } - - logger.Info("postAuthReq body:", string(body)) - var info map[string]interface{} - err = json.Unmarshal(body, &info) - if err != nil { - logger.Error("GetAuthorization json.Unmarshal failed, url:", u.String(), ", err:", err.Error()) - return authinfo, "", err - } - - authinfo, err = util.GetAuthorizationInfo(info["data"].(string)) - if nil == err { - logger.Error("err:", err) - return authinfo, info["data"].(string), nil - } - - if 500 == int(info["code"].(float64)) { - logger.Error("ret 500") - return authinfo, "", errors.New(info["msg"].(string)) - } - - if true != info["success"].(bool) { - logger.Error("not success") - return authinfo, "", errors.New(info["msg"].(string)) - } - - return authinfo, info["data"].(string), nil -} - -func GenQRCode() ([]byte, string, error) { - sn := util.GetSn() - var authInfo util.AuthorizationInfo - authInfo.Sn = sn - authInfo.DevId = config.Server.AnalyServerId - authInfo.MachineCode = licence.GetMachineCode() - authInfo.DeviceType = config.Server.DeviceType - authInfo.DeviceMode = config.Server.DeviceModel - authInfo.VGpu = util.GetVGpu() - - var sysInitApi bhomedbapi.SysInitApi - if bsi, rInfo := sysInitApi.GetRegInfo(); bsi { - rbd, e := json.Marshal(rInfo) - if e == nil { - var sysRI RegUserInfo - if e = json.Unmarshal(rbd, &sysRI); e == nil { - authInfo.UserType = sysRI.UserType - authInfo.Name = sysRI.Name - authInfo.PhoneNum = sysRI.PhoneNum - authInfo.ProvinceId = sysRI.ProvinceId - authInfo.CityId = sysRI.CityId - authInfo.CountyId = sysRI.CountyId - authInfo.Email = sysRI.Email - } else { - logger.Error("json.Unmarshal sysRI e:", e) - } - } else { - logger.Error("json.Marshal rInfo e:", e) - } - } - - hackQ, _ := HackAuthorizationInfo(authInfo) - - url := "http://" + util.GetShopUrl() + uriMobile + "?q=" + hackQ - - logger.Info("qrcode len:", len(url), " content:", url) - - // 鐢熸垚浜岀淮鐮� - q, err := qrcode.New(url, qrcode.Highest) - if err != nil { - return nil, url, err - } - - png, err1 := q.PNG(350) - - return png, url, err1 -} - -//鍒锋柊鎺堟潈鍒板叾浠栬繘绋� -func AuthorizationUpdate(c context.Context, ms *bhomeclient.MicroNode) { - //涓夊崄绉掓鏌ヤ竴娆¢厤缃苟鏇存柊 - // tick := time.Tick(30 * time.Second) - tick := time.Tick(24 * time.Hour) - - var authInfo util.AuthorizationInfo - var err error - for { - select { - case <-c.Done(): - logger.Info("proc close, self update exit") - return - case <-tick: - author := util.GetAuthorization() - sn := util.GetSn() - - authInfo, err = Authorization(sn, false) - if nil != err && !strings.Contains(err.Error(), "鎴愬姛") { - logger.Error("GetAuthorization error:", err.Error()) - if "" != author { - authInfo, err = util.GetAuthorizationInfo(author) - } - } - - logger.Debug("authInfo:", authInfo) - data, _ := json.Marshal(authInfo) - var nodes []bhome_msg.BHAddress - nodes = append(nodes, bhome_msg.BHAddress{}) - go ms.PublishNetTimeout(nodes, AuthorizationUpdateTopic, data, 10) - } - } -} - -func HackAuthorizationInfo(authorizationInfo util.AuthorizationInfo) (string, error) { - b, err := json.Marshal(authorizationInfo) - if nil != err { - return "", err - } - logger.Debug("authorInfo", authorizationInfo) - - info, err := util.RsaEncrypt(b) - if nil != err { - logger.Error("HackAuthorizationInfo utils.RsaEncrypt failed, err:", err.Error()) - return "", err - } - - return base64.StdEncoding.EncodeToString(info), nil -} - -func GetQ() string { - sn := util.GetSn() - var authinfo util.AuthorizationInfo - authinfo.Sn = sn - authinfo.DevId = config.Server.AnalyServerId - authinfo.MachineCode = licence.GetMachineCode() - authinfo.VGpu = util.GetVGpu() - q, err := HackAuthorizationInfo(authinfo) - if nil == err { - return q - } - return err.Error() -} - -func CancelAuthorization(passwd string, q string) (error, string) { - uApi := bhomedbapi.UserApi{} - ok, _ := uApi.Login("basic", passwd) - if !ok { - return errors.New("瀵嗙爜涓嶆纭�!"), "" - } - //鑾峰彇璇锋眰鐮侀噷鐨刣evId - qInfo, err := util.GetAuthorizationInfo(q) - if nil != err { - return errors.New("璇锋眰鐮佹牸寮忎笉姝g‘"), "" - } - - curAuthInfo := util.GetAuthorization() - - //鑾峰彇褰撳墠鎺堟潈鐮� - authInfo, err := util.GetAuthorizationInfo(curAuthInfo) - if nil != err { - return errors.New("褰撳墠鏈嶅姟鍣ㄦ巿鏉冧俊鎭笉瀹屾暣"), "" - } - authInfo.OldDeviceId = authInfo.DevId - authInfo.DevId = qInfo.DevId - authInfo.VGpu = util.GetVGpu() - sn := util.GetVamicroPath() + "/sn.txt" - authorization := util.GetVamicroPath() + "/auth.txt" - authCode, err := HackAuthorizationInfo(authInfo) - if nil != err { - return errors.New("浜у搧瀵嗛挜瀵煎嚭澶辫触"), "" - } - ioutil.WriteFile(sn, []byte(""), os.ModePerm) - time.Sleep(100 * time.Microsecond) - ioutil.WriteFile(authorization, []byte(""), os.ModePerm) - - _, _, err = postAuthReq(authInfo.Sn, authInfo.ActivateCode, qInfo.DevId, licence.GetMachineCode(), authInfo.OldDeviceId) - - if nil != err { - return err, "" - } - - return nil, authCode -} +package service + +import ( + "basic.com/valib/bhomeclient.git" + "basic.com/valib/bhomedbapi.git" + "basic.com/valib/c_bhomebus.git/proto/source/bhome_msg" + "basic.com/valib/licence.git" + "basic.com/valib/logger.git" + "basic.com/valib/version.git" + "context" + "crypto/md5" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "github.com/skip2/go-qrcode" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "path" + "runtime" + "strings" + "sync" + "time" + "vamicro/config" + "vamicro/extend/util" + "vamicro/version-control/models" + "vamicro/version-control/response" + "vamicro/version-control/utils" +) + +const ( + uriVersion string = "/data/api-u/upgrade/findUpgradeVersion" + uriDownload string = "/data/api-p/download" + uriAuth string = "/data/api-s/authorization" + uriMobile string = "/data/api-s/fromQrcode" +) + +type ( + Payload struct { + Arch string `json:"arch"` + Programs []*models.Program `json:"programs"` + Version string `json:"version"` + Intro string `json:"intro"` + PatchUrl string `json:"patchUrl"` + } + + UpdateInfo struct { + response.ResponseHead + Data []Payload `json:"data"` + } + + VersionInfo struct { + Build string `json:"build"` + Commit string `json:"commit"` + Name string `json:"name"` + Version string `json:"version"` + } + + UpdateNotice struct { + NoticeUser map[string]int + HaveNewVersion int64 //鏄惁鏈夋柊鐗堟湰锛�1鏈夛紝0娌℃湁 + PkgDownloaded int64 //鏄惁涓嬭浇瀹屾垚锛�1鏈夛紝0娌℃湁 + LastNoticeTime int64 + NewVersionProgram []*models.Program + NoticeStatus bool + } +) + +var ( + updateNotice UpdateNotice + updateNoticeLock sync.Mutex + LastDownFile []string + LastDownLock sync.RWMutex +) + +func Init() { + backUpPath := GetBackupPath() + if _, err := os.Stat(backUpPath); os.IsNotExist(err) { + _ = os.MkdirAll(backUpPath, 0777) + } + preDownPath := GetPreDownPath() + if _, err := os.Stat(preDownPath); os.IsNotExist(err) { + _ = os.MkdirAll(preDownPath, 0777) + } + updateNotice.NoticeUser = make(map[string]int) + LastDownFile = make([]string, 0) +} + +func OnlineUpgrade() ([]*models.Program, error) { + + programMap := make(map[string]*models.Program) + + LastDownLock.Lock() + defer LastDownLock.Unlock() + //鏌ユ壘棰勪笅杞藉崌绾у寘 + preDowns := GetLastDownFile() + logger.Info("绯荤粺寮�濮嬪崌绾э紒") + for _, preDown := range preDowns { + logger.Info(preDowns) + ps, err := UpgradeViaZip(preDown) + if err != nil { + return []*models.Program{}, err + } + for _, p := range ps { + programMap[p.Name] = p + } + } + logger.Info("绯荤粺鍗囩骇瀹屾垚锛侊紒") + + if len(programMap) > 0 { //浣跨敤棰勪笅杞藉崌绾у畬鎴� + programs := make([]*models.Program, 0, len(programMap)) + for _, v := range programMap { + programs = append(programs, v) + } + return programs, nil + } + + info, err := getUpdateInfo() + if nil != err { + return []*models.Program{}, errors.New("绯荤粺娌℃湁鏇存柊鍙敤") + } + + logger.Info("绯荤粺鍗囩骇寮�濮嬶紒") + //寰幆涓嬭浇锛岃В鍘嬶紝瑕嗙洊鍗囩骇鍖� + for _, payload := range info.Data { + ps, err := HandlerPatchPkg(payload) + if err != nil { + return []*models.Program{}, err + } + for _, p := range ps { + programMap[p.Name] = p + } + } + logger.Info("绯荤粺鍗囩骇瀹屾垚锛侊紒") + + if len(programMap) > 0 { // + programs := make([]*models.Program, 0, len(programMap)) + for _, v := range programMap { + programs = append(programs, v) + } + return programs, nil + } + + return []*models.Program{}, err +} + +//寰幆涓嬭浇锛岃В鍘嬶紝瑕嗙洊鍗囩骇鍖� +func HandlerPatchPkg(payload Payload) ([]*models.Program, error) { + if payload.PatchUrl == "" { + return []*models.Program{}, errors.New("No dist file get") + } + + //u, err := url.Parse("http://" + util.GetShopUrl() + uriDownload) + u, err := url.Parse(payload.PatchUrl) + if err != nil { + logger.Error("parse url failed, url:", payload.PatchUrl, ", err:", err.Error()) + return []*models.Program{}, err + } + upgradePath := GetPreDownPath() + upfile := upgradePath + "/" + GetMd5(payload.Version) + ".tgz" + //tmpFile, err := ioutil.TempFile("", "dist-*.zip") + tmpFile, err := os.OpenFile(upfile, os.O_CREATE|os.O_WRONLY, 0666) + if nil != err { + logger.Error("OnlineUpgrade create temp file failed, err:", err.Error()) + return []*models.Program{}, err + } + fmt.Println("OnlineUpgrade tmpFile.Name: ", tmpFile.Name()) + defer func() { + tmpFile.Close() + backupPath := GetBackupPath() + //鏂囦欢浠巙pgrade鐩綍绉诲姩鍒癰ackup鐩綍 + os.Rename(tmpFile.Name(), backupPath+"/"+tmpFile.Name()) + //os.Remove(tmpFile.Name()) + }() + + //query := u.Query() + //query.Set("filename", info.Data.Archive) + //u.RawQuery = query.Encode() + resp, err := http.Get(u.String()) + if err != nil { + logger.Error("OnlineUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) + return []*models.Program{}, err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + logger.Error("OnlineUpgrade incorrect status, url:", u.String(), ", status:", resp.StatusCode) + return []*models.Program{}, errors.New("Status code not 200") + } + + _, err = io.Copy(tmpFile, resp.Body) + if err != nil { + logger.Error("OnlineUpgrade save upgrade file failed, url:", u.String(), ", err:", err.Error()) + return []*models.Program{}, err + } + + return UpgradeViaZip(tmpFile.Name()) +} + +//寰幆涓嬭浇鍗囩骇鍖� +func DownloadPatchPkg(payload Payload) (string, error) { + if payload.PatchUrl == "" { + return "", errors.New("no dist file get") + } + + //u, err := url.Parse("http://" + util.GetShopUrl() + uriDownload) + u, err := url.Parse(payload.PatchUrl) + if err != nil { + logger.Error("parse url failed, url:", payload.PatchUrl, ", err:", err.Error()) + return "", err + } + + upgradePath := GetPreDownPath() + upfile := upgradePath + "/" + GetMd5(payload.Version) + ".tgz" + _, err = os.Stat(upfile) + if nil == err { + //宸蹭笅杞借繃 + logger.Info("PreDownUpgrade predown upgrade file have down:", upfile) + return upfile, nil + } + + tmpFile, err := os.OpenFile(upfile, os.O_CREATE|os.O_WRONLY, 0666) + if nil != err { + logger.Error("OnlineUpgrade create temp file failed, err:", err.Error()) + return "", err + } + + fmt.Println("OnlineUpgrade tmpFile.Name: ", tmpFile.Name()) + defer func() { + tmpFile.Close() + }() + + resp, err := http.Get(u.String()) + if err != nil { + logger.Error("OnlineUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) + return "", err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + logger.Error("OnlineUpgrade incorrect status, url:", u.String(), ", status:", resp.StatusCode) + return "", errors.New("status code not 200") + } + + _, err = io.Copy(tmpFile, resp.Body) + if err != nil { + logger.Error("PreDownUpgrade parse url failed, url:", u.String(), ", err:", err.Error()) + tmpFile.Close() + + os.Remove(upfile) + return "", err + } + + return upfile, nil +} + +//妫�鏌ユ槸鍚﹂渶瑕佹洿鏂扮増鏈� +func CheckVersion() (string, string, string) { + //鑾峰彇鏈嶅姟绔墍鏈夌▼搴忔渶鏂扮増鏈俊鎭�� + info, err := getUpdateInfo() + if nil != err { + return "", "", "" + } + + if len(info.Data) <= 0 { + logger.Error("checkVersion no programs get") + return "", "", "" + } + + //鑾峰彇闇�瑕佹洿鏂扮増鏈殑绋嬪簭鍒楄〃 + //programs := needUpgrade(info.Data.Programs) + last := len(info.Data) - 1 + return info.Data[last].PatchUrl, info.Data[last].Version, info.Data[last].Intro +} + +func GetCurVersion() string { + curEnv, err := GetRunVersionEnv() + if err != nil { + return "" + } + return curEnv +} + +//鑾峰彇鏈嶅姟绔渶鏂扮▼搴忓強鍏剁増鏈� +func getUpdateInfo() (*UpdateInfo, error) { + //const PrtSize = 32 << uintptr(^uintptr(0)>>63) + //wordSize := strconv.Itoa(PrtSize) + + u, err := url.Parse("http://" + util.GetShopUrl() + uriVersion) + if err != nil { + logger.Error("parse url failed, url:", "http://"+util.GetShopUrl()+uriVersion, ", err:", err.Error()) + return nil, err + } + + query := u.Query() + //query.Set("os", runtime.GOOS) + query.Set("arch", runtime.GOARCH) + query.Set("versionNum", GetCurVersion()) + //query.Set("wordSize", wordSize) + + u.RawQuery = query.Encode() + resp, err := http.Get(u.String()) + if err != nil { + logger.Error("checkVersion parse url failed, url:", u.String(), ", err:", err.Error()) + return nil, err + } + + if resp.StatusCode != 200 { + logger.Error("checkVersion incorrect status, url:", u.String(), ", status:", resp.StatusCode) + return nil, errors.New("Status code not 200") + } + + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + logger.Error("checkVersion read body failed, url:", u.String(), ", err:", err.Error()) + return nil, err + } + + logger.Info("checkVersion dump body:", string(body)) + var info UpdateInfo + err = json.Unmarshal(body, &info) + if err != nil { + logger.Error("checkVersion json.Unmarshal failed, url:", u.String(), ", err:", err.Error()) + return nil, err + } + + //b, err := json.Marshal(&info) + //if err != nil { + // logger.Error("checkVersion json.Marshal failed, url:", u.String(), ", err:", err.Error()) + //} else { + // logger.Info("checkVersion get response, url:", u.String(), ", response:", string(b)) + //} + + return &info, nil +} + +//闇�瑕佸崌绾х殑绋嬪簭 +func needUpgrade(programs []*models.Program) []*models.Program { + //鑾峰彇褰撳墠杩愯鐗堟湰鐩綍 + //dir := utils.GetExePath() + dir := util.GetVamicroPath() + + newPrograms := []*models.Program{} + for _, p := range programs { + exe := path.Join(dir, p.Name) + if !utils.PathExists(exe) { + newPrograms = append(newPrograms, p) + continue + } + + lVersion, err := dynamicGetVersion(dir, exe) + if err != nil { + logger.Error("exe:", exe, "get local version failed, err:", err.Error()) + continue + } + + //鐗堟湰鍚嶇О杞崲涓虹増鏈彿 + rVersion, err := vaversion.VersionName2VaVersion(p.Version) + if err != nil { + logger.Error("exe:", exe, "get remote version failed:", p.Version, ", err:", err.Error()) + continue + } + + c, err := lVersion.Compare(rVersion) + if err != nil { + logger.Error("exe:", exe, "version compare failed, remote:", p.Version, ", err:", err.Error()) + continue + } + + if c > 0 { + logger.Error("exe:", exe, "local version greater, local:", lVersion, "remote:", p.Version) + continue + } + + if c < 0 { + newPrograms = append(newPrograms, p) + } + } + + return newPrograms +} + +func NoticeTick(c context.Context) { + // tick := time.Tick(1 * time.Second) + tick := time.Tick(24 * time.Hour) + for { + select { + case <-c.Done(): + logger.Info("proc close, self update exit") + return + case <-tick: + //logger.Info("NoticeTick !!!") + updateNoticeLock.Lock() + for key, _ := range updateNotice.NoticeUser { + if 0 < updateNotice.NoticeUser[key] { + updateNotice.NoticeUser[key]-- + } + } + updateNoticeLock.Unlock() + } + } +} + +//鍗囩骇閰嶇疆澶勭悊 +func SelfUpdateStart(c context.Context, ms *bhomeclient.MicroNode) { + //涓夊崄绉掓鏌ヤ竴娆¢厤缃苟鏇存柊 + // tick := time.Tick(30 * time.Second) + tick := time.Tick(24 * time.Hour) + + var setting models.SysSetting + for { + select { + case <-c.Done(): + logger.Info("proc close, self update exit") + return + case <-tick: + settings, err := setting.GetAllSetting() + if nil != err { + logger.Error("fetch setting failed") + continue + } + + for _, set := range settings { + data, _ := json.Marshal(set) + var nodes []bhome_msg.BHAddress + nodes = append(nodes, bhome_msg.BHAddress{}) + + go ms.PublishNetTimeout(nodes, SysUpdateConfigTopic, data, 10) + + switch set.Name { + case "sys_auto_clean": + if "1" == set.Value { + err := os.RemoveAll(GetBackupPath()) + if nil != err { + logger.Error("clean update package failed:", err.Error()) + } + _ = os.MkdirAll(GetBackupPath(), 0777) + } + case "sys_update_notice": + { + // 鍒ゆ柇鏈夋柊鐗堟湰, 涓嶅啀閲嶅妫�娴� + if updateNotice.HaveNewVersion == 1 { + continue + } + + // 璁惧鏇存柊鎻愰啋 + updateNoticeLock.Lock() + + //鑾峰彇闇�瑕佹洿鏂扮増鏈殑绋嬪簭鍒楄〃 + _, version, _ := CheckVersion() + curVersion := GetCurVersion() + IsLastUpdate := true + if version != curVersion { + // 璁剧疆鏇存柊鎻愰啋, 閲嶆柊涓嬭浇鍗囩骇鍖� + updateNotice.HaveNewVersion = 1 + updateNotice.PkgDownloaded = 0 + IsLastUpdate = true + } else { + IsLastUpdate = false + } + + if !IsLastUpdate { //濡傛灉娌℃湁鏇存柊锛岃缃敤鎴峰欢杩熸椂闂翠负0 + for key, _ := range updateNotice.NoticeUser { + if 0 > updateNotice.NoticeUser[key] { + updateNotice.NoticeUser[key] = 0 + } + } + } + + if "1" == set.Value { + updateNotice.NoticeStatus = true + } else { + updateNotice.NoticeStatus = false + } + + updateNoticeLock.Unlock() + } + case "sys_auto_update": + { + if "1" == set.Value && updateNotice.HaveNewVersion > 0 && updateNotice.PkgDownloaded == 0 { + err := PreDownUpdateFile() + if nil != err { + logger.Error("pre download update file failed:", err.Error()) + } else { + updateNotice.PkgDownloaded = 1 + } + } + } + } + } + } + } +} + +//妫�鏌ユ槸鍚﹁窛涓婃姣旇緝鏈夋洿鏂� +func IsLastUpdate(programs []*models.Program, NewVersionProgram []*models.Program) bool { + for _, program := range programs { + for _, program2 := range NewVersionProgram { + if program.Name == program2.Name { + if program.Version != program2.Version { + return true + } + } + } + } + return true +} + +//鑾峰彇鏇存柊鎻愰啋 +func GetUpdateNotice() UpdateNotice { + return updateNotice +} + +//寤惰繜鎻愰啋 +func DelayNotice(uid string, second int) UpdateNotice { + updateNoticeLock.Lock() + updateNotice.NoticeUser[uid] = second + updateNoticeLock.Unlock() + return updateNotice +} + +//鑾峰彇浠g爜澶囦唤浣嶇疆 +func GetBackupPath() string { + dir := util.GetVamicroPath() + "/backup" + _, err := os.Stat(dir) + if nil != err { + if os.IsNotExist(err) { + os.Mkdir(dir, 0744) + } else { + return "./backup" + } + } + + return dir +} + +//鑾峰彇瑙e帇鍚庣殑琛ヤ竵鍖呬綅缃� +func GetPatchPath() string { + dir := util.GetVamicroPath() + "/patch" + _, err := os.Stat(dir) + if nil != err { + if os.IsNotExist(err) { + os.Mkdir(dir, 0744) + } else { + return "./patch" + } + } + + return dir +} + +//鑾峰彇棰勪笅杞藉崌绾у寘鐩綍 +func GetPreDownPath() string { + dir := util.GetVamicroPath() + "/upgrade" + _, err := os.Stat(dir) + if nil != err { + if os.IsNotExist(err) { + os.Mkdir(dir, 0744) + } else { + return "./upgrade" + } + } + + return dir +} + +//鑾峰彇涓婁紶鍗囩骇鍖呯洰褰� +func GetPreUploadPath() string { + dir := util.GetVamicroPath() + "/upgrade_manual" + _, err := os.Stat(dir) + if nil != err { + if os.IsNotExist(err) { + os.Mkdir(dir, 0744) + } else { + return "./upgrade_manual" + } + } + + return dir +} + +func GetMd5(in string) string { + data := md5.Sum([]byte(in)) + return fmt.Sprintf("%x", data) +} + +//棰勪笅杞藉崌绾ф枃浠� +func PreDownUpdateFile() error { + info, err := getUpdateInfo() + if nil != err { + return err + } + + LastDownLock.Lock() + defer LastDownLock.Unlock() + + LastDownFile = make([]string, 0) + + //寰幆涓嬭浇鍗囩骇鍖� + for _, payload := range info.Data { + logger.Info("姝e湪涓嬭浇鐗堟湰琛ヤ竵銆�" + payload.Version + "銆�") + upfile, err := DownloadPatchPkg(payload) + logger.Info("涓嬭浇鐗堟湰琛ヤ竵瀹屾垚銆�" + payload.Version + "銆�") + if err != nil { + return err + } + + LastDownFile = append(LastDownFile, upfile) + } + + return nil +} + +//鑾峰彇棰勪笅杞藉崌绾у寘 +func GetLastDownFile() []string { + var res = make([]string, 0) + if len(LastDownFile) > 0 { + for _, file := range LastDownFile { + _, err := os.Stat(file) + if nil == err { + res = append(res, file) + } + } + } + return res +} + +//鍥炴粴鐗堟湰 +func Rollback(version string) error { + dir := util.GetVamicroPath() + "/" + version + _, err := os.Stat(dir) + if nil != err { + return err + } + SetRunVersionEnv(version) + versionEnv = version + return nil +} + +type RegUserInfo struct { + UserType string `json:"userType"` //涓汉:personal 鍏徃: company + PhoneNum string `json:"phoneNum"` //鎵嬫満鍙风爜 + Name string `json:"name"` //濮撳悕鎴栧叕鍙稿悕绉� + ProvinceId string `json:"provinceId"` //鐪� + CityId string `json:"cityId"` //甯� + CountyId string `json:"countyId"` //鍘� + Email string `json:"email"` //閭 +} + +//鑾峰彇鎺堟潈 +func Authorization(code string, isManual bool) (authinfo util.AuthorizationInfo, err error) { + sn := util.GetVamicroPath() + "/sn.txt" + authorization := util.GetVamicroPath() + "/auth.txt" + + activateCode := "" + if len(code) == 29 && code[5:6] == "-" { //25浣嶆縺娲荤爜婵�娲� + activateCode = code + } + + if "" != code && len(code) != 29 && code[5:6] != "-" { + authinfo, err := util.GetAuthorizationInfo(code) + if nil == err { + activateCode = authinfo.ActivateCode + logger.Debug("code found:" + code) + if isManual { //鎵嬪姩鎿嶄綔鏇存柊鎺堟潈鏂囦欢锛屽垯绔嬪嵆杩斿洖锛屼笉鐢ㄥ啀娆¤闂晢鍩� + ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) + ioutil.WriteFile(authorization, []byte(code), os.ModePerm) + return authinfo, nil + } else { + //鍚﹀垯浠ュ晢鍩庝负鍑� + defer func() { + if nil != err { + //ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) + //ioutil.WriteFile(authorization, []byte(code), os.ModePerm) + } + }() + } + } else { + return authinfo, errors.New("闈炴硶鐨勬巿鏉�!!") + } + } + devId := config.Server.AnalyServerId + machineCode := licence.GetMachineCode() + + authinfo, authcode, err := postAuthReq(util.GetSn(), activateCode, devId, machineCode, "") + if nil != err { + logger.Error("Authorization err:", err.Error(), authcode) + //ioutil.WriteFile(authorization, []byte(authcode), os.ModePerm) //bug:灞�鍩熺綉浼氭妸鎺堟潈娓呴櫎 + return authinfo, err + } + + if authinfo.MachineCode != machineCode { + logger.Error("GetAuthorization machineCode not match, local:", machineCode, " remote:", authinfo.MachineCode) + return authinfo, errors.New("鎺堟潈涓嶅尮閰�") + } + + ioutil.WriteFile(sn, []byte(authinfo.ActivateCode), os.ModePerm) + ioutil.WriteFile(authorization, []byte(authcode), os.ModePerm) + + return authinfo, nil +} + +func postAuthReq(sn string, activateCode string, deviceId string, machineCode string, oldDeviceId string) (authinfo util.AuthorizationInfo, authcode string, err error) { + u, err := url.Parse("http://" + util.GetShopUrl() + uriAuth) + if err != nil { + logger.Error("parse url failed, url:", "http://"+util.GetShopUrl()+uriAuth, ", err:", err.Error()) + return authinfo, "", err + } + query := u.Query() + query.Set("sn", sn) + query.Set("activateCode", activateCode) + query.Set("deviceId", deviceId) + query.Set("machineCode", machineCode) + query.Set("oldDeviceId", oldDeviceId) + query.Set("deviceType", config.Server.DeviceType) + query.Set("deviceMode", config.Server.DeviceModel) + query.Set("vGpu", util.GetVGpu()) + + var sysInitApi bhomedbapi.SysInitApi + b, rInfo := sysInitApi.GetRegInfo() + if b { + rbd, e := json.Marshal(rInfo) + if e == nil { + var sysRI RegUserInfo + if e = json.Unmarshal(rbd, &sysRI); e == nil { + query.Set("userType", sysRI.UserType) + query.Set("name", sysRI.Name) + query.Set("phoneNum", sysRI.PhoneNum) + query.Set("provinceId", sysRI.ProvinceId) + query.Set("cityId", sysRI.CityId) + query.Set("countyId", sysRI.CountyId) + query.Set("email", sysRI.Email) + } else { + logger.Error("json.Unmarshal sysRI e:", e) + } + } else { + logger.Error("json.Marshal rInfo e:", e) + } + } + + u.RawQuery = query.Encode() + resp, err := http.Get(u.String()) + if err != nil { + logger.Error("GetAuthorization parse url failed, url:", u.String(), ", err:", err.Error()) + return authinfo, "", err + } + + if resp.StatusCode != 200 { + logger.Error("GetAuthorization incorrect status, url:", u.String(), ", status:", resp.StatusCode) + return authinfo, "", errors.New("Status code not 200") + } + + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + logger.Error("GetAuthorization read body failed, url:", u.String(), ", err:", err.Error()) + return authinfo, "", err + } + + logger.Info("postAuthReq body:", string(body)) + var info map[string]interface{} + err = json.Unmarshal(body, &info) + if err != nil { + logger.Error("GetAuthorization json.Unmarshal failed, url:", u.String(), ", err:", err.Error()) + return authinfo, "", err + } + + authinfo, err = util.GetAuthorizationInfo(info["data"].(string)) + if nil == err { + logger.Error("err:", err) + return authinfo, info["data"].(string), nil + } + + if 500 == int(info["code"].(float64)) { + logger.Error("ret 500") + return authinfo, "", errors.New(info["msg"].(string)) + } + + if true != info["success"].(bool) { + logger.Error("not success") + return authinfo, "", errors.New(info["msg"].(string)) + } + + return authinfo, info["data"].(string), nil +} + +func GenQRCode() ([]byte, string, error) { + sn := util.GetSn() + var authInfo util.AuthorizationInfo + authInfo.Sn = sn + authInfo.DevId = config.Server.AnalyServerId + authInfo.MachineCode = licence.GetMachineCode() + authInfo.DeviceType = config.Server.DeviceType + authInfo.DeviceMode = config.Server.DeviceModel + authInfo.VGpu = util.GetVGpu() + + var sysInitApi bhomedbapi.SysInitApi + if bsi, rInfo := sysInitApi.GetRegInfo(); bsi { + rbd, e := json.Marshal(rInfo) + if e == nil { + var sysRI RegUserInfo + if e = json.Unmarshal(rbd, &sysRI); e == nil { + authInfo.UserType = sysRI.UserType + authInfo.Name = sysRI.Name + authInfo.PhoneNum = sysRI.PhoneNum + authInfo.ProvinceId = sysRI.ProvinceId + authInfo.CityId = sysRI.CityId + authInfo.CountyId = sysRI.CountyId + authInfo.Email = sysRI.Email + } else { + logger.Error("json.Unmarshal sysRI e:", e) + } + } else { + logger.Error("json.Marshal rInfo e:", e) + } + } + + hackQ, _ := HackAuthorizationInfo(authInfo) + + url := "http://" + util.GetShopUrl() + uriMobile + "?q=" + hackQ + + logger.Info("qrcode len:", len(url), " content:", url) + + // 鐢熸垚浜岀淮鐮� + q, err := qrcode.New(url, qrcode.Highest) + if err != nil { + return nil, url, err + } + + png, err1 := q.PNG(350) + + return png, url, err1 +} + +//鍒锋柊鎺堟潈鍒板叾浠栬繘绋� +func AuthorizationUpdate(c context.Context, ms *bhomeclient.MicroNode) { + //涓夊崄绉掓鏌ヤ竴娆¢厤缃苟鏇存柊 + // tick := time.Tick(30 * time.Second) + tick := time.Tick(24 * time.Hour) + + var authInfo util.AuthorizationInfo + var err error + for { + select { + case <-c.Done(): + logger.Info("proc close, self update exit") + return + case <-tick: + author := util.GetAuthorization() + sn := util.GetSn() + + authInfo, err = Authorization(sn, false) + if nil != err && !strings.Contains(err.Error(), "鎴愬姛") { + logger.Error("GetAuthorization error:", err.Error()) + if "" != author { + authInfo, err = util.GetAuthorizationInfo(author) + } + } + + logger.Debug("authInfo:", authInfo) + data, _ := json.Marshal(authInfo) + var nodes []bhome_msg.BHAddress + nodes = append(nodes, bhome_msg.BHAddress{}) + go ms.PublishNetTimeout(nodes, AuthorizationUpdateTopic, data, 10) + } + } +} + +func HackAuthorizationInfo(authorizationInfo util.AuthorizationInfo) (string, error) { + b, err := json.Marshal(authorizationInfo) + if nil != err { + return "", err + } + logger.Debug("authorInfo", authorizationInfo) + + info, err := util.RsaEncrypt(b) + if nil != err { + logger.Error("HackAuthorizationInfo utils.RsaEncrypt failed, err:", err.Error()) + return "", err + } + + return base64.StdEncoding.EncodeToString(info), nil +} + +func GetQ() string { + sn := util.GetSn() + var authinfo util.AuthorizationInfo + authinfo.Sn = sn + authinfo.DevId = config.Server.AnalyServerId + authinfo.MachineCode = licence.GetMachineCode() + authinfo.VGpu = util.GetVGpu() + q, err := HackAuthorizationInfo(authinfo) + if nil == err { + return q + } + return err.Error() +} + +func CancelAuthorization(passwd string, q string) (error, string) { + uApi := bhomedbapi.UserApi{} + ok, _ := uApi.Login("basic", passwd) + if !ok { + return errors.New("瀵嗙爜涓嶆纭�!"), "" + } + //鑾峰彇璇锋眰鐮侀噷鐨刣evId + qInfo, err := util.GetAuthorizationInfo(q) + if nil != err { + return errors.New("璇锋眰鐮佹牸寮忎笉姝g‘"), "" + } + + curAuthInfo := util.GetAuthorization() + + //鑾峰彇褰撳墠鎺堟潈鐮� + authInfo, err := util.GetAuthorizationInfo(curAuthInfo) + if nil != err { + return errors.New("褰撳墠鏈嶅姟鍣ㄦ巿鏉冧俊鎭笉瀹屾暣"), "" + } + authInfo.OldDeviceId = authInfo.DevId + authInfo.DevId = qInfo.DevId + authInfo.VGpu = util.GetVGpu() + sn := util.GetVamicroPath() + "/sn.txt" + authorization := util.GetVamicroPath() + "/auth.txt" + authCode, err := HackAuthorizationInfo(authInfo) + if nil != err { + return errors.New("浜у搧瀵嗛挜瀵煎嚭澶辫触"), "" + } + ioutil.WriteFile(sn, []byte(""), os.ModePerm) + time.Sleep(100 * time.Microsecond) + ioutil.WriteFile(authorization, []byte(""), os.ModePerm) + + _, _, err = postAuthReq(authInfo.Sn, authInfo.ActivateCode, qInfo.DevId, licence.GetMachineCode(), authInfo.OldDeviceId) + + if nil != err { + return err, "" + } + + return nil, authCode +} -- Gitblit v1.8.0