-
Notifications
You must be signed in to change notification settings - Fork 13
/
auth.go
104 lines (89 loc) · 2.22 KB
/
auth.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
package mira
import (
"bytes"
b64 "encoding/base64"
"encoding/json"
"net/http"
"net/url"
"strings"
"time"
)
type Credentials struct {
ClientID string
ClientSecret string
Username string
Password string
UserAgent string
}
// Authenticate returns *Reddit object that has been authed
func Authenticate(c *Credentials) (*Reddit, error) {
// URL to get access_token
authURL := RedditBase + "api/v1/access_token"
// Define the data to send in the request
form := url.Values{}
form.Add("grant_type", "password")
form.Add("username", c.Username)
form.Add("password", c.Password)
// Encode the Authorization Header
raw := c.ClientID + ":" + c.ClientSecret
encoded := b64.StdEncoding.EncodeToString([]byte(raw))
// Create a request to allow customised headers
r, err := http.NewRequest("POST", authURL, strings.NewReader(form.Encode()))
if err != nil {
return nil, err
}
// Customise request headers
r.Header.Set("User-Agent", c.UserAgent)
r.Header.Set("Authorization", "Basic "+encoded)
// Create client
client := &http.Client{}
// Run the request
response, err := client.Do(r)
if err != nil {
return nil, err
}
defer response.Body.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(response.Body)
data := buf.Bytes()
if err := findRedditError(data); err != nil {
return nil, err
}
auth := Reddit{}
auth.Chain = make(chan *ChainVals, 32)
json.Unmarshal(data, &auth)
auth.Creds = *c
return &auth, nil
}
// This goroutine reauthenticates the user
// every 45 minutes. It should be run with the go
// statement
func (c *Reddit) autoRefresh() {
for {
time.Sleep(45 * time.Minute)
c.updateCredentials()
}
}
// Reauthenticate and updates the object itself
func (c *Reddit) updateCredentials() {
temp, _ := Authenticate(&c.Creds)
// Just updated the token
c.Token = temp.Token
}
// SetDefault sets all default values
func (c *Reddit) SetDefault() {
c.Stream = Streaming{
CommentListInterval: 8,
PostListInterval: 10,
ReportsInterval: 15,
ModQueueInterval: 15,
PostListSlice: 25,
}
c.Values = RedditVals{
GetSubmissionFromCommentTries: 32,
}
}
// SetClient sets mira's *http.Client to make requests
func (c *Reddit) SetClient(client *http.Client) {
c.Client = client
}