forked from yandex-cloud/go-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
credentials_test.go
124 lines (108 loc) · 3.83 KB
/
credentials_test.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (c) 2018 Yandex LLC. All rights reserved.
// Author: Vladimir Skipor <[email protected]>
package ycsdk
import (
"context"
"crypto"
"crypto/rsa"
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
jwt "github.com/golang-jwt/jwt/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/yandex-cloud/go-sdk/iamkey"
)
func TestOAuthToken(t *testing.T) {
const token = "AAAA00000000000000000000000000000000000"
creds := OAuthToken(token)
iamTokenReq, err := creds.(ExchangeableCredentials).IAMTokenRequest()
require.NoError(t, err)
assert.Equal(t, token, iamTokenReq.GetYandexPassportOauthToken())
}
func TestIAMToken(t *testing.T) {
const iamToken = "this-is-iam-token"
creds := NewIAMTokenCredentials(iamToken)
iamTokenResp, err := creds.IAMToken(context.Background())
require.NoError(t, err)
assert.Equal(t, iamToken, iamTokenResp.GetIamToken())
}
func TestServiceAccountKey(t *testing.T) {
key := testKey(t)
creds, err := ServiceAccountKey(key)
require.NoError(t, err)
iamTokenReq, err := creds.(ExchangeableCredentials).IAMTokenRequest()
require.NoError(t, err)
require.NotEmpty(t, iamTokenReq.GetJwt())
parser := jwt.Parser{}
jot, parts, err := parser.ParseUnverified(iamTokenReq.GetJwt(), &jwt.RegisteredClaims{})
require.NoError(t, err)
publicKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(key.PublicKey))
require.NoError(t, err)
// Force salt length: https://github.com/dgrijalva/jwt-go/issues/285
method := &jwt.SigningMethodRSAPSS{
SigningMethodRSA: jwt.SigningMethodPS256.SigningMethodRSA,
Options: &rsa.PSSOptions{
Hash: crypto.SHA256,
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
}
err = method.Verify(strings.Join(parts[:2], "."), parts[2], publicKey)
require.NoError(t, err, "token verification failed")
claims := jot.Claims.(*jwt.RegisteredClaims)
assert.Equal(t, key.Id, jot.Header["kid"])
assert.Equal(t, key.GetServiceAccountId(), claims.Issuer)
assert.Contains(t, claims.Audience, "https://iam.api.cloud.yandex.net/iam/v1/tokens")
issuedAt := claims.IssuedAt.Time
sinceIssued := time.Since(issuedAt)
assert.True(t, sinceIssued > 0)
assert.True(t, sinceIssued < time.Minute)
assert.Equal(t, time.Hour, claims.ExpiresAt.Sub(issuedAt))
}
func TestInstanceServiceAccount(t *testing.T) {
t.Run("success", func(t *testing.T) {
const token = "AAAAAAAAAAAAAAAAAAAAAAAA"
const expiresIn = 43167
server := httptest.NewServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
_, err := io.WriteString(rw, fmt.Sprintf(`{
"access_token": %q,
"expires_in": %v,
"token_type":"Bearer"
}`, token, expiresIn))
assert.NoError(t, err)
}))
defer server.Close()
creds := newInstanceServiceAccountCredentials(server.Listener.Addr().String())
iamToken, err := creds.IAMToken(context.Background())
require.NoError(t, err)
assert.Equal(t, token, iamToken.IamToken)
expectedExpiresAt := time.Now().Add(expiresIn * time.Second)
actualExpiresAt, err := iamToken.ExpiresAt.AsTime(), iamToken.ExpiresAt.CheckValid()
require.NoError(t, err)
assert.True(t, expectedExpiresAt.After(actualExpiresAt))
assert.True(t, expectedExpiresAt.Add(-10*time.Second).Before(actualExpiresAt))
})
t.Run("internal error", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(
func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusInternalServerError)
_, err := io.WriteString(rw, "ERRRORRRRR")
assert.NoError(t, err)
}))
defer server.Close()
creds := newInstanceServiceAccountCredentials(server.Listener.Addr().String())
_, err := creds.IAMToken(context.Background())
require.Error(t, err)
t.Log(err)
})
}
func testKey(t *testing.T) *iamkey.Key {
key, err := iamkey.ReadFromJSONFile("test_data/service_account_key.json")
require.NoError(t, err)
return key
}