Repository: vmware/govmomi (go)

Issue:
simulator is missing some AuthorizationManager methods
The vpx simulator supports `AuthorizationManager.HasPriviligeOnEntities` but none of the variations,
- `HasPrivilegeOnEntity`
- `HasUserPrivilegeOnEntities`
- `FetchUserPrivilegeOnEntities`

Attempting to use these other functions on the simulator results in errors like the below.

```
ServerFaultCode: AuthorizationManager:AuthorizationManager does not implement: HasPrivilegeOnEntity
```

This was tested in govmomi@0.23.1

Pull request description:
vcsim: add AuthorizationManager methods
- HasPrivilegeOnEntity
- HasUserPrivilegeOnEntities
- FetchUserPrivilegeOnEntities

Fixes #2132

Patch:
diff --git a/object/authorization_manager.go b/object/authorization_manager.go
index c87e3372..5cd6851a 100644
--- a/object/authorization_manager.go
+++ b/object/authorization_manager.go
@@ -188,3 +188,34 @@ func (m AuthorizationManager) HasUserPrivilegeOnEntities(ctx context.Context, en
 
 	return res.Returnval, nil
 }
+
+func (m AuthorizationManager) HasPrivilegeOnEntity(ctx context.Context, entity types.ManagedObjectReference, sessionID string, privID []string) ([]bool, error) {
+	req := types.HasPrivilegeOnEntity{
+		This:      m.Reference(),
+		Entity:    entity,
+		SessionId: sessionID,
+		PrivId:    privID,
+	}
+
+	res, err := methods.HasPrivilegeOnEntity(ctx, m.Client(), &req)
+	if err != nil {
+		return nil, err
+	}
+
+	return res.Returnval, nil
+}
+
+func (m AuthorizationManager) FetchUserPrivilegeOnEntities(ctx context.Context, entities []types.ManagedObjectReference, userName string) ([]types.UserPrivilegeResult, error) {
+	req := types.FetchUserPrivilegeOnEntities{
+		This:     m.Reference(),
+		Entities: entities,
+		UserName: userName,
+	}
+
+	res, err := methods.FetchUserPrivilegeOnEntities(ctx, m.Client(), &req)
+	if err != nil {
+		return nil, err
+	}
+
+	return res.Returnval, nil
+}
diff --git a/simulator/authorization_manager.go b/simulator/authorization_manager.go
index 0aceb071..924ff978 100644
--- a/simulator/authorization_manager.go
+++ b/simulator/authorization_manager.go
@@ -171,6 +171,62 @@ func (m *AuthorizationManager) HasPrivilegeOnEntities(req *types.HasPrivilegeOnE
 	}
 }
 
+func (m *AuthorizationManager) HasPrivilegeOnEntity(req *types.HasPrivilegeOnEntity) soap.HasFault {
+	p := make([]bool, len(req.PrivId))
+
+	for i := range req.PrivId {
+		p[i] = true
+	}
+
+	return &methods.HasPrivilegeOnEntityBody{
+		Res: &types.HasPrivilegeOnEntityResponse{
+			Returnval: p,
+		},
+	}
+}
+
+func (m *AuthorizationManager) HasUserPrivilegeOnEntities(req *types.HasUserPrivilegeOnEntities) soap.HasFault {
+	var p []types.EntityPrivilege
+
+	for _, e := range req.Entities {
+		priv := types.EntityPrivilege{Entity: e}
+
+		for _, id := range req.PrivId {
+			priv.PrivAvailability = append(priv.PrivAvailability, types.PrivilegeAvailability{
+				PrivId:    id,
+				IsGranted: true,
+			})
+		}
+
+		p = append(p, priv)
+	}
+
+	return &methods.HasUserPrivilegeOnEntitiesBody{
+		Res: &types.HasUserPrivilegeOnEntitiesResponse{
+			Returnval: p,
+		},
+	}
+}
+
+func (m *AuthorizationManager) FetchUserPrivilegeOnEntities(req *types.FetchUserPrivilegeOnEntities) soap.HasFault {
+	admin := object.AuthorizationRoleList(m.RoleList).ByName("Admin").Privilege
+
+	var p []types.UserPrivilegeResult
+
+	for _, e := range req.Entities {
+		p = append(p, types.UserPrivilegeResult{
+			Entity:     e,
+			Privileges: admin,
+		})
+	}
+
+	return &methods.FetchUserPrivilegeOnEntitiesBody{
+		Res: &types.FetchUserPrivilegeOnEntitiesResponse{
+			Returnval: p,
+		},
+	}
+}
+
 func (m *AuthorizationManager) AddAuthorizationRole(req *types.AddAuthorizationRole) soap.HasFault {
 	body := &methods.AddAuthorizationRoleBody{}
 


Test patch:
diff --git a/object/authorization_manager_test.go b/object/authorization_manager_test.go
new file mode 100644
index 00000000..594dab92
--- /dev/null
+++ b/object/authorization_manager_test.go
@@ -0,0 +1,62 @@
+/*
+Copyright (c) 2020 VMware, Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package object_test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/vmware/govmomi/object"
+	"github.com/vmware/govmomi/session"
+	"github.com/vmware/govmomi/simulator"
+	"github.com/vmware/govmomi/simulator/esx"
+	"github.com/vmware/govmomi/vim25"
+	"github.com/vmware/govmomi/vim25/types"
+)
+
+func TestAuthorizationManagerPrivilege(t *testing.T) {
+	simulator.Test(func(ctx context.Context, c *vim25.Client) {
+		m := object.NewAuthorizationManager(c)
+		objs := []types.ManagedObjectReference{c.ServiceContent.RootFolder}
+		plist := esx.RoleList[0].Privilege[0:2]
+		s, _ := session.NewManager(c).UserSession(ctx)
+
+		p, err := m.HasPrivilegeOnEntity(ctx, objs[0], s.Key, plist)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(p) != len(plist) {
+			t.Errorf("HasPrivilegeOnEntity=%v", p)
+		}
+
+		ep, err := m.HasUserPrivilegeOnEntities(ctx, objs, s.UserName, plist)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(ep[0].PrivAvailability) != len(plist) {
+			t.Errorf("HasUserPrivilegeOnEntities=%v", ep)
+		}
+
+		up, err := m.FetchUserPrivilegeOnEntities(ctx, objs, s.UserName)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(up) != 1 {
+			t.Errorf("FetchUserPrivilegeOnEntities=%v", up)
+		}
+	})
+}