~mattyw/gomaasapi/fix_for_httptest_build_leak

2.1.5 by Raphael Badin
Implement server.ListNodes.
1
// Copyright 2013 Canonical Ltd.  This software is licensed under the
2
// GNU Lesser General Public License version 3 (see the file COPYING).
3
4
package gomaasapi
5
6
import (
13.2.1 by Raphael Badin
Another round of fixes from the review.
7
	"crypto/rand"
2.1.5 by Raphael Badin
Implement server.ListNodes.
8
	"fmt"
13.2.1 by Raphael Badin
Another round of fixes from the review.
9
	"math/big"
2.1.5 by Raphael Badin
Implement server.ListNodes.
10
	"net/http"
11
	"net/url"
12
	"strconv"
13
	"strings"
14
	"time"
15
)
16
13.2.1 by Raphael Badin
Another round of fixes from the review.
17
var nonceMax = big.NewInt(100000000)
2.1.5 by Raphael Badin
Implement server.ListNodes.
18
13.2.1 by Raphael Badin
Another round of fixes from the review.
19
func generateNonce() (string, error) {
20
	randInt, err := rand.Int(rand.Reader, nonceMax)
21
	if err != nil {
22
		return "", err
23
	}
24
	return strconv.Itoa(int(randInt.Int64())), nil
2.1.5 by Raphael Badin
Implement server.ListNodes.
25
}
26
27
func generateTimestamp() string {
28
	return strconv.Itoa(int(time.Now().Unix()))
29
}
30
31
type OAuthSigner interface {
32
	OAuthSign(request *http.Request) error
33
}
34
35
type OAuthToken struct {
36
	ConsumerKey    string
37
	ConsumerSecret string
38
	TokenKey       string
39
	TokenSecret    string
40
}
41
13.2.1 by Raphael Badin
Another round of fixes from the review.
42
// Trick to ensure *plainTextOAuthSigner implements the OAuthSigner interface.
43
var _ OAuthSigner = (*plainTextOAuthSigner)(nil)
2.1.7 by Raphael Badin
Add checks to make sure the right interfaces are implemented.
44
13.2.1 by Raphael Badin
Another round of fixes from the review.
45
type plainTextOAuthSigner struct {
2.1.5 by Raphael Badin
Implement server.ListNodes.
46
	token *OAuthToken
47
	realm string
48
}
49
13.2.1 by Raphael Badin
Another round of fixes from the review.
50
func NewPlainTestOAuthSigner(token *OAuthToken, realm string) (OAuthSigner, error) {
51
	return &plainTextOAuthSigner{token, realm}, nil
2.1.5 by Raphael Badin
Implement server.ListNodes.
52
}
53
54
// OAuthSignPLAINTEXT signs the provided request using the OAuth PLAINTEXT
55
// method: http://oauth.net/core/1.0/#anchor22.
13.2.1 by Raphael Badin
Another round of fixes from the review.
56
func (signer plainTextOAuthSigner) OAuthSign(request *http.Request) error {
2.1.5 by Raphael Badin
Implement server.ListNodes.
57
58
	signature := signer.token.ConsumerSecret + `&` + signer.token.TokenSecret
13.2.1 by Raphael Badin
Another round of fixes from the review.
59
	nonce, err := generateNonce()
60
	if err != nil {
61
		return err
62
	}
2.1.5 by Raphael Badin
Implement server.ListNodes.
63
	authData := map[string]string{
64
		"realm":                  signer.realm,
65
		"oauth_consumer_key":     signer.token.ConsumerKey,
66
		"oauth_token":            signer.token.TokenKey,
67
		"oauth_signature_method": "PLAINTEXT",
68
		"oauth_signature":        signature,
69
		"oauth_timestamp":        generateTimestamp(),
13.2.1 by Raphael Badin
Another round of fixes from the review.
70
		"oauth_nonce":            nonce,
2.1.5 by Raphael Badin
Implement server.ListNodes.
71
		"oauth_version":          "1.0",
72
	}
73
	// Build OAuth header.
13.2.1 by Raphael Badin
Another round of fixes from the review.
74
	var authHeader []string
2.1.5 by Raphael Badin
Implement server.ListNodes.
75
	for key, value := range authData {
76
		authHeader = append(authHeader, fmt.Sprintf(`%s="%s"`, key, url.QueryEscape(value)))
77
	}
78
	strHeader := "OAuth " + strings.Join(authHeader, ", ")
79
	request.Header.Add("Authorization", strHeader)
80
	return nil
81
}