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 }