2015-03-18 20:19:19 +00:00
package vault
import (
2018-01-08 18:31:38 +00:00
"context"
2016-09-26 22:17:50 +00:00
"encoding/json"
2016-03-01 17:33:35 +00:00
"fmt"
2017-09-05 15:09:00 +00:00
"path"
2015-03-18 20:19:19 +00:00
"reflect"
2016-12-16 21:46:29 +00:00
"sort"
2016-03-01 17:33:35 +00:00
"strings"
2016-12-16 18:11:55 +00:00
"sync"
2017-11-01 19:52:59 +00:00
"sync/atomic"
2015-03-18 20:19:19 +00:00
"testing"
2015-03-24 22:10:46 +00:00
"time"
2018-10-15 16:56:24 +00:00
"github.com/go-test/deep"
"github.com/hashicorp/errwrap"
2019-07-01 09:39:54 +00:00
"github.com/hashicorp/go-hclog"
2021-07-16 00:17:31 +00:00
"github.com/hashicorp/go-secure-stdlib/parseutil"
2019-07-01 09:39:54 +00:00
"github.com/hashicorp/go-sockaddr"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/identity"
2020-10-13 23:38:21 +00:00
"github.com/hashicorp/vault/helper/metricsutil"
2018-09-18 03:03:00 +00:00
"github.com/hashicorp/vault/helper/namespace"
2019-04-13 07:44:06 +00:00
"github.com/hashicorp/vault/sdk/helper/locksutil"
2019-06-14 14:17:04 +00:00
"github.com/hashicorp/vault/sdk/helper/tokenutil"
2019-04-12 21:54:35 +00:00
"github.com/hashicorp/vault/sdk/logical"
2019-07-01 09:39:54 +00:00
"github.com/mitchellh/mapstructure"
2015-03-18 20:19:19 +00:00
)
2019-03-01 23:55:58 +00:00
func TestTokenStore_CreateOrphanResponse ( t * testing . T ) {
c , _ , root := TestCoreUnsealed ( t )
resp , err := c . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
Operation : logical . UpdateOperation ,
Path : "auth/token/create-orphan" ,
ClientToken : root ,
Data : map [ string ] interface { } {
"policies" : "default" ,
} ,
} )
if err != nil && ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v, resp: %#v" , err , resp )
}
if ! resp . Auth . Orphan {
t . Fatalf ( "failed to set orphan as true in the response" )
}
}
2019-01-09 18:53:41 +00:00
func TestTokenStore_CubbyholeDeletion ( t * testing . T ) {
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
for i := 0 ; i < 10 ; i ++ {
// Create a token
tokenReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "create" ,
ClientToken : root ,
2019-11-05 21:11:13 +00:00
Data : map [ string ] interface { } {
"ttl" : "600s" ,
} ,
2019-01-09 18:53:41 +00:00
}
// Supplying token ID forces SHA1 hashing to be used
if i % 2 == 0 {
tokenReq . Data = map [ string ] interface { } {
2019-11-05 21:11:13 +00:00
"id" : "testroot" ,
"ttl" : "600s" ,
2019-01-09 18:53:41 +00:00
}
}
resp := testMakeTokenViaRequest ( t , ts , tokenReq )
token := resp . Auth . ClientToken
// Write data in the token's cubbyhole
resp , err := c . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : token ,
Operation : logical . UpdateOperation ,
Path : "cubbyhole/sample/data" ,
Data : map [ string ] interface { } {
"foo" : "bar" ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Revoke the token
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : token ,
Path : "revoke-self" ,
Operation : logical . UpdateOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
}
// List the cubbyhole keys
cubbyholeKeys , err := ts . cubbyholeBackend . storageView . List ( namespace . RootContext ( nil ) , "" )
if err != nil {
t . Fatal ( err )
}
// There should be no entries
if len ( cubbyholeKeys ) != 0 {
t . Fatalf ( "bad: len(cubbyholeKeys); expected: 0, actual: %d" , len ( cubbyholeKeys ) )
}
}
func TestTokenStore_CubbyholeTidy ( t * testing . T ) {
c , _ , root := TestCoreUnsealed ( t )
2021-04-20 18:49:25 +00:00
testTokenStore_CubbyholeTidy ( t , c , root , namespace . RootContext ( nil ) )
}
func testTokenStore_CubbyholeTidy ( t * testing . T , c * Core , root string , nsCtx context . Context ) {
2019-01-09 18:53:41 +00:00
ts := c . tokenStore
2021-04-20 18:49:25 +00:00
backend := c . router . MatchingBackend ( nsCtx , cubbyholeMountPath )
view := c . router . MatchingStorageByAPIPath ( nsCtx , cubbyholeMountPath )
2019-01-09 18:53:41 +00:00
for i := 1 ; i <= 20 ; i ++ {
// Create 20 tokens
tokenReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "create" ,
ClientToken : root ,
2019-11-05 21:11:13 +00:00
Data : map [ string ] interface { } {
"ttl" : "600s" ,
} ,
2019-01-09 18:53:41 +00:00
}
2021-04-20 18:49:25 +00:00
resp := testMakeTokenViaRequestContext ( t , nsCtx , ts , tokenReq )
2019-01-09 18:53:41 +00:00
token := resp . Auth . ClientToken
// Supplying token ID forces SHA1 hashing to be used
if i % 3 == 0 {
tokenReq . Data = map [ string ] interface { } {
2019-11-05 21:11:13 +00:00
"id" : "testroot" ,
"ttl" : "600s" ,
2019-01-09 18:53:41 +00:00
}
}
// Create 4 junk cubbyhole entries
if i % 5 == 0 {
invalidToken , err := uuid . GenerateUUID ( )
if err != nil {
t . Fatal ( err )
}
2021-04-20 18:49:25 +00:00
resp , err := backend . HandleRequest ( nsCtx , & logical . Request {
2019-01-09 18:53:41 +00:00
ClientToken : invalidToken ,
Operation : logical . UpdateOperation ,
Path : "cubbyhole/sample/data" ,
Data : map [ string ] interface { } {
"foo" : "bar" ,
} ,
2021-04-20 18:49:25 +00:00
Storage : view ,
2019-01-09 18:53:41 +00:00
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
}
// Write into cubbyholes of 10 tokens
if i % 2 == 0 {
continue
}
2021-04-20 18:49:25 +00:00
resp , err := c . HandleRequest ( nsCtx , & logical . Request {
2019-01-09 18:53:41 +00:00
ClientToken : token ,
Operation : logical . UpdateOperation ,
Path : "cubbyhole/sample/data" ,
Data : map [ string ] interface { } {
"foo" : "bar" ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
}
2021-04-20 18:49:25 +00:00
// List all the cubbyhole storage keys
cubbyholeKeys , err := view . List ( nsCtx , "" )
if err != nil {
t . Fatal ( err )
}
if len ( cubbyholeKeys ) != 14 {
t . Fatalf ( "bad: len(cubbyholeKeys); expected: 14, actual: %d" , len ( cubbyholeKeys ) )
}
2019-01-09 18:53:41 +00:00
// Tidy cubbyhole storage
2021-04-20 18:49:25 +00:00
resp , err := ts . HandleRequest ( nsCtx , & logical . Request {
2019-01-09 18:53:41 +00:00
Path : "tidy" ,
Operation : logical . UpdateOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Wait for tidy operation to complete
time . Sleep ( 2 * time . Second )
// List all the cubbyhole storage keys
2021-04-20 18:49:25 +00:00
cubbyholeKeys , err = view . List ( nsCtx , "" )
2019-01-09 18:53:41 +00:00
if err != nil {
t . Fatal ( err )
}
// The junk entries must have been cleaned up
if len ( cubbyholeKeys ) != 10 {
t . Fatalf ( "bad: len(cubbyholeKeys); expected: 10, actual: %d" , len ( cubbyholeKeys ) )
}
}
2018-10-17 20:23:04 +00:00
func TestTokenStore_Salting ( t * testing . T ) {
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
saltedID , err := ts . SaltID ( namespace . RootContext ( nil ) , "foo" )
if err != nil {
t . Fatal ( err )
}
if strings . HasPrefix ( saltedID , "h" ) {
t . Fatalf ( "expected sha1 hash; got sha2-256 hmac" )
}
saltedID , err = ts . SaltID ( namespace . RootContext ( nil ) , "s.foo" )
if err != nil {
t . Fatal ( err )
}
if ! strings . HasPrefix ( saltedID , "h" ) {
t . Fatalf ( "expected sha2-256 hmac; got sha1 hash" )
}
2020-01-11 01:39:52 +00:00
nsCtx := namespace . ContextWithNamespace ( context . Background ( ) , & namespace . Namespace { ID : "testid" , Path : "ns1" } )
2018-10-17 20:23:04 +00:00
saltedID , err = ts . SaltID ( nsCtx , "foo" )
if err != nil {
t . Fatal ( err )
}
if ! strings . HasPrefix ( saltedID , "h" ) {
t . Fatalf ( "expected sha2-256 hmac; got sha1 hash" )
}
saltedID , err = ts . SaltID ( nsCtx , "s.foo" )
if err != nil {
t . Fatal ( err )
}
if ! strings . HasPrefix ( saltedID , "h" ) {
t . Fatalf ( "expected sha2-256 hmac; got sha1 hash" )
}
}
2016-09-26 22:17:50 +00:00
type TokenEntryOld struct {
ID string
Accessor string
Parent string
Policies [ ] string
Path string
Meta map [ string ] string
DisplayName string
NumUses int
CreationTime int64
TTL time . Duration
ExplicitMaxTTL time . Duration
Role string
Period time . Duration
}
func TestTokenStore_TokenEntryUpgrade ( t * testing . T ) {
var err error
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-09-26 22:17:50 +00:00
// Use a struct that does not have struct tags to store the items and
// check if the lookup code handles them properly while reading back
entry := & TokenEntryOld {
DisplayName : "test-display-name" ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
CreationTime : time . Now ( ) . Unix ( ) ,
ExplicitMaxTTL : 100 ,
NumUses : 10 ,
}
entry . ID , err = uuid . GenerateUUID ( )
if err != nil {
t . Fatal ( err )
}
enc , err := json . Marshal ( entry )
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
saltedID , err := ts . SaltID ( namespace . RootContext ( nil ) , entry . ID )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2016-09-26 22:17:50 +00:00
le := & logical . StorageEntry {
2018-09-18 03:03:00 +00:00
Key : saltedID ,
2016-09-26 22:17:50 +00:00
Value : enc ,
}
2018-11-05 16:11:32 +00:00
if err := ts . idView ( namespace . RootNamespace ) . Put ( namespace . RootContext ( nil ) , le ) ; err != nil {
2016-09-26 22:17:50 +00:00
t . Fatal ( err )
}
2018-06-03 22:14:51 +00:00
// Register with exp manager so lookup works
auth := & logical . Auth {
DisplayName : entry . DisplayName ,
CreationPath : entry . Path ,
Policies : entry . Policies ,
ExplicitMaxTTL : entry . ExplicitMaxTTL ,
NumUses : entry . NumUses ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
ClientToken : entry . ID ,
}
2018-09-18 03:03:00 +00:00
// Same as entry from TokenEntryOld, but used for RegisterAuth
registryEntry := & logical . TokenEntry {
DisplayName : entry . DisplayName ,
Path : entry . Path ,
Policies : entry . Policies ,
CreationTime : entry . CreationTime ,
ExplicitMaxTTL : entry . ExplicitMaxTTL ,
NumUses : entry . NumUses ,
NamespaceID : namespace . RootNamespaceID ,
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , registryEntry , auth ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , entry . ID )
2016-09-26 22:17:50 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out . DisplayName != "test-display-name" {
t . Fatalf ( "bad: display_name: expected: test-display-name, actual: %s" , out . DisplayName )
}
if out . CreationTime == 0 {
t . Fatal ( "bad: expected a non-zero creation time" )
}
if out . ExplicitMaxTTL != 100 {
t . Fatalf ( "bad: explicit_max_ttl: expected: 100, actual: %d" , out . ExplicitMaxTTL )
}
if out . NumUses != 10 {
t . Fatalf ( "bad: num_uses: expected: 10, actual: %d" , out . NumUses )
}
// Test the default case to ensure there are no regressions
2018-06-08 21:24:27 +00:00
ent := & logical . TokenEntry {
2016-09-26 22:17:50 +00:00
DisplayName : "test-display-name" ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
CreationTime : time . Now ( ) . Unix ( ) ,
ExplicitMaxTTL : 100 ,
NumUses : 10 ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-09-26 22:17:50 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2016-09-26 22:17:50 +00:00
t . Fatalf ( "err: %s" , err )
}
2018-06-03 22:14:51 +00:00
auth = & logical . Auth {
DisplayName : ent . DisplayName ,
CreationPath : ent . Path ,
Policies : ent . Policies ,
ExplicitMaxTTL : ent . ExplicitMaxTTL ,
NumUses : ent . NumUses ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
ClientToken : ent . ID ,
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , ent , auth ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2016-09-26 22:17:50 +00:00
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2016-09-26 22:17:50 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out . DisplayName != "test-display-name" {
t . Fatalf ( "bad: display_name: expected: test-display-name, actual: %s" , out . DisplayName )
}
if out . CreationTime == 0 {
t . Fatal ( "bad: expected a non-zero creation time" )
}
if out . ExplicitMaxTTL != 100 {
t . Fatalf ( "bad: explicit_max_ttl: expected: 100, actual: %d" , out . ExplicitMaxTTL )
}
if out . NumUses != 10 {
t . Fatalf ( "bad: num_uses: expected: 10, actual: %d" , out . NumUses )
}
// Fill in the deprecated fields and read out from proper fields
2018-06-08 21:24:27 +00:00
ent = & logical . TokenEntry {
2016-09-26 22:17:50 +00:00
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
DisplayNameDeprecated : "test-display-name" ,
CreationTimeDeprecated : time . Now ( ) . Unix ( ) ,
ExplicitMaxTTLDeprecated : 100 ,
NumUsesDeprecated : 10 ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-09-26 22:17:50 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2016-09-26 22:17:50 +00:00
t . Fatalf ( "err: %s" , err )
}
2018-06-03 22:14:51 +00:00
auth = & logical . Auth {
DisplayName : ent . DisplayName ,
CreationPath : ent . Path ,
Policies : ent . Policies ,
ExplicitMaxTTL : ent . ExplicitMaxTTL ,
NumUses : ent . NumUses ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
ClientToken : ent . ID ,
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , ent , auth ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2016-09-26 22:17:50 +00:00
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2016-09-26 22:17:50 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out . DisplayName != "test-display-name" {
t . Fatalf ( "bad: display_name: expected: test-display-name, actual: %s" , out . DisplayName )
}
if out . CreationTime == 0 {
t . Fatal ( "bad: expected a non-zero creation time" )
}
if out . ExplicitMaxTTL != 100 {
t . Fatalf ( "bad: explicit_max_ttl: expected: 100, actual: %d" , out . ExplicitMaxTTL )
}
if out . NumUses != 10 {
t . Fatalf ( "bad: num_uses: expected: 10, actual: %d" , out . NumUses )
}
// Check if NumUses picks up a lower value
2018-06-08 21:24:27 +00:00
ent = & logical . TokenEntry {
2016-09-26 22:17:50 +00:00
Path : "test" ,
NumUses : 5 ,
NumUsesDeprecated : 10 ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-09-26 22:17:50 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2016-09-26 22:17:50 +00:00
t . Fatalf ( "err: %s" , err )
}
2018-06-03 22:14:51 +00:00
auth = & logical . Auth {
DisplayName : ent . DisplayName ,
CreationPath : ent . Path ,
Policies : ent . Policies ,
ExplicitMaxTTL : ent . ExplicitMaxTTL ,
NumUses : ent . NumUses ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
ClientToken : ent . ID ,
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , ent , auth ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2016-09-26 22:17:50 +00:00
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2016-09-26 22:17:50 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out . NumUses != 5 {
t . Fatalf ( "bad: num_uses: expected: 5, actual: %d" , out . NumUses )
}
// Switch the values from deprecated and proper field and check if the
// lower value is still getting picked up
2018-06-08 21:24:27 +00:00
ent = & logical . TokenEntry {
2016-09-26 22:17:50 +00:00
Path : "test" ,
NumUses : 10 ,
NumUsesDeprecated : 5 ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-09-26 22:17:50 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2016-09-26 22:17:50 +00:00
t . Fatalf ( "err: %s" , err )
}
2018-06-03 22:14:51 +00:00
auth = & logical . Auth {
DisplayName : ent . DisplayName ,
CreationPath : ent . Path ,
Policies : ent . Policies ,
ExplicitMaxTTL : ent . ExplicitMaxTTL ,
NumUses : ent . NumUses ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
ClientToken : ent . ID ,
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , ent , auth ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2016-09-26 22:17:50 +00:00
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2016-09-26 22:17:50 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out . NumUses != 5 {
t . Fatalf ( "bad: num_uses: expected: 5, actual: %d" , out . NumUses )
}
}
2015-09-04 20:58:12 +00:00
func getBackendConfig ( c * Core ) * logical . BackendConfig {
return & logical . BackendConfig {
Logger : c . logger ,
System : logical . StaticSystemView {
DefaultLeaseTTLVal : time . Hour * 24 ,
2016-09-28 22:32:49 +00:00
MaxLeaseTTLVal : time . Hour * 24 * 32 ,
2015-09-04 20:58:12 +00:00
} ,
}
}
2018-10-15 16:56:24 +00:00
func testMakeServiceTokenViaBackend ( t testing . TB , ts * TokenStore , root , client , ttl string , policy [ ] string ) {
2019-11-05 21:11:13 +00:00
t . Helper ( )
2018-10-15 16:56:24 +00:00
testMakeTokenViaBackend ( t , ts , root , client , ttl , policy , false )
}
func testMakeTokenViaBackend ( t testing . TB , ts * TokenStore , root , client , ttl string , policy [ ] string , batch bool ) {
2019-11-05 21:11:13 +00:00
t . Helper ( )
2016-02-29 19:13:09 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
if batch {
req . Data [ "type" ] = "batch"
} else {
req . Data [ "id" ] = client
}
2016-02-29 19:13:09 +00:00
req . Data [ "policies" ] = policy
req . Data [ "ttl" ] = ttl
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken != client {
t . Fatalf ( "bad: %#v" , resp )
}
}
2016-02-29 19:13:09 +00:00
2018-06-03 22:14:51 +00:00
func testMakeTokenViaRequest ( t testing . TB , ts * TokenStore , req * logical . Request ) * logical . Response {
2019-11-05 21:11:13 +00:00
t . Helper ( )
2021-04-20 18:49:25 +00:00
return testMakeTokenViaRequestContext ( t , namespace . RootContext ( nil ) , ts , req )
}
func testMakeTokenViaRequestContext ( t testing . TB , ctx context . Context , ts * TokenStore , req * logical . Request ) * logical . Response {
t . Helper ( )
resp , err := ts . HandleRequest ( ctx , req )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
2016-02-29 19:13:09 +00:00
}
2018-06-03 22:14:51 +00:00
if resp == nil {
t . Fatalf ( "got nil token from create call" )
}
2018-10-15 16:56:24 +00:00
// Let the caller handle the error
if resp . IsError ( ) {
return resp
}
2018-06-03 22:14:51 +00:00
2021-04-20 18:49:25 +00:00
ns , err := namespace . FromContext ( ctx )
if err != nil {
t . Fatal ( err )
}
2018-09-18 03:03:00 +00:00
te := & logical . TokenEntry {
Path : resp . Auth . CreationPath ,
2021-04-20 18:49:25 +00:00
NamespaceID : ns . ID ,
2018-09-18 03:03:00 +00:00
}
2018-10-15 16:56:24 +00:00
if resp . Auth . TokenType != logical . TokenTypeBatch {
2021-04-20 18:49:25 +00:00
if err := ts . expiration . RegisterAuth ( ctx , te , resp . Auth ) ; err != nil {
2018-10-15 16:56:24 +00:00
t . Fatal ( err )
}
2016-02-29 19:13:09 +00:00
}
2018-06-03 22:14:51 +00:00
2021-04-20 18:49:25 +00:00
te , err = ts . Lookup ( ctx , resp . Auth . ClientToken )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
2018-06-03 22:14:51 +00:00
return resp
2016-02-29 19:13:09 +00:00
}
2018-06-08 21:24:27 +00:00
func testMakeTokenDirectly ( t testing . TB , ts * TokenStore , te * logical . TokenEntry ) {
2018-09-18 03:03:00 +00:00
if te . NamespaceID == "" {
te . NamespaceID = namespace . RootNamespaceID
}
2018-10-15 16:56:24 +00:00
if te . CreationTime == 0 {
te . CreationTime = time . Now ( ) . Unix ( )
}
2018-09-18 03:03:00 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , te ) ; err != nil {
2018-06-03 22:14:51 +00:00
t . Fatal ( err )
}
2018-10-15 16:56:24 +00:00
if te . Type == logical . TokenTypeDefault {
te . Type = logical . TokenTypeService
}
2018-06-03 22:14:51 +00:00
auth := & logical . Auth {
NumUses : te . NumUses ,
DisplayName : te . DisplayName ,
Policies : te . Policies ,
Metadata : te . Meta ,
LeaseOptions : logical . LeaseOptions {
TTL : te . TTL ,
Renewable : te . TTL > 0 ,
} ,
ClientToken : te . ID ,
Accessor : te . Accessor ,
EntityID : te . EntityID ,
Period : te . Period ,
ExplicitMaxTTL : te . ExplicitMaxTTL ,
CreationPath : te . Path ,
2018-10-15 16:56:24 +00:00
TokenType : te . Type ,
2018-06-03 22:14:51 +00:00
}
2018-11-05 16:11:32 +00:00
err := ts . expiration . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2018-10-15 16:56:24 +00:00
switch err {
case nil :
if te . Type == logical . TokenTypeBatch {
t . Fatal ( "expected error from trying to register auth with batch token" )
}
default :
if te . Type != logical . TokenTypeBatch {
t . Fatal ( err )
}
2018-06-03 22:14:51 +00:00
}
}
2018-10-15 16:56:24 +00:00
func testMakeServiceTokenViaCore ( t testing . TB , c * Core , root , client , ttl string , policy [ ] string ) {
2020-10-26 20:25:56 +00:00
testMakeTokenViaCore ( t , c , root , client , ttl , "" , policy , false , nil )
2018-10-15 16:56:24 +00:00
}
2020-10-26 20:25:56 +00:00
func testMakeTokenViaCore ( t testing . TB , c * Core , root , client , ttl , period string , policy [ ] string , batch bool , outAuth * logical . Auth ) {
2016-02-29 19:13:09 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/create" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
if batch {
req . Data [ "type" ] = "batch"
} else {
req . Data [ "id" ] = client
}
2016-02-29 19:13:09 +00:00
req . Data [ "policies" ] = policy
req . Data [ "ttl" ] = ttl
2020-10-26 20:25:56 +00:00
if len ( period ) != 0 {
req . Data [ "period" ] = period
}
2018-11-05 16:11:32 +00:00
resp , err := c . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2017-10-23 18:59:37 +00:00
}
2018-10-15 16:56:24 +00:00
if ! batch {
if resp . Auth . ClientToken != client {
t . Fatalf ( "bad: %#v" , * resp )
}
}
if outAuth != nil && resp != nil && resp . Auth != nil {
* outAuth = * resp . Auth
2016-02-29 19:13:09 +00:00
}
}
2016-03-09 17:50:26 +00:00
func TestTokenStore_AccessorIndex ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-03-09 17:50:26 +00:00
2018-06-08 21:24:27 +00:00
ent := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2016-03-09 17:50:26 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent )
2016-03-09 17:50:26 +00:00
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
// Ensure that accessor is created
if out == nil || out . Accessor == "" {
t . Fatalf ( "bad: %#v" , out )
}
2018-11-05 16:11:32 +00:00
aEntry , err := ts . lookupByAccessor ( namespace . RootContext ( nil ) , out . Accessor , false , false )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
// Verify that the value returned from the index matches the token ID
2016-07-29 22:20:38 +00:00
if aEntry . TokenID != ent . ID {
t . Fatalf ( "bad: got\n%s\nexpected\n%s\n" , aEntry . TokenID , ent . ID )
2016-03-09 17:50:26 +00:00
}
2018-10-15 16:56:24 +00:00
// Make sure a batch token doesn't get an accessor
ent . Type = logical . TokenTypeBatch
testMakeTokenDirectly ( t , ts , ent )
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
// Ensure that accessor is created
if out == nil || out . Accessor != "" {
t . Fatalf ( "bad: %#v" , out )
}
2016-03-09 17:50:26 +00:00
}
func TestTokenStore_HandleRequest_LookupAccessor ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "tokenid" , "60s" , [ ] string { "foo" } )
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out == nil {
t . Fatalf ( "err: %s" , err )
}
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "lookup-accessor" )
req . Data = map [ string ] interface { } {
"accessor" : out . Accessor ,
}
2016-03-09 17:50:26 +00:00
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Data == nil {
t . Fatalf ( "response should contain data" )
}
if resp . Data [ "accessor" ] . ( string ) == "" {
t . Fatalf ( "accessor should not be empty" )
}
// Verify that the lookup-accessor operation does not return the token ID
if resp . Data [ "id" ] . ( string ) != "" {
t . Fatalf ( "token ID should not be returned" )
}
}
2016-07-29 22:20:38 +00:00
func TestTokenStore_HandleRequest_ListAccessors ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-07-29 22:20:38 +00:00
testKeys := [ ] string { "token1" , "token2" , "token3" , "token4" }
for _ , key := range testKeys {
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , key , "60s" , [ ] string { "foo" } )
2016-07-29 22:20:38 +00:00
}
// Revoke root to make the number of accessors match
2018-11-05 16:11:32 +00:00
salted , err := ts . SaltID ( namespace . RootContext ( nil ) , root )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
ts . revokeInternal ( namespace . RootContext ( nil ) , salted , false )
2016-07-29 22:20:38 +00:00
2018-03-26 18:21:36 +00:00
req := logical . TestRequest ( t , logical . ListOperation , "accessors/" )
2016-07-29 22:20:38 +00:00
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-07-29 22:20:38 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Data == nil {
t . Fatalf ( "response should contain data" )
}
if resp . Data [ "keys" ] == nil {
t . Fatalf ( "keys should not be empty" )
}
keys := resp . Data [ "keys" ] . ( [ ] string )
if len ( keys ) != len ( testKeys ) {
t . Fatalf ( "wrong number of accessors found" )
}
2017-06-05 14:52:43 +00:00
if len ( resp . Warnings ) != 0 {
t . Fatalf ( "got warnings:\n%#v" , resp . Warnings )
2016-08-01 17:07:41 +00:00
}
2016-07-29 22:20:38 +00:00
// Test upgrade from old struct method of accessor storage (of token id)
for _ , accessor := range keys {
2018-11-05 16:11:32 +00:00
aEntry , err := ts . lookupByAccessor ( namespace . RootContext ( nil ) , accessor , false , false )
2016-07-29 22:20:38 +00:00
if err != nil {
t . Fatal ( err )
}
if aEntry . TokenID == "" || aEntry . AccessorID == "" {
t . Fatalf ( "error, accessor entry looked up is empty, but no error thrown" )
}
2018-11-05 16:11:32 +00:00
saltID , err := ts . SaltID ( namespace . RootContext ( nil ) , accessor )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2018-09-18 03:03:00 +00:00
le := & logical . StorageEntry { Key : saltID , Value : [ ] byte ( aEntry . TokenID ) }
2018-11-05 16:11:32 +00:00
if err := ts . accessorView ( namespace . RootNamespace ) . Put ( namespace . RootContext ( nil ) , le ) ; err != nil {
2016-07-29 22:20:38 +00:00
t . Fatalf ( "failed to persist accessor index entry: %v" , err )
}
}
// Do the lookup again, should get same result
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-07-29 22:20:38 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Data == nil {
t . Fatalf ( "response should contain data" )
}
if resp . Data [ "keys" ] == nil {
t . Fatalf ( "keys should not be empty" )
}
keys2 := resp . Data [ "keys" ] . ( [ ] string )
if len ( keys ) != len ( testKeys ) {
t . Fatalf ( "wrong number of accessors found" )
}
2017-06-05 14:52:43 +00:00
if len ( resp . Warnings ) != 0 {
t . Fatalf ( "got warnings:\n%#v" , resp . Warnings )
2016-08-01 17:07:41 +00:00
}
2016-07-29 22:20:38 +00:00
for _ , accessor := range keys2 {
2018-11-05 16:11:32 +00:00
aEntry , err := ts . lookupByAccessor ( namespace . RootContext ( nil ) , accessor , false , false )
2016-07-29 22:20:38 +00:00
if err != nil {
t . Fatal ( err )
}
if aEntry . TokenID == "" || aEntry . AccessorID == "" {
t . Fatalf ( "error, accessor entry looked up is empty, but no error thrown" )
}
}
}
2019-11-08 16:32:01 +00:00
func TestTokenStore_HandleRequest_Renew_Revoke_Accessor ( t * testing . T ) {
2018-05-10 22:22:04 +00:00
exp := mockExpiration ( t )
ts := exp . tokenStore
2018-11-05 16:11:32 +00:00
rootToken , err := ts . rootToken ( namespace . RootContext ( nil ) )
2019-09-18 21:18:08 +00:00
if err != nil {
t . Fatal ( err )
}
2018-05-10 22:22:04 +00:00
root := rootToken . ID
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "tokenid" , "" , [ ] string { "foo" } )
2018-05-10 22:22:04 +00:00
auth := & logical . Auth {
ClientToken : "tokenid" ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
Renewable : true ,
} ,
}
2018-09-18 03:03:00 +00:00
2018-11-05 16:11:32 +00:00
te , err := ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2018-05-10 22:22:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out == nil {
t . Fatalf ( "err: %s" , err )
}
2019-11-08 16:32:01 +00:00
lookupAccessor := func ( ) int64 {
req := logical . TestRequest ( t , logical . UpdateOperation , "lookup-accessor" )
req . Data = map [ string ] interface { } {
"accessor" : out . Accessor ,
}
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Data == nil {
t . Fatal ( "response should contain data" )
}
if resp . Data [ "accessor" ] . ( string ) == "" {
t . Fatal ( "accessor should not be empty" )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
if ttl == 0 {
t . Fatal ( "ttl was zero" )
}
return ttl
}
firstTTL := lookupAccessor ( )
// Sleep so we can verify renew behavior
time . Sleep ( 10 * time . Second )
secondTTL := lookupAccessor ( )
if secondTTL >= firstTTL {
t . Fatalf ( "second TTL %d was greater than first %d" , secondTTL , firstTTL )
}
req := logical . TestRequest ( t , logical . UpdateOperation , "renew-accessor" )
req . Data = map [ string ] interface { } {
"accessor" : out . Accessor ,
}
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Auth == nil {
t . Fatal ( "resp auth is nil" )
}
if resp . Auth . ClientToken != "" {
t . Fatal ( "client token found in response" )
}
thirdTTL := lookupAccessor ( )
if thirdTTL <= secondTTL {
t . Fatalf ( "third TTL %d was not greater than second %d" , thirdTTL , secondTTL )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "revoke-accessor" )
2016-08-24 19:59:43 +00:00
req . Data = map [ string ] interface { } {
"accessor" : out . Accessor ,
}
2016-03-09 17:50:26 +00:00
2018-11-05 16:11:32 +00:00
_ , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2018-05-11 16:12:44 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out != nil {
t . Fatalf ( "bad:\ngot %#v\nexpected: nil\n" , out )
}
// Now test without registering the token through the expiration manager
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "tokenid" , "" , [ ] string { "foo" } )
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2018-05-11 16:12:44 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out == nil {
t . Fatalf ( "err: %s" , err )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "revoke-accessor" )
req . Data = map [ string ] interface { } {
"accessor" : out . Accessor ,
}
2018-11-05 16:11:32 +00:00
_ , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-05-11 16:12:44 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2016-03-09 17:50:26 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if out != nil {
t . Fatalf ( "bad:\ngot %#v\nexpected: nil\n" , out )
}
}
2015-03-24 00:16:37 +00:00
func TestTokenStore_RootToken ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 00:16:37 +00:00
2018-11-05 16:11:32 +00:00
te , err := ts . rootToken ( namespace . RootContext ( nil ) )
2015-03-24 00:16:37 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if te . ID == "" {
t . Fatalf ( "missing ID" )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , te . ID )
2015-03-24 00:16:37 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , te ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , te , out )
2015-03-24 00:16:37 +00:00
}
}
2018-10-15 16:56:24 +00:00
func TestTokenStore_NoRootBatch ( t * testing . T ) {
c , _ , root := TestCoreUnsealed ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/create" )
req . ClientToken = root
req . Data [ "type" ] = "batch"
req . Data [ "policies" ] = "root"
req . Data [ "ttl" ] = "5m"
2018-11-05 16:11:32 +00:00
resp , err := c . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "expected response" )
}
if ! resp . IsError ( ) {
t . Fatalf ( "expected error, got %#v" , * resp )
}
}
2015-03-18 20:19:19 +00:00
func TestTokenStore_CreateLookup ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-18 20:19:19 +00:00
2018-06-08 21:24:27 +00:00
ent := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
TTL : time . Hour ,
2015-03-18 20:19:19 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent )
2015-03-18 20:19:19 +00:00
if ent . ID == "" {
t . Fatalf ( "missing ID" )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-03-18 20:19:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , ent ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , ent , out )
2015-03-24 21:22:50 +00:00
}
// New store should share the salt
2018-11-05 16:11:32 +00:00
ts2 , err := NewTokenStore ( namespace . RootContext ( nil ) , hclog . New ( & hclog . LoggerOptions { } ) , c , getBackendConfig ( c ) )
2015-03-24 21:22:50 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2017-09-05 15:09:00 +00:00
ts2 . SetExpirationManager ( c . expiration )
2015-03-24 21:22:50 +00:00
// Should still match
2018-11-05 16:11:32 +00:00
out , err = ts2 . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-03-24 21:22:50 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , ent ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , ent , out )
2015-03-24 21:22:50 +00:00
}
}
func TestTokenStore_CreateLookup_ProvidedID ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 21:22:50 +00:00
2018-06-08 21:24:27 +00:00
ent := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
ID : "foobarbaz" ,
NamespaceID : namespace . RootNamespaceID ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
TTL : time . Hour ,
2015-03-24 21:22:50 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent )
2015-03-24 21:22:50 +00:00
if ent . ID != "foobarbaz" {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: ent.ID: expected:\"foobarbaz\"\n actual:%s" , ent . ID )
2015-03-24 21:22:50 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err == nil {
2017-06-24 00:52:48 +00:00
t . Fatal ( "expected error creating token with the same ID" )
}
2015-03-24 21:22:50 +00:00
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-03-24 21:22:50 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , ent ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , ent , out )
2015-03-18 20:19:19 +00:00
}
// New store should share the salt
2018-11-05 16:11:32 +00:00
ts2 , err := NewTokenStore ( namespace . RootContext ( nil ) , hclog . New ( & hclog . LoggerOptions { } ) , c , getBackendConfig ( c ) )
2015-03-18 20:19:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2017-09-05 15:09:00 +00:00
ts2 . SetExpirationManager ( c . expiration )
2015-03-18 20:19:19 +00:00
// Should still match
2018-11-05 16:11:32 +00:00
out , err = ts2 . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-03-18 20:19:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , ent ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , ent , out )
2015-03-18 20:19:19 +00:00
}
}
2015-03-18 20:50:36 +00:00
2017-09-05 15:09:00 +00:00
func TestTokenStore_CreateLookup_ExpirationInRestoreMode ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2017-09-05 15:09:00 +00:00
2018-09-18 03:03:00 +00:00
ent := & logical . TokenEntry {
NamespaceID : namespace . RootNamespaceID ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
}
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2017-09-05 15:09:00 +00:00
t . Fatalf ( "err: %v" , err )
}
if ent . ID == "" {
t . Fatalf ( "missing ID" )
}
// Replace the lease with a lease with an expire time in the past
2018-11-05 16:11:32 +00:00
saltedID , err := ts . SaltID ( namespace . RootContext ( nil ) , ent . ID )
2017-09-05 15:09:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Create a lease entry
leaseID := path . Join ( ent . Path , saltedID )
le := & leaseEntry {
LeaseID : leaseID ,
ClientToken : ent . ID ,
Path : ent . Path ,
IssueTime : time . Now ( ) ,
ExpireTime : time . Now ( ) . Add ( 1 * time . Hour ) ,
2018-09-18 03:03:00 +00:00
namespace : namespace . RootNamespace ,
2017-09-05 15:09:00 +00:00
}
2018-11-05 16:11:32 +00:00
if err := ts . expiration . persistEntry ( namespace . RootContext ( nil ) , le ) ; err != nil {
2017-09-05 15:09:00 +00:00
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2017-09-05 15:09:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( out , ent ) {
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , ent , out )
}
// Set to expired lease time
le . ExpireTime = time . Now ( ) . Add ( - 1 * time . Hour )
2018-11-05 16:11:32 +00:00
if err := ts . expiration . persistEntry ( namespace . RootContext ( nil ) , le ) ; err != nil {
2017-09-05 15:09:00 +00:00
t . Fatalf ( "err: %v" , err )
}
2021-05-06 14:19:53 +00:00
err = c . stopExpiration ( )
2017-09-05 15:09:00 +00:00
if err != nil {
t . Fatal ( err )
}
// Reset expiration manager to restore mode
ts . expiration . restoreModeLock . Lock ( )
2018-06-09 19:35:22 +00:00
atomic . StoreInt32 ( ts . expiration . restoreMode , 1 )
2017-09-05 15:09:00 +00:00
ts . expiration . restoreLocks = locksutil . CreateLocks ( )
ts . expiration . restoreModeLock . Unlock ( )
// Test that the token lookup does not return the token entry due to the
// expired lease
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2017-09-05 15:09:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "lease expired, no token expected: %#v" , out )
}
}
2015-04-17 18:51:04 +00:00
func TestTokenStore_UseToken ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-04-17 18:51:04 +00:00
// Lookup the root token
2018-11-05 16:11:32 +00:00
ent , err := ts . Lookup ( namespace . RootContext ( nil ) , root )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Root is an unlimited use token, should be a no-op
2018-11-05 16:11:32 +00:00
te , err := ts . UseToken ( namespace . RootContext ( nil ) , ent )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2016-05-02 07:11:14 +00:00
if te == nil {
t . Fatalf ( "token entry after use was nil" )
}
2015-04-17 18:51:04 +00:00
// Lookup the root token again
2018-11-05 16:11:32 +00:00
ent2 , err := ts . Lookup ( namespace . RootContext ( nil ) , root )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( ent , ent2 ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: ent:%#v ent2:%#v" , ent , ent2 )
2015-04-17 18:51:04 +00:00
}
2018-03-20 18:54:10 +00:00
// Create a restricted token
2018-06-08 21:24:27 +00:00
ent = & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
NumUses : 2 ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2015-04-17 18:51:04 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent )
2015-04-17 18:51:04 +00:00
// Use the token
2018-11-05 16:11:32 +00:00
te , err = ts . UseToken ( namespace . RootContext ( nil ) , ent )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2016-05-02 07:11:14 +00:00
if te == nil {
t . Fatalf ( "token entry for use #1 was nil" )
}
2015-04-17 18:51:04 +00:00
// Lookup the token
2018-11-05 16:11:32 +00:00
ent2 , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Should be reduced
if ent2 . NumUses != 1 {
t . Fatalf ( "bad: %#v" , ent2 )
}
// Use the token
2018-11-05 16:11:32 +00:00
te , err = ts . UseToken ( namespace . RootContext ( nil ) , ent )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2016-05-02 07:11:14 +00:00
if te == nil {
t . Fatalf ( "token entry for use #2 was nil" )
}
2018-05-10 19:50:02 +00:00
if te . NumUses != tokenRevocationPending {
2016-05-02 07:11:14 +00:00
t . Fatalf ( "token entry after use #2 did not have revoke flag" )
}
2018-11-05 16:11:32 +00:00
ts . revokeOrphan ( namespace . RootContext ( nil ) , te . ID )
2015-04-17 18:51:04 +00:00
// Lookup the token
2018-11-05 16:11:32 +00:00
ent2 , err = ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-04-17 18:51:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Should be revoked
if ent2 != nil {
t . Fatalf ( "bad: %#v" , ent2 )
}
}
2015-03-18 20:50:36 +00:00
func TestTokenStore_Revoke ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-18 20:50:36 +00:00
2018-09-18 03:03:00 +00:00
ent := & logical . TokenEntry { Path : "test" , Policies : [ ] string { "dev" , "ops" } , NamespaceID : namespace . RootNamespaceID }
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2015-03-18 20:50:36 +00:00
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
err := ts . revokeOrphan ( namespace . RootContext ( nil ) , "" )
2015-03-18 20:50:36 +00:00
if err . Error ( ) != "cannot revoke blank token" {
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
err = ts . revokeOrphan ( namespace . RootContext ( nil ) , ent . ID )
2015-03-18 20:50:36 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent . ID )
2015-03-18 20:50:36 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %#v" , out )
}
}
2015-04-10 22:12:04 +00:00
func TestTokenStore_Revoke_Leases ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2017-01-07 23:18:22 +00:00
view := NewBarrierView ( c . barrier , "noop/" )
2015-04-10 22:12:04 +00:00
// Mount a noop backend
noop := & NoopBackend { }
2018-09-18 03:03:00 +00:00
err := ts . expiration . router . Mount ( noop , "noop/" , & MountEntry { UUID : "noopuuid" , Accessor : "noopaccessor" , namespace : namespace . RootNamespace } , view )
2017-07-01 20:06:15 +00:00
if err != nil {
t . Fatal ( err )
}
2015-04-10 22:12:04 +00:00
2018-09-18 03:03:00 +00:00
ent := & logical . TokenEntry { Path : "test" , Policies : [ ] string { "dev" , "ops" } , NamespaceID : namespace . RootNamespaceID }
2018-11-05 16:11:32 +00:00
if err := ts . create ( namespace . RootContext ( nil ) , ent ) ; err != nil {
2015-04-10 22:12:04 +00:00
t . Fatalf ( "err: %v" , err )
}
// Register a lease
req := & logical . Request {
Operation : logical . ReadOperation ,
2017-07-01 20:06:15 +00:00
Path : "noop/foo" ,
2015-04-10 22:12:04 +00:00
ClientToken : ent . ID ,
}
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( ent )
2015-04-10 22:12:04 +00:00
resp := & logical . Response {
Secret : & logical . Secret {
LeaseOptions : logical . LeaseOptions {
2015-08-21 00:47:17 +00:00
TTL : 20 * time . Millisecond ,
2015-04-10 22:12:04 +00:00
} ,
} ,
Data : map [ string ] interface { } {
"access_key" : "xyz" ,
"secret_key" : "abcd" ,
} ,
}
2018-11-05 16:11:32 +00:00
leaseID , err := ts . expiration . Register ( namespace . RootContext ( nil ) , req , resp )
2015-04-10 22:12:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Revoke the token
2018-11-05 16:11:32 +00:00
err = ts . revokeOrphan ( namespace . RootContext ( nil ) , ent . ID )
2015-04-10 22:12:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2015-04-10 22:12:04 +00:00
// Verify the lease is gone
2018-11-05 16:11:32 +00:00
out , err := ts . expiration . loadEntry ( namespace . RootContext ( nil ) , leaseID )
2015-04-10 22:12:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %#v" , out )
}
}
2015-03-18 20:50:36 +00:00
func TestTokenStore_Revoke_Orphan ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-18 20:50:36 +00:00
2018-06-08 21:24:27 +00:00
ent := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
Path : "test" ,
Policies : [ ] string { "dev" , "ops" } ,
TTL : time . Hour ,
2015-03-18 20:50:36 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent )
2015-03-18 20:50:36 +00:00
2018-06-08 21:24:27 +00:00
ent2 := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
Parent : ent . ID ,
TTL : time . Hour ,
2015-03-18 20:50:36 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent2 )
2015-03-18 20:50:36 +00:00
2018-11-05 16:11:32 +00:00
err := ts . revokeOrphan ( namespace . RootContext ( nil ) , ent . ID )
2015-03-18 20:50:36 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , ent2 . ID )
2015-03-18 20:50:36 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-03-27 15:12:06 +00:00
// Unset the expected token parent's ID
ent2 . Parent = ""
2015-03-18 20:50:36 +00:00
if ! reflect . DeepEqual ( out , ent2 ) {
2018-09-18 03:03:00 +00:00
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v" , ent2 , out )
2015-03-18 20:50:36 +00:00
}
}
2017-12-11 21:51:37 +00:00
// This was the original function name, and now it just calls
// the non recursive version for a variety of depths.
2015-03-18 20:50:36 +00:00
func TestTokenStore_RevokeTree ( t * testing . T ) {
2018-09-20 21:56:38 +00:00
testTokenStore_RevokeTree_NonRecursive ( t , 1 , false )
testTokenStore_RevokeTree_NonRecursive ( t , 2 , false )
testTokenStore_RevokeTree_NonRecursive ( t , 10 , false )
// corrupted trees with cycles
testTokenStore_RevokeTree_NonRecursive ( t , 1 , true )
testTokenStore_RevokeTree_NonRecursive ( t , 10 , true )
2017-12-11 21:51:37 +00:00
}
2015-03-18 20:50:36 +00:00
2017-12-11 21:51:37 +00:00
// Revokes a given Token Store tree non recursively.
// The second parameter refers to the depth of the tree.
2018-09-20 21:56:38 +00:00
func testTokenStore_RevokeTree_NonRecursive ( t testing . TB , depth uint64 , injectCycles bool ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2017-12-11 21:51:37 +00:00
root , children := buildTokenTree ( t , ts , depth )
2018-09-20 21:56:38 +00:00
var cyclePaths [ ] string
if injectCycles {
// Make the root the parent of itself
2018-11-05 16:11:32 +00:00
saltedRoot , _ := ts . SaltID ( namespace . RootContext ( nil ) , root . ID )
2018-09-20 21:56:38 +00:00
key := fmt . Sprintf ( "%s/%s" , saltedRoot , saltedRoot )
cyclePaths = append ( cyclePaths , key )
le := & logical . StorageEntry { Key : key }
2018-11-05 16:11:32 +00:00
if err := ts . parentView ( namespace . RootNamespace ) . Put ( namespace . RootContext ( nil ) , le ) ; err != nil {
2018-09-20 21:56:38 +00:00
t . Fatalf ( "err: %v" , err )
}
// Make a deep child the parent of a shallow child
2018-11-05 16:11:32 +00:00
shallow , _ := ts . SaltID ( namespace . RootContext ( nil ) , children [ 0 ] . ID )
deep , _ := ts . SaltID ( namespace . RootContext ( nil ) , children [ len ( children ) - 1 ] . ID )
2018-09-20 21:56:38 +00:00
key = fmt . Sprintf ( "%s/%s" , deep , shallow )
cyclePaths = append ( cyclePaths , key )
le = & logical . StorageEntry { Key : key }
2018-11-05 16:11:32 +00:00
if err := ts . parentView ( namespace . RootNamespace ) . Put ( namespace . RootContext ( nil ) , le ) ; err != nil {
2018-09-20 21:56:38 +00:00
t . Fatalf ( "err: %v" , err )
}
}
2018-11-05 16:11:32 +00:00
err := ts . revokeTree ( namespace . RootContext ( nil ) , & leaseEntry { } )
2017-12-11 21:51:37 +00:00
if err . Error ( ) != "cannot tree-revoke blank token" {
2018-09-18 03:03:00 +00:00
t . Fatal ( err )
2015-03-18 20:50:36 +00:00
}
2018-11-05 16:11:32 +00:00
saltCtx := namespace . RootContext ( nil )
2018-09-18 03:03:00 +00:00
saltedID , err := c . tokenStore . SaltID ( saltCtx , root . ID )
if err != nil {
t . Fatal ( err )
}
tokenLeaseID := path . Join ( root . Path , saltedID )
2018-11-05 16:11:32 +00:00
tokenLease , err := ts . expiration . loadEntry ( namespace . RootContext ( nil ) , tokenLeaseID )
2018-09-18 03:03:00 +00:00
if err != nil || tokenLease == nil {
t . Fatalf ( "err: %v, tokenLease: %#v" , err , tokenLease )
}
2015-03-18 20:50:36 +00:00
2018-09-18 03:03:00 +00:00
// Nuke tree non recursively.
2018-11-05 16:11:32 +00:00
err = ts . revokeTree ( namespace . RootContext ( nil ) , tokenLease )
2015-03-18 20:50:36 +00:00
if err != nil {
2018-09-18 03:03:00 +00:00
t . Fatal ( err )
2015-03-18 20:50:36 +00:00
}
2017-12-11 21:51:37 +00:00
// Append the root to ensure it was successfully
// deleted.
children = append ( children , root )
for _ , entry := range children {
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , entry . ID )
2015-03-18 20:50:36 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %#v" , out )
}
}
2018-09-20 21:56:38 +00:00
for _ , path := range cyclePaths {
2018-11-05 16:11:32 +00:00
entry , err := ts . parentView ( namespace . RootNamespace ) . Get ( namespace . RootContext ( nil ) , path )
2018-09-20 21:56:38 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if entry != nil {
t . Fatalf ( "expected reference to be deleted: %v" , entry )
}
}
2015-03-18 20:50:36 +00:00
}
2017-12-11 21:51:37 +00:00
// A benchmark function that tests testTokenStore_RevokeTree_NonRecursive
// for a variety of different depths.
func BenchmarkTokenStore_RevokeTree ( b * testing . B ) {
benchmarks := [ ] uint64 { 0 , 1 , 2 , 4 , 8 , 16 , 20 }
for _ , depth := range benchmarks {
b . Run ( fmt . Sprintf ( "Tree of Depth %d" , depth ) , func ( b * testing . B ) {
for i := 0 ; i < b . N ; i ++ {
2018-09-20 21:56:38 +00:00
testTokenStore_RevokeTree_NonRecursive ( b , depth , false )
2017-12-11 21:51:37 +00:00
}
} )
}
}
// Builds a TokenTree of a specified depth, so that
// we may run revoke tests on it.
2018-06-08 21:24:27 +00:00
func buildTokenTree ( t testing . TB , ts * TokenStore , depth uint64 ) ( root * logical . TokenEntry , children [ ] * logical . TokenEntry ) {
root = & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
TTL : time . Hour ,
2017-12-11 21:51:37 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , root )
2017-12-11 21:51:37 +00:00
2018-06-08 21:24:27 +00:00
frontier := [ ] * logical . TokenEntry { root }
2017-12-11 21:51:37 +00:00
current := uint64 ( 0 )
for current < depth {
2018-06-08 21:24:27 +00:00
next := make ( [ ] * logical . TokenEntry , 0 , 2 * len ( frontier ) )
2017-12-11 21:51:37 +00:00
for _ , node := range frontier {
2018-06-08 21:24:27 +00:00
left := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Parent : node . ID ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2017-12-11 21:51:37 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , left )
2017-12-11 21:51:37 +00:00
2018-06-08 21:24:27 +00:00
right := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Parent : node . ID ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2017-12-11 21:51:37 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , right )
2017-12-11 21:51:37 +00:00
children = append ( children , left , right )
next = append ( next , left , right )
}
frontier = next
current ++
}
return root , children
}
2015-09-17 17:22:30 +00:00
func TestTokenStore_RevokeSelf ( t * testing . T ) {
2018-05-18 19:13:37 +00:00
exp := mockExpiration ( t )
ts := exp . tokenStore
2015-09-17 17:22:30 +00:00
2018-06-08 21:24:27 +00:00
ent1 := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2015-09-17 17:22:30 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent1 )
2015-09-17 17:22:30 +00:00
2018-06-08 21:24:27 +00:00
ent2 := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Parent : ent1 . ID ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2015-09-17 17:22:30 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent2 )
2015-09-17 17:22:30 +00:00
2018-06-08 21:24:27 +00:00
ent3 := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Parent : ent2 . ID ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2015-09-17 17:22:30 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent3 )
2015-09-17 17:22:30 +00:00
2018-06-08 21:24:27 +00:00
ent4 := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
Parent : ent2 . ID ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2015-09-17 17:22:30 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , ent4 )
2015-09-17 17:22:30 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke-self" )
2015-09-17 17:22:30 +00:00
req . ClientToken = ent1 . ID
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-09-17 17:22:30 +00:00
}
lookup := [ ] string { ent1 . ID , ent2 . ID , ent3 . ID , ent4 . ID }
2018-06-08 21:24:27 +00:00
var out * logical . TokenEntry
2015-09-17 17:22:30 +00:00
for _ , id := range lookup {
2018-05-30 12:41:55 +00:00
var found bool
for i := 0 ; i < 10 ; i ++ {
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , id )
2018-05-30 12:41:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out == nil {
found = true
break
}
time . Sleep ( 1000 * time . Millisecond )
2015-09-17 17:22:30 +00:00
}
2018-05-30 12:41:55 +00:00
if ! found {
2015-09-17 17:22:30 +00:00
t . Fatalf ( "bad: %#v" , out )
}
}
}
2016-07-25 19:59:02 +00:00
func TestTokenStore_HandleRequest_NonAssignable ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-07-25 19:59:02 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "default" , "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-07-25 19:59:02 +00:00
}
2016-09-29 04:01:28 +00:00
req . Data [ "policies" ] = [ ] string { "default" , "foo" , responseWrappingPolicyName }
2016-07-25 19:59:02 +00:00
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-07-25 19:59:02 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "got a nil response" )
}
if ! resp . IsError ( ) {
t . Fatalf ( "expected error; response is %#v" , * resp )
}
2018-10-15 16:56:24 +00:00
// Batch tokens too
req . Data [ "type" ] = "batch"
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "got a nil response" )
}
if ! resp . IsError ( ) {
t . Fatalf ( "expected error; response is %#v" , * resp )
}
2016-07-25 19:59:02 +00:00
}
2015-04-15 21:24:07 +00:00
func TestTokenStore_HandleRequest_CreateToken_DisplayName ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-04-15 21:24:07 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-04-15 21:24:07 +00:00
req . ClientToken = root
req . Data [ "display_name" ] = "foo_bar.baz!"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-04-15 21:24:07 +00:00
}
2018-06-08 21:24:27 +00:00
expected := & logical . TokenEntry {
2015-04-15 21:24:07 +00:00
ID : resp . Auth . ClientToken ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-03-09 18:45:36 +00:00
Accessor : resp . Auth . Accessor ,
2015-04-15 21:24:07 +00:00
Parent : root ,
Policies : [ ] string { "root" } ,
Path : "auth/token/create" ,
DisplayName : "token-foo-bar-baz" ,
2015-09-18 20:33:52 +00:00
TTL : 0 ,
2018-10-15 16:56:24 +00:00
Type : logical . TokenTypeService ,
2015-04-15 21:24:07 +00:00
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-04-15 21:24:07 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-09-18 20:33:52 +00:00
expected . CreationTime = out . CreationTime
2018-10-17 20:23:04 +00:00
expected . CubbyholeID = out . CubbyholeID
2015-04-15 21:24:07 +00:00
if ! reflect . DeepEqual ( out , expected ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , expected , out )
2015-04-15 21:24:07 +00:00
}
}
2015-04-17 18:34:25 +00:00
func TestTokenStore_HandleRequest_CreateToken_NumUses ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-04-17 18:34:25 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-04-17 18:34:25 +00:00
req . ClientToken = root
req . Data [ "num_uses" ] = "1"
2018-10-15 16:56:24 +00:00
// Make sure batch tokens can't do limited use counts
req . Data [ "type" ] = "batch"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2021-06-11 15:41:31 +00:00
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp == nil || ! resp . IsError ( ) {
2021-06-11 15:41:31 +00:00
t . Fatalf ( "expected response error: resp: %#v " , resp )
2018-10-15 16:56:24 +00:00
}
delete ( req . Data , "type" )
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-04-17 18:34:25 +00:00
}
2018-06-08 21:24:27 +00:00
expected := & logical . TokenEntry {
2015-04-17 18:34:25 +00:00
ID : resp . Auth . ClientToken ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-03-09 18:45:36 +00:00
Accessor : resp . Auth . Accessor ,
2015-04-17 18:34:25 +00:00
Parent : root ,
Policies : [ ] string { "root" } ,
Path : "auth/token/create" ,
DisplayName : "token" ,
NumUses : 1 ,
2015-09-18 20:33:52 +00:00
TTL : 0 ,
2018-10-15 16:56:24 +00:00
Type : logical . TokenTypeService ,
2015-04-17 18:34:25 +00:00
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-04-17 18:34:25 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-09-18 20:33:52 +00:00
expected . CreationTime = out . CreationTime
2018-10-17 20:23:04 +00:00
expected . CubbyholeID = out . CubbyholeID
2015-04-17 18:34:25 +00:00
if ! reflect . DeepEqual ( out , expected ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , expected , out )
2015-04-17 18:34:25 +00:00
}
}
func TestTokenStore_HandleRequest_CreateToken_NumUses_Invalid ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-04-17 18:34:25 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-04-17 18:34:25 +00:00
req . ClientToken = root
req . Data [ "num_uses" ] = "-1"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-04-17 18:34:25 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-04-17 18:34:25 +00:00
}
}
func TestTokenStore_HandleRequest_CreateToken_NumUses_Restricted ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-04-17 18:34:25 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-04-17 18:34:25 +00:00
req . ClientToken = root
req . Data [ "num_uses" ] = "1"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-04-17 18:34:25 +00:00
}
// We should NOT be able to use the restricted token to create a new token
req . ClientToken = resp . Auth . ClientToken
2018-11-05 16:11:32 +00:00
_ , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-04-17 18:34:25 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-04-17 18:34:25 +00:00
}
}
2015-03-24 22:10:46 +00:00
func TestTokenStore_HandleRequest_CreateToken_NoPolicy ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
2018-10-15 16:56:24 +00:00
// Make sure batch tokens won't automatically assign root
req . Data [ "type" ] = "batch"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2021-06-11 15:41:31 +00:00
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp == nil || ! resp . IsError ( ) {
2021-06-11 15:41:31 +00:00
t . Fatalf ( "expected response error: resp: %#v" , resp )
2018-10-15 16:56:24 +00:00
}
delete ( req . Data , "type" )
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-04-07 21:19:52 +00:00
2018-06-08 21:24:27 +00:00
expected := & logical . TokenEntry {
2015-04-15 21:24:07 +00:00
ID : resp . Auth . ClientToken ,
2018-09-18 03:03:00 +00:00
NamespaceID : namespace . RootNamespaceID ,
2016-03-09 18:45:36 +00:00
Accessor : resp . Auth . Accessor ,
2015-04-15 21:24:07 +00:00
Parent : root ,
Policies : [ ] string { "root" } ,
Path : "auth/token/create" ,
DisplayName : "token" ,
2015-09-18 20:33:52 +00:00
TTL : 0 ,
2018-10-15 16:56:24 +00:00
Type : logical . TokenTypeService ,
2015-04-07 21:19:52 +00:00
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-04-07 21:19:52 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-09-18 20:33:52 +00:00
expected . CreationTime = out . CreationTime
2018-10-17 20:23:04 +00:00
expected . CubbyholeID = out . CubbyholeID
2015-04-07 21:19:52 +00:00
if ! reflect . DeepEqual ( out , expected ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , expected , out )
2015-03-24 22:10:46 +00:00
}
}
func TestTokenStore_HandleRequest_CreateToken_BadParent ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , _ := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = "random"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-24 22:10:46 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2018-05-18 16:30:03 +00:00
if resp . Data [ "error" ] != "parent token lookup failed: no parent found" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
func TestTokenStore_HandleRequest_CreateToken ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken == "" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
func TestTokenStore_HandleRequest_CreateToken_RootID ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
req . Data [ "id" ] = "foobar"
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken != "foobar" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
// Retry with batch; batch should not actually accept a custom ID
req . Data [ "type" ] = "batch"
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
2018-11-05 16:11:32 +00:00
out , _ := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2018-10-15 16:56:24 +00:00
if out . ID == "foobar" {
t . Fatalf ( "bad: %#v" , out )
}
2015-03-24 22:10:46 +00:00
}
func TestTokenStore_HandleRequest_CreateToken_NonRootID ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "client" , "" , [ ] string { "foo" } )
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = "client"
req . Data [ "id" ] = "foobar"
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-24 22:10:46 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-09-19 16:33:52 +00:00
if resp . Data [ "error" ] != "root or sudo privileges required to specify token id" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
// Retry with batch
req . Data [ "type" ] = "batch"
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v resp: %#v" , err , resp )
}
if resp . Data [ "error" ] != "root or sudo privileges required to specify token id" {
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-24 22:10:46 +00:00
}
func TestTokenStore_HandleRequest_CreateToken_NonRoot_Subset ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "client" , "" , [ ] string { "foo" , "bar" } )
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = "client"
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken == "" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
ent := & logical . TokenEntry {
NamespaceID : namespace . RootNamespaceID ,
Path : "test" ,
Policies : [ ] string { "foo" , "bar" } ,
TTL : time . Hour ,
}
testMakeTokenDirectly ( t , ts , ent )
req . ClientToken = ent . ID
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-24 22:10:46 +00:00
}
func TestTokenStore_HandleRequest_CreateToken_NonRoot_InvalidSubset ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "client" , "" , [ ] string { "foo" , "bar" } )
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = "client"
req . Data [ "policies" ] = [ ] string { "foo" , "bar" , "baz" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-24 22:10:46 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-03-24 22:12:52 +00:00
if resp . Data [ "error" ] != "child policies must be subset of parent" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
2016-08-03 18:32:17 +00:00
func TestTokenStore_HandleRequest_CreateToken_NonRoot_RootChild ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
2016-08-05 22:56:22 +00:00
ps := core . policyStore
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
2016-08-05 22:56:22 +00:00
policy . Name = "test1"
2018-11-05 16:11:32 +00:00
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
2016-08-05 22:56:22 +00:00
t . Fatal ( err )
}
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "sudoClient" , "" , [ ] string { "test1" } )
2016-08-03 18:32:17 +00:00
2016-08-05 14:04:02 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2016-08-05 21:58:48 +00:00
req . ClientToken = "sudoClient"
2016-08-06 00:07:18 +00:00
req . MountPoint = "auth/token/"
2016-08-06 00:22:07 +00:00
req . Data [ "policies" ] = [ ] string { "root" }
2016-08-05 14:04:02 +00:00
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-03 18:32:17 +00:00
if err != logical . ErrInvalidRequest {
2016-08-06 00:22:07 +00:00
t . Fatalf ( "err: %v; resp: %#v" , err , resp )
2016-08-06 00:07:18 +00:00
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "expected a response" )
2016-08-03 18:32:17 +00:00
}
2016-08-05 22:56:22 +00:00
if resp . Data [ "error" ] . ( string ) != "root tokens may not be created without parent token being root" {
2016-08-03 18:32:17 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
2016-08-10 00:32:40 +00:00
func TestTokenStore_HandleRequest_CreateToken_Root_RootChild_NoExpiry_Expiry ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-08-10 00:32:40 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
2021-01-04 14:48:22 +00:00
"ttl" : "5m" ,
"policies" : "root" ,
2016-08-10 00:32:40 +00:00
}
2021-01-04 14:48:22 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2016-08-10 00:32:40 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "root" } ) {
t . Fatalf ( "bad: policies: expected: root; actual: %s" , resp . Auth . Policies )
}
if resp . Auth . TTL . Seconds ( ) != 300 {
t . Fatalf ( "bad: expected 300 second ttl, got %v" , resp . Auth . TTL . Seconds ( ) )
}
req . ClientToken = resp . Auth . ClientToken
req . Data = map [ string ] interface { } {
"ttl" : "0" ,
}
2021-01-04 14:48:22 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-10 00:32:40 +00:00
if err == nil {
t . Fatalf ( "expected error" )
}
2021-01-04 14:48:22 +00:00
expectedErr := "expiring root tokens cannot create non-expiring root tokens"
if resp . Data [ "error" ] . ( string ) != expectedErr {
t . Fatalf ( "got err=%v, expected=%v" , resp . Data [ "error" ] , expectedErr )
}
2016-08-10 00:32:40 +00:00
}
2016-08-05 14:04:02 +00:00
func TestTokenStore_HandleRequest_CreateToken_Root_RootChild ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-08-05 14:04:02 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-05 14:04:02 +00:00
if err != nil {
2016-08-06 00:22:07 +00:00
t . Fatalf ( "err: %v; resp: %#v" , err , resp )
}
if resp == nil || resp . Auth == nil {
t . Fatalf ( "failed to create a root token using another root token" )
}
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "root" } ) {
t . Fatalf ( "bad: policies: expected: root; actual: %s" , resp . Auth . Policies )
2016-08-05 14:04:02 +00:00
}
}
2015-03-24 22:10:46 +00:00
func TestTokenStore_HandleRequest_CreateToken_NonRoot_NoParent ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "client" , "" , [ ] string { "foo" } )
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = "client"
req . Data [ "no_parent" ] = true
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-24 22:10:46 +00:00
if err != logical . ErrInvalidRequest {
2018-04-29 11:47:42 +00:00
t . Fatalf ( "err: %v resp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2015-09-19 16:33:52 +00:00
if resp . Data [ "error" ] != "root or sudo privileges required to create orphan token" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
func TestTokenStore_HandleRequest_CreateToken_Root_NoParent ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
req . Data [ "no_parent" ] = true
req . Data [ "policies" ] = [ ] string { "foo" }
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2015-11-03 20:10:46 +00:00
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , _ := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-11-03 20:10:46 +00:00
if out . Parent != "" {
t . Fatalf ( "bad: %#v" , out )
}
}
func TestTokenStore_HandleRequest_CreateToken_PathBased_NoParent ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-11-03 20:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create-orphan" )
2015-11-03 20:10:46 +00:00
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "foo" }
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2018-04-29 11:47:42 +00:00
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken == "" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , _ := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-03-24 22:10:46 +00:00
if out . Parent != "" {
t . Fatalf ( "bad: %#v" , out )
}
}
func TestTokenStore_HandleRequest_CreateToken_Metadata ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "foo" }
2015-03-31 03:26:39 +00:00
meta := map [ string ] string {
2015-03-24 22:10:46 +00:00
"user" : "armon" ,
"source" : "github" ,
}
req . Data [ "meta" ] = meta
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken == "" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , _ := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2015-03-24 22:10:46 +00:00
if ! reflect . DeepEqual ( out . Meta , meta ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , meta , out . Meta )
2015-03-24 22:10:46 +00:00
}
2018-10-15 16:56:24 +00:00
// Test with batch tokens
req . Data [ "type" ] = "batch"
resp = testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , _ = ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2018-10-15 16:56:24 +00:00
if ! reflect . DeepEqual ( out . Meta , meta ) {
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , meta , out . Meta )
}
2015-03-24 22:10:46 +00:00
}
func TestTokenStore_HandleRequest_CreateToken_Lease ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-03-24 22:10:46 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "foo" }
req . Data [ "lease" ] = "1h"
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2015-03-31 03:26:39 +00:00
if resp . Auth . ClientToken == "" {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2015-08-21 00:47:17 +00:00
if resp . Auth . TTL != time . Hour {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2015-04-03 21:04:50 +00:00
if ! resp . Auth . Renewable {
2015-03-24 22:10:46 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
}
2015-09-25 13:46:20 +00:00
func TestTokenStore_HandleRequest_CreateToken_TTL ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2015-09-25 13:46:20 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
2015-09-25 13:46:20 +00:00
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "foo" }
req . Data [ "ttl" ] = "1h"
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , req )
2015-09-25 13:46:20 +00:00
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
if resp . Auth . TTL != time . Hour {
t . Fatalf ( "bad: %#v" , resp )
}
if ! resp . Auth . Renewable {
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
// Test batch tokens
req . Data [ "type" ] = "batch"
resp = testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
if resp . Auth . TTL != time . Hour {
t . Fatalf ( "bad: %#v" , resp )
}
if resp . Auth . Renewable {
t . Fatalf ( "bad: %#v" , resp )
}
2015-09-25 13:46:20 +00:00
}
2020-06-02 18:40:54 +00:00
func TestTokenStore_HandleRequest_CreateToken_Metric ( t * testing . T ) {
2020-07-22 17:52:10 +00:00
c , _ , root , sink := TestCoreUnsealedWithMetrics ( t )
2020-06-18 17:55:50 +00:00
ts := c . tokenStore
2020-06-02 18:40:54 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data [ "ttl" ] = "3h"
req . Data [ "policies" ] = [ ] string { "foo" }
req . MountPoint = "test/mount"
resp := testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2020-07-22 17:52:10 +00:00
expectSingleCount ( t , sink , "token.creation" )
2020-06-02 18:40:54 +00:00
}
2015-03-24 22:30:09 +00:00
func TestTokenStore_HandleRequest_Revoke ( t * testing . T ) {
2018-05-10 22:22:04 +00:00
exp := mockExpiration ( t )
ts := exp . tokenStore
2018-11-05 16:11:32 +00:00
rootToken , err := ts . rootToken ( namespace . RootContext ( nil ) )
2019-09-18 21:18:08 +00:00
if err != nil {
t . Fatal ( err )
}
2018-05-10 22:22:04 +00:00
root := rootToken . ID
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "child" , "60s" , [ ] string { "root" , "foo" } )
2018-05-10 22:22:04 +00:00
2018-11-05 16:11:32 +00:00
te , err := ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
2018-05-10 22:22:04 +00:00
auth := & logical . Auth {
ClientToken : "child" ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
Renewable : true ,
} ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2018-05-10 22:22:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , "child" , "sub-child" , "50s" , [ ] string { "foo" } )
2015-03-24 22:30:09 +00:00
2018-11-05 16:11:32 +00:00
te , err = ts . Lookup ( namespace . RootContext ( nil ) , "sub-child" )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
2018-05-10 22:22:04 +00:00
auth = & logical . Auth {
ClientToken : "sub-child" ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
Renewable : true ,
} ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2018-05-10 22:22:04 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke" )
req . Data = map [ string ] interface { } {
"token" : "child" ,
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:30:09 +00:00
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2015-03-24 22:30:09 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
2018-05-10 22:22:04 +00:00
t . Fatalf ( "bad: %#v" , out )
2015-03-24 22:30:09 +00:00
}
// Sub-child should not exist
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "sub-child" )
2015-03-24 22:30:09 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %v" , out )
}
2018-05-11 16:12:44 +00:00
// Now test without registering the tokens through the expiration manager
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "child" , "60s" , [ ] string { "root" , "foo" } )
testMakeServiceTokenViaBackend ( t , ts , "child" , "sub-child" , "50s" , [ ] string { "foo" } )
2018-05-11 16:12:44 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "revoke" )
req . Data = map [ string ] interface { } {
"token" : "child" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-05-11 16:12:44 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
time . Sleep ( 200 * time . Millisecond )
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2018-05-11 16:12:44 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %#v" , out )
}
// Sub-child should not exist
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "sub-child" )
2018-05-11 16:12:44 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %v" , out )
}
2015-03-24 22:30:09 +00:00
}
func TestTokenStore_HandleRequest_RevokeOrphan ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "child" , "60s" , [ ] string { "root" , "foo" } )
testMakeServiceTokenViaBackend ( t , ts , "child" , "sub-child" , "50s" , [ ] string { "foo" } )
2015-03-24 22:30:09 +00:00
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke-orphan" )
req . Data = map [ string ] interface { } {
"token" : "child" ,
}
2015-09-16 13:22:15 +00:00
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:30:09 +00:00
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2015-03-24 22:30:09 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "bad: %v" , out )
}
2018-03-27 15:12:06 +00:00
// Check that the parent entry is properly cleaned up
2018-11-05 16:11:32 +00:00
saltedID , err := ts . SaltID ( namespace . RootContext ( nil ) , "child" )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
children , err := ts . idView ( namespace . RootNamespace ) . List ( namespace . RootContext ( nil ) , parentPrefix + saltedID + "/" )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if len ( children ) != 0 {
t . Fatalf ( "bad: %v" , children )
}
2015-03-24 22:30:09 +00:00
// Sub-child should exist!
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "sub-child" )
2015-03-24 22:30:09 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out == nil {
t . Fatalf ( "bad: %v" , out )
}
}
2015-09-16 13:22:15 +00:00
func TestTokenStore_HandleRequest_RevokeOrphan_NonRoot ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2019-11-05 21:11:13 +00:00
testMakeServiceTokenViaBackend ( t , ts , root , "child" , "60s" , [ ] string { "foo" } )
2015-09-16 13:22:15 +00:00
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2015-09-16 13:22:15 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out == nil {
t . Fatalf ( "bad: %v" , out )
}
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke-orphan" )
req . Data = map [ string ] interface { } {
"token" : "child" ,
}
2015-09-16 13:22:15 +00:00
req . ClientToken = "child"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-09-16 13:22:15 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "did not get error when non-root revoking itself with orphan flag; resp is %#v" , resp )
}
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2015-09-16 13:22:15 +00:00
// Should still exist
2018-11-05 16:11:32 +00:00
out , err = ts . Lookup ( namespace . RootContext ( nil ) , "child" )
2015-09-16 13:22:15 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out == nil {
t . Fatalf ( "bad: %v" , out )
}
}
2015-03-24 22:39:33 +00:00
func TestTokenStore_HandleRequest_Lookup ( t * testing . T ) {
2020-10-26 20:25:56 +00:00
t . Run ( "service_token" , func ( t * testing . T ) {
testTokenStoreHandleRequestLookup ( t , false , false )
} )
t . Run ( "service_token_periodic" , func ( t * testing . T ) {
testTokenStoreHandleRequestLookup ( t , false , true )
} )
t . Run ( "batch_token" , func ( t * testing . T ) {
testTokenStoreHandleRequestLookup ( t , true , false )
} )
2018-10-15 16:56:24 +00:00
}
2020-10-26 20:25:56 +00:00
func testTokenStoreHandleRequestLookup ( t * testing . T , batch , periodic bool ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "lookup" )
req . Data = map [ string ] interface { } {
"token" : root ,
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:39:33 +00:00
}
if resp == nil {
t . Fatalf ( "bad: %#v" , resp )
}
exp := map [ string ] interface { } {
2016-05-11 20:51:18 +00:00
"id" : root ,
"accessor" : resp . Data [ "accessor" ] . ( string ) ,
"policies" : [ ] string { "root" } ,
"path" : "auth/token/root" ,
"meta" : map [ string ] string ( nil ) ,
"display_name" : "root" ,
"orphan" : true ,
"num_uses" : 0 ,
"creation_ttl" : int64 ( 0 ) ,
"ttl" : int64 ( 0 ) ,
"explicit_max_ttl" : int64 ( 0 ) ,
2017-05-04 02:03:42 +00:00
"expire_time" : nil ,
2017-10-11 17:21:20 +00:00
"entity_id" : "" ,
2018-10-15 16:56:24 +00:00
"type" : "service" ,
2015-12-30 19:30:02 +00:00
}
2016-07-12 20:28:27 +00:00
if resp . Data [ "creation_time" ] . ( int64 ) == 0 {
2015-12-30 19:30:02 +00:00
t . Fatalf ( "creation time was zero" )
2015-03-31 19:50:07 +00:00
}
2015-09-18 20:33:52 +00:00
delete ( resp . Data , "creation_time" )
2015-12-30 19:30:02 +00:00
2015-03-31 19:50:07 +00:00
if ! reflect . DeepEqual ( resp . Data , exp ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , exp , resp . Data )
2015-11-09 18:19:59 +00:00
}
2020-10-26 20:25:56 +00:00
period := ""
if periodic {
period = "3600s"
}
2018-10-15 16:56:24 +00:00
outAuth := new ( logical . Auth )
2020-10-26 20:25:56 +00:00
testMakeTokenViaCore ( t , c , root , "client" , "3600s" , period , [ ] string { "foo" } , batch , outAuth )
2018-10-15 16:56:24 +00:00
tokenType := "service"
expID := "client"
if batch {
tokenType = "batch"
expID = outAuth . ClientToken
}
2015-11-09 18:19:59 +00:00
2018-10-15 16:56:24 +00:00
// Test via POST
2016-08-24 19:59:43 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "lookup" )
req . Data = map [ string ] interface { } {
2018-10-15 16:56:24 +00:00
"token" : expID ,
2016-08-24 19:59:43 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-11-09 18:19:59 +00:00
}
if resp == nil {
t . Fatalf ( "bad: %#v" , resp )
}
exp = map [ string ] interface { } {
2018-10-15 16:56:24 +00:00
"id" : expID ,
2016-05-11 20:51:18 +00:00
"accessor" : resp . Data [ "accessor" ] ,
"policies" : [ ] string { "default" , "foo" } ,
"path" : "auth/token/create" ,
"meta" : map [ string ] string ( nil ) ,
"display_name" : "token" ,
"orphan" : false ,
"num_uses" : 0 ,
"creation_ttl" : int64 ( 3600 ) ,
"ttl" : int64 ( 3600 ) ,
"explicit_max_ttl" : int64 ( 0 ) ,
2018-10-15 16:56:24 +00:00
"renewable" : ! batch ,
2017-10-11 17:21:20 +00:00
"entity_id" : "" ,
2018-10-15 16:56:24 +00:00
"type" : tokenType ,
2015-12-30 19:30:02 +00:00
}
2020-10-26 20:25:56 +00:00
if periodic {
exp [ "period" ] = int64 ( 3600 )
2016-04-28 19:15:37 +00:00
}
2016-07-12 20:28:27 +00:00
if resp . Data [ "creation_time" ] . ( int64 ) == 0 {
2016-04-28 19:15:37 +00:00
t . Fatalf ( "creation time was zero" )
}
delete ( resp . Data , "creation_time" )
2017-05-04 02:03:42 +00:00
if resp . Data [ "issue_time" ] . ( time . Time ) . IsZero ( ) {
t . Fatal ( "issue time is default time" )
}
delete ( resp . Data , "issue_time" )
if resp . Data [ "expire_time" ] . ( time . Time ) . IsZero ( ) {
t . Fatal ( "expire time is default time" )
}
delete ( resp . Data , "expire_time" )
2016-04-28 19:15:37 +00:00
// Depending on timing of the test this may have ticked down, so accept 3599
if resp . Data [ "ttl" ] . ( int64 ) == 3599 {
resp . Data [ "ttl" ] = int64 ( 3600 )
}
2018-10-15 16:56:24 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; diff != nil {
t . Fatal ( diff )
2016-04-28 19:15:37 +00:00
}
2015-12-30 19:30:02 +00:00
// Test last_renewal_time functionality
2016-08-24 19:59:43 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "renew" )
req . Data = map [ string ] interface { } {
2018-10-15 16:56:24 +00:00
"token" : expID ,
2016-08-24 19:59:43 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
2015-12-30 19:30:02 +00:00
}
if resp == nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
if batch && ! resp . IsError ( ) || ! batch && resp . IsError ( ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-24 19:59:43 +00:00
}
2018-10-15 16:56:24 +00:00
req . Path = "lookup"
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-12-30 19:30:02 +00:00
}
if resp == nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
if ! batch {
if resp . Data [ "last_renewal_time" ] . ( int64 ) == 0 {
t . Fatalf ( "last_renewal_time was zero" )
}
} else if _ , ok := resp . Data [ "last_renewal_time" ] ; ok {
t . Fatal ( "expected zero last renewal time" )
2015-12-30 19:30:02 +00:00
}
2015-03-31 19:50:07 +00:00
}
func TestTokenStore_HandleRequest_LookupSelf ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaCore ( t , c , root , "client" , "3600s" , [ ] string { "foo" } )
2017-05-04 02:03:42 +00:00
2015-03-31 19:51:00 +00:00
req := logical . TestRequest ( t , logical . ReadOperation , "lookup-self" )
2017-05-04 02:03:42 +00:00
req . ClientToken = "client"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-31 19:50:07 +00:00
}
if resp == nil {
t . Fatalf ( "bad: %#v" , resp )
}
exp := map [ string ] interface { } {
2017-05-04 02:03:42 +00:00
"id" : "client" ,
2016-05-11 20:51:18 +00:00
"accessor" : resp . Data [ "accessor" ] ,
2017-05-04 02:03:42 +00:00
"policies" : [ ] string { "default" , "foo" } ,
"path" : "auth/token/create" ,
2016-05-11 20:51:18 +00:00
"meta" : map [ string ] string ( nil ) ,
2017-05-04 02:03:42 +00:00
"display_name" : "token" ,
"orphan" : false ,
"renewable" : true ,
2016-05-11 20:51:18 +00:00
"num_uses" : 0 ,
2017-05-04 02:03:42 +00:00
"creation_ttl" : int64 ( 3600 ) ,
"ttl" : int64 ( 3600 ) ,
2016-05-11 20:51:18 +00:00
"explicit_max_ttl" : int64 ( 0 ) ,
2017-10-11 17:21:20 +00:00
"entity_id" : "" ,
2018-10-15 16:56:24 +00:00
"type" : "service" ,
2015-12-30 19:30:02 +00:00
}
2016-07-12 20:28:27 +00:00
if resp . Data [ "creation_time" ] . ( int64 ) == 0 {
2015-12-30 19:30:02 +00:00
t . Fatalf ( "creation time was zero" )
2015-03-24 22:39:33 +00:00
}
2015-09-18 20:33:52 +00:00
delete ( resp . Data , "creation_time" )
2017-05-04 02:03:42 +00:00
if resp . Data [ "issue_time" ] . ( time . Time ) . IsZero ( ) {
t . Fatalf ( "creation time was zero" )
}
delete ( resp . Data , "issue_time" )
if resp . Data [ "expire_time" ] . ( time . Time ) . IsZero ( ) {
t . Fatalf ( "expire time was zero" )
}
delete ( resp . Data , "expire_time" )
// Depending on timing of the test this may have ticked down, so accept 3599
if resp . Data [ "ttl" ] . ( int64 ) == 3599 {
resp . Data [ "ttl" ] = int64 ( 3600 )
}
2015-12-30 19:30:02 +00:00
2015-03-24 22:39:33 +00:00
if ! reflect . DeepEqual ( resp . Data , exp ) {
2016-07-07 21:44:14 +00:00
t . Fatalf ( "bad: expected:%#v\nactual:%#v" , exp , resp . Data )
2015-03-24 22:39:33 +00:00
}
}
2015-04-03 19:11:49 +00:00
func TestTokenStore_HandleRequest_Renew ( t * testing . T ) {
exp := mockExpiration ( t )
ts := exp . tokenStore
// Create new token
2018-11-05 16:11:32 +00:00
root , err := ts . rootToken ( namespace . RootContext ( nil ) )
2015-04-03 19:11:49 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Create a new token
auth := & logical . Auth {
ClientToken : root . ID ,
2015-04-09 19:14:04 +00:00
LeaseOptions : logical . LeaseOptions {
2015-08-21 00:47:17 +00:00
TTL : time . Hour ,
2015-04-09 19:14:04 +00:00
Renewable : true ,
} ,
2015-04-03 19:11:49 +00:00
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , root , auth )
2015-04-03 19:11:49 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-04-11 04:21:06 +00:00
// Get the original expire time to compare
originalExpire := auth . ExpirationTime ( )
2016-07-07 21:44:14 +00:00
beforeRenew := time . Now ( )
2016-08-24 19:59:43 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "renew" )
req . Data = map [ string ] interface { } {
"token" : root . ID ,
"increment" : "3600s" ,
}
2015-06-17 22:58:20 +00:00
req . Data [ "increment" ] = "3600s"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-04-03 19:11:49 +00:00
}
2015-04-11 04:21:06 +00:00
// Get the new expire time
newExpire := resp . Auth . ExpirationTime ( )
2015-06-17 21:28:13 +00:00
if newExpire . Before ( originalExpire ) {
2015-10-07 16:49:13 +00:00
t . Fatalf ( "should expire later: %s %s" , newExpire , originalExpire )
}
if newExpire . Before ( beforeRenew . Add ( time . Hour ) ) {
t . Fatalf ( "should have at least an hour: %s %s" , newExpire , beforeRenew )
}
}
2019-07-01 09:39:54 +00:00
func TestTokenStore_HandleRequest_CreateToken_ExistingEntityAlias ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
i := core . identityStore
ctx := namespace . RootContext ( nil )
testPolicyName := "testpolicy"
entityAliasName := "testentityalias"
testRoleName := "test"
// Create manually an entity
resp , err := i . HandleRequest ( ctx , & logical . Request {
Path : "entity" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : "testentity" ,
"policies" : [ ] string { testPolicyName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
entityID := resp . Data [ "id" ] . ( string )
// Find mount accessor
resp , err = core . systemBackend . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
Path : "auth" ,
Operation : logical . ReadOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
tokenMountAccessor := resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] . ( string )
// Create manually an entity alias
resp , err = i . HandleRequest ( ctx , & logical . Request {
Path : "entity-alias" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : entityAliasName ,
"canonical_id" : entityID ,
"mount_accessor" : tokenMountAccessor ,
} ,
} )
2019-09-18 21:18:08 +00:00
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
2019-07-01 09:39:54 +00:00
// Create token role
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/roles/" + testRoleName ,
ClientToken : root ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"orphan" : true ,
"period" : "72h" ,
"path_suffix" : "happenin" ,
"bound_cidrs" : [ ] string { "0.0.0.0/0" } ,
"allowed_entity_aliases" : [ ] string { "test1" , "test2" , entityAliasName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasName ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if resp == nil {
t . Fatal ( "expected a response" )
}
if resp . Auth . EntityID != entityID {
t . Fatalf ( "expected '%s' got '%s'" , entityID , resp . Auth . EntityID )
}
policyFound := false
for _ , policy := range resp . Auth . IdentityPolicies {
if policy == testPolicyName {
policyFound = true
}
}
if ! policyFound {
t . Fatalf ( "Policy '%s' not derived by entity but should be. Auth %#v" , testPolicyName , resp . Auth )
}
}
2021-01-27 17:56:54 +00:00
func TestTokenStore_HandleRequest_CreateToken_ExistingEntityAliasMixedCase ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
i := core . identityStore
ctx := namespace . RootContext ( nil )
testPolicyName := "testpolicy"
entityAliasName := "tEStEntityAliaS"
entityAliasNameLower := "testentityalias"
testRoleName := "test"
// Create manually an entity
resp , err := i . HandleRequest ( ctx , & logical . Request {
Path : "entity" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : "testentity" ,
"policies" : [ ] string { testPolicyName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
entityID := resp . Data [ "id" ] . ( string )
// Find mount accessor
resp , err = core . systemBackend . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
Path : "auth" ,
Operation : logical . ReadOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
tokenMountAccessor := resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] . ( string )
// Create manually an entity alias
resp , err = i . HandleRequest ( ctx , & logical . Request {
Path : "entity-alias" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : entityAliasName ,
"canonical_id" : entityID ,
"mount_accessor" : tokenMountAccessor ,
} ,
} )
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
// Create token role
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/roles/" + testRoleName ,
ClientToken : root ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"orphan" : true ,
"period" : "72h" ,
"path_suffix" : "happenin" ,
"bound_cidrs" : [ ] string { "0.0.0.0/0" } ,
"allowed_entity_aliases" : [ ] string { "test1" , "test2" , entityAliasName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
respMixedCase , err := core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasName ,
} ,
} )
2021-06-11 15:41:31 +00:00
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
2021-01-27 17:56:54 +00:00
if respMixedCase . Auth . EntityID != entityID {
t . Fatalf ( "expected '%s' got '%s'" , entityID , respMixedCase . Auth . EntityID )
}
// lowercase entity alias should match a mixed case alias
respLowerCase , err := core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasNameLower ,
} ,
} )
2021-06-11 15:41:31 +00:00
if err != nil {
t . Fatalf ( "error handling request: %v" , err )
}
2021-01-27 17:56:54 +00:00
// A token created with the mixed case alias should return the same entity
// id as the normal case response.
if respLowerCase . Auth . EntityID != entityID {
t . Fatalf ( "expected '%s' got '%s'" , entityID , respLowerCase . Auth . EntityID )
}
}
2019-07-01 09:39:54 +00:00
func TestTokenStore_HandleRequest_CreateToken_NonExistingEntityAlias ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
i := core . identityStore
ctx := namespace . RootContext ( nil )
entityAliasName := "testentityalias"
testRoleName := "test"
// Create token role
resp , err := core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/roles/" + testRoleName ,
ClientToken : root ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"period" : "72h" ,
"path_suffix" : "happenin" ,
"bound_cidrs" : [ ] string { "0.0.0.0/0" } ,
"allowed_entity_aliases" : [ ] string { "test1" , "test2" , entityAliasName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
// Create token with non existing entity alias
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasName ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if resp == nil {
t . Fatal ( "expected a response" )
}
// Read the new entity
resp , err = i . HandleRequest ( ctx , & logical . Request {
Path : "entity/id/" + resp . Auth . EntityID ,
Operation : logical . ReadOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Get the attached alias information
aliases := resp . Data [ "aliases" ] . ( [ ] interface { } )
if len ( aliases ) != 1 {
t . Fatalf ( "expected only one alias but got %d; Aliases: %#v" , len ( aliases ) , aliases )
}
alias := & identity . Alias { }
if err := mapstructure . Decode ( aliases [ 0 ] , alias ) ; err != nil {
t . Fatal ( err )
}
// Validate
if alias . Name != entityAliasName {
t . Fatalf ( "alias name should be '%s' but is '%s'" , entityAliasName , alias . Name )
}
}
func TestTokenStore_HandleRequest_CreateToken_GlobPatternWildcardEntityAlias ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
i := core . identityStore
ctx := namespace . RootContext ( nil )
testRoleName := "test"
tests := [ ] struct {
name string
globPattern string
aliasName string
} {
{
name : "prefix-asterisk" ,
globPattern : "*-web" ,
aliasName : "department-web" ,
} ,
{
name : "suffix-asterisk" ,
globPattern : "web-*" ,
aliasName : "web-department" ,
} ,
{
name : "middle-asterisk" ,
globPattern : "web-*-web" ,
aliasName : "web-department-web" ,
} ,
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
// Create token role
resp , err := core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/roles/" + testRoleName ,
ClientToken : root ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"period" : "72h" ,
"path_suffix" : "happening" ,
"bound_cidrs" : [ ] string { "0.0.0.0/0" } ,
"allowed_entity_aliases" : [ ] string { "test1" , "test2" , test . globPattern } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
// Create token with non existing entity alias
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : test . aliasName ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if resp == nil {
t . Fatal ( "expected a response" )
}
// Read the new entity
resp , err = i . HandleRequest ( ctx , & logical . Request {
Path : "entity/id/" + resp . Auth . EntityID ,
Operation : logical . ReadOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Get the attached alias information
aliases := resp . Data [ "aliases" ] . ( [ ] interface { } )
if len ( aliases ) != 1 {
t . Fatalf ( "expected only one alias but got %d; Aliases: %#v" , len ( aliases ) , aliases )
}
alias := & identity . Alias { }
if err := mapstructure . Decode ( aliases [ 0 ] , alias ) ; err != nil {
t . Fatal ( err )
}
// Validate
if alias . Name != test . aliasName {
t . Fatalf ( "alias name should be '%s' but is '%s'" , test . aliasName , alias . Name )
}
} )
}
}
func TestTokenStore_HandleRequest_CreateToken_NotAllowedEntityAlias ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
i := core . identityStore
ctx := namespace . RootContext ( nil )
testPolicyName := "testpolicy"
entityAliasName := "testentityalias"
testRoleName := "test"
// Create manually an entity
resp , err := i . HandleRequest ( ctx , & logical . Request {
Path : "entity" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : "testentity" ,
"policies" : [ ] string { testPolicyName } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
entityID := resp . Data [ "id" ] . ( string )
// Find mount accessor
resp , err = core . systemBackend . HandleRequest ( ctx , & logical . Request {
Path : "auth" ,
Operation : logical . ReadOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
tokenMountAccessor := resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] . ( string )
// Create manually an entity alias
resp , err = i . HandleRequest ( ctx , & logical . Request {
Path : "entity-alias" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"name" : entityAliasName ,
"canonical_id" : entityID ,
"mount_accessor" : tokenMountAccessor ,
} ,
} )
2019-12-02 18:03:24 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
2019-07-01 09:39:54 +00:00
// Create token role
resp , err = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/roles/" + testRoleName ,
ClientToken : root ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"period" : "72h" ,
"allowed_entity_aliases" : [ ] string { "test1" , "test2" , "testentityaliasn" } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
resp , _ = core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create/" + testRoleName ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasName ,
} ,
} )
if resp == nil || resp . Data == nil {
t . Fatal ( "expected a response" )
}
if resp . Data [ "error" ] != "invalid 'entity_alias' value" {
t . Fatalf ( "wrong error returned. Err: %s" , resp . Data [ "error" ] )
}
}
func TestTokenStore_HandleRequest_CreateToken_NoRoleEntityAlias ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
ctx := namespace . RootContext ( nil )
entityAliasName := "testentityalias"
resp , _ := core . HandleRequest ( ctx , & logical . Request {
Path : "auth/token/create" ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
Data : map [ string ] interface { } {
"entity_alias" : entityAliasName ,
} ,
} )
if resp == nil || resp . Data == nil {
t . Fatal ( "expected a response" )
}
if resp . Data [ "error" ] != "'entity_alias' is only allowed in combination with token role" {
t . Fatalf ( "wrong error returned. Err: %s" , resp . Data [ "error" ] )
}
}
2015-10-07 16:49:13 +00:00
func TestTokenStore_HandleRequest_RenewSelf ( t * testing . T ) {
exp := mockExpiration ( t )
ts := exp . tokenStore
// Create new token
2018-11-05 16:11:32 +00:00
root , err := ts . rootToken ( namespace . RootContext ( nil ) )
2015-10-07 16:49:13 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Create a new token
auth := & logical . Auth {
ClientToken : root . ID ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
Renewable : true ,
} ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , root , auth )
2015-10-07 16:49:13 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Get the original expire time to compare
originalExpire := auth . ExpirationTime ( )
2016-07-07 21:44:14 +00:00
beforeRenew := time . Now ( )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "renew-self" )
2015-10-07 16:49:13 +00:00
req . ClientToken = auth . ClientToken
req . Data [ "increment" ] = "3600s"
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-10-07 16:49:13 +00:00
}
// Get the new expire time
newExpire := resp . Auth . ExpirationTime ( )
if newExpire . Before ( originalExpire ) {
2015-06-17 21:28:13 +00:00
t . Fatalf ( "should expire later: %s %s" , newExpire , originalExpire )
}
if newExpire . Before ( beforeRenew . Add ( time . Hour ) ) {
t . Fatalf ( "should have at least an hour: %s %s" , newExpire , beforeRenew )
2015-04-03 19:11:49 +00:00
}
}
2016-02-29 19:13:09 +00:00
func TestTokenStore_RoleCRUD ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
2016-02-29 19:13:09 +00:00
2016-03-09 16:59:54 +00:00
req := logical . TestRequest ( t , logical . ReadOperation , "auth/token/roles/test" )
2015-03-24 22:10:46 +00:00
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:10:46 +00:00
}
2016-02-29 19:13:09 +00:00
if resp != nil {
t . Fatalf ( "should not see a role" )
2015-03-24 22:10:46 +00:00
}
2015-03-24 22:52:07 +00:00
2016-03-09 16:59:54 +00:00
// First test creation
req . Operation = logical . CreateOperation
2016-02-29 19:13:09 +00:00
req . Data = map [ string ] interface { } {
"orphan" : true ,
"period" : "72h" ,
"allowed_policies" : "test1,test2" ,
2016-03-01 20:30:37 +00:00
"path_suffix" : "happenin" ,
2019-03-04 17:39:29 +00:00
"bound_cidrs" : [ ] string { "0.0.0.0/0" } ,
2019-06-14 14:17:04 +00:00
"explicit_max_ttl" : "2h" ,
"token_num_uses" : 123 ,
2016-02-29 19:13:09 +00:00
}
2015-03-24 22:52:07 +00:00
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2015-03-24 22:52:07 +00:00
}
2018-04-29 11:47:42 +00:00
2016-02-29 19:13:09 +00:00
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Operation = logical . ReadOperation
req . Data = map [ string ] interface { } { }
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-02-29 19:13:09 +00:00
}
2018-04-29 11:47:42 +00:00
2016-02-29 19:13:09 +00:00
if resp == nil {
t . Fatalf ( "got a nil response" )
}
2016-04-14 11:56:09 +00:00
expected := map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : true ,
"token_period" : int64 ( 259200 ) ,
"period" : int64 ( 259200 ) ,
"allowed_policies" : [ ] string { "test1" , "test2" } ,
"disallowed_policies" : [ ] string { } ,
"allowed_policies_glob" : [ ] string { } ,
"disallowed_policies_glob" : [ ] string { } ,
"path_suffix" : "happenin" ,
"explicit_max_ttl" : int64 ( 7200 ) ,
"token_explicit_max_ttl" : int64 ( 7200 ) ,
"renewable" : true ,
"token_type" : "default-service" ,
"token_num_uses" : 123 ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2016-02-29 19:13:09 +00:00
}
2019-03-05 01:44:00 +00:00
if resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "bound_cidrs" )
2019-06-14 14:17:04 +00:00
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "token_bound_cidrs" )
2019-03-05 01:44:00 +00:00
2018-11-07 14:45:09 +00:00
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
2016-02-29 19:13:09 +00:00
}
2016-03-09 16:59:54 +00:00
// Now test updating; this should be set to an UpdateOperation
// automatically due to the existence check
req . Operation = logical . CreateOperation
req . Data = map [ string ] interface { } {
2021-09-21 16:53:08 +00:00
"period" : "79h" ,
"allowed_policies" : "test3" ,
"path_suffix" : "happenin" ,
"renewable" : false ,
"explicit_max_ttl" : "80h" ,
"token_num_uses" : 0 ,
"token_no_default_policy" : true ,
2016-03-09 16:59:54 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-09 16:59:54 +00:00
}
2018-04-29 11:47:42 +00:00
2016-03-09 16:59:54 +00:00
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Operation = logical . ReadOperation
req . Data = map [ string ] interface { } { }
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-09 16:59:54 +00:00
}
if resp == nil {
t . Fatalf ( "got a nil response" )
}
2016-04-14 11:56:09 +00:00
expected = map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : true ,
"period" : int64 ( 284400 ) ,
"token_period" : int64 ( 284400 ) ,
"allowed_policies" : [ ] string { "test3" } ,
"disallowed_policies" : [ ] string { } ,
"allowed_policies_glob" : [ ] string { } ,
"disallowed_policies_glob" : [ ] string { } ,
"path_suffix" : "happenin" ,
"token_explicit_max_ttl" : int64 ( 288000 ) ,
"explicit_max_ttl" : int64 ( 288000 ) ,
"renewable" : false ,
"token_type" : "default-service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : true ,
2016-05-11 20:51:18 +00:00
}
2019-03-05 01:44:00 +00:00
if resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "bound_cidrs" )
2019-06-14 14:17:04 +00:00
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "token_bound_cidrs" )
2019-03-05 01:44:00 +00:00
2018-11-07 14:45:09 +00:00
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
2016-05-11 20:51:18 +00:00
}
// Now set explicit max ttl and clear the period
req . Operation = logical . CreateOperation
req . Data = map [ string ] interface { } {
"explicit_max_ttl" : "5" ,
"period" : "0s" ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
req . Operation = logical . ReadOperation
req . Data = map [ string ] interface { } { }
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
if resp == nil {
t . Fatalf ( "got a nil response" )
}
expected = map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : true ,
"explicit_max_ttl" : int64 ( 5 ) ,
"token_explicit_max_ttl" : int64 ( 5 ) ,
"allowed_policies" : [ ] string { "test3" } ,
"disallowed_policies" : [ ] string { } ,
"allowed_policies_glob" : [ ] string { } ,
"disallowed_policies_glob" : [ ] string { } ,
"path_suffix" : "happenin" ,
"period" : int64 ( 0 ) ,
"token_period" : int64 ( 0 ) ,
"renewable" : false ,
"token_type" : "default-service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : true ,
2019-03-04 17:39:29 +00:00
}
2019-03-05 01:44:00 +00:00
if resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "bound_cidrs" )
2019-06-14 14:17:04 +00:00
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "0.0.0.0/0" {
t . Fatal ( "unexpected bound cidrs" )
}
delete ( resp . Data , "token_bound_cidrs" )
2019-03-05 01:44:00 +00:00
2019-03-04 17:39:29 +00:00
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
}
// Update path_suffix and bound_cidrs with empty values
req . Operation = logical . CreateOperation
req . Data = map [ string ] interface { } {
2021-09-21 16:53:08 +00:00
"path_suffix" : "" ,
"bound_cidrs" : [ ] string { } ,
"token_no_default_policy" : false ,
2019-03-04 17:39:29 +00:00
}
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
req . Operation = logical . ReadOperation
req . Data = map [ string ] interface { } { }
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp == nil {
t . Fatalf ( "got a nil response" )
}
expected = map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : true ,
"token_explicit_max_ttl" : int64 ( 5 ) ,
"explicit_max_ttl" : int64 ( 5 ) ,
"allowed_policies" : [ ] string { "test3" } ,
"disallowed_policies" : [ ] string { } ,
"allowed_policies_glob" : [ ] string { } ,
"disallowed_policies_glob" : [ ] string { } ,
"path_suffix" : "" ,
"period" : int64 ( 0 ) ,
"token_period" : int64 ( 0 ) ,
"renewable" : false ,
"token_type" : "default-service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2016-03-09 16:59:54 +00:00
}
2018-11-07 14:45:09 +00:00
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
2016-03-09 16:59:54 +00:00
}
2016-02-29 19:13:09 +00:00
req . Operation = logical . ListOperation
2016-03-09 16:59:54 +00:00
req . Path = "auth/token/roles"
2016-02-29 19:13:09 +00:00
req . Data = map [ string ] interface { } { }
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-02-29 19:13:09 +00:00
}
if resp == nil {
t . Fatalf ( "got a nil response" )
}
keysInt , ok := resp . Data [ "keys" ]
if ! ok {
t . Fatalf ( "did not find keys in response" )
}
keys , ok := keysInt . ( [ ] string )
if ! ok {
t . Fatalf ( "could not convert keys interface to key list" )
}
if len ( keys ) != 1 {
t . Fatalf ( "unexpected number of keys: %d" , len ( keys ) )
}
if keys [ 0 ] != "test" {
t . Fatalf ( "expected \"test\", got \"%s\"" , keys [ 0 ] )
}
req . Operation = logical . DeleteOperation
2016-03-09 16:59:54 +00:00
req . Path = "auth/token/roles/test"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-02-29 19:13:09 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Operation = logical . ReadOperation
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-02-29 19:13:09 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
2015-03-24 22:52:07 +00:00
}
}
2016-03-01 17:33:35 +00:00
2017-01-18 02:34:14 +00:00
func TestTokenStore_RoleDisallowedPoliciesWithRoot ( t * testing . T ) {
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2017-01-18 02:34:14 +00:00
// Don't set disallowed_policies. Verify that a read on the role does return a non-nil value.
roleReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "roles/role1" ,
Data : map [ string ] interface { } {
"disallowed_policies" : "root,testpolicy" ,
} ,
ClientToken : root ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2017-01-18 02:34:14 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2017-01-18 02:34:14 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
expected := [ ] string { "root" , "testpolicy" }
if ! reflect . DeepEqual ( resp . Data [ "disallowed_policies" ] , expected ) {
t . Fatalf ( "bad: expected: %#v, actual: %#v" , expected , resp . Data [ "disallowed_policies" ] )
}
}
2016-08-02 19:21:15 +00:00
func TestTokenStore_RoleDisallowedPolicies ( t * testing . T ) {
var req * logical . Request
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
2016-08-02 19:21:15 +00:00
ps := core . policyStore
// Create 3 different policies
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
2016-08-02 19:21:15 +00:00
policy . Name = "test1"
2018-11-05 16:11:32 +00:00
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
2016-08-02 19:21:15 +00:00
t . Fatal ( err )
}
2018-09-18 03:03:00 +00:00
policy , _ = ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
2016-08-02 19:21:15 +00:00
policy . Name = "test2"
2018-11-05 16:11:32 +00:00
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
2016-08-02 19:21:15 +00:00
t . Fatal ( err )
}
2018-09-18 03:03:00 +00:00
policy , _ = ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
2016-08-02 19:21:15 +00:00
policy . Name = "test3"
2018-11-05 16:11:32 +00:00
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
2016-08-02 19:21:15 +00:00
t . Fatal ( err )
}
// Create roles with different disallowed_policies configuration
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test1" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies" : "test1" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test23" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies" : "test2,test3" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test123" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies" : "test1,test2,test3" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2021-09-21 15:25:06 +00:00
// policy containing a glob character in the non-glob disallowed_policies field
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/testglobdisabled" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies" : "test*" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2016-08-02 19:21:15 +00:00
// Create a token that has all the policies defined above
req = logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "test1" , "test2" , "test3" }
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , req )
2016-08-02 19:21:15 +00:00
if resp == nil || resp . Auth == nil {
t . Fatal ( "got nil response" )
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: ClientToken; resp:%#v" , resp )
}
parentToken := resp . Auth . ClientToken
2021-09-21 15:25:06 +00:00
// Test that the parent token's policies are rejected by disallowed_policies
2016-08-02 19:21:15 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test1" )
req . ClientToken = parentToken
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err == nil || resp != nil && ! resp . IsError ( ) {
2016-12-16 05:36:39 +00:00
t . Fatalf ( "expected an error response, got %#v" , resp )
2016-08-02 19:21:15 +00:00
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test23" )
req . ClientToken = parentToken
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err == nil || resp != nil && ! resp . IsError ( ) {
2018-06-03 22:14:51 +00:00
t . Fatalf ( "expected an error response, got %#v" , resp )
2016-08-02 19:21:15 +00:00
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test123" )
req . ClientToken = parentToken
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err == nil || resp != nil && ! resp . IsError ( ) {
2018-06-03 22:14:51 +00:00
t . Fatalf ( "expected an error response, got %#v" , resp )
2016-08-02 19:21:15 +00:00
}
2017-01-18 21:11:25 +00:00
// Disallowed should act as a blacklist so make sure we can still make
// something with other policies in the request
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test123" )
req . Data [ "policies" ] = [ ] string { "foo" , "bar" }
req . ClientToken = parentToken
2018-06-03 22:14:51 +00:00
testMakeTokenViaRequest ( t , ts , req )
2017-01-18 21:11:25 +00:00
2021-09-21 15:25:06 +00:00
// Check to be sure 'test*' without globbing matches 'test*'
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testglobdisabled" )
req . Data [ "policies" ] = [ ] string { "test*" }
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatalf ( "expected an error response, got %#v" , resp )
}
// Check to be sure 'test*' without globbing doesn't match 'test1' or 'test'
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testglobdisabled" )
req . Data [ "policies" ] = [ ] string { "test1" , "test" }
req . ClientToken = parentToken
testMakeTokenViaRequest ( t , ts , req )
2016-08-02 19:21:15 +00:00
// Create a role to have 'default' policy disallowed
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/default" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies" : "default" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create/default" )
req . ClientToken = parentToken
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-02 19:21:15 +00:00
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatal ( "expected an error response" )
}
}
2016-08-02 17:33:03 +00:00
func TestTokenStore_RoleAllowedPolicies ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-03-01 17:33:35 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"allowed_policies" : "test1,test2" ,
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Data = map [ string ] interface { } { }
req . Path = "create/test"
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "test2" }
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , req )
2016-03-01 17:33:35 +00:00
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2016-12-16 05:36:39 +00:00
2021-09-21 15:25:06 +00:00
// test not glob matching when using allowed_policies instead of allowed_policies_glob
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/testnoglob" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"allowed_policies" : "test*" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Path = "create/testnoglob"
req . Data [ "policies" ] = [ ] string { "test" }
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "testfoo" }
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "test*" }
resp = testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2016-12-16 05:36:39 +00:00
// When allowed_policies is blank, should fall back to a subset of the parent policies
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"allowed_policies" : "" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-12-16 05:36:39 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "test1" , "test2" , "test3" }
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , req )
2016-12-16 05:36:39 +00:00
if resp == nil || resp . Auth == nil {
t . Fatal ( "got nil response" )
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: ClientToken; resp:%#v" , resp )
}
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "test1" , "test2" , "test3" } ) {
t . Fatalf ( "bad: %#v" , resp . Auth . Policies )
}
parentToken := resp . Auth . ClientToken
req . Data = map [ string ] interface { } { }
req . ClientToken = parentToken
req . Path = "create/test"
req . Data [ "policies" ] = [ ] string { "foo" }
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-12-16 05:36:39 +00:00
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "test2" }
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , req )
2016-12-16 05:36:39 +00:00
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
delete ( req . Data , "policies" )
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , req )
2016-12-16 05:36:39 +00:00
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "test1" , "test2" , "test3" } ) {
t . Fatalf ( "bad: %#v" , resp . Auth . Policies )
}
2016-03-01 17:33:35 +00:00
}
2021-09-21 15:25:06 +00:00
func TestTokenStore_RoleDisallowedPoliciesGlob ( t * testing . T ) {
var req * logical . Request
var resp * logical . Response
var err error
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
ps := core . policyStore
// Create 4 different policies
policy , _ := ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
policy . Name = "test1"
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
t . Fatal ( err )
}
policy , _ = ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
policy . Name = "test2"
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
t . Fatal ( err )
}
policy , _ = ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
policy . Name = "test3"
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
t . Fatal ( err )
}
policy , _ = ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
policy . Name = "test3b"
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
t . Fatal ( err )
}
// Create roles with different disallowed_policies configuration
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test1" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies_glob" : "test1" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/testnot23" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies_glob" : "test2,test3*" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
// Create a token that has all the policies defined above
req = logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root
req . Data [ "policies" ] = [ ] string { "test1" , "test2" , "test3" , "test3b" }
resp = testMakeTokenViaRequest ( t , ts , req )
if resp == nil || resp . Auth == nil {
t . Fatal ( "got nil response" )
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: ClientToken; resp:%#v" , resp )
}
parentToken := resp . Auth . ClientToken
// Test that the parent token's policies are rejected by disallowed_policies
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test1" )
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatalf ( "expected an error response, got %#v" , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testnot23" )
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatalf ( "expected an error response, got %#v" , resp )
}
// Disallowed should act as a blacklist so make sure we can still make
// something with other policies in the request
req = logical . TestRequest ( t , logical . UpdateOperation , "create/test1" )
req . Data [ "policies" ] = [ ] string { "foo" , "bar" }
req . ClientToken = parentToken
testMakeTokenViaRequest ( t , ts , req )
// Check to be sure 'test3*' matches 'test3'
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testnot23" )
req . Data [ "policies" ] = [ ] string { "test3" }
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatalf ( "expected an error response, got %#v" , resp )
}
// Check to be sure 'test3*' matches 'test3b'
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testnot23" )
req . Data [ "policies" ] = [ ] string { "test3b" }
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatalf ( "expected an error response, got %#v" , resp )
}
// Check that non-blacklisted policies still work
req = logical . TestRequest ( t , logical . UpdateOperation , "create/testnot23" )
req . Data [ "policies" ] = [ ] string { "test1" }
req . ClientToken = parentToken
testMakeTokenViaRequest ( t , ts , req )
// Create a role to have 'default' policy disallowed
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/default" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"disallowed_policies_glob" : "default" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "create/default" )
req . ClientToken = parentToken
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil || resp != nil && ! resp . IsError ( ) {
t . Fatal ( "expected an error response" )
}
}
func TestTokenStore_RoleAllowedPoliciesGlob ( t * testing . T ) {
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
// test literal matching works in allowed_policies_glob
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"allowed_policies_glob" : "test1,test2" ,
}
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Data = map [ string ] interface { } { }
req . Path = "create/test"
req . Data [ "policies" ] = [ ] string { "foo" }
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "test2" }
resp = testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// test glob matching in allowed_policies_glob
req = logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"allowed_policies_glob" : "test*" ,
}
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Path = "create/test"
req . Data [ "policies" ] = [ ] string { "footest" }
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
if err == nil {
t . Fatalf ( "expected error" )
}
req . Data [ "policies" ] = [ ] string { "testfoo" , "test2" , "test" }
resp = testMakeTokenViaRequest ( t , ts , req )
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
}
2016-03-01 17:33:35 +00:00
func TestTokenStore_RoleOrphan ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-03-01 17:33:35 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"orphan" : true ,
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Path = "create/test"
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out . Parent != "" {
t . Fatalf ( "expected orphan token, but found a parent" )
}
if ! strings . HasPrefix ( out . Path , "auth/token/create/test" ) {
t . Fatalf ( "expected role in path but did not find it" )
}
}
2016-03-01 20:30:37 +00:00
func TestTokenStore_RolePathSuffix ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-03-01 17:33:35 +00:00
2018-10-15 16:56:24 +00:00
req := logical . TestRequest ( t , logical . CreateOperation , "roles/test" )
2016-03-01 17:33:35 +00:00
req . ClientToken = root
req . Data = map [ string ] interface { } {
2016-03-01 20:30:37 +00:00
"path_suffix" : "happenin" ,
2016-03-01 17:33:35 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req . Path = "create/test"
2018-10-15 16:56:24 +00:00
req . Operation = logical . UpdateOperation
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
out , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2016-03-01 20:30:37 +00:00
if out . Path != "auth/token/create/test/happenin" {
2016-03-01 17:33:35 +00:00
t . Fatalf ( "expected role in path but did not find it" )
}
}
func TestTokenStore_RolePeriod ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
2016-03-01 17:33:35 +00:00
2016-07-01 15:59:39 +00:00
core . defaultLeaseTTL = 10 * time . Second
core . maxLeaseTTL = 10 * time . Second
2016-03-01 17:33:35 +00:00
// Note: these requests are sent to Core since Core handles registration
// with the expiration manager and we need the storage to be consistent
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
2017-12-15 18:30:05 +00:00
"period" : 5 ,
2016-03-01 17:33:35 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// This first set of logic is to verify that a normal non-root token will
2016-07-01 15:59:39 +00:00
// be given a TTL of 10 seconds, and that renewing will not cause the TTL to
2016-03-01 17:33:35 +00:00
// increase since that's the configured backend max. Then we verify that
// increment works.
{
req . Path = "auth/token/create"
req . Data = map [ string ] interface { } {
"policies" : [ ] string { "default" } ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:59:39 +00:00
if ttl > 10 {
2016-03-01 17:33:35 +00:00
t . Fatalf ( "TTL too large" )
}
2016-07-01 15:59:39 +00:00
// Let the TTL go down a bit to 8 seconds
2016-03-01 17:33:35 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:59:39 +00:00
if ttl > 8 {
2018-04-03 16:20:20 +00:00
t . Fatalf ( "TTL too large: %d" , ttl )
2016-03-01 17:33:35 +00:00
}
2016-07-01 15:59:39 +00:00
// Renewing should not have the increment increase since we've hit the
// max
2016-03-01 17:33:35 +00:00
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
2021-05-18 21:55:38 +00:00
"increment" : 2 ,
2016-03-01 17:33:35 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:59:39 +00:00
if ttl > 8 {
2016-03-01 17:33:35 +00:00
t . Fatalf ( "TTL too large" )
}
}
// Now we create a token against the role. We should be able to renew;
// increment should be ignored as well.
{
req . ClientToken = root
req . Operation = logical . UpdateOperation
req . Path = "auth/token/create/test"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-03-01 17:33:35 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl > 5 {
t . Fatalf ( "TTL too large (expected %d, got %d" , 5 , ttl )
2016-03-01 17:33:35 +00:00
}
// Let the TTL go down a bit to 3 seconds
2016-08-16 20:47:46 +00:00
time . Sleep ( 3 * time . Second )
2016-03-01 17:33:35 +00:00
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
2021-05-18 21:55:38 +00:00
"increment" : 2 ,
2016-03-01 17:33:35 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-03-01 17:33:35 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-01 17:33:35 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl > 5 {
t . Fatalf ( "TTL too large (expected %d, got %d" , 5 , ttl )
2016-03-01 17:33:35 +00:00
}
}
}
2016-05-11 20:51:18 +00:00
func TestTokenStore_RoleExplicitMaxTTL ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
2016-05-11 20:51:18 +00:00
core . defaultLeaseTTL = 5 * time . Second
core . maxLeaseTTL = 5 * time . Hour
// Note: these requests are sent to Core since Core handles registration
// with the expiration manager and we need the storage to be consistent
2016-05-11 22:46:55 +00:00
// Make sure we can't make it larger than the system/mount max; we should get a warning on role write and an error on token creation
2016-05-11 20:51:18 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
2016-05-11 22:46:55 +00:00
"explicit_max_ttl" : "100h" ,
2016-05-11 20:51:18 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
2016-05-11 22:46:55 +00:00
if resp == nil {
t . Fatalf ( "expected a warning" )
}
req . Operation = logical . UpdateOperation
req . Path = "auth/token/create/test"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-06-08 19:25:17 +00:00
if err != nil {
2016-05-11 22:46:55 +00:00
t . Fatalf ( "expected an error" )
}
2017-06-05 14:52:43 +00:00
if len ( resp . Warnings ) == 0 {
2016-06-08 19:25:17 +00:00
t . Fatalf ( "expected a warning" )
}
2016-05-11 22:46:55 +00:00
// Reset to a good explicit max
req = logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
2016-07-01 15:37:27 +00:00
"explicit_max_ttl" : "10s" ,
2016-05-11 22:46:55 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 22:46:55 +00:00
}
2016-05-11 20:51:18 +00:00
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// This first set of logic is to verify that a normal non-root token will
// be given a TTL of 5 seconds, and that renewing will cause the TTL to
// increase
{
req . Path = "auth/token/create"
req . Data = map [ string ] interface { } {
"policies" : [ ] string { "default" } ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
if ttl > 5 {
t . Fatalf ( "TTL too large" )
}
// Let the TTL go down a bit to 3 seconds
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
if ttl < 4 {
t . Fatalf ( "TTL too small after renewal" )
}
}
// Now we create a token against the role. After renew our max should still
// be the same.
{
req . ClientToken = root
req . Operation = logical . UpdateOperation
req . Path = "auth/token/create/test"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-05-11 20:51:18 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:37:27 +00:00
if ttl > 10 {
2016-05-11 20:51:18 +00:00
t . Fatalf ( "TTL too big" )
}
2018-04-03 16:20:20 +00:00
// explicit max ttl is stored in the role so not returned here
2016-05-11 20:51:18 +00:00
maxTTL := resp . Data [ "explicit_max_ttl" ] . ( int64 )
2018-04-03 16:20:20 +00:00
if maxTTL != 0 {
t . Fatalf ( "expected 0 for explicit max TTL, got %d" , maxTTL )
2016-05-11 20:51:18 +00:00
}
2016-07-01 15:37:27 +00:00
// Let the TTL go down a bit to ~7 seconds (8 against explicit max)
2016-05-11 20:51:18 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
"increment" : 300 ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:37:27 +00:00
if ttl > 8 {
2018-04-03 16:20:20 +00:00
t . Fatalf ( "TTL too big: %d" , ttl )
2016-05-11 20:51:18 +00:00
}
2016-07-01 15:37:27 +00:00
// Let the TTL go down a bit more to ~5 seconds (6 against explicit max)
2016-05-11 20:51:18 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
"increment" : 300 ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-05-11 20:51:18 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2016-07-01 15:37:27 +00:00
if ttl > 6 {
2016-05-11 20:51:18 +00:00
t . Fatalf ( "TTL too big" )
}
// It should expire
2016-07-01 15:37:27 +00:00
time . Sleep ( 8 * time . Second )
2016-05-11 20:51:18 +00:00
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
"increment" : 300 ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-05-11 20:51:18 +00:00
if err == nil {
t . Fatalf ( "expected error" )
}
2017-09-05 15:09:00 +00:00
time . Sleep ( 2 * time . Second )
2016-05-11 20:51:18 +00:00
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-09-05 15:09:00 +00:00
if resp != nil && err == nil {
t . Fatalf ( "expected error, response is %#v" , * resp )
}
2016-05-11 20:51:18 +00:00
if err == nil {
t . Fatalf ( "expected error" )
}
}
}
2016-08-13 18:03:22 +00:00
2019-06-14 14:17:04 +00:00
func TestTokenStore_RoleTokenFields ( t * testing . T ) {
c , _ , _ := TestCoreUnsealed ( t )
2021-04-08 16:43:39 +00:00
// c, _, root := TestCoreUnsealed(t)
2019-06-14 14:17:04 +00:00
ts := c . tokenStore
rootContext := namespace . RootContext ( context . Background ( ) )
boundCIDRs , err := parseutil . ParseAddrs ( [ ] string { "127.0.0.1/32" } )
if err != nil {
t . Fatal ( err )
}
// First test the upgrade case. Create a role with values and ensure they
// are reflected properly on read.
{
roleEntry := & tsRoleEntry {
Name : "test" ,
TokenParams : tokenutil . TokenParams {
TokenType : logical . TokenTypeBatch ,
} ,
Period : time . Second ,
ExplicitMaxTTL : time . Hour ,
}
roleEntry . BoundCIDRs = boundCIDRs
ns := namespace . RootNamespace
jsonEntry , err := logical . StorageEntryJSON ( "test" , roleEntry )
if err != nil {
t . Fatal ( err )
}
if err := ts . rolesView ( ns ) . Put ( rootContext , jsonEntry ) ; err != nil {
t . Fatal ( err )
}
// Read it back
roleEntry , err = ts . tokenStoreRole ( rootContext , "test" )
if err != nil {
t . Fatal ( err )
}
expRoleEntry := & tsRoleEntry {
Name : "test" ,
TokenParams : tokenutil . TokenParams {
TokenPeriod : time . Second ,
TokenExplicitMaxTTL : time . Hour ,
TokenBoundCIDRs : boundCIDRs ,
TokenType : logical . TokenTypeBatch ,
} ,
Period : time . Second ,
ExplicitMaxTTL : time . Hour ,
BoundCIDRs : boundCIDRs ,
}
if diff := deep . Equal ( expRoleEntry , roleEntry ) ; diff != nil {
t . Fatal ( diff )
}
}
// Now, read that back through the API and verify we see what we expect
{
req := logical . TestRequest ( t , logical . ReadOperation , "roles/test" )
resp , err := ts . HandleRequest ( rootContext , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
expected := map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : false ,
"period" : int64 ( 1 ) ,
"token_period" : int64 ( 1 ) ,
"allowed_policies" : [ ] string ( nil ) ,
"disallowed_policies" : [ ] string ( nil ) ,
"allowed_policies_glob" : [ ] string ( nil ) ,
"disallowed_policies_glob" : [ ] string ( nil ) ,
"path_suffix" : "" ,
"token_explicit_max_ttl" : int64 ( 3600 ) ,
"explicit_max_ttl" : int64 ( 3600 ) ,
"renewable" : false ,
"token_type" : "batch" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2019-06-14 14:17:04 +00:00
}
if resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected bound cidrs: %s" , resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "bound_cidrs" )
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected token bound cidrs: %s" , resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "token_bound_cidrs" )
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
}
}
// Put values in just the old locations, but through the API
{
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . Data = map [ string ] interface { } {
"explicit_max_ttl" : 7200 ,
2019-07-01 01:03:36 +00:00
"token_type" : "default-service" ,
2019-06-14 14:17:04 +00:00
"period" : 5 ,
"bound_cidrs" : boundCIDRs [ 0 ] . String ( ) ,
}
resp , err := ts . HandleRequest ( rootContext , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req = logical . TestRequest ( t , logical . ReadOperation , "roles/test" )
resp , err = ts . HandleRequest ( rootContext , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
expected := map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : false ,
"period" : int64 ( 5 ) ,
"token_period" : int64 ( 5 ) ,
"allowed_policies" : [ ] string ( nil ) ,
"disallowed_policies" : [ ] string ( nil ) ,
"allowed_policies_glob" : [ ] string ( nil ) ,
"disallowed_policies_glob" : [ ] string ( nil ) ,
"path_suffix" : "" ,
"token_explicit_max_ttl" : int64 ( 7200 ) ,
"explicit_max_ttl" : int64 ( 7200 ) ,
"renewable" : false ,
"token_type" : "default-service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2019-06-14 14:17:04 +00:00
}
if resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected bound cidrs: %s" , resp . Data [ "bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "bound_cidrs" )
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected token bound cidrs: %s" , resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "token_bound_cidrs" )
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
}
}
// Same thing for just the new locations
{
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . Data = map [ string ] interface { } {
"token_explicit_max_ttl" : 5200 ,
"token_type" : "default-service" ,
"token_period" : 7 ,
"token_bound_cidrs" : boundCIDRs [ 0 ] . String ( ) ,
}
resp , err := ts . HandleRequest ( rootContext , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
req = logical . TestRequest ( t , logical . ReadOperation , "roles/test" )
resp , err = ts . HandleRequest ( rootContext , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
expected := map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : false ,
"period" : int64 ( 0 ) ,
"token_period" : int64 ( 7 ) ,
"allowed_policies" : [ ] string ( nil ) ,
"disallowed_policies" : [ ] string ( nil ) ,
"allowed_policies_glob" : [ ] string ( nil ) ,
"disallowed_policies_glob" : [ ] string ( nil ) ,
"path_suffix" : "" ,
"token_explicit_max_ttl" : int64 ( 5200 ) ,
"explicit_max_ttl" : int64 ( 0 ) ,
"renewable" : false ,
"token_type" : "default-service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2019-06-14 14:17:04 +00:00
}
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected token bound cidrs: %s" , resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "token_bound_cidrs" )
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
}
}
// Put values in both locations
{
req := logical . TestRequest ( t , logical . UpdateOperation , "roles/test" )
req . Data = map [ string ] interface { } {
"token_explicit_max_ttl" : 7200 ,
"explicit_max_ttl" : 5200 ,
"token_type" : "service" ,
"token_period" : 5 ,
"period" : 1 ,
"token_bound_cidrs" : boundCIDRs [ 0 ] . String ( ) ,
"bound_cidrs" : boundCIDRs [ 0 ] . String ( ) ,
}
resp , err := ts . HandleRequest ( rootContext , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp == nil {
t . Fatalf ( "expected a non-nil response" )
}
if len ( resp . Warnings ) != 3 {
t . Fatalf ( "expected 3 warnings, got %#v" , resp . Warnings )
}
req = logical . TestRequest ( t , logical . ReadOperation , "roles/test" )
resp , err = ts . HandleRequest ( rootContext , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
expected := map [ string ] interface { } {
2021-09-21 15:25:06 +00:00
"name" : "test" ,
"orphan" : false ,
"period" : int64 ( 0 ) ,
"token_period" : int64 ( 5 ) ,
"allowed_policies" : [ ] string ( nil ) ,
"disallowed_policies" : [ ] string ( nil ) ,
"allowed_policies_glob" : [ ] string ( nil ) ,
"disallowed_policies_glob" : [ ] string ( nil ) ,
"path_suffix" : "" ,
"token_explicit_max_ttl" : int64 ( 7200 ) ,
"explicit_max_ttl" : int64 ( 0 ) ,
"renewable" : false ,
"token_type" : "service" ,
"allowed_entity_aliases" : [ ] string ( nil ) ,
2021-09-21 16:53:08 +00:00
"token_no_default_policy" : false ,
2019-06-14 14:17:04 +00:00
}
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" {
t . Fatalf ( "unexpected token bound cidrs: %s" , resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) )
}
delete ( resp . Data , "token_bound_cidrs" )
if diff := deep . Equal ( expected , resp . Data ) ; diff != nil {
t . Fatal ( diff )
}
}
}
2016-08-13 18:03:22 +00:00
func TestTokenStore_Periodic ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
2016-08-13 18:03:22 +00:00
core . defaultLeaseTTL = 10 * time . Second
core . maxLeaseTTL = 10 * time . Second
// Note: these requests are sent to Core since Core handles registration
// with the expiration manager and we need the storage to be consistent
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
2017-12-15 18:30:05 +00:00
"period" : 5 ,
2016-08-13 18:03:22 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-13 18:03:22 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// First make one directly and verify on renew it uses the period.
{
req . ClientToken = root
req . Operation = logical . UpdateOperation
req . Path = "auth/token/create"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-08-13 18:03:22 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl > 5 {
t . Fatalf ( "TTL too large (expected %d, got %d)" , 5 , ttl )
2016-08-13 18:03:22 +00:00
}
2016-08-14 11:17:14 +00:00
// Let the TTL go down a bit
2016-08-13 18:03:22 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
"increment" : 1 ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-13 18:03:22 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl > 5 {
t . Fatalf ( "TTL too large (expected %d, got %d)" , 5 , ttl )
2016-08-13 18:03:22 +00:00
}
}
2018-04-03 16:20:20 +00:00
// Now we create a token against the role and also set the te value
// directly. We should use the smaller of the two and be able to renew;
// increment should be ignored as well.
2016-08-13 18:03:22 +00:00
{
req . ClientToken = root
req . Operation = logical . UpdateOperation
2018-04-03 16:20:20 +00:00
req . Path = "auth/token/create/test"
2016-08-13 18:03:22 +00:00
req . Data = map [ string ] interface { } {
2018-04-03 16:20:20 +00:00
"period" : 5 ,
2016-08-13 18:03:22 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-13 18:03:22 +00:00
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-08-13 18:03:22 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2018-04-03 16:20:20 +00:00
if ttl < 4 || ttl > 5 {
t . Fatalf ( "TTL bad (expected %d, got %d)" , 4 , ttl )
2016-08-13 18:03:22 +00:00
}
2016-08-14 11:17:14 +00:00
// Let the TTL go down a bit
2016-08-13 18:03:22 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
2018-04-03 16:20:20 +00:00
"increment" : 1 ,
2016-08-13 18:03:22 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-13 18:03:22 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2018-04-03 16:20:20 +00:00
if ttl > 5 {
t . Fatalf ( "TTL bad (expected less than %d, got %d)" , 5 , ttl )
2016-08-13 18:03:22 +00:00
}
}
2018-04-03 16:20:20 +00:00
}
2016-08-13 18:03:22 +00:00
2019-06-14 14:17:04 +00:00
func testTokenStore_NumUses_ErrorCheckHelper ( t * testing . T , resp * logical . Response , err error ) {
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
}
func testTokenStore_NumUses_SelfLookupHelper ( t * testing . T , core * Core , clientToken string , expectedNumUses int ) {
req := logical . TestRequest ( t , logical . ReadOperation , "auth/token/lookup-self" )
req . ClientToken = clientToken
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Just used the token, this should decrement the num_uses counter
expectedNumUses = expectedNumUses - 1
actualNumUses := resp . Data [ "num_uses" ] . ( int )
if actualNumUses != expectedNumUses {
t . Fatalf ( "num_uses mismatch (expected %d, got %d)" , expectedNumUses , actualNumUses )
}
}
2021-04-08 16:43:39 +00:00
2019-06-14 14:17:04 +00:00
func TestTokenStore_NumUses ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
roleNumUses := 10
lesserNumUses := 5
greaterNumUses := 15
// Create a test role with limited token_num_uses
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test-limited-uses" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"token_num_uses" : roleNumUses ,
}
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// Create a test role with unlimited token_num_uses
req . Path = "auth/token/roles/test-unlimited-uses"
req . Data = map [ string ] interface { } { }
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// Generate some tokens from the test roles
req . Path = "auth/token/create/test-limited-uses"
// first token, num_uses is expected to come from the limited uses role
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
testTokenStore_NumUses_ErrorCheckHelper ( t , resp , err )
noOverrideToken := resp . Auth . ClientToken
// second token, override num_uses with a lesser value, this should become the value
// applied to the token
req . Data = map [ string ] interface { } {
"num_uses" : lesserNumUses ,
}
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
testTokenStore_NumUses_ErrorCheckHelper ( t , resp , err )
lesserOverrideToken := resp . Auth . ClientToken
// third token, override num_uses with a greater value, the value
// applied to the token should come from the limited uses role
req . Data = map [ string ] interface { } {
"num_uses" : greaterNumUses ,
}
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
testTokenStore_NumUses_ErrorCheckHelper ( t , resp , err )
greaterOverrideToken := resp . Auth . ClientToken
// fourth token, override num_uses with a zero value, a num_uses value of zero
// has an internal meaning of unlimited so num_uses == 1 is actually less than
// num_uses == 0. In this case, the lesser value of the limited-uses role should be applied.
req . Data = map [ string ] interface { } {
"num_uses" : 0 ,
}
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
testTokenStore_NumUses_ErrorCheckHelper ( t , resp , err )
zeroOverrideToken := resp . Auth . ClientToken
// fifth token, override num_uses with a value from a role that has unlimited num_uses. num_uses
// should be the specified num_uses parameter at the create endpoint
req . Path = "auth/token/create/test-unlimited-uses"
req . Data = map [ string ] interface { } {
"num_uses" : lesserNumUses ,
}
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
testTokenStore_NumUses_ErrorCheckHelper ( t , resp , err )
unlimitedRoleOverrideToken := resp . Auth . ClientToken
testTokenStore_NumUses_SelfLookupHelper ( t , core , noOverrideToken , roleNumUses )
testTokenStore_NumUses_SelfLookupHelper ( t , core , lesserOverrideToken , lesserNumUses )
testTokenStore_NumUses_SelfLookupHelper ( t , core , greaterOverrideToken , roleNumUses )
testTokenStore_NumUses_SelfLookupHelper ( t , core , zeroOverrideToken , roleNumUses )
testTokenStore_NumUses_SelfLookupHelper ( t , core , unlimitedRoleOverrideToken , lesserNumUses )
}
2018-04-03 16:20:20 +00:00
func TestTokenStore_Periodic_ExplicitMax ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
2018-04-03 16:20:20 +00:00
core . defaultLeaseTTL = 10 * time . Second
core . maxLeaseTTL = 10 * time . Second
// Note: these requests are sent to Core since Core handles registration
// with the expiration manager and we need the storage to be consistent
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/token/roles/test" )
req . ClientToken = root
req . Data = map [ string ] interface { } {
"period" : 5 ,
}
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2018-04-03 16:20:20 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
// First make one directly and verify on renew it uses the period.
2016-08-13 18:03:22 +00:00
{
req . ClientToken = root
req . Operation = logical . UpdateOperation
2018-04-03 16:20:20 +00:00
req . Path = "auth/token/create"
2016-08-13 18:03:22 +00:00
req . Data = map [ string ] interface { } {
2018-04-03 16:20:20 +00:00
"period" : 5 ,
"explicit_max_ttl" : 4 ,
2016-08-13 18:03:22 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
2018-04-03 16:20:20 +00:00
t . Fatal ( err )
2016-08-13 18:03:22 +00:00
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-08-13 18:03:22 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2018-04-03 16:20:20 +00:00
if ttl < 3 || ttl > 4 {
t . Fatalf ( "TTL bad (expected %d, got %d)" , 3 , ttl )
2016-08-13 18:03:22 +00:00
}
2016-08-14 11:17:14 +00:00
// Let the TTL go down a bit
2016-08-13 18:03:22 +00:00
time . Sleep ( 2 * time . Second )
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
2018-04-03 16:20:20 +00:00
"increment" : 76 ,
2016-08-13 18:03:22 +00:00
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-13 18:03:22 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-13 18:03:22 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2018-04-03 16:20:20 +00:00
if ttl > 2 {
t . Fatalf ( "TTL bad (expected less than %d, got %d)" , 2 , ttl )
2016-08-14 11:17:14 +00:00
}
}
2018-04-03 16:20:20 +00:00
// Now we create a token against the role and also set the te value
// directly. We should use the smaller of the two and be able to renew;
// increment should be ignored as well.
2016-08-14 11:17:14 +00:00
{
req . Path = "auth/token/roles/test"
req . ClientToken = root
2017-12-15 18:30:05 +00:00
req . Operation = logical . UpdateOperation
2016-08-14 11:17:14 +00:00
req . Data = map [ string ] interface { } {
2017-12-15 18:30:05 +00:00
"period" : 5 ,
"explicit_max_ttl" : 4 ,
}
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2017-12-15 18:30:05 +00:00
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
2016-08-14 11:17:14 +00:00
}
req . ClientToken = root
req . Operation = logical . UpdateOperation
req . Path = "auth/token/create/test"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-14 11:17:14 +00:00
}
if resp == nil {
t . Fatal ( "response was nil" )
}
if resp . Auth == nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( fmt . Sprintf ( "response auth was nil, resp is %#v" , * resp ) )
2016-08-14 11:17:14 +00:00
}
if resp . Auth . ClientToken == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req . ClientToken = resp . Auth . ClientToken
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-14 11:17:14 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl := resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl < 3 || ttl > 4 {
t . Fatalf ( "TTL bad (expected %d, got %d)" , 3 , ttl )
2016-08-14 11:17:14 +00:00
}
// Let the TTL go down a bit
2017-12-15 18:30:05 +00:00
time . Sleep ( 2 * time . Second )
2016-08-14 11:17:14 +00:00
req . Operation = logical . UpdateOperation
req . Path = "auth/token/renew-self"
req . Data = map [ string ] interface { } {
"increment" : 1 ,
}
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-08-14 11:17:14 +00:00
}
req . Operation = logical . ReadOperation
req . Path = "auth/token/lookup-self"
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-14 11:17:14 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
ttl = resp . Data [ "ttl" ] . ( int64 )
2017-12-15 18:30:05 +00:00
if ttl > 2 {
t . Fatalf ( "TTL bad (expected less than %d, got %d)" , 2 , ttl )
2016-08-13 18:03:22 +00:00
}
}
}
2016-12-16 05:36:39 +00:00
func TestTokenStore_NoDefaultPolicy ( t * testing . T ) {
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
2016-12-16 05:36:39 +00:00
ps := core . policyStore
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , tokenCreationPolicy )
2016-12-16 05:36:39 +00:00
policy . Name = "policy1"
2018-11-05 16:11:32 +00:00
if err := ps . SetPolicy ( namespace . RootContext ( nil ) , policy ) ; err != nil {
2016-12-16 05:36:39 +00:00
t . Fatal ( err )
}
// Root token creates a token with desired policy. The created token
// should also have 'default' attached to it.
tokenData := map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
}
tokenReq := & logical . Request {
Path : "create" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : tokenData ,
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy, default]; actual: %s" , resp . Auth . Policies )
}
newToken := resp . Auth . ClientToken
// Root token creates a token with desired policy, but also requests
// that the token to not have 'default' policy. The resulting token
// should not have 'default' policy on it.
tokenData [ "no_default_policy" ] = true
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
// A non-root token which has 'default' policy attached requests for a
// child token. Child token should also have 'default' policy attached.
tokenReq . ClientToken = newToken
tokenReq . Data = nil
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [default policy1]; actual: %s" , resp . Auth . Policies )
}
2018-02-01 17:01:46 +00:00
// A non-root token which has 'default' policy attached and period explicitly
// set to its zero value requests for a child token. Child token should be
// successfully created and have 'default' policy attached.
tokenReq . Data = map [ string ] interface { } {
"period" : "0s" ,
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2018-02-01 17:01:46 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [default policy1]; actual: %s" , resp . Auth . Policies )
}
2016-12-16 05:36:39 +00:00
// A non-root token which has 'default' policy attached, request for a
// child token to not have 'default' policy while not sending a list
tokenReq . Data = map [ string ] interface { } {
"no_default_policy" : true ,
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
// In this case "default" shouldn't exist because we are not inheriting
// parent policies
tokenReq . Data = map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
"no_default_policy" : true ,
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
// This is a non-root token which does not have 'default' policy
// attached
newToken = resp . Auth . ClientToken
tokenReq . Data = nil
tokenReq . ClientToken = newToken
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
roleReq := & logical . Request {
ClientToken : root ,
Path : "roles/role1" ,
Operation : logical . CreateOperation ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
tokenReq . Path = "create/role1"
tokenReq . Data = map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
// If 'allowed_policies' in role does not have 'default' in it, the
// tokens generated using that role should still have the 'default' policy
// attached to them.
roleReq . Operation = logical . UpdateOperation
roleReq . Data = map [ string ] interface { } {
"allowed_policies" : "policy1" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [default policy1]; actual: %s" , resp . Auth . Policies )
}
// If 'allowed_policies' in role does not have 'default' in it, the
// tokens generated using that role should not have 'default' policy
// attached to them if disallowed_policies contains "default"
roleReq . Operation = logical . UpdateOperation
roleReq . Data = map [ string ] interface { } {
"allowed_policies" : "policy1" ,
"disallowed_policies" : "default" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
roleReq . Data = map [ string ] interface { } {
"allowed_policies" : "" ,
"disallowed_policies" : "default" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
2018-06-03 22:14:51 +00:00
resp = testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 05:36:39 +00:00
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy1]; actual: %s" , resp . Auth . Policies )
}
// Ensure that if default is in both allowed and disallowed, disallowed wins
roleReq . Data = map [ string ] interface { } {
"allowed_policies" : "default" ,
"disallowed_policies" : "default" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
delete ( tokenReq . Data , "policies" )
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err == nil || ( resp != nil && ! resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
}
func TestTokenStore_AllowedDisallowedPolicies ( t * testing . T ) {
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-12-16 05:36:39 +00:00
roleReq := & logical . Request {
ClientToken : root ,
Path : "roles/role1" ,
Operation : logical . CreateOperation ,
Data : map [ string ] interface { } {
"allowed_policies" : "allowed1,allowed2" ,
"disallowed_policies" : "disallowed1,disallowed2" ,
} ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
tokenReq := & logical . Request {
Path : "create/role1" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "allowed1" } ,
} ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
expected := [ ] string { "allowed1" , "default" }
if ! reflect . DeepEqual ( resp . Auth . Policies , expected ) {
t . Fatalf ( "bad: expected:%#v actual:%#v" , expected , resp . Auth . Policies )
}
// Try again with automatic default adding turned off
tokenReq = & logical . Request {
Path : "create/role1" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "allowed1" } ,
"no_default_policy" : true ,
} ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
expected = [ ] string { "allowed1" }
if ! reflect . DeepEqual ( resp . Auth . Policies , expected ) {
t . Fatalf ( "bad: expected:%#v actual:%#v" , expected , resp . Auth . Policies )
}
tokenReq . Data = map [ string ] interface { } {
"policies" : [ ] string { "disallowed1" } ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err == nil {
t . Fatalf ( "expected an error" )
}
roleReq . Operation = logical . UpdateOperation
roleReq . Data = map [ string ] interface { } {
"allowed_policies" : "allowed1,common" ,
"disallowed_policies" : "disallowed1,common" ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , roleReq )
2016-12-16 05:36:39 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v, resp: %v" , err , resp )
}
tokenReq . Data = map [ string ] interface { } {
"policies" : [ ] string { "allowed1" , "common" } ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 05:36:39 +00:00
if err == nil {
t . Fatalf ( "expected an error" )
}
}
2016-12-16 18:11:55 +00:00
// Issue 2189
func TestTokenStore_RevokeUseCountToken ( t * testing . T ) {
var resp * logical . Response
var err error
cubbyFuncLock := & sync . RWMutex { }
cubbyFuncLock . Lock ( )
exp := mockExpiration ( t )
ts := exp . tokenStore
2018-11-05 16:11:32 +00:00
root , _ := exp . tokenStore . rootToken ( namespace . RootContext ( nil ) )
2016-12-16 18:11:55 +00:00
tokenReq := & logical . Request {
Path : "create" ,
ClientToken : root . ID ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"num_uses" : 1 ,
} ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tokenReq )
2016-12-16 18:11:55 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
tut := resp . Auth . ClientToken
2018-11-05 16:11:32 +00:00
saltTut , err := ts . SaltID ( namespace . RootContext ( nil ) , tut )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
te , err := ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , false )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "nil entry" )
}
if te . NumUses != 1 {
t . Fatalf ( "bad: %d" , te . NumUses )
}
2018-11-05 16:11:32 +00:00
te , err = ts . UseToken ( namespace . RootContext ( nil ) , te )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "nil entry" )
}
2018-05-10 19:50:02 +00:00
if te . NumUses != tokenRevocationPending {
2016-12-16 18:11:55 +00:00
t . Fatalf ( "bad: %d" , te . NumUses )
}
// Should return no entry because it's tainted
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , false )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te != nil {
t . Fatalf ( "%#v" , te )
}
// But it should show up in an API lookup call
req := & logical . Request {
Path : "lookup-self" ,
ClientToken : tut ,
Operation : logical . UpdateOperation ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil || resp . Data == nil || resp . Data [ "num_uses" ] == nil {
t . Fatal ( "nil resp or data" )
}
if resp . Data [ "num_uses" ] . ( int ) != - 1 {
t . Fatalf ( "bad: %v" , resp . Data [ "num_uses" ] )
}
// Should return tainted entries
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , true )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "nil entry" )
}
2018-05-10 19:50:02 +00:00
if te . NumUses != tokenRevocationPending {
2016-12-16 18:11:55 +00:00
t . Fatalf ( "bad: %d" , te . NumUses )
}
origDestroyCubbyhole := ts . cubbyholeDestroyer
2018-09-18 03:03:00 +00:00
ts . cubbyholeDestroyer = func ( context . Context , * TokenStore , * logical . TokenEntry ) error {
2016-12-16 18:11:55 +00:00
return fmt . Errorf ( "keep it frosty" )
}
2018-11-05 16:11:32 +00:00
err = ts . revokeInternal ( namespace . RootContext ( nil ) , saltTut , false )
2016-12-16 18:11:55 +00:00
if err == nil {
t . Fatalf ( "expected err" )
}
2018-05-10 19:50:02 +00:00
// Since revocation failed we should still be able to get a token
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , true )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
2018-05-10 19:50:02 +00:00
t . Fatal ( "nil token entry" )
2016-12-16 18:11:55 +00:00
}
// Check the race condition situation by making the process sleep
2018-09-18 03:03:00 +00:00
ts . cubbyholeDestroyer = func ( context . Context , * TokenStore , * logical . TokenEntry ) error {
2016-12-16 18:11:55 +00:00
time . Sleep ( 1 * time . Second )
return fmt . Errorf ( "keep it frosty" )
}
cubbyFuncLock . Unlock ( )
2019-09-18 21:18:08 +00:00
errCh := make ( chan error )
defer close ( errCh )
2016-12-16 18:11:55 +00:00
go func ( ) {
cubbyFuncLock . RLock ( )
2018-11-05 16:11:32 +00:00
err := ts . revokeInternal ( namespace . RootContext ( nil ) , saltTut , false )
2016-12-16 18:11:55 +00:00
cubbyFuncLock . RUnlock ( )
2019-09-18 21:18:08 +00:00
errCh <- err
2016-12-16 18:11:55 +00:00
} ( )
// Give time for the function to start and grab locks
time . Sleep ( 200 * time . Millisecond )
2019-09-18 21:18:08 +00:00
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , true )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
2018-05-10 19:50:02 +00:00
t . Fatal ( "nil token entry" )
2016-12-16 18:11:55 +00:00
}
2019-09-18 21:18:08 +00:00
err = <- errCh
if err == nil {
t . Fatal ( "expected error on ts.revokeInternal() in anonymous goroutine" )
}
2016-12-16 18:11:55 +00:00
// Put back to normal
cubbyFuncLock . Lock ( )
defer cubbyFuncLock . Unlock ( )
ts . cubbyholeDestroyer = origDestroyCubbyhole
2018-11-05 16:11:32 +00:00
err = ts . revokeInternal ( namespace . RootContext ( nil ) , saltTut , false )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltTut , true , true )
2016-12-16 18:11:55 +00:00
if err != nil {
t . Fatal ( err )
}
if te != nil {
t . Fatal ( "found entry" )
}
}
2016-12-16 20:29:27 +00:00
// Create a token, delete the token entry while leaking accessors, invoke tidy
// and check if the dangling accessor entry is getting removed
func TestTokenStore_HandleTidyCase1 ( t * testing . T ) {
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2016-12-16 20:29:27 +00:00
// List the number of accessors. Since there is only root token
// present, the list operation should return only one key.
accessorListReq := & logical . Request {
Operation : logical . ListOperation ,
2018-03-26 18:21:36 +00:00
Path : "accessors/" ,
2016-12-16 20:29:27 +00:00
ClientToken : root ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2016-12-16 20:29:27 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
numberOfAccessors := len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != 1 {
t . Fatalf ( "bad: number of accessors. Expected: 1, Actual: %d" , numberOfAccessors )
}
2016-12-16 20:40:34 +00:00
for i := 1 ; i <= 100 ; i ++ {
// Create a regular token
tokenReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "create" ,
ClientToken : root ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
} ,
}
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , tokenReq )
2016-12-16 20:40:34 +00:00
tut := resp . Auth . ClientToken
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
// Creation of another token should end up with incrementing
// the number of accessors
// the storage
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2016-12-16 20:40:34 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
numberOfAccessors = len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != i + 1 {
t . Fatalf ( "bad: number of accessors. Expected: %d, Actual: %d" , i + 1 , numberOfAccessors )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
// Revoke the token while leaking other items associated with the
// token. Do this by doing what revokeSalted used to do before it was
// fixed, i.e., by deleting the storage entry for token and its
// cubbyhole and by not deleting its secondary index, its accessor and
// associated leases.
2016-12-16 20:29:27 +00:00
2018-11-05 16:11:32 +00:00
saltedTut , err := ts . SaltID ( namespace . RootContext ( nil ) , tut )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
te , err := ts . lookupInternal ( namespace . RootContext ( nil ) , saltedTut , true , true )
2016-12-16 20:40:34 +00:00
if err != nil {
t . Fatalf ( "failed to lookup token: %v" , err )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
// Destroy the token index
2018-11-05 16:11:32 +00:00
if ts . idView ( namespace . RootNamespace ) . Delete ( namespace . RootContext ( nil ) , saltedTut ) ; err != nil {
2016-12-16 20:40:34 +00:00
t . Fatalf ( "failed to delete token entry: %v" , err )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
// Destroy the cubby space
2018-11-05 16:11:32 +00:00
err = ts . cubbyholeDestroyer ( namespace . RootContext ( nil ) , ts , te )
2016-12-16 20:40:34 +00:00
if err != nil {
t . Fatalf ( "failed to destroyCubbyhole: %v" , err )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
// Leaking of accessor should have resulted in no change to the number
// of accessors
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2016-12-16 20:40:34 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2016-12-16 20:29:27 +00:00
2016-12-16 20:40:34 +00:00
numberOfAccessors = len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != i + 1 {
t . Fatalf ( "bad: number of accessors. Expected: %d, Actual: %d" , i + 1 , numberOfAccessors )
}
2016-12-16 20:29:27 +00:00
}
tidyReq := & logical . Request {
Path : "tidy" ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tidyReq )
2016-12-16 20:29:27 +00:00
if err != nil {
t . Fatal ( err )
}
if resp != nil && resp . IsError ( ) {
t . Fatalf ( "resp: %#v" , resp )
}
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2018-06-16 22:21:33 +00:00
// Tidy runs async so give it time
time . Sleep ( 10 * time . Second )
2016-12-16 20:40:34 +00:00
// Tidy should have removed all the dangling accessor entries
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2016-12-16 20:29:27 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
numberOfAccessors = len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != 1 {
t . Fatalf ( "bad: number of accessors. Expected: 1, Actual: %d" , numberOfAccessors )
}
}
2016-12-16 21:46:29 +00:00
2018-03-27 15:12:06 +00:00
// Create a set of tokens along with a child token for each of them, delete the
// token entry while leaking accessors, invoke tidy and check if the dangling
// accessor entry is getting removed and check if child tokens are still present
// and turned into orphan tokens.
func TestTokenStore_HandleTidy_parentCleanup ( t * testing . T ) {
var resp * logical . Response
var err error
2018-06-03 22:14:51 +00:00
c , _ , root := TestCoreUnsealed ( t )
ts := c . tokenStore
2018-03-27 15:12:06 +00:00
// List the number of accessors. Since there is only root token
// present, the list operation should return only one key.
accessorListReq := & logical . Request {
Operation : logical . ListOperation ,
Path : "accessors/" ,
ClientToken : root ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2018-03-27 15:12:06 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
numberOfAccessors := len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != 1 {
t . Fatalf ( "bad: number of accessors. Expected: 1, Actual: %d" , numberOfAccessors )
}
for i := 1 ; i <= 100 ; i ++ {
// Create a token
tokenReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "create" ,
ClientToken : root ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
} ,
}
2018-06-03 22:14:51 +00:00
resp := testMakeTokenViaRequest ( t , ts , tokenReq )
2018-03-27 15:12:06 +00:00
tut := resp . Auth . ClientToken
// Create a child token
tokenReq = & logical . Request {
Operation : logical . UpdateOperation ,
Path : "create" ,
ClientToken : tut ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
} ,
}
2018-06-03 22:14:51 +00:00
testMakeTokenViaRequest ( t , ts , tokenReq )
2018-03-27 15:12:06 +00:00
// Creation of another token should end up with incrementing the number of
// accessors the storage
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2018-03-27 15:12:06 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
numberOfAccessors = len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != ( i * 2 ) + 1 {
t . Fatalf ( "bad: number of accessors. Expected: %d, Actual: %d" , i + 1 , numberOfAccessors )
}
// Revoke the token while leaking other items associated with the
// token. Do this by doing what revokeSalted used to do before it was
// fixed, i.e., by deleting the storage entry for token and its
// cubbyhole and by not deleting its secondary index, its accessor and
// associated leases.
2018-11-05 16:11:32 +00:00
saltedTut , err := ts . SaltID ( namespace . RootContext ( nil ) , tut )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
te , err := ts . lookupInternal ( namespace . RootContext ( nil ) , saltedTut , true , true )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatalf ( "failed to lookup token: %v" , err )
}
// Destroy the token index
2018-11-05 16:11:32 +00:00
if ts . idView ( namespace . RootNamespace ) . Delete ( namespace . RootContext ( nil ) , saltedTut ) ; err != nil {
2018-03-27 15:12:06 +00:00
t . Fatalf ( "failed to delete token entry: %v" , err )
}
// Destroy the cubby space
2018-11-05 16:11:32 +00:00
err = ts . cubbyholeDestroyer ( namespace . RootContext ( nil ) , ts , te )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatalf ( "failed to destroyCubbyhole: %v" , err )
}
// Leaking of accessor should have resulted in no change to the number
// of accessors
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2018-03-27 15:12:06 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
numberOfAccessors = len ( resp . Data [ "keys" ] . ( [ ] string ) )
if numberOfAccessors != ( i * 2 ) + 1 {
t . Fatalf ( "bad: number of accessors. Expected: %d, Actual: %d" , ( i * 2 ) + 1 , numberOfAccessors )
}
}
tidyReq := & logical . Request {
Path : "tidy" ,
Operation : logical . UpdateOperation ,
ClientToken : root ,
}
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , tidyReq )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatal ( err )
}
if resp != nil && resp . IsError ( ) {
t . Fatalf ( "resp: %#v" , resp )
}
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
2018-06-16 22:21:33 +00:00
// Tidy runs async so give it time
time . Sleep ( 10 * time . Second )
2018-03-27 15:12:06 +00:00
// Tidy should have removed all the dangling accessor entries
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , accessorListReq )
2018-03-27 15:12:06 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%v" , err , resp )
}
// The number of accessors should be equal to number of valid child tokens
// (100) + the root token (1)
keys := resp . Data [ "keys" ] . ( [ ] string )
numberOfAccessors = len ( keys )
if numberOfAccessors != 101 {
t . Fatalf ( "bad: number of accessors. Expected: 1, Actual: %d" , numberOfAccessors )
}
req := logical . TestRequest ( t , logical . UpdateOperation , "lookup-accessor" )
for _ , accessor := range keys {
req . Data = map [ string ] interface { } {
"accessor" : accessor ,
}
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-03-27 15:12:06 +00:00
if err != nil {
t . Fatalf ( "err: %s" , err )
}
if resp . Data == nil {
t . Fatalf ( "response should contain data" )
}
// These tokens should now be orphaned
if resp . Data [ "orphan" ] != true {
t . Fatalf ( "token should be orphan" )
}
}
}
2016-12-16 21:46:29 +00:00
func TestTokenStore_TidyLeaseRevocation ( t * testing . T ) {
exp := mockExpiration ( t )
ts := exp . tokenStore
noop := & NoopBackend { }
_ , barrier , _ := mockBarrier ( t )
view := NewBarrierView ( barrier , "logical/" )
meUUID , err := uuid . GenerateUUID ( )
if err != nil {
t . Fatal ( err )
}
2018-09-18 03:03:00 +00:00
err = exp . router . Mount ( noop , "prod/aws/" , & MountEntry { UUID : meUUID , Accessor : "awsaccessor" , namespace : namespace . RootNamespace } , view )
2017-07-01 20:06:15 +00:00
if err != nil {
t . Fatal ( err )
}
2016-12-16 21:46:29 +00:00
// Create new token
2018-11-05 16:11:32 +00:00
root , err := ts . rootToken ( namespace . RootContext ( nil ) )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-09-18 03:03:00 +00:00
// Create a new token
2016-12-16 21:46:29 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "create" )
req . ClientToken = root . ID
req . Data [ "policies" ] = [ ] string { "default" }
2018-11-05 16:11:32 +00:00
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-29 11:47:42 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v\nresp: %#v" , err , resp )
2016-12-16 21:46:29 +00:00
}
auth := & logical . Auth {
ClientToken : resp . Auth . ClientToken ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
Renewable : true ,
} ,
}
2018-09-18 03:03:00 +00:00
te := & logical . TokenEntry {
Path : resp . Auth . CreationPath ,
NamespaceID : namespace . RootNamespaceID ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-09-18 03:03:00 +00:00
// Verify token entry through lookup
2018-11-05 16:11:32 +00:00
testTokenEntry , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatal ( err )
}
if testTokenEntry == nil {
t . Fatal ( "token entry was nil" )
}
2016-12-16 21:46:29 +00:00
tut := resp . Auth . ClientToken
req = & logical . Request {
Path : "prod/aws/foo" ,
ClientToken : tut ,
}
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( testTokenEntry )
2016-12-16 21:46:29 +00:00
resp = & logical . Response {
Secret : & logical . Secret {
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
} ,
}
leases := [ ] string { }
for i := 0 ; i < 10 ; i ++ {
2018-11-05 16:11:32 +00:00
leaseID , err := exp . Register ( namespace . RootContext ( nil ) , req , resp )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatal ( err )
}
2018-05-11 16:12:44 +00:00
leases = append ( leases , leaseID )
2016-12-16 21:46:29 +00:00
}
sort . Strings ( leases )
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , tut , false , true )
2018-09-18 03:03:00 +00:00
if err != nil {
t . Fatalf ( "failed to lookup token: %v" , err )
}
if te == nil {
t . Fatal ( "got nil token entry" )
}
2018-11-05 16:11:32 +00:00
storedLeases , err := exp . lookupLeasesByToken ( namespace . RootContext ( nil ) , te )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatal ( err )
}
sort . Strings ( storedLeases )
if ! reflect . DeepEqual ( leases , storedLeases ) {
t . Fatalf ( "bad: %#v vs %#v" , leases , storedLeases )
}
// Now, delete the token entry. The leases should still exist.
2018-11-05 16:11:32 +00:00
saltedTut , err := ts . SaltID ( namespace . RootContext ( nil ) , tut )
2017-07-18 16:02:03 +00:00
if err != nil {
t . Fatal ( err )
}
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltedTut , true , true )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatalf ( "failed to lookup token: %v" , err )
}
if te == nil {
t . Fatal ( "got nil token entry" )
}
// Destroy the token index
2018-11-05 16:11:32 +00:00
if ts . idView ( namespace . RootNamespace ) . Delete ( namespace . RootContext ( nil ) , saltedTut ) ; err != nil {
2016-12-16 21:46:29 +00:00
t . Fatalf ( "failed to delete token entry: %v" , err )
}
2018-11-05 16:11:32 +00:00
te , err = ts . lookupInternal ( namespace . RootContext ( nil ) , saltedTut , true , true )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatalf ( "failed to lookup token: %v" , err )
}
if te != nil {
t . Fatal ( "got token entry" )
}
// Verify leases still exist
2018-11-05 16:11:32 +00:00
storedLeases , err = exp . lookupLeasesByToken ( namespace . RootContext ( nil ) , testTokenEntry )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatal ( err )
}
sort . Strings ( storedLeases )
if ! reflect . DeepEqual ( leases , storedLeases ) {
t . Fatalf ( "bad: %#v vs %#v" , leases , storedLeases )
}
// Call tidy
2018-11-05 16:11:32 +00:00
ts . handleTidy ( namespace . RootContext ( nil ) , & logical . Request { } , nil )
2016-12-16 21:46:29 +00:00
2018-05-11 16:12:44 +00:00
time . Sleep ( 200 * time . Millisecond )
2018-05-10 19:50:02 +00:00
2016-12-16 21:46:29 +00:00
// Verify leases are gone
2018-11-05 16:11:32 +00:00
storedLeases , err = exp . lookupLeasesByToken ( namespace . RootContext ( nil ) , testTokenEntry )
2016-12-16 21:46:29 +00:00
if err != nil {
t . Fatal ( err )
}
if len ( storedLeases ) > 0 {
t . Fatal ( "found leases" )
}
}
2018-10-15 16:56:24 +00:00
func TestTokenStore_Batch_CannotCreateChildren ( t * testing . T ) {
var resp * logical . Response
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
req := & logical . Request {
Path : "create" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
"type" : "batch" ,
} ,
}
resp = testMakeTokenViaRequest ( t , ts , req )
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy, default]; actual: %s" , resp . Auth . Policies )
}
req . ClientToken = resp . Auth . ClientToken
resp = testMakeTokenViaRequest ( t , ts , req )
if ! resp . IsError ( ) {
t . Fatalf ( "bad: expected error, got %#v" , * resp )
}
}
func TestTokenStore_Batch_CannotRevoke ( t * testing . T ) {
var resp * logical . Response
var err error
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
req := & logical . Request {
Path : "create" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
"type" : "batch" ,
} ,
}
resp = testMakeTokenViaRequest ( t , ts , req )
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy, default]; actual: %s" , resp . Auth . Policies )
}
req . Path = "revoke"
req . Data [ "token" ] = resp . Auth . ClientToken
2018-11-05 16:11:32 +00:00
resp , err = ts . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
}
if ! resp . IsError ( ) {
t . Fatalf ( "bad: expected error, got %#v" , * resp )
}
}
func TestTokenStore_Batch_NoCubbyhole ( t * testing . T ) {
var resp * logical . Response
var err error
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
req := & logical . Request {
Path : "create" ,
ClientToken : root ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "policy1" } ,
"type" : "batch" ,
} ,
}
resp = testMakeTokenViaRequest ( t , ts , req )
if ! reflect . DeepEqual ( resp . Auth . Policies , [ ] string { "default" , "policy1" } ) {
t . Fatalf ( "bad: policies: expected: [policy, default]; actual: %s" , resp . Auth . Policies )
}
2018-11-05 16:11:32 +00:00
te , err := ts . Lookup ( namespace . RootContext ( nil ) , resp . Auth . ClientToken )
2018-10-15 16:56:24 +00:00
if err != nil {
t . Fatal ( err )
}
req . Path = "cubbyhole/foo"
req . Operation = logical . CreateOperation
req . ClientToken = te . ID
req . SetTokenEntry ( te )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-10-15 16:56:24 +00:00
if err != nil && ! errwrap . Contains ( err , logical . ErrInvalidRequest . Error ( ) ) {
t . Fatal ( err )
}
if ! resp . IsError ( ) {
t . Fatalf ( "bad: expected error, got %#v" , * resp )
}
}
2020-04-27 16:39:33 +00:00
func TestTokenStore_TokenID ( t * testing . T ) {
t . Run ( "no custom ID provided" , func ( t * testing . T ) {
c , _ , initToken := TestCoreUnsealed ( t )
ts := c . tokenStore
// Ensure that a regular service token has a "s." prefix
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : initToken ,
Path : "create" ,
Operation : logical . UpdateOperation ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if ! strings . HasPrefix ( resp . Auth . ClientToken , "s." ) {
t . Fatalf ( "token %q does not have a 's.' prefix" , resp . Auth . ClientToken )
}
} )
t . Run ( "plain custom ID" , func ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : root ,
Path : "create" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"id" : "foobar" ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Ensure that using a custom token ID results in a warning
expectedWarning := "Supplying a custom ID for the token uses the weaker SHA1 hashing instead of the more secure SHA2-256 HMAC for token obfuscation. SHA1 hashed tokens on the wire leads to less secure lookups."
if resp . Warnings [ 0 ] != expectedWarning {
t . Fatalf ( "expected warning not present" )
}
} )
t . Run ( "service token prefix in custom ID" , func ( t * testing . T ) {
c , _ , initToken := TestCoreUnsealed ( t )
ts := c . tokenStore
// Ensure that custom token ID having a "s." prefix fails
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : initToken ,
Path : "create" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"id" : "s.foobar" ,
} ,
} )
if err == nil {
t . Fatalf ( "expected an error" )
}
if resp . Error ( ) . Error ( ) != "custom token ID cannot have the 's.' prefix" {
t . Fatalf ( "expected input error not present in error response" )
}
} )
t . Run ( "period in custom ID" , func ( t * testing . T ) {
core , _ , root := TestCoreUnsealed ( t )
ts := core . tokenStore
resp , err := ts . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
ClientToken : root ,
Path : "create" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"id" : "foobar.baz" ,
} ,
} )
if err == nil {
t . Fatalf ( "expected an error" )
}
if resp . Error ( ) . Error ( ) != "custom token ID cannot have a '.' in the value" {
t . Fatalf ( "expected input error not present in error response" )
}
} )
}
2020-06-23 23:36:24 +00:00
func expectInGaugeCollection ( t * testing . T , expectedLabels map [ string ] string , expectedValue float32 , actual [ ] metricsutil . GaugeLabelValues ) {
t . Helper ( )
for _ , glv := range actual {
actualLabels := make ( map [ string ] string )
for _ , l := range glv . Labels {
actualLabels [ l . Name ] = l . Value
}
if labelsMatch ( actualLabels , expectedLabels ) {
if expectedValue != glv . Value {
t . Errorf ( "expeced %v for %v, got %v" , expectedValue , expectedLabels , glv . Value )
}
return
}
}
t . Errorf ( "didn't find labels %v" , expectedLabels )
}
func TestTokenStore_Collectors ( t * testing . T ) {
ctx := namespace . RootContext ( nil )
exp := mockExpiration ( t )
ts := exp . tokenStore
// This helper is defined in expiration.go
sampleToken ( t , exp , "auth/userpass/login" , true , "default" )
sampleToken ( t , exp , "auth/userpass/login" , true , "policy23457" )
sampleToken ( t , exp , "auth/token/create" , false , "root" )
sampleToken ( t , exp , "auth/github/login" , true , "root" )
sampleToken ( t , exp , "auth/github/login" , false , "root" )
waitForRestore ( t , exp )
// By namespace:
values , err := ts . gaugeCollector ( ctx )
if err != nil {
t . Fatalf ( "bad collector run: %v" , err )
}
if len ( values ) != 1 {
t . Errorf ( "got %v values, expected 1" , len ( values ) )
}
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" } ,
5.0 ,
values )
values , err = ts . gaugeCollectorByPolicy ( ctx )
if err != nil {
t . Fatalf ( "bad collector run: %v" , err )
}
if len ( values ) != 3 {
t . Errorf ( "got %v values, expected 3" , len ( values ) )
}
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" , "policy" : "root" } ,
3.0 ,
values )
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" , "policy" : "default" } ,
1.0 ,
values )
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" , "policy" : "policy23457" } ,
1.0 ,
values )
values , err = ts . gaugeCollectorByTtl ( ctx )
if err != nil {
t . Fatalf ( "bad collector run: %v" , err )
}
if len ( values ) != 2 {
t . Errorf ( "got %v values, expected 2" , len ( values ) )
}
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" , "creation_ttl" : "1h" } ,
3.0 ,
values )
expectInGaugeCollection ( t ,
map [ string ] string { "namespace" : "root" , "creation_ttl" : "+Inf" } ,
2.0 ,
values )
// Need to set up router for this to work, TODO
// ts.gaugeCollectorByMethod( ctx )
}