use of org.activityinfo.model.type.attachment.Attachment in project activityinfo by bedatadriven.
the class AttachmentUploadFieldWidget method setValue.
@Override
public Promise<Void> setValue(AttachmentValue value) {
if (value != null && value.getValues() != null && value.getValues().size() > 0) {
rows.clear();
for (Attachment rowValue : value.getValues()) {
addNewRow(rowValue);
}
setState(true);
} else {
clearValue();
}
return Promise.done();
}
use of org.activityinfo.model.type.attachment.Attachment in project activityinfo by bedatadriven.
the class GcsBlobFieldStorageServiceTest method blobPermissionAttack.
/**
* 1. user1 : persist blob with FormInstance1 (FormClass1) user1
* 2. user2 : persist the same blob with FormInstance2 (FormClass2) -> try to steal blob access
*/
@Test
@OnDataSet("/dbunit/sites-simple-blob-security.db.xml")
public void blobPermissionAttack() throws IOException {
blobService.setTestBucketName();
int activityId = 1;
int databaseId = 1;
int locationType = 10;
ResourceId attachmentFieldId = ResourceId.generateFieldId(AttachmentType.TYPE_CLASS);
FormClass formClass = addAttachmentField(activityId, attachmentFieldId);
blobId = BlobId.generate();
blobService.put(user, "attachment;filename=" + FILE_NAME, MimeTypeUtil.mimeTypeFromFileName(FILE_NAME), blobId, formClass.getId(), GcsBlobFieldStorageServiceTest.class.getResourceAsStream("goabout.png"));
FormInstance instance = new FormInstance(CuidAdapter.cuid(SITE_DOMAIN, new KeyGenerator().generateInt()), formClass.getId());
Attachment attachment = new Attachment();
attachment.setMimeType(MimeTypeUtil.mimeTypeFromFileName(FILE_NAME));
attachment.setBlobId(blobId.asString());
attachment.setFilename(FILE_NAME);
AttachmentValue attachmentValue = new AttachmentValue();
attachmentValue.getValues().add(attachment);
instance.set(indicatorField(1), 1);
instance.set(indicatorField(2), 2);
instance.set(attachmentFieldId, attachmentValue);
instance.set(locationField(activityId), locationRef(CuidAdapter.locationFormClass(locationType), 1));
instance.set(partnerField(activityId), partnerRef(databaseId, 1));
instance.set(projectField(activityId), projectRef(databaseId, 1));
instance.set(field(formClass.getId(), START_DATE_FIELD), new LocalDate(2014, 1, 1));
instance.set(field(formClass.getId(), END_DATE_FIELD), new LocalDate(2014, 1, 1));
instance.set(field(formClass.getId(), COMMENT_FIELD), "My comment");
assertResolves(locator.persist(instance));
assertInstanceExists(formClass.getId(), instance.getId());
AuthenticationModuleStub.setUserId(USER_WITHOUT_ACCESS_TO_DB_1);
int anotherActivityId = 32;
ResourceId newAttachmentFieldId = ResourceId.generateFieldId(AttachmentType.TYPE_CLASS);
addAttachmentField(anotherActivityId, newAttachmentFieldId);
instance.setId(CuidAdapter.cuid(SITE_DOMAIN, new KeyGenerator().generateInt()));
instance.setClassId(CuidAdapter.activityFormClass(anotherActivityId));
instance.set(newAttachmentFieldId, attachmentValue);
instance.set(field(instance.getFormId(), START_DATE_FIELD), new LocalDate(2014, 1, 1));
instance.set(field(instance.getFormId(), END_DATE_FIELD), new LocalDate(2014, 1, 1));
instance.set(partnerField(anotherActivityId), partnerRef(databaseId, 1));
boolean persisted = true;
try {
// this must fail because of blob permission check
assertResolves(locator.persist(instance));
} catch (RuntimeException e) {
e.printStackTrace();
persisted = false;
}
assertFalse("Access to blob is stolen! Permissions check for blobs is broken.", persisted);
}
use of org.activityinfo.model.type.attachment.Attachment in project activityinfo by bedatadriven.
the class XFormSubmissionResource method persist.
private void persist(AuthenticatedUser user, XFormInstance instance, AttachmentValue fieldValue) {
Attachment attachment = fieldValue.getValues().get(0);
if (attachment.getFilename() != null) {
try {
BodyPart bodyPart = ((XFormInstanceImpl) instance).findBodyPartByFilename(attachment.getFilename());
String mimeType = bodyPart.getContentType();
attachment.setMimeType(mimeType);
blobFieldStorageService.put(user, bodyPart.getDisposition(), mimeType, new BlobId(attachment.getBlobId()), instance.getFormClassId(), bodyPart.getInputStream());
} catch (MessagingException messagingException) {
LOGGER.log(Level.SEVERE, "Unable to parse input", messagingException);
throw new WebApplicationException(Response.status(BAD_REQUEST).build());
} catch (IOException ioException) {
LOGGER.log(Level.SEVERE, "Could not write attachment to GCS", ioException);
throw new WebApplicationException(Response.status(SERVICE_UNAVAILABLE).build());
}
}
}
use of org.activityinfo.model.type.attachment.Attachment in project activityinfo by bedatadriven.
the class Updater method checkBlobPermissions.
/**
* Verifies that the user has permission to associate the given blob with this record.
*
* <p>Updating blob-valued fields is done by the user in two steps. First, the user uploads a file and
* receives a unique id for the blob. Then, the user updates a record's field with the blob's unique id. </p>
*
* <p>Once the blob is associated with the record, then any user with permission to view the record is extended
* permission to view the blob. This opens an avenue of attack where by an attacker with seeks to obtain access
* to a blob with some id by assigning it to an unrelated record to which they have access.</p>
*
* <p>For this reason, only users who originally uploaded the blob may assign the blob to a record's field value.</p>
*/
private void checkBlobPermissions(FormField field, Optional<FormRecord> existingResource, AttachmentValue updatedValue) {
AttachmentType fieldType = (AttachmentType) field.getType();
// Identity the blob ids that are already associated with this record
Set<String> existingBlobIds = new HashSet<>();
if (existingResource.isPresent()) {
JsonValue existingFieldValue = existingResource.get().getFields().get(field.getId().asString());
if (!existingFieldValue.isJsonNull()) {
AttachmentValue existingValue = fieldType.parseJsonValue(existingFieldValue);
for (Attachment attachment : existingValue.getValues()) {
existingBlobIds.add(attachment.getBlobId());
}
}
}
// Assert that the user owns the blob they are associating with the record
for (Attachment attachment : updatedValue.getValues()) {
if (!existingBlobIds.contains(attachment.getBlobId())) {
if (!blobAuthorizer.isOwner(userId, attachment.getBlobId())) {
throw new InvalidUpdateException(String.format("User %d does not own blob %s", userId, attachment.getBlobId()));
}
}
}
}
use of org.activityinfo.model.type.attachment.Attachment in project activityinfo by bedatadriven.
the class ImageUploadFieldWidget method clearValue.
@Override
public void clearValue() {
uploader.setAttachment(new Attachment());
setState(State.NONE);
}
Aggregations