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

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