mirror of https://github.com/docker/cli.git
Fix issue where secret ID is masked by name
This fix tries to address the issue in 28884 where it is possible to mask the secret ID by name. The reason was that searching a secret is based on name. However, searching a secret should be done based on: - Full ID - Full Name - Partial ID (prefix) This fix addresses the issue by changing related implementation in `getCliRequestedSecretIDs()` An integration test has been added to cover the changes. This fix fixes 28884 Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
parent
0449997cf6
commit
ff9ff6fdd2
|
@ -1,6 +1,9 @@
|
|||
package secret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
|
@ -8,10 +11,11 @@ import (
|
|||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func getSecretsByName(ctx context.Context, client client.APIClient, names []string) ([]swarm.Secret, error) {
|
||||
func getSecretsByNameOrIDPrefixes(ctx context.Context, client client.APIClient, terms []string) ([]swarm.Secret, error) {
|
||||
args := filters.NewArgs()
|
||||
for _, n := range names {
|
||||
for _, n := range terms {
|
||||
args.Add("names", n)
|
||||
args.Add("id", n)
|
||||
}
|
||||
|
||||
return client.SecretList(ctx, types.SecretListOptions{
|
||||
|
@ -19,29 +23,53 @@ func getSecretsByName(ctx context.Context, client client.APIClient, names []stri
|
|||
})
|
||||
}
|
||||
|
||||
func getCliRequestedSecretIDs(ctx context.Context, client client.APIClient, names []string) ([]string, error) {
|
||||
ids := names
|
||||
|
||||
// attempt to lookup secret by name
|
||||
secrets, err := getSecretsByName(ctx, client, ids)
|
||||
func getCliRequestedSecretIDs(ctx context.Context, client client.APIClient, terms []string) ([]string, error) {
|
||||
secrets, err := getSecretsByNameOrIDPrefixes(ctx, client, terms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lookup := make(map[string]struct{})
|
||||
for _, id := range ids {
|
||||
lookup[id] = struct{}{}
|
||||
}
|
||||
|
||||
if len(secrets) > 0 {
|
||||
ids = []string{}
|
||||
|
||||
found := make(map[string]struct{})
|
||||
next:
|
||||
for _, term := range terms {
|
||||
// attempt to lookup secret by full ID
|
||||
for _, s := range secrets {
|
||||
if _, ok := lookup[s.Spec.Annotations.Name]; ok {
|
||||
ids = append(ids, s.ID)
|
||||
if s.ID == term {
|
||||
found[s.ID] = struct{}{}
|
||||
continue next
|
||||
}
|
||||
}
|
||||
// attempt to lookup secret by full name
|
||||
for _, s := range secrets {
|
||||
if s.Spec.Annotations.Name == term {
|
||||
found[s.ID] = struct{}{}
|
||||
continue next
|
||||
}
|
||||
}
|
||||
// attempt to lookup secret by partial ID (prefix)
|
||||
// return error if more than one matches found (ambiguous)
|
||||
n := 0
|
||||
for _, s := range secrets {
|
||||
if strings.HasPrefix(s.ID, term) {
|
||||
found[s.ID] = struct{}{}
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n > 1 {
|
||||
return nil, fmt.Errorf("secret %s is ambiguous (%d matches found)", term, n)
|
||||
}
|
||||
}
|
||||
|
||||
// We already collected all the IDs found.
|
||||
// Now we will remove duplicates by converting the map to slice
|
||||
ids := []string{}
|
||||
for id := range found {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
return terms, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue