credential/app-id: support associating a name with app ID [GH-9]

This commit is contained in:
Mitchell Hashimoto 2015-04-17 10:00:48 -07:00
parent 37af1683c6
commit e643b48235
4 changed files with 86 additions and 5 deletions

View File

@ -12,9 +12,23 @@ func Factory(map[string]string) (logical.Backend, error) {
func Backend() *framework.Backend {
var b backend
b.MapAppId = &framework.PolicyMap{
PathMap: framework.PathMap{Name: "app-id"},
PathMap: framework.PathMap{
Name: "app-id",
Schema: map[string]*framework.FieldSchema{
"display_name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "A name to map to this app ID for logs.",
},
"value": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Policies for the app ID.",
},
},
},
DefaultKey: "default",
}
b.MapUserId = &framework.PathMap{
Name: "user-id",
}

View File

@ -13,7 +13,19 @@ func TestBackend_basic(t *testing.T) {
Steps: []logicaltest.TestStep{
testAccStepMapAppId(t),
testAccStepMapUserId(t),
testAccLogin(t),
testAccLogin(t, ""),
testAccLoginInvalid(t),
},
})
}
func TestBackend_displayName(t *testing.T) {
logicaltest.Test(t, logicaltest.TestCase{
Backend: Backend(),
Steps: []logicaltest.TestStep{
testAccStepMapAppIdDisplayName(t),
testAccStepMapUserId(t),
testAccLogin(t, "tubbin"),
testAccLoginInvalid(t),
},
})
@ -29,6 +41,17 @@ func testAccStepMapAppId(t *testing.T) logicaltest.TestStep {
}
}
func testAccStepMapAppIdDisplayName(t *testing.T) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.WriteOperation,
Path: "map/app-id/foo",
Data: map[string]interface{}{
"display_name": "tubbin",
"value": "foo,bar",
},
}
}
func testAccStepMapUserId(t *testing.T) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.WriteOperation,
@ -39,7 +62,7 @@ func testAccStepMapUserId(t *testing.T) logicaltest.TestStep {
}
}
func testAccLogin(t *testing.T) logicaltest.TestStep {
func testAccLogin(t *testing.T, display string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.WriteOperation,
Path: "login",
@ -49,7 +72,10 @@ func testAccLogin(t *testing.T) logicaltest.TestStep {
},
Unauthenticated: true,
Check: logicaltest.TestCheckAuth([]string{"bar", "foo"}),
Check: logicaltest.TestCheckMulti(
logicaltest.TestCheckAuth([]string{"bar", "foo"}),
logicaltest.TestCheckAuthDisplayName(display),
),
}
}

View File

@ -67,9 +67,22 @@ func (b *backend) pathLogin(
return nil, err
}
// Get the raw data associated with the app
appRaw, err := b.MapAppId.Get(req.Storage, appId)
if err != nil {
return nil, err
}
// Check if we have a display name
var displayName string
if raw, ok := appRaw["display_name"]; ok {
displayName = raw.(string)
}
return &logical.Response{
Auth: &logical.Auth{
Policies: policies,
DisplayName: displayName,
Policies: policies,
},
}, nil
}

View File

@ -234,6 +234,19 @@ func Test(t TestT, c TestCase) {
}
}
// TestCheckMulti is a helper to have multiple checks.
func TestCheckMulti(fs ...TestCheckFunc) TestCheckFunc {
return func(resp *logical.Response) error {
for _, f := range fs {
if err := f(resp); err != nil {
return err
}
}
return nil
}
}
// TestCheckAuth is a helper to check that a request generated an
// auth token with the proper policies.
func TestCheckAuth(policies []string) TestCheckFunc {
@ -249,6 +262,21 @@ func TestCheckAuth(policies []string) TestCheckFunc {
}
}
// TestCheckAuthDisplayName is a helper to check that a request generated a
// valid display name.
func TestCheckAuthDisplayName(n string) TestCheckFunc {
return func(resp *logical.Response) error {
if resp.Auth == nil {
return fmt.Errorf("no auth in response")
}
if n != "" && resp.Auth.DisplayName != "mnt-"+n {
return fmt.Errorf("invalid display name: %#v", resp.Auth.DisplayName)
}
return nil
}
}
// TestCheckError is a helper to check that a response is an error.
func TestCheckError() TestCheckFunc {
return func(resp *logical.Response) error {