storj/pkg/macaroon/apikey_test.go
JT Olio ccb158c99b
pkg/auth: add monkit task to missing places (#2123)
What: add monkit.Task to a bunch of functions that are missing it

Why: this will significantly help our instrumentation, data collection, and tracing about what's going on in the network
2019-06-05 07:47:01 -06:00

143 lines
3.7 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package macaroon
import (
"bytes"
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/zeebo/errs"
)
var ctx = context.Background() // test context
func TestSerializeParseRestrictAndCheck(t *testing.T) {
secret, err := NewSecret()
require.NoError(t, err)
key, err := NewAPIKey(secret)
require.NoError(t, err)
serialized := key.Serialize()
parsedKey, err := ParseAPIKey(serialized)
require.NoError(t, err)
require.True(t, bytes.Equal(key.Head(), parsedKey.Head()))
require.True(t, bytes.Equal(key.Tail(), parsedKey.Tail()))
restricted, err := key.Restrict(Caveat{
AllowedPaths: []*Caveat_Path{{
Bucket: []byte("a-test-bucket"),
EncryptedPathPrefix: []byte("a-test-path"),
}},
})
require.NoError(t, err)
serialized = restricted.Serialize()
parsedKey, err = ParseAPIKey(serialized)
require.NoError(t, err)
require.True(t, bytes.Equal(key.Head(), parsedKey.Head()))
require.False(t, bytes.Equal(key.Tail(), parsedKey.Tail()))
now := time.Now()
action1 := Action{
Op: ActionRead,
Time: now,
Bucket: []byte("a-test-bucket"),
EncryptedPath: []byte("a-test-path"),
}
action2 := Action{
Op: ActionRead,
Time: now,
Bucket: []byte("another-test-bucket"),
EncryptedPath: []byte("another-test-path"),
}
require.NoError(t, key.Check(ctx, secret, action1, nil))
require.NoError(t, key.Check(ctx, secret, action2, nil))
require.NoError(t, parsedKey.Check(ctx, secret, action1, nil))
err = parsedKey.Check(ctx, secret, action2, nil)
require.True(t, ErrUnauthorized.Has(err), err)
}
func TestRevocation(t *testing.T) {
secret, err := NewSecret()
require.NoError(t, err)
key, err := NewAPIKey(secret)
require.NoError(t, err)
restricted, err := key.Restrict(Caveat{
DisallowReads: true,
})
require.NoError(t, err)
now := time.Now()
action := Action{
Op: ActionWrite,
Time: now,
}
require.NoError(t, key.Check(ctx, secret, action, nil))
require.NoError(t, restricted.Check(ctx, secret, action, nil))
require.True(t, ErrRevoked.Has(key.Check(ctx, secret, action, [][]byte{restricted.Head()})))
require.True(t, ErrRevoked.Has(restricted.Check(ctx, secret, action, [][]byte{restricted.Head()})))
}
func TestExpiration(t *testing.T) {
secret, err := NewSecret()
require.NoError(t, err)
key, err := NewAPIKey(secret)
require.NoError(t, err)
now := time.Now()
minuteAgo := now.Add(-time.Minute)
minuteFromNow := now.Add(time.Minute)
twoMinutesAgo := now.Add(-2 * time.Minute)
twoMinutesFromNow := now.Add(2 * time.Minute)
notBeforeMinuteFromNow, err := key.Restrict(Caveat{
NotBefore: &minuteFromNow,
})
require.NoError(t, err)
notAfterMinuteAgo, err := key.Restrict(Caveat{
NotAfter: &minuteAgo,
})
require.NoError(t, err)
for i, test := range []struct {
keyToTest *APIKey
timestampToTest time.Time
errClass *errs.Class
}{
{key, time.Time{}, &Error},
{notBeforeMinuteFromNow, time.Time{}, &Error},
{notAfterMinuteAgo, time.Time{}, &Error},
{key, now, nil},
{notBeforeMinuteFromNow, now, &ErrUnauthorized},
{notAfterMinuteAgo, now, &ErrUnauthorized},
{key, twoMinutesAgo, nil},
{notBeforeMinuteFromNow, twoMinutesAgo, &ErrUnauthorized},
{notAfterMinuteAgo, twoMinutesAgo, nil},
{key, twoMinutesFromNow, nil},
{notBeforeMinuteFromNow, twoMinutesFromNow, nil},
{notAfterMinuteAgo, twoMinutesFromNow, &ErrUnauthorized},
} {
err := test.keyToTest.Check(ctx, secret, Action{
Op: ActionRead,
Time: test.timestampToTest,
}, nil)
if test.errClass == nil {
require.NoError(t, err, fmt.Sprintf("test #%d", i+1))
} else {
require.False(t, !test.errClass.Has(err), fmt.Sprintf("test #%d", i+1))
}
}
}