github.com/vmware/govmomi@v0.43.0/simulator/authorization_manager.go (about)

     1  /*
     2  Copyright (c) 2017 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package simulator
    18  
    19  import (
    20  	"strings"
    21  
    22  	"github.com/vmware/govmomi/object"
    23  	"github.com/vmware/govmomi/simulator/esx"
    24  	"github.com/vmware/govmomi/vim25/methods"
    25  	"github.com/vmware/govmomi/vim25/mo"
    26  	"github.com/vmware/govmomi/vim25/soap"
    27  	"github.com/vmware/govmomi/vim25/types"
    28  )
    29  
    30  type AuthorizationManager struct {
    31  	mo.AuthorizationManager
    32  
    33  	permissions map[types.ManagedObjectReference][]types.Permission
    34  	privileges  map[string]struct{}
    35  	system      []string
    36  	nextID      int32
    37  }
    38  
    39  func (m *AuthorizationManager) init(r *Registry) {
    40  	if len(m.RoleList) == 0 {
    41  		m.RoleList = make([]types.AuthorizationRole, len(esx.RoleList))
    42  		copy(m.RoleList, esx.RoleList)
    43  	}
    44  
    45  	m.permissions = make(map[types.ManagedObjectReference][]types.Permission)
    46  
    47  	l := object.AuthorizationRoleList(m.RoleList)
    48  	m.system = l.ByName("ReadOnly").Privilege
    49  	admin := l.ByName("Admin")
    50  	m.privileges = make(map[string]struct{}, len(admin.Privilege))
    51  
    52  	for _, id := range admin.Privilege {
    53  		m.privileges[id] = struct{}{}
    54  	}
    55  
    56  	root := r.content().RootFolder
    57  
    58  	for _, u := range DefaultUserGroup {
    59  		m.permissions[root] = append(m.permissions[root], types.Permission{
    60  			Entity:    &root,
    61  			Principal: u.Principal,
    62  			Group:     u.Group,
    63  			RoleId:    admin.RoleId,
    64  			Propagate: true,
    65  		})
    66  	}
    67  }
    68  
    69  func (m *AuthorizationManager) RetrieveEntityPermissions(req *types.RetrieveEntityPermissions) soap.HasFault {
    70  	e := Map.Get(req.Entity).(mo.Entity)
    71  
    72  	p := m.permissions[e.Reference()]
    73  
    74  	if req.Inherited {
    75  		for {
    76  			parent := e.Entity().Parent
    77  			if parent == nil {
    78  				break
    79  			}
    80  
    81  			e = Map.Get(parent.Reference()).(mo.Entity)
    82  
    83  			p = append(p, m.permissions[e.Reference()]...)
    84  		}
    85  	}
    86  
    87  	return &methods.RetrieveEntityPermissionsBody{
    88  		Res: &types.RetrieveEntityPermissionsResponse{
    89  			Returnval: p,
    90  		},
    91  	}
    92  }
    93  
    94  func (m *AuthorizationManager) RetrieveAllPermissions(req *types.RetrieveAllPermissions) soap.HasFault {
    95  	var p []types.Permission
    96  
    97  	for _, v := range m.permissions {
    98  		p = append(p, v...)
    99  	}
   100  
   101  	return &methods.RetrieveAllPermissionsBody{
   102  		Res: &types.RetrieveAllPermissionsResponse{
   103  			Returnval: p,
   104  		},
   105  	}
   106  }
   107  
   108  func (m *AuthorizationManager) RemoveEntityPermission(req *types.RemoveEntityPermission) soap.HasFault {
   109  	var p []types.Permission
   110  
   111  	for _, v := range m.permissions[req.Entity] {
   112  		if v.Group == req.IsGroup && v.Principal == req.User {
   113  			continue
   114  		}
   115  		p = append(p, v)
   116  	}
   117  
   118  	m.permissions[req.Entity] = p
   119  
   120  	return &methods.RemoveEntityPermissionBody{
   121  		Res: &types.RemoveEntityPermissionResponse{},
   122  	}
   123  }
   124  
   125  func (m *AuthorizationManager) SetEntityPermissions(req *types.SetEntityPermissions) soap.HasFault {
   126  	m.permissions[req.Entity] = req.Permission
   127  
   128  	return &methods.SetEntityPermissionsBody{
   129  		Res: &types.SetEntityPermissionsResponse{},
   130  	}
   131  }
   132  
   133  func (m *AuthorizationManager) RetrieveRolePermissions(req *types.RetrieveRolePermissions) soap.HasFault {
   134  	var p []types.Permission
   135  
   136  	for _, set := range m.permissions {
   137  		for _, v := range set {
   138  			if v.RoleId == req.RoleId {
   139  				p = append(p, v)
   140  			}
   141  		}
   142  	}
   143  
   144  	return &methods.RetrieveRolePermissionsBody{
   145  		Res: &types.RetrieveRolePermissionsResponse{
   146  			Returnval: p,
   147  		},
   148  	}
   149  }
   150  
   151  func (m *AuthorizationManager) HasPrivilegeOnEntities(req *types.HasPrivilegeOnEntities) soap.HasFault {
   152  	var p []types.EntityPrivilege
   153  
   154  	for _, e := range req.Entity {
   155  		priv := types.EntityPrivilege{Entity: e}
   156  
   157  		for _, id := range req.PrivId {
   158  			priv.PrivAvailability = append(priv.PrivAvailability, types.PrivilegeAvailability{
   159  				PrivId:    id,
   160  				IsGranted: true,
   161  			})
   162  		}
   163  
   164  		p = append(p, priv)
   165  	}
   166  
   167  	return &methods.HasPrivilegeOnEntitiesBody{
   168  		Res: &types.HasPrivilegeOnEntitiesResponse{
   169  			Returnval: p,
   170  		},
   171  	}
   172  }
   173  
   174  func (m *AuthorizationManager) HasPrivilegeOnEntity(req *types.HasPrivilegeOnEntity) soap.HasFault {
   175  	p := make([]bool, len(req.PrivId))
   176  
   177  	for i := range req.PrivId {
   178  		p[i] = true
   179  	}
   180  
   181  	return &methods.HasPrivilegeOnEntityBody{
   182  		Res: &types.HasPrivilegeOnEntityResponse{
   183  			Returnval: p,
   184  		},
   185  	}
   186  }
   187  
   188  func (m *AuthorizationManager) HasUserPrivilegeOnEntities(req *types.HasUserPrivilegeOnEntities) soap.HasFault {
   189  	var p []types.EntityPrivilege
   190  
   191  	for _, e := range req.Entities {
   192  		priv := types.EntityPrivilege{Entity: e}
   193  
   194  		for _, id := range req.PrivId {
   195  			priv.PrivAvailability = append(priv.PrivAvailability, types.PrivilegeAvailability{
   196  				PrivId:    id,
   197  				IsGranted: true,
   198  			})
   199  		}
   200  
   201  		p = append(p, priv)
   202  	}
   203  
   204  	return &methods.HasUserPrivilegeOnEntitiesBody{
   205  		Res: &types.HasUserPrivilegeOnEntitiesResponse{
   206  			Returnval: p,
   207  		},
   208  	}
   209  }
   210  
   211  func (m *AuthorizationManager) FetchUserPrivilegeOnEntities(req *types.FetchUserPrivilegeOnEntities) soap.HasFault {
   212  	admin := object.AuthorizationRoleList(m.RoleList).ByName("Admin").Privilege
   213  
   214  	var p []types.UserPrivilegeResult
   215  
   216  	for _, e := range req.Entities {
   217  		p = append(p, types.UserPrivilegeResult{
   218  			Entity:     e,
   219  			Privileges: admin,
   220  		})
   221  	}
   222  
   223  	return &methods.FetchUserPrivilegeOnEntitiesBody{
   224  		Res: &types.FetchUserPrivilegeOnEntitiesResponse{
   225  			Returnval: p,
   226  		},
   227  	}
   228  }
   229  
   230  func (m *AuthorizationManager) AddAuthorizationRole(req *types.AddAuthorizationRole) soap.HasFault {
   231  	body := &methods.AddAuthorizationRoleBody{}
   232  
   233  	for _, role := range m.RoleList {
   234  		if role.Name == req.Name {
   235  			body.Fault_ = Fault("", &types.AlreadyExists{})
   236  			return body
   237  		}
   238  	}
   239  
   240  	ids, err := m.privIDs(req.PrivIds)
   241  	if err != nil {
   242  		body.Fault_ = err
   243  		return body
   244  	}
   245  
   246  	m.RoleList = append(m.RoleList, types.AuthorizationRole{
   247  		Info: &types.Description{
   248  			Label:   req.Name,
   249  			Summary: req.Name,
   250  		},
   251  		RoleId:    m.nextID,
   252  		Privilege: ids,
   253  		Name:      req.Name,
   254  		System:    false,
   255  	})
   256  
   257  	m.nextID++
   258  
   259  	body.Res = &types.AddAuthorizationRoleResponse{}
   260  
   261  	return body
   262  }
   263  
   264  func (m *AuthorizationManager) UpdateAuthorizationRole(req *types.UpdateAuthorizationRole) soap.HasFault {
   265  	body := &methods.UpdateAuthorizationRoleBody{}
   266  
   267  	for _, role := range m.RoleList {
   268  		if role.Name == req.NewName && role.RoleId != req.RoleId {
   269  			body.Fault_ = Fault("", &types.AlreadyExists{})
   270  			return body
   271  		}
   272  	}
   273  
   274  	for i, role := range m.RoleList {
   275  		if role.RoleId == req.RoleId {
   276  			if len(req.PrivIds) != 0 {
   277  				ids, err := m.privIDs(req.PrivIds)
   278  				if err != nil {
   279  					body.Fault_ = err
   280  					return body
   281  				}
   282  				m.RoleList[i].Privilege = ids
   283  			}
   284  
   285  			m.RoleList[i].Name = req.NewName
   286  
   287  			body.Res = &types.UpdateAuthorizationRoleResponse{}
   288  			return body
   289  		}
   290  	}
   291  
   292  	body.Fault_ = Fault("", &types.NotFound{})
   293  
   294  	return body
   295  }
   296  
   297  func (m *AuthorizationManager) RemoveAuthorizationRole(req *types.RemoveAuthorizationRole) soap.HasFault {
   298  	body := &methods.RemoveAuthorizationRoleBody{}
   299  
   300  	for i, role := range m.RoleList {
   301  		if role.RoleId == req.RoleId {
   302  			m.RoleList = append(m.RoleList[:i], m.RoleList[i+1:]...)
   303  
   304  			body.Res = &types.RemoveAuthorizationRoleResponse{}
   305  			return body
   306  		}
   307  	}
   308  
   309  	body.Fault_ = Fault("", &types.NotFound{})
   310  
   311  	return body
   312  }
   313  
   314  func (m *AuthorizationManager) privIDs(ids []string) ([]string, *soap.Fault) {
   315  	system := make(map[string]struct{}, len(m.system))
   316  
   317  	for _, id := range ids {
   318  		if _, ok := m.privileges[id]; !ok {
   319  			return nil, Fault("", &types.InvalidArgument{InvalidProperty: "privIds"})
   320  		}
   321  
   322  		if strings.HasPrefix(id, "System.") {
   323  			system[id] = struct{}{}
   324  		}
   325  	}
   326  
   327  	for _, id := range m.system {
   328  		if _, ok := system[id]; ok {
   329  			continue
   330  		}
   331  
   332  		ids = append(ids, id)
   333  	}
   334  
   335  	return ids, nil
   336  }