PLT-6924 Added ability to disable file uploads/downloads on old mobile apps (#7117)

This commit is contained in:
Harrison Healey
2017-08-04 14:05:33 -04:00
committed by Christopher Speller
parent 3998659236
commit fb2022fb1c
8 changed files with 176 additions and 97 deletions

View File

@@ -66,6 +66,53 @@ export default class StorageSettings extends AdminSettings {
}
renderSettings() {
const mobileUploadDownloadSettings = [];
if (window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
mobileUploadDownloadSettings.push(
<BooleanSetting
key='enableMobileUpload'
id='enableMobileUpload'
label={
<FormattedMessage
id='admin.file.enableMobileUploadTitle'
defaultMessage='Allow File Uploads on Mobile:'
/>
}
helpText={
<FormattedMessage
id='admin.file.enableMobileUploadDesc'
defaultMessage='When false, disables file uploads on mobile apps. If Allow File Sharing is set to true, users can still upload files from a mobile web browser.'
/>
}
value={this.state.enableMobileUpload}
onChange={this.handleChange}
disabled={!this.state.enableFileAttachments}
/>
);
mobileUploadDownloadSettings.push(
<BooleanSetting
key='enableMobileDownload'
id='enableMobileDownload'
label={
<FormattedMessage
id='admin.file.enableMobileDownloadTitle'
defaultMessage='Allow File Downloads on Mobile:'
/>
}
helpText={
<FormattedMessage
id='admin.file.enableMobileDownloadDesc'
defaultMessage='When false, disables file downloads on mobile apps. Users can still download files from a mobile web browser.'
/>
}
value={this.state.enableMobileDownload}
onChange={this.handleChange}
disabled={!this.state.enableFileAttachments}
/>
);
}
return (
<SettingsGroup>
<DropdownSetting
@@ -222,42 +269,7 @@ export default class StorageSettings extends AdminSettings {
value={this.state.enableFileAttachments}
onChange={this.handleChange}
/>
<BooleanSetting
id='enableMobileUpload'
label={
<FormattedMessage
id='admin.file.enableMobileUploadTitle'
defaultMessage='Allow File Uploads on Mobile:'
/>
}
helpText={
<FormattedMessage
id='admin.file.enableMobileUploadDesc'
defaultMessage='When false, disables file uploads on mobile apps. If Allow File Sharing is set to true, users can still upload files from a mobile web browser.'
/>
}
value={this.state.enableMobileUpload}
onChange={this.handleChange}
disabled={!this.state.enableFileAttachments}
/>
<BooleanSetting
id='enableMobileDownload'
label={
<FormattedMessage
id='admin.file.enableMobileDownloadTitle'
defaultMessage='Allow File Downloads on Mobile:'
/>
}
helpText={
<FormattedMessage
id='admin.file.enableMobileDownloadDesc'
defaultMessage='When false, disables file downloads on mobile apps. Users can still download files from a mobile web browser.'
/>
}
value={this.state.enableMobileDownload}
onChange={this.handleChange}
disabled={!this.state.enableFileAttachments}
/>
{mobileUploadDownloadSettings}
<TextSetting
id='maxFileSize'
label={

View File

@@ -28,6 +28,7 @@ import TeamStore from 'stores/team_store.jsx';
import ConfirmModal from './confirm_modal.jsx';
import Constants from 'utils/constants.jsx';
import * as FileUtils from 'utils/file_utils';
import {FormattedHTMLMessage, FormattedMessage} from 'react-intl';
import {browserHistory} from 'react-router/es6';
@@ -710,7 +711,7 @@ export default class CreatePost extends React.Component {
}
let attachmentsDisabled = '';
if (global.window.mm_config.EnableFileAttachments === 'false') {
if (!FileUtils.canUploadFiles()) {
attachmentsDisabled = ' post-create--attachment-disabled';
}

View File

@@ -1,15 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Constants from 'utils/constants.jsx';
import {getFileUrl, getFileThumbnailUrl} from 'mattermost-redux/utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import PropTypes from 'prop-types';
import React from 'react';
import {Tooltip, OverlayTrigger} from 'react-bootstrap';
import PropTypes from 'prop-types';
import Constants from 'utils/constants.jsx';
import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import React from 'react';
import {getFileUrl, getFileThumbnailUrl} from 'mattermost-redux/utils/file_utils';
export default class FileAttachment extends React.Component {
constructor(props) {
@@ -101,6 +101,8 @@ export default class FileAttachment extends React.Component {
trimmedFilename = fileName;
}
const canDownloadFiles = FileUtils.canDownloadFiles();
let filenameOverlay;
if (this.props.compactDisplay) {
filenameOverlay = (
@@ -124,7 +126,7 @@ export default class FileAttachment extends React.Component {
</a>
</OverlayTrigger>
);
} else {
} else if (canDownloadFiles) {
filenameOverlay = (
<OverlayTrigger
trigger={['hover', 'focus']}
@@ -143,6 +145,27 @@ export default class FileAttachment extends React.Component {
</a>
</OverlayTrigger>
);
} else {
filenameOverlay = (
<span className='post-image__name'>
{trimmedFilename}
</span>
);
}
let downloadButton = null;
if (canDownloadFiles) {
downloadButton = (
<a
href={fileUrl}
download={fileName}
className='post-image__download'
target='_blank'
rel='noopener noreferrer'
>
<span className='fa fa-download'/>
</a>
);
}
return (
@@ -157,15 +180,7 @@ export default class FileAttachment extends React.Component {
<div className='post-image__details'>
{filenameOverlay}
<div>
<a
href={fileUrl}
download={fileName}
className='post-image__download'
target='_blank'
rel='noopener noreferrer'
>
<span className='fa fa-download'/>
</a>
{downloadButton}
<span className='post-image__type'>{fileInfo.extension.toUpperCase()}</span>
<span className='post-image__size'>{Utils.fileSizeToString(fileInfo.size)}</span>
</div>

View File

@@ -1,10 +1,10 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import PropTypes from 'prop-types';
import React from 'react';
import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
export default class FileInfoPreview extends React.Component {
@@ -35,17 +35,31 @@ export default class FileInfoPreview extends React.Component {
const infoString = infoParts.join(', ');
return (
<div className='file-details__container'>
let preview = null;
if (FileUtils.canDownloadFiles()) {
preview = (
<a
className={'file-details__preview'}
to={fileUrl}
className='file-details__preview'
href={fileUrl}
target='_blank'
rel='noopener noreferrer'
>
<span className='file-details__preview-helper'/>
<img src={Utils.getFileIconPath(fileInfo)}/>
</a>
);
} else {
preview = (
<span className='file-details__preview'>
<span className='file-details__preview-helper'/>
<img src={Utils.getFileIconPath(fileInfo)}/>
</span>
);
}
return (
<div className='file-details__container'>
{preview}
<div className='file-details'>
<div className='file-details__name'>{fileInfo.name}</div>
<div className='file-details__info'>{infoString}</div>

View File

@@ -8,6 +8,7 @@ import Constants from 'utils/constants.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import DelayedAction from 'utils/delayed_action.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import {intlShape, injectIntl, defineMessages} from 'react-intl';
@@ -135,7 +136,7 @@ class FileUpload extends React.Component {
}
handleDrop(e) {
if (global.window.mm_config.EnableFileAttachments === 'false') {
if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -172,7 +173,7 @@ class FileUpload extends React.Component {
});
let dragsterActions = {};
if (global.window.mm_config.EnableFileAttachments === 'true') {
if (FileUtils.canUploadFiles()) {
dragsterActions = {
enter(dragsterEvent, e) {
var files = e.originalEvent.dataTransfer;
@@ -263,7 +264,7 @@ class FileUpload extends React.Component {
// This looks redundant, but must be done this way due to
// setState being an asynchronous call
if (items && items.length > 0) {
if (global.window.mm_config.EnableFileAttachments === 'false') {
if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -326,7 +327,7 @@ class FileUpload extends React.Component {
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.U) {
e.preventDefault();
if (global.window.mm_config.EnableFileAttachments === 'false') {
if (!FileUtils.canUploadFiles()) {
this.props.onUploadError(Utils.localizeMessage('file_upload.disabled', 'File attachments are disabled.'));
return;
}
@@ -377,7 +378,7 @@ class FileUpload extends React.Component {
const uploadsRemaining = Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId);
let fileDiv;
if (global.window.mm_config.EnableFileAttachments === 'true') {
if (FileUtils.canUploadFiles()) {
fileDiv = (
<div className='icon--attachment'>
<span

View File

@@ -1,25 +1,26 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AudioVideoPreview from './audio_video_preview.jsx';
import CodePreview from './code_preview.jsx';
import PDFPreview from './pdf_preview.jsx';
import FileInfoPreview from './file_info_preview.jsx';
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import * as Utils from 'utils/utils.jsx';
import {getFileUrl, getFilePreviewUrl} from 'mattermost-redux/utils/file_utils';
import Constants from 'utils/constants.jsx';
const KeyCodes = Constants.KeyCodes;
import $ from 'jquery';
import PropTypes from 'prop-types';
import React from 'react';
import {Modal} from 'react-bootstrap';
import * as GlobalActions from 'actions/global_actions.jsx';
import * as FileUtils from 'utils/file_utils';
import * as Utils from 'utils/utils.jsx';
import {KeyCodes} from 'utils/constants.jsx';
import {getFileUrl, getFilePreviewUrl} from 'mattermost-redux/utils/file_utils';
import AudioVideoPreview from './audio_video_preview.jsx';
import CodePreview from './code_preview.jsx';
import FileInfoPreview from './file_info_preview.jsx';
import PDFPreview from './pdf_preview.jsx';
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
import loadingGif from 'images/load.gif';
export default class ViewImageModal extends React.Component {
@@ -350,6 +351,10 @@ function ImagePreview({fileInfo, fileUrl}) {
previewUrl = fileUrl;
}
if (!FileUtils.canDownloadFiles()) {
return <img src={previewUrl}/>;
}
return (
<a
href={fileUrl}

View File

@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import PropTypes from 'prop-types';
import React from 'react';
import {FormattedMessage} from 'react-intl';
import PropTypes from 'prop-types';
import * as FileUtils from 'utils/file_utils';
import React from 'react';
export default class ViewImagePopoverBar extends React.Component {
export default class ViewImagePopoverBar extends React.PureComponent {
render() {
var publicLink = '';
if (global.window.mm_config.EnablePublicLink === 'true') {
@@ -34,21 +34,9 @@ export default class ViewImagePopoverBar extends React.Component {
footerClass += ' footer--show';
}
return (
<div
ref='imageFooter'
className={footerClass}
>
<span className='pull-left text'>
<FormattedMessage
id='view_image_popover.file'
defaultMessage='File {count, number} of {total, number}'
values={{
count: (this.props.fileId + 1),
total: this.props.totalFiles
}}
/>
</span>
let downloadLinks = null;
if (FileUtils.canDownloadFiles()) {
downloadLinks = (
<div className='image-links'>
{publicLink}
<a
@@ -64,6 +52,25 @@ export default class ViewImagePopoverBar extends React.Component {
/>
</a>
</div>
);
}
return (
<div
ref='imageFooter'
className={footerClass}
>
<span className='pull-left text'>
<FormattedMessage
id='view_image_popover.file'
defaultMessage='File {count, number} of {total, number}'
values={{
count: (this.props.fileId + 1),
total: this.props.totalFiles
}}
/>
</span>
{downloadLinks}
</div>
);
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import * as UserAgent from 'utils/user_agent';
export function canUploadFiles() {
if (window.mm_config.EnableFileAttachments === 'false') {
return false;
}
if (UserAgent.isMobileApp() && window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
return window.mm_config.EnableMobileFileUpload !== 'false';
}
return true;
}
export function canDownloadFiles() {
if (UserAgent.isMobileApp() && window.mm_license.IsLicensed === 'true' && window.mm_license.Compliance === 'true') {
return window.mm_config.EnableMobileFileDownload !== 'false';
}
return true;
}