/** * Checks Permissions and deletes the given property descriptor from database for resource */ public void deletePropertyDescriptorForResource(ForeignableOwner deletingOwner, Integer resourceId, PropertyDescriptorEntity descriptor, boolean forceDelete) throws AMWException, ForeignableOwnerViolationException { if (descriptor != null && descriptor.getId() != null) { ResourceEntity attachedResource = entityManager.find(ResourceEntity.class, resourceId); ResourceContextEntity resourceContext = attachedResource.getOrCreateContext(contextService.getGlobalResourceContextEntity()); permissionBoundary.checkPermissionAndFireException(Permission.RESOURCE, null, Action.UPDATE, attachedResource.getResourceGroup(), null, null); foreignableService.verifyDeletableByOwner(deletingOwner, descriptor); if (forceDelete) { propertyDescriptorService.deletePropertyDescriptorByOwnerIncludingPropertyValues(descriptor, resourceContext, attachedResource); } else { propertyDescriptorService.deletePropertyDescriptorByOwnerInResourceContext(descriptor, resourceContext, resourceId); } } }
/** * Checks Permissions and deletes the given property descriptor from database for resource type */ public void deletePropertyDescriptorForResourceType(ForeignableOwner deletingOwner, Integer resourceTypeId, PropertyDescriptorEntity descriptor, boolean forceDelete) throws AMWException, ForeignableOwnerViolationException { if (descriptor != null && descriptor.getId() != null) { ResourceTypeEntity attachedResourceType = entityManager.find(ResourceTypeEntity.class, resourceTypeId); ResourceTypeContextEntity resourceTypeContextEntity = attachedResourceType.getOrCreateContext(contextService.getGlobalResourceContextEntity()); permissionBoundary.checkPermissionAndFireException(Permission.RESOURCETYPE, null, Action.UPDATE, null, attachedResourceType, null); foreignableService.verifyDeletableByOwner(deletingOwner, descriptor); if (forceDelete) { propertyDescriptorService.deletePropertyDescriptorByOwnerIncludingPropertyValues(descriptor, resourceTypeContextEntity, attachedResourceType); } else { propertyDescriptorService.deletePropertyDescriptorByOwnerInResourceTypeContext(descriptor, resourceTypeContextEntity, resourceTypeId); } } }
/** * Deletes PropertyDescriptors and their PropertyTags PropertyDescriptors including all its Properties * The owner is ignored - therefore this method deletes the property descriptor regardless of the foreignable ownership! */ public void deletePropertyDescriptorByOwnerIncludingPropertyValues(PropertyDescriptorEntity descriptorToDelete, AbstractContext abstractContext, HasContexts attachedResource) throws AMWException { PropertyDescriptorEntity descriptorToDeleteWithTags = getPropertyDescriptorWithTags(descriptorToDelete.getId()); Set<PropertyEntity> propertiesToBeDeleted = descriptorToDeleteWithTags.getProperties(); Set<ContextDependency> resourceContexts = attachedResource.getContexts(); auditService.storeIdInThreadLocalForAuditLog(attachedResource); for (ContextDependency context : resourceContexts) { if (context.getProperties().size() > 0) { for (PropertyEntity property : propertiesToBeDeleted) { context.removeProperty(property); } } if (context.getPropertyDescriptors().size() > 0) { context.removePropertyDescriptor(descriptorToDelete); } } if (attachedResource instanceof ResourceEntity) { removeRelationPropertyValues((ResourceEntity) attachedResource, propertiesToBeDeleted); } else if (attachedResource instanceof ResourceTypeEntity) { removeInstancePropertyValues((ResourceTypeEntity) attachedResource, propertiesToBeDeleted); removeRelationPropertyValues((ResourceTypeEntity) attachedResource, propertiesToBeDeleted); } removePropertyDescriptorByOwner(descriptorToDeleteWithTags, abstractContext, true); }
/** * Verify if the change is allowed by given owner and persists a given PropertyDescriptor, handles its encryption/decryption and manages its PropertyTags * * @throws AMWException is thrown when technical key is invalid or another PropertyDescriptor with same technical key already exists * @throws ForeignableOwnerViolationException is thrown when the change is not permitted by changing owner */ public PropertyDescriptorEntity savePropertyDescriptorForOwner(ForeignableOwner changingOwner, AbstractContext abstractContext, PropertyDescriptorEntity descriptor, List<PropertyTagEntity> tags, ResourceEntity resource) throws AMWException { checkForValidTechnicalKey(descriptor); auditService.storeIdInThreadLocalForAuditLog(resource); if (descriptor.getId() == null) { preventDuplicateTechnicalKeys(abstractContext, descriptor); createNewPropertyDescriptor(changingOwner, descriptor, abstractContext, tags); } else { saveExistingPropertyDescriptor(descriptor, tags, resource); } return descriptor; }
/** * Deletes PropertyDescriptors and their PropertyTags PropertyDescriptors to be deleted must not have any Properties * The owner is ignored - therefore this method deletes the property descriptor regardless of the foreignable ownership! */ public void deletePropertyDescriptorByOwnerInResourceContext(PropertyDescriptorEntity descriptorToDelete, AbstractContext abstractContext, int resourceId) throws AMWException { auditService.setResourceIdInThreadLocal(resourceId); PropertyDescriptorEntity descriptorToDeleteWithTags = getPropertyDescriptorWithTags(descriptorToDelete.getId()); removePropertyDescriptorByOwner(descriptorToDeleteWithTags, abstractContext, false); }
public void savePropertyDescriptorWithTags(PropertyDescriptorEntity propDesc, List<String> tags, ResourceEntity resourceEntity, ForeignableOwner owner) throws AMWException { ResourceContextEntity resourceContext = resourceEntity.getOrCreateContext(globalContext); List<PropertyTagEntity> propertyTags = createPropertyTags(tags); descriptorService.savePropertyDescriptorForOwner(owner, resourceContext, propDesc, propertyTags, resourceEntity); }
@Test public void shouldStoreResourceTypeIdInThreadLocalDuringPropertyUpdateInResourceTypeContext() throws AMWException { // given Integer resourceTypeIdForAuditLog = 1; ForeignableOwner deletingOwner = ForeignableOwner.AMW; Set<PropertyEntity> properties = new HashSet<>(); properties.add(new PropertyEntity()); PropertyDescriptorEntity descriptor = new PropertyDescriptorEntityBuilder().withOwner(deletingOwner).withId(1).withProperties(properties).build(); AbstractContext abstractContextMock = mock(AbstractContext.class); doNothing().when(service).removePropertyDescriptorByOwner(eq(descriptor), eq(abstractContextMock), anyBoolean()); doReturn(descriptor).when(service).getPropertyDescriptorWithTags(anyInt()); // when service.deletePropertyDescriptorByOwnerInResourceTypeContext(descriptor, abstractContextMock, resourceTypeIdForAuditLog); // then assertThat("The resourceTypeId Param must be stored as ThreadLocal variable for auditing (envers)", ThreadLocalUtil.getThreadVariable(ThreadLocalUtil.KEY_RESOURCE_TYPE_ID), is(CoreMatchers.notNullValue())); int resourceTypeId = (int) ThreadLocalUtil.getThreadVariable(ThreadLocalUtil.KEY_RESOURCE_TYPE_ID); assertThat(resourceTypeId, is(resourceTypeIdForAuditLog)); }
@Test public void shouldStoreResourceIdInThreadLocalForDuringPropertyUpdateInResourceContext() throws AMWException { // given Integer resourceIdForAuditLog = 200; ForeignableOwner deletingOwner = ForeignableOwner.AMW; Set<PropertyEntity> properties = new HashSet<>(); properties.add(new PropertyEntity()); PropertyDescriptorEntity descriptor = new PropertyDescriptorEntityBuilder().withOwner(deletingOwner).withId(1).withProperties(properties).build(); AbstractContext abstractContextMock = mock(AbstractContext.class); doNothing().when(service).removePropertyDescriptorByOwner(eq(descriptor), eq(abstractContextMock), anyBoolean()); doReturn(descriptor).when(service).getPropertyDescriptorWithTags(anyInt()); // when service.deletePropertyDescriptorByOwnerInResourceContext(descriptor, abstractContextMock, resourceIdForAuditLog); // then assertThat("The resourceId Param must be stored as ThreadLocal variable for auditing (envers)", ThreadLocalUtil.getThreadVariable(ThreadLocalUtil.KEY_RESOURCE_ID), is(CoreMatchers.notNullValue())); int resourceId = (int) ThreadLocalUtil.getThreadVariable(ThreadLocalUtil.KEY_RESOURCE_ID); assertThat(resourceId, is(resourceIdForAuditLog)); }
@Test public void deletePropertyDescriptorByOwnerIncludingPropertyValuesWhenDeletingOwnerIsOwnerOfDescriptorWithPropertiesOnResourceShouldSucceed() throws AMWException { // given ForeignableOwner deletingOwner = ForeignableOwner.AMW; AbstractContext abstractContextMock = mock(AbstractContext.class); ResourceEntity resourceEntityMock = mock(ResourceEntity.class); PropertyEntity property = new PropertyEntity(); Set<PropertyEntity> properties = new HashSet<>(); properties.add(property); PropertyDescriptorEntity descriptor = new PropertyDescriptorEntityBuilder().withOwner(deletingOwner).withId(1).withProperties(properties).build(); Assert.assertEquals(deletingOwner, descriptor.getOwner()); ResourceContextEntity resourceContextEntityMock = mock(ResourceContextEntity.class); TypedQuery<PropertyDescriptorEntity> queryMock = mock(TypedQuery.class); when(entityManagerMock.createQuery("from PropertyDescriptorEntity d left join fetch d.propertyTags where d.id = :propertyDescriptorId ", PropertyDescriptorEntity.class)).thenReturn(queryMock); when(queryMock.getSingleResult()).thenReturn(descriptor); when(resourceEntityMock.getContexts()).thenReturn(Collections.singleton(resourceContextEntityMock)); when(resourceContextEntityMock.getProperties()).thenReturn(properties); // when service.deletePropertyDescriptorByOwnerIncludingPropertyValues(descriptor, abstractContextMock, resourceEntityMock); // then verify(resourceContextEntityMock).removeProperty(property); verify(entityManagerMock).remove(descriptor); }
public void removeProperty(PropertyDescriptorEntity propertyDescriptor, ResourceEntity resourceEntity) { ResourceContextEntity resourceContext = resourceEntity.getOrCreateContext(globalContext); try { descriptorService.deletePropertyDescriptorByOwnerInResourceContext(propertyDescriptor, resourceContext, resourceEntity.getId()); } catch (AMWException e) { throw new AMWRuntimeException("Failed to delete property " + propertyDescriptor.getPropertyDescriptorDisplayName() + " which has still assigned values"); } }
private void saveExistingPropertyDescriptor(PropertyDescriptorEntity descriptor, List<PropertyTagEntity> tags, ResourceTypeEntity resourceType) { PropertyDescriptorEntity oldDescriptor = entityManager.find(PropertyDescriptorEntity.class, descriptor.getId()); List<Integer> encryptedPropertyIds = new ArrayList<>(); if (oldDescriptor.isEncrypt()) { encryptedPropertyIds.add(oldDescriptor.getId()); } PropertyDescriptorEntity mergedDescriptor = entityManager.merge(descriptor); propertyTagEditingService.updateTags(tags, mergedDescriptor); boolean canDecrypt = false; // decryption required - check permission if (!mergedDescriptor.isEncrypt() && encryptedPropertyIds.contains(mergedDescriptor.getId())) { // context? canDecrypt = permissionService.hasPermission(Permission.RESOURCETYPE_PROPERTY_DECRYPT, null, Action.ALL, null, resourceType); } manageChangeOfEncryptedPropertyDescriptor(mergedDescriptor, encryptedPropertyIds, canDecrypt); }
public PropertyDescriptorEntity getPropertyDescriptor(Integer propertyDescriptorId) { return propertyDescriptorService.getPropertyDescriptorWithTags(propertyDescriptorId); }
/** * Loads all property descriptors for the given resource (but not of its resource type) except those * which are marked to have a special cardinality (usually system properties) * * @param resource * @return */ public List<PropertyDescriptorEntity> getPropertyDescriptorsForResourceWithNullCardinality( ResourceEntity resource) { return propertyDescriptorService .getPropertyDescriptorsForHasContextWithNullCardinality(entityManager.find( ResourceEntity.class, resource.getId())); }
private PropertyDescriptorEntity savePropertyDescriptorResourceType(ForeignableOwner editingOwner, Integer resourceTypeId, PropertyDescriptorEntity descriptor, String propertyTagsString) throws AMWException { ResourceTypeEntity attachedResourceType = entityManager.find(ResourceTypeEntity.class, resourceTypeId); ResourceTypeContextEntity resourceTypeContextEntity = attachedResourceType.getOrCreateContext(contextService.getGlobalResourceContextEntity()); return propertyDescriptorService.savePropertyDescriptorForOwner(editingOwner, resourceTypeContextEntity, descriptor, propertyTagEditingService.convertToTags(propertyTagsString), attachedResourceType); }
/** * Deletes PropertyDescriptors and their PropertyTags PropertyDescriptors to be deleted must not have any * Properties * The owner is ignored - therefore this method deletes the property descriptor regardless of the foreignable ownership! */ public void deletePropertyDescriptorByOwnerInResourceTypeContext(PropertyDescriptorEntity descriptorToDelete, AbstractContext abstractContext, int resourceTypeId) throws AMWException { auditService.setResourceTypeIdInThreadLocal(resourceTypeId); PropertyDescriptorEntity descriptorToDeleteWithTags = getPropertyDescriptorWithTags(descriptorToDelete.getId()); removePropertyDescriptorByOwner(descriptorToDeleteWithTags, abstractContext, false); }
/** * Verify if the change is allowed by given owner and persists a given PropertyDescriptor, handles its encryption/decryption and manages its PropertyTags * * @throws AMWException is thrown when technical key is invalid or another PropertyDescriptor with same technical key already exists * @throws ForeignableOwnerViolationException is thrown when the change is not permitted by changing owner */ public PropertyDescriptorEntity savePropertyDescriptorForOwner(ForeignableOwner changingOwner, AbstractContext abstractContext, PropertyDescriptorEntity descriptor, List<PropertyTagEntity> tags, ResourceTypeEntity resourceType) throws AMWException { checkForValidTechnicalKey(descriptor); auditService.storeIdInThreadLocalForAuditLog(resourceType); if (descriptor.getId() == null) { preventDuplicateTechnicalKeys(abstractContext, descriptor); createNewPropertyDescriptor(changingOwner, descriptor, abstractContext, tags); } else { saveExistingPropertyDescriptor(descriptor, tags, resourceType); } return descriptor; }
@Test public void deletePropertyDescriptorByOwnerIncludingPropertyValuesWhenDeletingOwnerIsOwnerOfDescriptorDefinedOnResourceTypeWithPropertiesOnResourceShouldSucceed() throws AMWException { // given ForeignableOwner deletingOwner = ForeignableOwner.AMW; AbstractContext abstractContextMock = mock(AbstractContext.class); ResourceTypeEntity resourceTypeEntityMock = mock(ResourceTypeEntity.class); ResourceEntity resourceEntityMock = mock(ResourceEntity.class); ResourceContextEntity resourceContextEntityMock = mock(ResourceContextEntity.class); PropertyDescriptorEntity descriptor = new PropertyDescriptorEntityBuilder().withOwner(deletingOwner).withId(1).build(); PropertyEntity property = new PropertyEntityBuilder().buildPropertyEntity("propVal", descriptor); descriptor.addProperty(property); Set<PropertyEntity> properties = new HashSet<>(); properties.add(property); TypedQuery<PropertyDescriptorEntity> queryMock = mock(TypedQuery.class); when(entityManagerMock.createQuery("from PropertyDescriptorEntity d left join fetch d.propertyTags where d.id = :propertyDescriptorId ", PropertyDescriptorEntity.class)).thenReturn(queryMock); when(queryMock.getSingleResult()).thenReturn(descriptor); when(entityManagerMock.find(PropertyDescriptorEntity.class, descriptor.getId())).thenReturn(descriptor); when(resourceTypeEntityMock.getResources()).thenReturn(Collections.singleton(resourceEntityMock)); when(resourceEntityMock.getContexts()).thenReturn(Collections.singleton(resourceContextEntityMock)); when(resourceContextEntityMock.getProperties()).thenReturn(properties); // when service.deletePropertyDescriptorByOwnerIncludingPropertyValues(descriptor, abstractContextMock, resourceTypeEntityMock); // then verify(resourceContextEntityMock).removeProperty(property); verify(entityManagerMock).remove(descriptor); }
@Test public void deletePropertyDescriptorByOwnerWhenDeletingOwnerIsOwnerOfDescriptorAndNoPropertiesShouldDeletePropertyDescriptor() throws AMWException { // given ForeignableOwner deletingOwner = ForeignableOwner.AMW; AbstractContext abstractContextMock = mock(AbstractContext.class); PropertyDescriptorEntity descriptor = new PropertyDescriptorEntityBuilder().withOwner(deletingOwner).withId(1).build(); Assert.assertEquals(deletingOwner, descriptor.getOwner()); TypedQuery<PropertyDescriptorEntity> queryMock = mock(TypedQuery.class); when(entityManagerMock.createQuery("from PropertyDescriptorEntity d left join fetch d.propertyTags where d.id = :propertyDescriptorId ", PropertyDescriptorEntity.class)).thenReturn(queryMock); when(queryMock.getSingleResult()).thenReturn(descriptor); // when service.deletePropertyDescriptorByOwnerInResourceContext(descriptor, abstractContextMock, dummyResourceId); // then verify(entityManagerMock).remove(descriptor); }
private void saveExistingPropertyDescriptor(PropertyDescriptorEntity descriptor, List<PropertyTagEntity> tags, ResourceEntity resource) { PropertyDescriptorEntity oldDescriptor = entityManager.find(PropertyDescriptorEntity.class, descriptor.getId()); List<Integer> encryptedPropertyIds = new ArrayList<>(); if (oldDescriptor.isEncrypt()) { encryptedPropertyIds.add(oldDescriptor.getId()); } PropertyDescriptorEntity mergedDescriptor = entityManager.merge(descriptor); propertyTagEditingService.updateTags(tags, mergedDescriptor); boolean canDecrypt = false; // decryption required - check permission if (!mergedDescriptor.isEncrypt() && encryptedPropertyIds.contains(mergedDescriptor.getId())) { // context? canDecrypt = permissionService.hasPermission(Permission.RESOURCE_PROPERTY_DECRYPT, null, Action.ALL, resource.getResourceGroup(), null); } manageChangeOfEncryptedPropertyDescriptor(mergedDescriptor, encryptedPropertyIds, canDecrypt); }
public List<PropertyDescriptorEntity> getAllPropertyDescriptorsForResourceWithNullCardinality( ResourceEntity resource) { return propertyDescriptorService .getPropertyDescriptorsForHasContextWithNullCardinality(entityManager.find( ResourceEntity.class, resource.getId())); }