From 9bd3ca6b09e737730ea66ba72ed865dccf54553b Mon Sep 17 00:00:00 2001 From: Yanqiang Miao Date: Wed, 28 Dec 2016 11:38:13 +0800 Subject: [PATCH] Rewrite the function 'validatePrivileges' without checking order Signed-off-by: Yanqiang Miao Upstream-commit: dafeeac4fd0ba811a4d88fe9ee335992680c8ad3 Component: engine --- .../engine/api/types/plugin_responses.go | 15 +++++ components/engine/plugin/manager.go | 30 +++++++++- components/engine/plugin/manager_test.go | 55 +++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 components/engine/plugin/manager_test.go diff --git a/components/engine/api/types/plugin_responses.go b/components/engine/api/types/plugin_responses.go index d6f7553119..1c6461f2d9 100644 --- a/components/engine/api/types/plugin_responses.go +++ b/components/engine/api/types/plugin_responses.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "fmt" + "sort" ) // PluginsListResponse contains the response for the Engine API @@ -62,3 +63,17 @@ type PluginPrivilege struct { // PluginPrivileges is a list of PluginPrivilege type PluginPrivileges []PluginPrivilege + +func (s PluginPrivileges) Len() int { + return len(s) +} + +func (s PluginPrivileges) Less(i, j int) bool { + return s[i].Name < s[j].Name +} + +func (s PluginPrivileges) Swap(i, j int) { + sort.Strings(s[i].Value) + sort.Strings(s[j].Value) + s[i], s[j] = s[j], s[i] +} diff --git a/components/engine/plugin/manager.go b/components/engine/plugin/manager.go index a81c3edb47..8573a74e93 100644 --- a/components/engine/plugin/manager.go +++ b/components/engine/plugin/manager.go @@ -8,6 +8,7 @@ import ( "path/filepath" "reflect" "regexp" + "sort" "strings" "sync" @@ -289,13 +290,38 @@ func attachToLog(id string) func(libcontainerd.IOPipe) error { } func validatePrivileges(requiredPrivileges, privileges types.PluginPrivileges) error { - // todo: make a better function that doesn't check order - if !reflect.DeepEqual(privileges, requiredPrivileges) { + if !isEqual(requiredPrivileges, privileges, isEqualPrivilege) { return errors.New("incorrect privileges") } + return nil } +func isEqual(arrOne, arrOther types.PluginPrivileges, compare func(x, y types.PluginPrivilege) bool) bool { + if len(arrOne) != len(arrOther) { + return false + } + + sort.Sort(arrOne) + sort.Sort(arrOther) + + for i := 1; i < arrOne.Len(); i++ { + if !compare(arrOne[i], arrOther[i]) { + return false + } + } + + return true +} + +func isEqualPrivilege(a, b types.PluginPrivilege) bool { + if a.Name != b.Name { + return false + } + + return reflect.DeepEqual(a.Value, b.Value) +} + func configToRootFS(c []byte) (*image.RootFS, error) { var pluginConfig types.PluginConfig if err := json.Unmarshal(c, &pluginConfig); err != nil { diff --git a/components/engine/plugin/manager_test.go b/components/engine/plugin/manager_test.go new file mode 100644 index 0000000000..35efe1f8dd --- /dev/null +++ b/components/engine/plugin/manager_test.go @@ -0,0 +1,55 @@ +package plugin + +import ( + "testing" + + "github.com/docker/docker/api/types" +) + +func TestValidatePrivileges(t *testing.T) { + testData := map[string]struct { + requiredPrivileges types.PluginPrivileges + privileges types.PluginPrivileges + result bool + }{ + "diff-len": { + requiredPrivileges: []types.PluginPrivilege{ + {"Privilege1", "Description", []string{"abc", "def", "ghi"}}, + }, + privileges: []types.PluginPrivilege{ + {"Privilege1", "Description", []string{"abc", "def", "ghi"}}, + {"Privilege2", "Description", []string{"123", "456", "789"}}, + }, + result: false, + }, + "diff-value": { + requiredPrivileges: []types.PluginPrivilege{ + {"Privilege1", "Description", []string{"abc", "def", "GHI"}}, + {"Privilege2", "Description", []string{"123", "456", "***"}}, + }, + privileges: []types.PluginPrivilege{ + {"Privilege1", "Description", []string{"abc", "def", "ghi"}}, + {"Privilege2", "Description", []string{"123", "456", "789"}}, + }, + result: false, + }, + "diff-order-but-same-value": { + requiredPrivileges: []types.PluginPrivilege{ + {"Privilege1", "Description", []string{"abc", "def", "GHI"}}, + {"Privilege2", "Description", []string{"123", "456", "789"}}, + }, + privileges: []types.PluginPrivilege{ + {"Privilege2", "Description", []string{"123", "456", "789"}}, + {"Privilege1", "Description", []string{"GHI", "abc", "def"}}, + }, + result: true, + }, + } + + for key, data := range testData { + err := validatePrivileges(data.requiredPrivileges, data.privileges) + if (err == nil) != data.result { + t.Fatalf("Test item %s expected result to be %t, got %t", key, data.result, (err == nil)) + } + } +}