NEW Restrict upload abilities in UploadField

This commit is contained in:
Ingo Schommer 2013-01-09 11:34:02 +01:00
parent 5f8115f4c7
commit 9310b8d86d
5 changed files with 70 additions and 11 deletions

View File

@ -16,8 +16,8 @@ Used in side panels and action tabs
.ss-uploadfield .middleColumn { width: 526px; padding: 0; background: #fff; border: 1px solid #b3b3b3; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); }
.ss-uploadfield .ss-uploadfield-item { margin: 0; padding: 15px; overflow: auto; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview { height: 60px; line-height: 60px; width: 80px; text-align: center; font-weight: bold; float: left; overflow: hidden; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview.ss-uploadfield-dropzone { -webkit-box-shadow: gray 0 0 4px 0 inset; -moz-box-shadow: gray 0 0 4px 0 inset; box-shadow: gray 0 0 4px 0 inset; border: 2px dashed gray; background: #d0d3d5; display: none; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info { margin: 0 0 0 100px; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-preview.ss-uploadfield-dropzone { -webkit-box-shadow: gray 0 0 4px 0 inset; -moz-box-shadow: gray 0 0 4px 0 inset; box-shadow: gray 0 0 4px 0 inset; border: 2px dashed gray; background: #d0d3d5; display: none; margin-right: 15px; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info { float: left; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name { display: block; line-height: 13px; height: 26px; margin: 0; text-align: left; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name b { font-weight: bold; padding: 0 5px 0 0; }
.ss-uploadfield .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .name { font-size: 11px; color: #848484; width: 290px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; display: inline; float: left; }

View File

@ -81,6 +81,10 @@ class UploadField extends FileField {
* @var int
*/
'allowedMaxFileNumber' => null,
/**
* @var boolean Can the user upload new files, or just select from existing files.
*/
'canUpload' => true,
/**
* @var int
*/
@ -441,7 +445,9 @@ class UploadField extends FileField {
* @return string json
*/
public function upload(SS_HTTPRequest $request) {
if($this->isDisabled() || $this->isReadonly()) return $this->httpError(403);
if($this->isDisabled() || $this->isReadonly() || !$this->canUpload()) {
return $this->httpError(403);
}
// Protect against CSRF on destructive action
$token = $this->getForm()->getSecurityToken();
@ -629,6 +635,12 @@ class UploadField extends FileField {
// Don't allow upload or edit of a relation when the underlying record hasn't been persisted yet
return (!$record || !$this->managesRelation() || $record->exists());
}
public function canUpload() {
$can = $this->getConfig('canUpload');
return (is_bool($can)) ? $can : Permission::check($can);
}
}
/**

View File

@ -47,11 +47,12 @@
border: 2px dashed $color-medium-separator;
background: $color-light-separator;
display: none;
margin-right: 15px;
}
}
.ss-uploadfield-item-info {
margin: 0 0 0 100px;
float: left;
.ss-uploadfield-item-name {
display: block;
line-height: 13px;

View File

@ -34,6 +34,7 @@
<% end_if %>
<% else %>
<div class="ss-uploadfield-item ss-uploadfield-addfile<% if $Items && $displayInput %> borderTop<% end_if %>" <% if not $displayInput %>style="display: none;"<% end_if %>>
<% if canUpload %>
<div class="ss-uploadfield-item-preview ss-uploadfield-dropzone ui-corner-all">
<% if $multiple %>
<% _t('UploadField.DROPFILES', 'drop files') %>
@ -41,6 +42,7 @@
<% _t('UploadField.DROPFILE', 'drop a file') %>
<% end_if %>
</div>
<% end_if %>
<div class="ss-uploadfield-item-info">
<label class="ss-uploadfield-item-name"><b>
<% if $multiple %>
@ -49,10 +51,12 @@
<% _t('UploadField.ATTACHFILE', 'Attach a file') %>
<% end_if %>
</b></label>
<label class="ss-uploadfield-fromcomputer ss-ui-button ui-corner-all" data-icon="drive-upload">
<% _t('UploadField.FROMCOMPUTER', 'From your computer') %>
<input id="$id" name="$getName" class="$extraClass ss-uploadfield-fromcomputer-fileinput" data-config="$configString" type="file"<% if $multiple %> multiple="multiple"<% end_if %> />
</label>
<% if canUpload %>
<label class="ss-uploadfield-fromcomputer ss-ui-button ui-corner-all" data-icon="drive-upload">
<% _t('UploadField.FROMCOMPUTER', 'From your computer') %>
<input id="$id" name="$getName" class="$extraClass ss-uploadfield-fromcomputer-fileinput" data-config="$configString" type="file"<% if $multiple %> multiple="multiple"<% end_if %> />
</label>
<% end_if %>
<button class="ss-uploadfield-fromfiles ss-ui-button ui-corner-all" data-icon="network-cloud"><% _t('UploadField.FROMFILES', 'From files') %></button>
<% if not $autoUpload %>
<button class="ss-uploadfield-startall ss-ui-button ui-corner-all" data-icon="navigation"><% _t('UploadField.STARTALL', 'Start all') %></button>

View File

@ -476,6 +476,42 @@ class UploadFieldTest extends FunctionalTest {
}
public function testCanUpload() {
$this->loginWithPermission('ADMIN');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$this->assertFalse(
(bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-fromcomputer-fileinput'),
'Removes input file control'
);
$this->assertFalse((bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-dropzone'),
'Removes dropzone');
$this->assertTrue(
(bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-fromfiles'),
'Keeps "From files" button'
);
}
public function testCanUploadWithPermissionCode() {
$field = new UploadField('MyField');
$field->setConfig('canUpload', true);
$this->assertTrue($field->canUpload());
$field->setConfig('canUpload', false);
$this->assertFalse($field->canUpload());
$this->loginWithPermission('ADMIN');
$field->setConfig('canUpload', false);
$this->assertFalse($field->canUpload());
$field->setConfig('canUpload', 'ADMIN');
$this->assertTrue($field->canUpload());
}
public function testIsSaveable() {
$form = $this->getMockForm();
@ -775,6 +811,10 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
$fieldSubfolder->setFolderName('UploadFieldTest/subfolder1');
$fieldSubfolder->setRecord($record);
$fieldCanUploadFalse = new UploadField('CanUploadFalseField');
$fieldCanUploadFalse->setConfig('canUpload', false);
$fieldCanUploadFalse->setRecord($record);
$form = new Form(
$this,
'Form',
@ -789,7 +829,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
$fieldManyMany,
$fieldReadonly,
$fieldDisabled,
$fieldSubfolder
$fieldSubfolder,
$fieldCanUploadFalse
),
new FieldList(
new FormAction('submit')
@ -805,7 +846,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
'ManyManyFiles',
'ReadonlyField',
'DisabledField',
'SubfolderField'
'SubfolderField',
'CanUploadFalseField'
)
);
return $form;