-
Notifications
You must be signed in to change notification settings - Fork 36
/
oauth.go
80 lines (69 loc) · 2.03 KB
/
oauth.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
// Copyright 2012-2016 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package gomaasapi
import (
"crypto/rand"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)
// Not a true uuidgen, but at least creates same length random
func generateNonce() (string, error) {
randBytes := make([]byte, 16)
_, err := rand.Read(randBytes)
if err != nil {
return "", err
}
return fmt.Sprintf("%16x", randBytes), nil
}
func generateTimestamp() string {
return strconv.Itoa(int(time.Now().Unix()))
}
type OAuthSigner interface {
OAuthSign(request *http.Request) error
}
type OAuthToken struct {
ConsumerKey string
ConsumerSecret string
TokenKey string
TokenSecret string
}
// Trick to ensure *plainTextOAuthSigner implements the OAuthSigner interface.
var _ OAuthSigner = (*plainTextOAuthSigner)(nil)
type plainTextOAuthSigner struct {
token *OAuthToken
realm string
}
func NewPlainTestOAuthSigner(token *OAuthToken, realm string) (OAuthSigner, error) {
return &plainTextOAuthSigner{token, realm}, nil
}
// OAuthSignPLAINTEXT signs the provided request using the OAuth PLAINTEXT
// method: http://oauth.net/core/1.0/#anchor22.
func (signer plainTextOAuthSigner) OAuthSign(request *http.Request) error {
signature := signer.token.ConsumerSecret + `&` + signer.token.TokenSecret
nonce, err := generateNonce()
if err != nil {
return err
}
authData := map[string]string{
"realm": signer.realm,
"oauth_consumer_key": signer.token.ConsumerKey,
"oauth_token": signer.token.TokenKey,
"oauth_signature_method": "PLAINTEXT",
"oauth_signature": signature,
"oauth_timestamp": generateTimestamp(),
"oauth_nonce": nonce,
"oauth_version": "1.0",
}
// Build OAuth header.
var authHeader []string
for key, value := range authData {
authHeader = append(authHeader, fmt.Sprintf(`%s="%s"`, key, url.QueryEscape(value)))
}
strHeader := "OAuth " + strings.Join(authHeader, ", ")
request.Header.Set("Authorization", strHeader)
return nil
}