2016-05-30 18:30:01 +00:00
package approle
import (
2018-01-08 18:31:38 +00:00
"context"
2019-07-01 20:30:08 +00:00
"encoding/json"
2019-08-14 13:45:40 +00:00
"fmt"
2016-05-30 18:30:01 +00:00
"reflect"
2017-11-10 16:32:04 +00:00
"strings"
2016-05-30 18:30:01 +00:00
"testing"
"time"
2019-07-01 20:30:08 +00:00
"github.com/go-test/deep"
"github.com/hashicorp/go-sockaddr"
2019-04-12 22:08:46 +00:00
"github.com/hashicorp/vault/sdk/helper/policyutil"
2019-07-01 20:30:08 +00:00
"github.com/hashicorp/vault/sdk/helper/tokenutil"
2019-04-12 21:54:35 +00:00
"github.com/hashicorp/vault/sdk/logical"
2016-05-30 18:30:01 +00:00
"github.com/mitchellh/mapstructure"
)
2018-04-24 21:52:42 +00:00
func TestAppRole_LocalSecretIDsRead ( t * testing . T ) {
2018-04-24 19:48:07 +00:00
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
2018-04-24 21:52:42 +00:00
"local_secret_ids" : true ,
"bind_secret_id" : true ,
2018-04-24 19:48:07 +00:00
}
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/testrole" ,
Storage : storage ,
Data : roleData ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Operation : logical . ReadOperation ,
Storage : storage ,
2018-04-24 21:52:42 +00:00
Path : "role/testrole/local-secret-ids" ,
2018-04-24 19:48:07 +00:00
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-04-24 21:52:42 +00:00
if ! resp . Data [ "local_secret_ids" ] . ( bool ) {
t . Fatalf ( "expected local_secret_ids to be returned" )
2018-04-24 19:48:07 +00:00
}
}
2018-06-05 20:12:11 +00:00
func TestAppRole_LocalNonLocalSecretIDs ( t * testing . T ) {
2018-04-24 15:02:11 +00:00
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
2018-04-24 21:52:42 +00:00
// Create a role with local_secret_ids set
2018-04-24 15:02:11 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole1" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
2018-04-24 21:52:42 +00:00
"policies" : [ ] string { "default" , "role1policy" } ,
"bind_secret_id" : true ,
"local_secret_ids" : true ,
2018-04-24 15:02:11 +00:00
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\n resp: %#v" , err , resp )
}
2018-04-24 21:52:42 +00:00
// Create another role without setting local_secret_ids
2018-04-24 15:02:11 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole2" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"policies" : [ ] string { "default" , "role1policy" } ,
"bind_secret_id" : true ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\n resp: %#v" , err , resp )
}
count := 10
// Create secret IDs on testrole1
for i := 0 ; i < count ; i ++ {
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole1/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
}
// Check the number of secret IDs generated
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole1/secret-id" ,
Operation : logical . ListOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if len ( resp . Data [ "keys" ] . ( [ ] string ) ) != count {
t . Fatalf ( "failed to list secret IDs" )
}
// Create secret IDs on testrole1
for i := 0 ; i < count ; i ++ {
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole2/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
}
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole2/secret-id" ,
Operation : logical . ListOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if len ( resp . Data [ "keys" ] . ( [ ] string ) ) != count {
t . Fatalf ( "failed to list secret IDs" )
}
}
2018-06-05 20:12:11 +00:00
func TestAppRole_UpgradeSecretIDPrefix ( t * testing . T ) {
2018-04-24 13:53:36 +00:00
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
2018-04-24 15:02:11 +00:00
// Create a role entry directly in storage without SecretIDPrefix
err = b . setRoleEntry ( context . Background ( ) , storage , "testrole" , & roleStorageEntry {
2018-04-24 13:53:36 +00:00
RoleID : "testroleid" ,
HMACKey : "testhmackey" ,
Policies : [ ] string { "default" } ,
BindSecretID : true ,
BoundCIDRListOld : "127.0.0.1/18,192.178.1.2/24" ,
2018-04-24 15:02:11 +00:00
} , "" )
if err != nil {
t . Fatal ( err )
2018-04-24 13:53:36 +00:00
}
2018-04-24 15:02:11 +00:00
// Reading the role entry should upgrade it to contain SecretIDPrefix
role , err := b . roleEntry ( context . Background ( ) , storage , "testrole" )
2018-04-24 13:53:36 +00:00
if err != nil {
t . Fatal ( err )
}
2018-04-24 15:02:11 +00:00
if role . SecretIDPrefix == "" {
t . Fatalf ( "expected SecretIDPrefix to be set" )
}
2018-04-24 13:53:36 +00:00
2018-04-24 21:52:42 +00:00
// Ensure that the API response contains local_secret_ids
2018-04-24 13:53:36 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . ReadOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\n resp: %#v" , err , resp )
}
2018-04-24 21:52:42 +00:00
_ , ok := resp . Data [ "local_secret_ids" ]
2018-04-24 14:05:17 +00:00
if ! ok {
2018-04-24 21:52:42 +00:00
t . Fatalf ( "expected local_secret_ids to be present in the response" )
2018-04-24 14:05:17 +00:00
}
}
2018-06-05 20:12:11 +00:00
func TestAppRole_LocalSecretIDImmutability ( t * testing . T ) {
2018-04-24 14:05:17 +00:00
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
2018-04-24 21:52:42 +00:00
"policies" : [ ] string { "default" } ,
"bind_secret_id" : true ,
"bound_cidr_list" : [ ] string { "127.0.0.1/18" , "192.178.1.2/24" } ,
"local_secret_ids" : true ,
2018-04-24 14:05:17 +00:00
}
2018-04-24 21:52:42 +00:00
// Create a role with local_secret_ids set
2018-04-24 14:05:17 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : roleData ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
2018-04-24 21:52:42 +00:00
// Attempt to modify local_secret_ids should fail
2018-04-24 14:05:17 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : roleData ,
} )
2021-07-05 15:00:12 +00:00
if err != nil {
t . Fatal ( err )
}
2018-04-24 15:02:11 +00:00
if resp == nil || ! resp . IsError ( ) {
2018-04-24 21:52:42 +00:00
t . Fatalf ( "expected an error since local_secret_ids can't be overwritten" )
2018-04-24 14:05:17 +00:00
}
2018-04-24 13:53:36 +00:00
}
2018-06-05 20:12:11 +00:00
func TestAppRole_UpgradeBoundCIDRList ( t * testing . T ) {
2018-03-08 22:49:08 +00:00
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"policies" : [ ] string { "default" } ,
"bind_secret_id" : true ,
"bound_cidr_list" : [ ] string { "127.0.0.1/18" , "192.178.1.2/24" } ,
}
// Create a role with bound_cidr_list set
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : roleData ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
// Read the role and check that the bound_cidr_list is set properly
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . ReadOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
expected := [ ] string { "127.0.0.1/18" , "192.178.1.2/24" }
2018-06-20 02:57:11 +00:00
actual := resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string )
2018-03-08 22:49:08 +00:00
if ! reflect . DeepEqual ( expected , actual ) {
2018-06-20 02:57:11 +00:00
t . Fatalf ( "bad: secret_id_bound_cidrs; expected: %#v\nactual: %#v\n" , expected , actual )
2018-03-08 22:49:08 +00:00
}
// Modify the storage entry of the role to hold the old style string typed bound_cidr_list
role := & roleStorageEntry {
RoleID : "testroleid" ,
HMACKey : "testhmackey" ,
Policies : [ ] string { "default" } ,
BindSecretID : true ,
BoundCIDRListOld : "127.0.0.1/18,192.178.1.2/24" ,
2018-04-23 20:31:47 +00:00
SecretIDPrefix : secretIDPrefix ,
2018-03-08 22:49:08 +00:00
}
err = b . setRoleEntry ( context . Background ( ) , storage , "testrole" , role , "" )
if err != nil {
t . Fatal ( err )
}
// Read the role. The upgrade code should have migrated the old type to the new type
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole" ,
Operation : logical . ReadOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: bound_cidr_list; expected: %#v\nactual: %#v\n" , expected , actual )
}
// Create a secret-id by supplying a subset of the role's CIDR blocks with the new type
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"cidr_list" : [ ] string { "127.0.0.1/24" } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
if resp . Data [ "secret_id" ] . ( string ) == "" {
t . Fatalf ( "failed to generate secret-id" )
}
// Check that the backwards compatibility for the string type is not broken
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
Path : "role/testrole/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"cidr_list" : "127.0.0.1/24" ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: err: %v\nresp: %#v" , err , resp )
}
if resp . Data [ "secret_id" ] . ( string ) == "" {
t . Fatalf ( "failed to generate secret-id" )
}
}
2018-06-05 20:12:11 +00:00
func TestAppRole_RoleNameLowerCasing ( t * testing . T ) {
2017-12-11 21:41:17 +00:00
var resp * logical . Response
var err error
var roleID , secretID string
b , storage := createBackendWithStorage ( t )
// Save a role with out LowerCaseRoleName set
role := & roleStorageEntry {
2018-04-23 20:31:47 +00:00
RoleID : "testroleid" ,
HMACKey : "testhmackey" ,
Policies : [ ] string { "default" } ,
BindSecretID : true ,
SecretIDPrefix : secretIDPrefix ,
2017-12-11 21:41:17 +00:00
}
2018-01-19 06:44:44 +00:00
err = b . setRoleEntry ( context . Background ( ) , storage , "testRoleName" , role , "" )
2017-12-11 21:41:17 +00:00
if err != nil {
t . Fatal ( err )
}
secretIDReq := & logical . Request {
Path : "role/testRoleName/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2017-12-11 21:41:17 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
secretID = resp . Data [ "secret_id" ] . ( string )
roleID = "testroleid"
// Regular login flow. This should succeed.
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "login" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"role_id" : roleID ,
"secret_id" : secretID ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Lower case the role name when generating the secret id
secretIDReq . Path = "role/testrolename/secret-id"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2017-12-11 21:41:17 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
secretID = resp . Data [ "secret_id" ] . ( string )
// Login should fail
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "login" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"role_id" : roleID ,
"secret_id" : secretID ,
} ,
} )
if err != nil {
t . Fatal ( err )
}
if resp == nil || ! resp . IsError ( ) {
t . Fatalf ( "expected an error" )
}
// Delete the role and create it again. This time don't directly persist
// it, but route the request to the creation handler so that it sets the
// LowerCaseRoleName to true.
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "role/testRoleName" ,
Operation : logical . DeleteOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
roleReq := & logical . Request {
Path : "role/testRoleName" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"bind_secret_id" : true ,
} ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-12-11 21:41:17 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
// Create secret id with lower cased role name
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "role/testrolename/secret-id" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
secretID = resp . Data [ "secret_id" ] . ( string )
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "role/testrolename/role-id" ,
Operation : logical . ReadOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
roleID = resp . Data [ "role_id" ] . ( string )
// Login should pass
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "login" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"role_id" : roleID ,
"secret_id" : secretID ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr:%v" , resp , err )
}
// Lookup of secret ID should work in case-insensitive manner
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "role/testrolename/secret-id/lookup" ,
Operation : logical . UpdateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"secret_id" : secretID ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if resp == nil {
t . Fatalf ( "failed to lookup secret IDs" )
}
// Listing of secret IDs should work in case-insensitive manner
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , & logical . Request {
2017-12-11 21:41:17 +00:00
Path : "role/testrolename/secret-id" ,
Operation : logical . ListOperation ,
Storage : storage ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
if len ( resp . Data [ "keys" ] . ( [ ] string ) ) != 1 {
t . Fatalf ( "failed to list secret IDs" )
}
}
2017-11-10 16:32:04 +00:00
func TestAppRole_RoleReadSetIndex ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleReq := & logical . Request {
Path : "role/testrole" ,
Operation : logical . CreateOperation ,
Storage : storage ,
Data : map [ string ] interface { } {
"bind_secret_id" : true ,
} ,
}
// Create a role
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-11-10 16:32:04 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\n err: %v\n" , resp , err )
}
roleIDReq := & logical . Request {
Path : "role/testrole/role-id" ,
Operation : logical . ReadOperation ,
Storage : storage ,
}
// Get the role ID
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDReq )
2017-11-10 16:32:04 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\n err: %v\n" , resp , err )
}
roleID := resp . Data [ "role_id" ] . ( string )
// Delete the role ID index
2018-01-19 06:44:44 +00:00
err = b . roleIDEntryDelete ( context . Background ( ) , storage , roleID )
2017-11-10 16:32:04 +00:00
if err != nil {
t . Fatal ( err )
}
// Read the role again. This should add the index and return a warning
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-11-10 16:32:04 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\n err: %v\n" , resp , err )
}
// Check if the warning is being returned
2019-07-01 20:30:08 +00:00
if ! strings . Contains ( resp . Warnings [ 0 ] , "Role identifier was missing an index back to role name." ) {
2017-11-10 16:32:04 +00:00
t . Fatalf ( "bad: expected a warning in the response" )
}
2018-01-19 06:44:44 +00:00
roleIDIndex , err := b . roleIDEntry ( context . Background ( ) , storage , roleID )
2017-11-10 16:32:04 +00:00
if err != nil {
t . Fatal ( err )
}
// Check if the index has been successfully created
if roleIDIndex == nil || roleIDIndex . Name != "testrole" {
t . Fatalf ( "bad: expected role to have an index" )
}
roleReq . Operation = logical . UpdateOperation
roleReq . Data = map [ string ] interface { } {
"bind_secret_id" : true ,
"policies" : "default" ,
}
// Check if updating and reading of roles work and that there are no lock
// contentions dangling due to previous operation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-11-10 16:32:04 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\n err: %v\n" , resp , err )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-11-10 16:32:04 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\n err: %v\n" , resp , err )
}
}
2016-09-19 18:40:43 +00:00
func TestAppRole_CIDRSubset ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"role_id" : "role-id-123" ,
"policies" : "a,b" ,
"bound_cidr_list" : "127.0.0.1/24" ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/testrole1" ,
Storage : storage ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-09-19 18:40:43 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v resp: %#v" , err , resp )
}
secretIDData := map [ string ] interface { } {
"cidr_list" : "127.0.0.1/16" ,
}
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/testrole1/secret-id" ,
Data : secretIDData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2021-10-19 00:29:47 +00:00
if resp != nil {
2016-09-21 23:41:08 +00:00
t . Fatalf ( "resp:%#v" , resp )
2016-09-19 18:40:43 +00:00
}
2016-09-21 23:41:08 +00:00
if err == nil {
t . Fatal ( "expected an error" )
2016-09-19 18:40:43 +00:00
}
roleData [ "bound_cidr_list" ] = "192.168.27.29/16,172.245.30.40/24,10.20.30.40/30"
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-09-19 18:40:43 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err: %v resp: %#v" , err , resp )
}
secretIDData [ "cidr_list" ] = "192.168.27.29/20,172.245.30.40/25,10.20.30.40/32"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2017-07-07 12:23:12 +00:00
if err != nil {
t . Fatal ( err )
}
2016-09-19 18:40:43 +00:00
if resp != nil && resp . IsError ( ) {
t . Fatalf ( "resp: %#v" , resp )
}
}
2016-09-13 20:03:15 +00:00
func TestAppRole_RoleConstraints ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"role_id" : "role-id-123" ,
"policies" : "a,b" ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/testrole1" ,
Storage : storage ,
Data : roleData ,
}
// Set bind_secret_id, which is enabled by default
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-09-13 20:03:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
// Set bound_cidr_list alone by explicitly disabling bind_secret_id
roleReq . Operation = logical . UpdateOperation
roleData [ "bind_secret_id" ] = false
roleData [ "bound_cidr_list" ] = "0.0.0.0/0"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-09-13 20:03:15 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
// Remove both constraints
roleReq . Operation = logical . UpdateOperation
roleData [ "bound_cidr_list" ] = ""
roleData [ "bind_secret_id" ] = false
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-09-13 20:03:15 +00:00
if resp != nil && resp . IsError ( ) {
2017-05-02 03:34:10 +00:00
t . Fatalf ( "err:%v, resp:%#v" , err , resp )
2016-09-13 20:03:15 +00:00
}
if err == nil {
t . Fatalf ( "expected an error" )
}
}
2016-10-14 16:56:29 +00:00
func TestAppRole_RoleIDUpdate ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"role_id" : "role-id-123" ,
"policies" : "a,b" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/testrole1" ,
Storage : storage ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-10-14 16:56:29 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleIDUpdateReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "role/testrole1/role-id" ,
Storage : storage ,
Data : map [ string ] interface { } {
"role_id" : "customroleid" ,
} ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDUpdateReq )
2016-10-14 16:56:29 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/testrole1/secret-id" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-10-14 16:56:29 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
secretID := resp . Data [ "secret_id" ] . ( string )
loginData := map [ string ] interface { } {
"role_id" : "customroleid" ,
"secret_id" : secretID ,
}
loginReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "login" ,
Storage : storage ,
Data : loginData ,
Connection : & logical . Connection {
RemoteAddr : "127.0.0.1" ,
} ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , loginReq )
2016-10-14 16:56:29 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Auth == nil {
t . Fatalf ( "expected a non-nil auth object in the response" )
}
}
2016-05-30 18:30:01 +00:00
func TestAppRole_RoleIDUniqueness ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"role_id" : "role-id-123" ,
"policies" : "a,b" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/testrole1" ,
Storage : storage ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Path = "role/testrole2"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err == nil && ! ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "expected an error: got resp:%#v" , resp )
}
roleData [ "role_id" ] = "role-id-456"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . UpdateOperation
roleData [ "role_id" ] = "role-id-123"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err == nil && ! ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "expected an error: got resp:%#v" , resp )
}
roleReq . Path = "role/testrole1"
roleData [ "role_id" ] = "role-id-456"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err == nil && ! ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "expected an error: got resp:%#v" , resp )
}
roleIDData := map [ string ] interface { } {
"role_id" : "role-id-456" ,
}
roleIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "role/testrole1/role-id" ,
Storage : storage ,
Data : roleIDData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDReq )
2016-05-30 18:30:01 +00:00
if err == nil && ! ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "expected an error: got resp:%#v" , resp )
}
roleIDData [ "role_id" ] = "role-id-123"
roleIDReq . Path = "role/testrole2/role-id"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDReq )
2016-05-30 18:30:01 +00:00
if err == nil && ! ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "expected an error: got resp:%#v" , resp )
}
roleIDData [ "role_id" ] = "role-id-2000"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleIDData [ "role_id" ] = "role-id-1000"
roleIDReq . Path = "role/testrole1/role-id"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
}
func TestAppRole_RoleDeleteSecretID ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
createRole ( t , b , storage , "role1" , "a,b" )
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
// Create 3 secrets on the role
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
listReq := & logical . Request {
Operation : logical . ListOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , listReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
secretIDAccessors := resp . Data [ "keys" ] . ( [ ] string )
if len ( secretIDAccessors ) != 3 {
t . Fatalf ( "bad: len of secretIDAccessors: expected:3 actual:%d" , len ( secretIDAccessors ) )
}
roleReq := & logical . Request {
Operation : logical . DeleteOperation ,
Storage : storage ,
Path : "role/role1" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , listReq )
2016-05-30 18:30:01 +00:00
if err != nil || resp == nil || ( resp != nil && ! resp . IsError ( ) ) {
t . Fatalf ( "expected an error. err:%v resp:%#v" , err , resp )
}
}
func TestAppRole_RoleSecretIDReadDelete ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
2016-08-21 18:42:49 +00:00
createRole ( t , b , storage , "role1" , "a,b" )
secretIDCreateReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDCreateReq )
2016-08-21 18:42:49 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2016-09-29 00:22:37 +00:00
2016-08-21 18:42:49 +00:00
secretID := resp . Data [ "secret_id" ] . ( string )
2016-09-29 00:22:37 +00:00
if secretID == "" {
t . Fatal ( "expected non empty secret ID" )
}
2016-08-21 18:42:49 +00:00
secretIDReq := & logical . Request {
2016-09-29 00:22:37 +00:00
Operation : logical . UpdateOperation ,
2016-08-21 18:42:49 +00:00
Storage : storage ,
2016-09-29 00:22:37 +00:00
Path : "role/role1/secret-id/lookup" ,
Data : map [ string ] interface { } {
"secret_id" : secretID ,
} ,
2016-08-21 18:42:49 +00:00
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-08-21 18:42:49 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data == nil {
t . Fatal ( err )
}
2016-09-29 00:22:37 +00:00
deleteSecretIDReq := & logical . Request {
Operation : logical . DeleteOperation ,
Storage : storage ,
Path : "role/role1/secret-id/destroy" ,
Data : map [ string ] interface { } {
"secret_id" : secretID ,
} ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , deleteSecretIDReq )
2016-08-21 18:42:49 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-08-21 18:42:49 +00:00
if resp != nil && resp . IsError ( ) {
2016-12-21 18:08:27 +00:00
t . Fatalf ( "error response:%#v" , resp )
2016-08-21 18:42:49 +00:00
}
if err != nil {
t . Fatal ( err )
}
}
func TestAppRole_RoleSecretIDAccessorReadDelete ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
2016-05-30 18:30:01 +00:00
createRole ( t , b , storage , "role1" , "a,b" )
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
listReq := & logical . Request {
Operation : logical . ListOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , listReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
hmacSecretID := resp . Data [ "keys" ] . ( [ ] string ) [ 0 ]
hmacReq := & logical . Request {
2016-09-29 00:22:37 +00:00
Operation : logical . UpdateOperation ,
2016-05-30 18:30:01 +00:00
Storage : storage ,
2016-09-29 00:22:37 +00:00
Path : "role/role1/secret-id-accessor/lookup" ,
Data : map [ string ] interface { } {
"secret_id_accessor" : hmacSecretID ,
} ,
2016-05-30 18:30:01 +00:00
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , hmacReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data == nil {
t . Fatal ( err )
}
2016-09-29 00:22:37 +00:00
hmacReq . Path = "role/role1/secret-id-accessor/destroy"
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , hmacReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
hmacReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , hmacReq )
2016-05-30 18:30:01 +00:00
if resp != nil && resp . IsError ( ) {
2017-05-02 03:34:10 +00:00
t . Fatalf ( "err:%v resp:%#v" , err , resp )
2016-05-30 18:30:01 +00:00
}
if err == nil {
t . Fatalf ( "expected an error" )
}
}
2021-10-11 14:07:51 +00:00
func TestAppRoleSecretIDLookup ( t * testing . T ) {
b , storage := createBackendWithStorage ( t )
createRole ( t , b , storage , "role1" , "a,b" )
req := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/role1/secret-id-accessor/lookup" ,
Data : map [ string ] interface { } {
"secret_id_accessor" : "invalid" ,
} ,
}
resp , err := b . HandleRequest ( context . Background ( ) , req )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
expected := & logical . Response {
Data : map [ string ] interface { } {
"http_content_type" : "application/json" ,
"http_raw_body" : ` { "request_id":"","lease_id":"","renewable":false,"lease_duration":0,"data": { "error":"failed to find accessor entry for secret_id_accessor: \"invalid\""},"wrap_info":null,"warnings":null,"auth":null} ` ,
"http_status_code" : 404 ,
} ,
}
if ! reflect . DeepEqual ( resp , expected ) {
t . Fatalf ( "resp:%#v expected:%#v" , resp , expected )
}
}
2016-05-30 18:30:01 +00:00
func TestAppRoleRoleListSecretID ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
createRole ( t , b , storage , "role1" , "a,b" )
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Storage : storage ,
Path : "role/role1/secret-id" ,
}
// Create 5 'secret_id's
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
listReq := & logical . Request {
Operation : logical . ListOperation ,
Storage : storage ,
Path : "role/role1/secret-id/" ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , listReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
secrets := resp . Data [ "keys" ] . ( [ ] string )
if len ( secrets ) != 5 {
t . Fatalf ( "bad: len of secrets: expected:5 actual:%d" , len ( secrets ) )
}
}
func TestAppRole_RoleList ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
createRole ( t , b , storage , "role1" , "a,b" )
createRole ( t , b , storage , "role2" , "c,d" )
createRole ( t , b , storage , "role3" , "e,f" )
createRole ( t , b , storage , "role4" , "g,h" )
createRole ( t , b , storage , "role5" , "i,j" )
listReq := & logical . Request {
Operation : logical . ListOperation ,
Path : "role" ,
Storage : storage ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , listReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
actual := resp . Data [ "keys" ] . ( [ ] string )
expected := [ ] string { "role1" , "role2" , "role3" , "role4" , "role5" }
if ! policyutil . EquivalentPolicies ( actual , expected ) {
t . Fatalf ( "bad: listed roles: expected:%s\nactual:%s" , expected , actual )
}
}
func TestAppRole_RoleSecretID ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"policies" : "p,q,r,s" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/role1" ,
Storage : storage ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleSecretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "role/role1/secret-id" ,
Storage : storage ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleSecretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id" ] . ( string ) == "" {
t . Fatalf ( "failed to generate secret_id" )
}
roleSecretIDReq . Path = "role/role1/custom-secret-id"
roleCustomSecretIDData := map [ string ] interface { } {
"secret_id" : "abcd123" ,
}
roleSecretIDReq . Data = roleCustomSecretIDData
roleSecretIDReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleSecretIDReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id" ] != "abcd123" {
t . Fatalf ( "failed to set specific secret_id to role" )
}
}
func TestAppRole_RoleCRUD ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
2018-06-20 02:57:11 +00:00
"policies" : "p,q,r,s" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"secret_id_bound_cidrs" : "127.0.0.1/32,127.0.0.1/16" ,
2016-05-30 18:30:01 +00:00
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/role1" ,
Storage : storage ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected := map [ string ] interface { } {
2018-06-20 02:57:11 +00:00
"bind_secret_id" : true ,
"policies" : [ ] string { "p" , "q" , "r" , "s" } ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"secret_id_bound_cidrs" : [ ] string { "127.0.0.1/32" , "127.0.0.1/16" } ,
"token_bound_cidrs" : [ ] string { } ,
2018-10-15 16:56:24 +00:00
"token_type" : "default" ,
2016-05-30 18:30:01 +00:00
}
2018-03-08 22:49:08 +00:00
2016-05-30 18:30:01 +00:00
var expectedStruct roleStorageEntry
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
var actualStruct roleStorageEntry
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
expectedStruct . RoleID = actualStruct . RoleID
2019-07-01 20:30:08 +00:00
if diff := deep . Equal ( expectedStruct , actualStruct ) ; diff != nil {
t . Fatal ( diff )
2016-05-30 18:30:01 +00:00
}
roleData = map [ string ] interface { } {
"role_id" : "test_role_id" ,
"policies" : "a,b,c,d" ,
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
}
roleReq . Data = roleData
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected = map [ string ] interface { } {
2017-09-13 15:36:52 +00:00
"policies" : [ ] string { "a" , "b" , "c" , "d" } ,
2016-05-30 18:30:01 +00:00
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
}
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expectedStruct , actualStruct ) {
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v\n" , expectedStruct , actualStruct )
}
// RU for role_id field
roleReq . Path = "role/role1/role-id"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "role_id" ] . ( string ) != "test_role_id" {
t . Fatalf ( "bad: role_id: expected:test_role_id actual:%s\n" , resp . Data [ "role_id" ] . ( string ) )
}
roleReq . Data = map [ string ] interface { } { "role_id" : "custom_role_id" }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "role_id" ] . ( string ) != "custom_role_id" {
t . Fatalf ( "bad: role_id: expected:custom_role_id actual:%s\n" , resp . Data [ "role_id" ] . ( string ) )
}
// RUD for bind_secret_id field
roleReq . Path = "role/role1/bind-secret-id"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "bind_secret_id" : false }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "bind_secret_id" ] . ( bool ) {
t . Fatalf ( "bad: bind_secret_id: expected:false actual:%t\n" , resp . Data [ "bind_secret_id" ] . ( bool ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if ! resp . Data [ "bind_secret_id" ] . ( bool ) {
t . Fatalf ( "expected the default value of 'true' to be set" )
}
2017-03-03 14:31:20 +00:00
// RUD for policies field
2016-05-30 18:30:01 +00:00
roleReq . Path = "role/role1/policies"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "policies" : "a1,b1,c1,d1" }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2017-09-13 15:36:52 +00:00
if ! reflect . DeepEqual ( resp . Data [ "policies" ] . ( [ ] string ) , [ ] string { "a1" , "b1" , "c1" , "d1" } ) {
2016-05-30 18:30:01 +00:00
t . Fatalf ( "bad: policies: actual:%s\n" , resp . Data [ "policies" ] . ( [ ] string ) )
}
2019-07-01 20:30:08 +00:00
if ! reflect . DeepEqual ( resp . Data [ "token_policies" ] . ( [ ] string ) , [ ] string { "a1" , "b1" , "c1" , "d1" } ) {
t . Fatalf ( "bad: policies: actual:%s\n" , resp . Data [ "policies" ] . ( [ ] string ) )
}
2016-05-30 18:30:01 +00:00
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2019-07-01 20:30:08 +00:00
expectedPolicies := [ ] string { }
actualPolicies := resp . Data [ "token_policies" ] . ( [ ] string )
2016-05-30 18:30:01 +00:00
if ! policyutil . EquivalentPolicies ( expectedPolicies , actualPolicies ) {
2019-07-01 20:30:08 +00:00
t . Fatalf ( "bad: token_policies: expected:%s actual:%s" , expectedPolicies , actualPolicies )
2016-05-30 18:30:01 +00:00
}
// RUD for secret-id-num-uses field
roleReq . Path = "role/role1/secret-id-num-uses"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "secret_id_num_uses" : 200 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_num_uses" ] . ( int ) != 200 {
t . Fatalf ( "bad: secret_id_num_uses: expected:200 actual:%d\n" , resp . Data [ "secret_id_num_uses" ] . ( int ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_num_uses" ] . ( int ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
// RUD for secret_id_ttl field
roleReq . Path = "role/role1/secret-id-ttl"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "secret_id_ttl" : 3001 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_ttl" ] . ( time . Duration ) != 3001 {
t . Fatalf ( "bad: secret_id_ttl: expected:3001 actual:%d\n" , resp . Data [ "secret_id_ttl" ] . ( time . Duration ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_ttl" ] . ( time . Duration ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
2017-03-03 14:31:20 +00:00
// RUD for secret-id-num-uses field
roleReq . Path = "role/role1/token-num-uses"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-03-03 14:31:20 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_num_uses" ] . ( int ) != 600 {
t . Fatalf ( "bad: token_num_uses: expected:600 actual:%d\n" , resp . Data [ "token_num_uses" ] . ( int ) )
}
roleReq . Data = map [ string ] interface { } { "token_num_uses" : 60 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-03-03 14:31:20 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-03-03 14:31:20 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_num_uses" ] . ( int ) != 60 {
t . Fatalf ( "bad: token_num_uses: expected:60 actual:%d\n" , resp . Data [ "token_num_uses" ] . ( int ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-03-03 14:31:20 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2017-03-03 14:31:20 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_num_uses" ] . ( int ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
2016-05-30 18:30:01 +00:00
// RUD for 'period' field
roleReq . Path = "role/role1/period"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "period" : 9001 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "period" ] . ( time . Duration ) != 9001 {
t . Fatalf ( "bad: period: expected:9001 actual:%d\n" , resp . Data [ "9001" ] . ( time . Duration ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2019-07-01 20:30:08 +00:00
if resp . Data [ "token_period" ] . ( time . Duration ) != 0 {
2016-05-30 18:30:01 +00:00
t . Fatalf ( "expected value to be reset" )
}
// RUD for token_ttl field
roleReq . Path = "role/role1/token-ttl"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "token_ttl" : 4001 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_ttl" ] . ( time . Duration ) != 4001 {
t . Fatalf ( "bad: token_ttl: expected:4001 actual:%d\n" , resp . Data [ "token_ttl" ] . ( time . Duration ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_ttl" ] . ( time . Duration ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
// RUD for token_max_ttl field
roleReq . Path = "role/role1/token-max-ttl"
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Data = map [ string ] interface { } { "token_max_ttl" : 5001 }
roleReq . Operation = logical . UpdateOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_max_ttl" ] . ( time . Duration ) != 5001 {
t . Fatalf ( "bad: token_max_ttl: expected:5001 actual:%d\n" , resp . Data [ "token_max_ttl" ] . ( time . Duration ) )
}
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "token_max_ttl" ] . ( time . Duration ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
// Delete test for role
roleReq . Path = "role/role1"
roleReq . Operation = logical . DeleteOperation
2018-06-20 02:57:11 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
}
func TestAppRole_RoleWithTokenBoundCIDRsCRUD ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"policies" : "p,q,r,s" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"secret_id_bound_cidrs" : "127.0.0.1/32,127.0.0.1/16" ,
"token_bound_cidrs" : "127.0.0.1/32,127.0.0.1/16" ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/role1" ,
Storage : storage ,
Data : roleData ,
}
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected := map [ string ] interface { } {
"bind_secret_id" : true ,
"policies" : [ ] string { "p" , "q" , "r" , "s" } ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"token_bound_cidrs" : [ ] string { "127.0.0.1/32" , "127.0.0.1/16" } ,
"secret_id_bound_cidrs" : [ ] string { "127.0.0.1/32" , "127.0.0.1/16" } ,
2018-10-15 16:56:24 +00:00
"token_type" : "default" ,
2018-06-20 02:57:11 +00:00
}
var expectedStruct roleStorageEntry
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
var actualStruct roleStorageEntry
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
expectedStruct . RoleID = actualStruct . RoleID
if ! reflect . DeepEqual ( expectedStruct , actualStruct ) {
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v\n" , expectedStruct , actualStruct )
}
roleData = map [ string ] interface { } {
"role_id" : "test_role_id" ,
"policies" : "a,b,c,d" ,
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
}
roleReq . Data = roleData
roleReq . Operation = logical . UpdateOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected = map [ string ] interface { } {
"policies" : [ ] string { "a" , "b" , "c" , "d" } ,
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
}
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expectedStruct , actualStruct ) {
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v\n" , expectedStruct , actualStruct )
}
// RUD for secret-id-bound-cidrs field
roleReq . Path = "role/role1/secret-id-bound-cidrs"
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string ) [ 0 ] != "127.0.0.1/32" ||
resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string ) [ 1 ] != "127.0.0.1/16" {
t . Fatalf ( "bad: secret_id_bound_cidrs: expected:127.0.0.1/32,127.0.0.1/16 actual:%d\n" , resp . Data [ "secret_id_bound_cidrs" ] . ( int ) )
}
roleReq . Data = map [ string ] interface { } { "secret_id_bound_cidrs" : [ ] string { "127.0.0.1/20" } }
roleReq . Operation = logical . UpdateOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string ) [ 0 ] != "127.0.0.1/20" {
t . Fatalf ( "bad: secret_id_bound_cidrs: expected:127.0.0.1/20 actual:%s\n" , resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string ) [ 0 ] )
}
roleReq . Operation = logical . DeleteOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if len ( resp . Data [ "secret_id_bound_cidrs" ] . ( [ ] string ) ) != 0 {
t . Fatalf ( "expected value to be reset" )
}
// RUD for token-bound-cidrs field
roleReq . Path = "role/role1/token-bound-cidrs"
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2019-07-01 20:30:08 +00:00
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1" ||
resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 1 ] . String ( ) != "127.0.0.1/16" {
m , err := json . Marshal ( resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) )
if err != nil {
t . Fatal ( err )
}
t . Fatalf ( "bad: token_bound_cidrs: expected:127.0.0.1/32,127.0.0.1/16 actual:%s\n" , string ( m ) )
2018-06-20 02:57:11 +00:00
}
roleReq . Data = map [ string ] interface { } { "token_bound_cidrs" : [ ] string { "127.0.0.1/20" } }
roleReq . Operation = logical . UpdateOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2019-07-01 20:30:08 +00:00
if resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] . String ( ) != "127.0.0.1/20" {
t . Fatalf ( "bad: token_bound_cidrs: expected:127.0.0.1/20 actual:%s\n" , resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) [ 0 ] )
2018-06-20 02:57:11 +00:00
}
roleReq . Operation = logical . DeleteOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
2019-07-01 20:30:08 +00:00
if len ( resp . Data [ "token_bound_cidrs" ] . ( [ ] * sockaddr . SockAddrMarshaler ) ) != 0 {
2018-06-20 02:57:11 +00:00
t . Fatalf ( "expected value to be reset" )
}
// Delete test for role
roleReq . Path = "role/role1"
roleReq . Operation = logical . DeleteOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2021-06-24 17:03:41 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
}
func TestAppRole_RoleWithTokenTypeCRUD ( t * testing . T ) {
var resp * logical . Response
var err error
b , storage := createBackendWithStorage ( t )
roleData := map [ string ] interface { } {
"policies" : "p,q,r,s" ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"token_type" : "default-service" ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/role1" ,
Storage : storage ,
Data : roleData ,
}
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if 0 == len ( resp . Warnings ) {
t . Fatalf ( "bad:\nexpected warning in resp:%#v\n" , resp . Warnings )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected := map [ string ] interface { } {
"bind_secret_id" : true ,
"policies" : [ ] string { "p" , "q" , "r" , "s" } ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
"token_num_uses" : 600 ,
"token_type" : "service" ,
}
var expectedStruct roleStorageEntry
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
var actualStruct roleStorageEntry
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
expectedStruct . RoleID = actualStruct . RoleID
if ! reflect . DeepEqual ( expectedStruct , actualStruct ) {
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v\n" , expectedStruct , actualStruct )
}
roleData = map [ string ] interface { } {
"role_id" : "test_role_id" ,
"policies" : "a,b,c,d" ,
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
"token_type" : "default-service" ,
}
roleReq . Data = roleData
roleReq . Operation = logical . UpdateOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if 0 == len ( resp . Warnings ) {
t . Fatalf ( "bad:\nexpected a warning in resp:%#v\n" , resp . Warnings )
}
roleReq . Operation = logical . ReadOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
expected = map [ string ] interface { } {
"policies" : [ ] string { "a" , "b" , "c" , "d" } ,
"secret_id_num_uses" : 100 ,
"secret_id_ttl" : 3000 ,
"token_ttl" : 4000 ,
"token_max_ttl" : 5000 ,
"token_type" : "service" ,
}
err = mapstructure . Decode ( expected , & expectedStruct )
if err != nil {
t . Fatal ( err )
}
err = mapstructure . Decode ( resp . Data , & actualStruct )
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expectedStruct , actualStruct ) {
t . Fatalf ( "bad:\nexpected:%#v\nactual:%#v\n" , expectedStruct , actualStruct )
}
// Delete test for role
roleReq . Path = "role/role1"
roleReq . Operation = logical . DeleteOperation
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
roleReq . Operation = logical . ReadOperation
2018-01-08 18:31:38 +00:00
resp , err = b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
if resp != nil {
t . Fatalf ( "expected a nil response" )
}
}
func createRole ( t * testing . T , b * backend , s logical . Storage , roleName , policies string ) {
roleData := map [ string ] interface { } {
"policies" : policies ,
"secret_id_num_uses" : 10 ,
"secret_id_ttl" : 300 ,
"token_ttl" : 400 ,
"token_max_ttl" : 500 ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/" + roleName ,
Storage : s ,
Data : roleData ,
}
2018-01-08 18:31:38 +00:00
resp , err := b . HandleRequest ( context . Background ( ) , roleReq )
2016-05-30 18:30:01 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
}
2019-07-01 20:30:08 +00:00
// TestAppRole_TokenutilUpgrade ensures that when we read values out that are
// values with upgrade logic we see the correct struct entries populated
func TestAppRole_TokenutilUpgrade ( t * testing . T ) {
2019-08-14 13:45:40 +00:00
tests := [ ] struct {
name string
storageValMissing bool
storageVal string
expectedTokenType logical . TokenType
} {
{
"token_type_missing" ,
true ,
"" ,
logical . TokenTypeDefault ,
} ,
{
"token_type_empty" ,
false ,
"" ,
logical . TokenTypeDefault ,
} ,
{
"token_type_service" ,
false ,
"service" ,
logical . TokenTypeService ,
} ,
}
2019-07-01 20:30:08 +00:00
s := & logical . InmemStorage { }
config := logical . TestBackendConfig ( )
config . StorageView = s
ctx := context . Background ( )
b , err := Backend ( config )
if err != nil {
t . Fatal ( err )
}
if b == nil {
t . Fatalf ( "failed to create backend" )
}
if err := b . Setup ( ctx , config ) ; err != nil {
t . Fatal ( err )
}
2019-08-14 13:45:40 +00:00
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
// Construct the storage entry object based on our test case.
tokenTypeKV := ""
if ! tt . storageValMissing {
tokenTypeKV = fmt . Sprintf ( ` , "token_type": "%s" ` , tt . storageVal )
}
entryVal := fmt . Sprintf ( ` { "policies": ["foo"], "period": 300000000000, "token_bound_cidrs": ["127.0.0.1", "10.10.10.10/24"]%s} ` , tokenTypeKV )
// Hand craft JSON because there is overlap between fields
if err := s . Put ( ctx , & logical . StorageEntry {
Key : "role/" + tt . name ,
Value : [ ] byte ( entryVal ) ,
} ) ; err != nil {
t . Fatal ( err )
}
resEntry , err := b . roleEntry ( ctx , s , tt . name )
if err != nil {
t . Fatal ( err )
}
exp := & roleStorageEntry {
SecretIDPrefix : "secret_id/" ,
Policies : [ ] string { "foo" } ,
Period : 300 * time . Second ,
TokenParams : tokenutil . TokenParams {
TokenPolicies : [ ] string { "foo" } ,
TokenPeriod : 300 * time . Second ,
TokenBoundCIDRs : [ ] * sockaddr . SockAddrMarshaler {
{ SockAddr : sockaddr . MustIPAddr ( "127.0.0.1" ) } ,
{ SockAddr : sockaddr . MustIPAddr ( "10.10.10.10/24" ) } ,
} ,
TokenType : tt . expectedTokenType ,
} ,
}
if diff := deep . Equal ( resEntry , exp ) ; diff != nil {
t . Fatal ( diff )
}
} )
2019-07-01 20:30:08 +00:00
}
}
2021-02-04 00:32:16 +00:00
func TestAppRole_SecretID_WithTTL ( t * testing . T ) {
tests := [ ] struct {
name string
roleName string
ttl int64
sysTTLCap bool
} {
{
"zero ttl" ,
"role-zero-ttl" ,
0 ,
false ,
} ,
{
"custom ttl" ,
"role-custom-ttl" ,
60 ,
false ,
} ,
{
"system ttl capped" ,
"role-sys-ttl-cap" ,
700000000 ,
true ,
} ,
}
b , storage := createBackendWithStorage ( t )
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
// Create role
roleData := map [ string ] interface { } {
"policies" : "default" ,
"secret_id_ttl" : tt . ttl ,
}
roleReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "role/" + tt . roleName ,
Storage : storage ,
Data : roleData ,
}
resp , err := b . HandleRequest ( context . Background ( ) , roleReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
// Generate secret ID
secretIDReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "role/" + tt . roleName + "/secret-id" ,
Storage : storage ,
}
resp , err = b . HandleRequest ( context . Background ( ) , secretIDReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "err:%v resp:%#v" , err , resp )
}
// Extract the "ttl" value from the response data if it exists
ttlRaw , okTTL := resp . Data [ "secret_id_ttl" ]
if ! okTTL {
t . Fatalf ( "expected TTL value in response" )
}
var (
respTTL int64
ok bool
)
respTTL , ok = ttlRaw . ( int64 )
if ! ok {
t . Fatalf ( "expected ttl to be an integer, got: %s" , err )
}
// Verify secret ID response for different cases
switch {
case tt . sysTTLCap :
if respTTL != int64 ( b . System ( ) . MaxLeaseTTL ( ) . Seconds ( ) ) {
t . Fatalf ( "expected TTL value to be system's max lease TTL, got: %d" , respTTL )
}
default :
if respTTL != tt . ttl {
t . Fatalf ( "expected TTL value to be %d, got: %d" , tt . ttl , respTTL )
}
}
} )
}
}