-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathifog.go
110 lines (101 loc) · 2.99 KB
/
ifog.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package ifog
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"strings"
"github.com/petitout/ifog/fmip"
"github.com/petitout/ifog/login"
"github.com/petitout/ifog/models"
)
// Session ICloud session structure
type Session struct {
client *http.Client
cookies []*http.Cookie
User models.User
Webservices map[string]models.WebService
Devices []models.Device
LoginURL string
}
// NewSession creates a new Icloud session
func NewSession() *Session {
s := new(Session)
s.LoginURL = login.URL
return s
}
// Login allows to login into ICloud
func (s *Session) Login(requestBody login.RequestBody) error {
s.client = &http.Client{}
responseBody := login.ResponseBody{}
err := s.sendRequest(requestBody, s.LoginURL, &responseBody, true)
if err != nil {
return err
}
s.User = responseBody.User
s.Webservices = responseBody.Webservices
return nil
}
// PopulateDevices retrieves device information associated with the currently logged in ICloud user
func (s *Session) PopulateDevices() error {
requestBody := fmip.RefreshClientRequestBody{RequestCommonBody: fmip.RequestCommonBody{Dsid: s.User.Dsid, ClientId: "whatever"}, ClientContext: fmip.DefaultClientContext}
responseBody := fmip.ResponseBody{}
err := s.sendRequest(requestBody, s.Webservices[fmip.URLKey].Url+fmip.RefreshClientURL, &responseBody, false)
if err != nil {
return err
}
s.Devices = responseBody.Devices
return nil
}
// SendMessage sends a message to the given device
func (s *Session) SendMessage(msg string, deviceID string, subject string) error {
requestBody := fmip.SendMessageRequestBody{RequestCommonBody: fmip.RequestCommonBody{Dsid: s.User.Dsid, ClientId: "whatever"}, Device: deviceID, Subject: subject, Sound: false, UserText: true, Text: msg}
err := s.sendRequest(requestBody, s.Webservices[fmip.URLKey].Url+fmip.SendMessageURL, nil, false)
if err != nil {
return err
}
return nil
}
func (s *Session) sendRequest(body interface{}, url string, responseBody interface{}, saveCookies bool) error {
if s.client == nil {
return errors.New("You have to login first")
}
data, e := json.Marshal(body)
if e != nil {
return e
}
req, e := http.NewRequest(fmip.Method, url, bytes.NewReader(data))
if e != nil {
return e
}
for _, cookie := range s.cookies {
if strings.Index(cookie.String(), "X-APPLE-WEBAUTH-LOGIN") != -1 || strings.Index(cookie.String(), "X-APPLE-WEBAUTH-USER") != -1 {
req.Header.Add("Cookie", cookie.Name+"=\""+cookie.Value+"\"")
}
}
setCommonHeaders(req)
var resp *http.Response
if resp, e = s.client.Do(req); e != nil {
return e
}
defer resp.Body.Close()
rawBody, e := ioutil.ReadAll(resp.Body)
if e != nil {
return e
}
if saveCookies {
s.cookies = resp.Cookies()
}
if responseBody != nil {
err := json.Unmarshal(rawBody, responseBody)
if err != nil {
return err
}
}
return nil
}
func setCommonHeaders(request *http.Request) {
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Origin", "https://www.icloud.com")
}