From 4235406c2cf1ea01eda697b6259c3f482353728a Mon Sep 17 00:00:00 2001 From: Vladislav Yarmak Date: Thu, 25 Mar 2021 22:09:36 +0200 Subject: [PATCH] WIP --- main.go | 8 ++++++ seclient/hash.go | 12 +++++++++ seclient/messages.go | 11 ++++++++ seclient/seclient.go | 62 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 seclient/hash.go diff --git a/main.go b/main.go index da20006..4951ca1 100644 --- a/main.go +++ b/main.go @@ -25,4 +25,12 @@ func main() { log.Fatalln(err) } log.Printf("seclient = %#v", seclient) + //log.Printf("jar = %#v", seclient.HttpClient.Jar) + + log.Println("------------ DOING DEVICE REGISTRATION ------------") + err = seclient.RegisterDevice(context.TODO()) + if err != nil { + log.Fatalln(err) + } + log.Printf("seclient = %#v", seclient) } diff --git a/seclient/hash.go b/seclient/hash.go new file mode 100644 index 0000000..674dd51 --- /dev/null +++ b/seclient/hash.go @@ -0,0 +1,12 @@ +package seclient + +import ( + "crypto/sha1" + "encoding/hex" + "strings" +) + +func capitalHexSHA1(input string) string { + h := sha1.Sum([]byte(input)) + return strings.ToUpper(hex.EncodeToString(h[:])) +} diff --git a/seclient/messages.go b/seclient/messages.go index c6b4884..ba15fd8 100644 --- a/seclient/messages.go +++ b/seclient/messages.go @@ -48,3 +48,14 @@ type SERegisterSubscriberResponse struct { Data interface{} `json:"data"` Status SEStatusPair `json:"return_code"` } + +type SERegisterDeviceData struct { + ClientType string `json:"client_type"` + DeviceID string `json:"device_id"` + DevicePassword string `json:"device_password"` +} + +type SERegisterDeviceResponse struct { + Data SERegisterDeviceData `json:"data"` + Status SEStatusPair `json:"return_code"` +} diff --git a/seclient/seclient.go b/seclient/seclient.go index a3b1bec..9d564b0 100644 --- a/seclient/seclient.go +++ b/seclient/seclient.go @@ -42,7 +42,6 @@ var DefaultSEEndpoints = SEEndpoints{ type SESettings struct { ClientVersion string ClientType string - DeviceHash string DeviceName string OperatingSystem string UserAgent string @@ -54,7 +53,6 @@ var DefaultSESettings = SESettings{ ClientType: "se0316", UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36 OPR/74.0.3911.232", DeviceName: "Opera-Browser-Client", - DeviceHash: "", OperatingSystem: "Windows", Endpoints: DefaultSEEndpoints, } @@ -66,7 +64,7 @@ type SEClient struct { SubscriberPassword string DeviceID string AssignedDeviceID string - AssignedDevideIDHash string + AssignedDeviceIDHash string DevicePassword string rng *rand.Rand } @@ -144,6 +142,10 @@ func (c *SEClient) Register(ctx context.Context) error { return err } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("bad http status: %s", resp.Status) + } + decoder := json.NewDecoder(resp.Body) var regRes SERegisterSubscriberResponse err = decoder.Decode(®Res) @@ -159,10 +161,58 @@ func (c *SEClient) Register(ctx context.Context) error { return nil } +func (c *SEClient) RegisterDevice(ctx context.Context) error { + registerDeviceInput := url.Values{ + "client_type": {c.Settings.ClientType}, + "device_hash": {c.DeviceID}, + "device_name": {c.Settings.DeviceName}, + } + req, err := http.NewRequestWithContext( + ctx, + "POST", + c.Settings.Endpoints.RegisterDevice, + strings.NewReader(registerDeviceInput.Encode()), + ) + if err != nil { + return err + } + c.populateRequest(req) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Accept", "application/json") + + resp, err := c.HttpClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("bad http status: %s", resp.Status) + } + + decoder := json.NewDecoder(resp.Body) + var regRes SERegisterDeviceResponse + err = decoder.Decode(®Res) + cleanupBody(resp.Body) + + if err != nil { + return err + } + + if regRes.Status.Code != SE_STATUS_OK { + return fmt.Errorf("API responded with error message: code=%d, msg=\"%s\"", + regRes.Status.Code, regRes.Status.Message) + } + + c.AssignedDeviceID = regRes.Data.DeviceID + c.DevicePassword = regRes.Data.DevicePassword + c.AssignedDeviceIDHash = capitalHexSHA1(regRes.Data.DeviceID) + return nil +} + func (c *SEClient) populateRequest(req *http.Request) { - req.Header.Set("SE-Client-Version", c.Settings.ClientVersion) - req.Header.Set("SE-Operating-System", c.Settings.OperatingSystem) - req.Header.Set("User-Agent", c.Settings.UserAgent) + req.Header["SE-Client-Version"] = []string{c.Settings.ClientVersion} + req.Header["SE-Operating-System"] = []string{c.Settings.OperatingSystem} + req.Header["User-Agent"] = []string{c.Settings.UserAgent} } // Does cleanup of HTTP response in order to make it reusable by keep-alive