1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 07:27:04 +00:00

receive share from other service

This commit is contained in:
lian
2021-09-27 17:44:23 +08:00
parent 5f61dbdb48
commit aee169b3f2
17 changed files with 711 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ import ShareAdminShareLinks from './pages/share-admin/share-links';
import ShareAdminUploadLinks from './pages/share-admin/upload-links';
import SharedLibraries from './pages/shared-libs/shared-libs';
import ShareWithOCM from './pages/share-with-ocm/shared-with-ocm';
import OCMViaWebdav from './pages/ocm-via-webdav/ocm-via-webdav';
import OCMRepoDir from './pages/share-with-ocm/remote-dir-view';
import MyLibraries from './pages/my-libs/my-libs';
import MyLibDeleted from './pages/my-libs/my-libs-deleted';
@@ -41,6 +42,7 @@ const StarredWrapper = MainContentWrapper(Starred);
const LinkedDevicesWrapper = MainContentWrapper(LinkedDevices);
const SharedLibrariesWrapper = MainContentWrapper(SharedLibraries);
const SharedWithOCMWrapper = MainContentWrapper(ShareWithOCM);
const OCMViaWebdavWrapper = MainContentWrapper(OCMViaWebdav);
const ShareAdminLibrariesWrapper = MainContentWrapper(ShareAdminLibraries);
const ShareAdminFoldersWrapper = MainContentWrapper(ShareAdminFolders);
const ShareAdminShareLinksWrapper = MainContentWrapper(ShareAdminShareLinks);
@@ -261,6 +263,7 @@ class App extends Component {
<ShareAdminUploadLinksWrapper path={siteRoot + 'share-admin-upload-links'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<SharedLibrariesWrapper path={siteRoot + 'shared-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<SharedWithOCMWrapper path={siteRoot + 'shared-with-ocm'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<OCMViaWebdavWrapper path={siteRoot + 'ocm-via-webdav'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<MyLibraries path={siteRoot + 'my-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
<MyLibDeleted path={siteRoot + 'my-libs/deleted/'} onSearchedClick={this.onSearchedClick} />
<LibContentView path={siteRoot + 'library/:repoID/*'} pathPrefix={this.state.pathPrefix} onMenuClick={this.onShowSidePanel} onTabNavClick={this.tabItemClick}/>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Link } from '@reach/router';
import { Badge } from 'reactstrap';
import { gettext, siteRoot, canPublishRepo, canAddRepo, canGenerateShareLink, canGenerateUploadLink, canInvitePeople, dtableWebServer, enableOCM } from '../utils/constants';
import { gettext, siteRoot, canPublishRepo, canAddRepo, canGenerateShareLink, canGenerateUploadLink, canInvitePeople, dtableWebServer, enableOCM, enableOCMViaWebdav } from '../utils/constants';
import { seafileAPI } from '../utils/seafile-api';
import { Utils } from '../utils/utils';
import toaster from './toast';
@@ -224,6 +224,14 @@ class MainSideNav extends React.Component {
</Link>
</li>
}
{enableOCMViaWebdav &&
<li className="nav-item">
<Link to={siteRoot + 'ocm-via-webdav/'} className={`nav-link ellipsis ${this.getActiveClass('ocm-via-webdav')}`} title={gettext('Shared from other servers')} onClick={(e) => this.tabItemClick(e, 'ocm-via-webdav')}>
<span className="sf3-font-share-from-other-servers sf3-font" aria-hidden="true"></span>
<span className="nav-text">{gettext('Shared from other servers')}</span>
</Link>
</li>
}
</ul>

View File

@@ -0,0 +1,184 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { Link } from '@reach/router';
import { gettext, siteRoot } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import toaster from '../../components/toast';
import Loading from '../../components/loading';
import EmptyTip from '../../components/empty-tip';
class Content extends Component {
render() {
const { loading, errorMsg, items } = this.props;
const emptyTip = (
<EmptyTip>
<h2>{gettext('No libraries have been shared with you')}</h2>
<p>{gettext('No libraries have been shared with you from other servers.')}</p>
</EmptyTip>
);
if (loading) {
return <Loading />;
} else if (errorMsg) {
return <p className="error text-center">{errorMsg}</p>;
} else {
const table = (
<table>
<thead>
<tr>
<th width="5%"></th>
<th width="30%">{gettext('Name')}</th>
<th width="35%">{gettext('Shared by')}</th>
<th width="20%">{gettext('Time')}</th>
<th width="5%">{/* operations */}</th>
<th width="5%">{/* operations */}</th>
</tr>
</thead>
<tbody>
{items.map((item, index) => {
return <Item
key={index}
item={item}
leaveShare={this.props.leaveShare}
/>;
})}
</tbody>
</table>
);
return items.length ? table : emptyTip;
}
}
}
Content.propTypes = {
loading: PropTypes.bool.isRequired,
errorMsg: PropTypes.string.isRequired,
items: PropTypes.array.isRequired,
};
class Item extends Component {
constructor(props) {
super(props);
this.state = {
isOpIconShown: false
};
}
handleMouseOver = () => {
this.setState({
isOpIconShown: true
});
}
handleMouseOut = () => {
this.setState({
isOpIconShown: false
});
}
downloadFile = () => {
let downloadUrl = siteRoot + 'ocm-via-webdav/download-received-file/?share_id=' + this.props.item.id;
window.location.href = downloadUrl;
}
leaveShare = (e) => {
e.preventDefault();
this.props.leaveShare(this.props.item);
}
render() {
const item = this.props.item;
const { isOpIconShown } = this.state;
item.icon_url = Utils.getFileIconUrl(item.name);
return (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
<td><img src={item.icon_url} width="24" /></td>
<td>
{item.name}
</td>
<td>{item.shared_by}</td>
<td title={moment(item.last_modified).format('llll')}>{moment(item.ctime).fromNow()}</td>
<td>
<a href="#" className={`action-icon sf2-icon-download ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Download')} onClick={this.downloadFile}></a>
</td>
<td>
<a href="#" className={`action-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Leave Share')} onClick={this.leaveShare}></a>
</td>
</tr>
);
}
}
Item.propTypes = {
item: PropTypes.object.isRequired
};
class OCMViaWebdav extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
errorMsg: '',
items: []
};
}
componentDidMount() {
const url = seafileAPI.server + '/ocm-via-webdav/received-shares/';
seafileAPI.req.get(url).then((res) => {
this.setState({
loading: false,
items: res.data.received_share_list
});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
leaveShare = (item) => {
const { id, name } = item;
const url = seafileAPI.server + '/ocm-via-webdav/received-shares/' + id + '/';
seafileAPI.req.delete(url).then((res) => {
let items = this.state.items.filter(item => {
return item.id != id;
});
this.setState({items: items});
toaster.success(gettext('Successfully unshared {name}').replace('{name}', name));
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
render() {
return (
<Fragment>
<div className="main-panel-center">
<div className="cur-view-container">
<div className="cur-view-path">
<h3 className="sf-heading m-0">{gettext('Shared from other servers')}</h3>
</div>
<div className="cur-view-content">
<Content
loading={this.state.loading}
errorMsg={this.state.errorMsg}
items={this.state.items}
leaveShare={this.leaveShare}
/>
</div>
</div>
</div>
</Fragment>
);
}
}
export default OCMViaWebdav;

View File

@@ -74,6 +74,7 @@ export const maxUploadFileSize = window.app.pageOptions.maxUploadFileSize;
export const maxNumberOfFilesForFileupload = window.app.pageOptions.maxNumberOfFilesForFileupload;
export const enableOCM = window.app.pageOptions.enableOCM;
export const ocmRemoteServers = window.app.pageOptions.ocmRemoteServers;
export const enableOCMViaWebdav = window.app.pageOptions.enableOCMViaWebdav;
export const curNoteMsg = window.app.pageOptions.curNoteMsg;
export const curNoteID = window.app.pageOptions.curNoteID;

View File

View File

@@ -0,0 +1,38 @@
# Generated by Django 2.2.14 on 2021-09-16 16:55
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ShareReceived',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.CharField(blank=True, max_length=255, null=True)),
('name', models.CharField(db_index=True, max_length=255)),
('owner', models.CharField(db_index=True, max_length=255)),
('owner_display_name', models.CharField(blank=True, max_length=255, null=True)),
('protocol_name', models.CharField(db_index=True, max_length=255)),
('shared_secret', models.CharField(db_index=True, max_length=255)),
('permissions', models.CharField(db_index=True, max_length=255)),
('provider_id', models.CharField(db_index=True, max_length=255)),
('resource_type', models.CharField(db_index=True, max_length=255)),
('share_type', models.CharField(db_index=True, max_length=255)),
('share_with', models.CharField(db_index=True, max_length=255)),
('shared_by', models.CharField(db_index=True, max_length=255)),
('shared_by_display_name', models.CharField(blank=True, max_length=255, null=True)),
('ctime', models.DateTimeField(default=django.utils.timezone.now)),
],
options={
'db_table': 'ocm_via_webdav_share_received',
},
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 2.2.14 on 2021-09-26 15:03
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('ocm_via_webdav', '0001_initial'),
]
operations = [
migrations.RenameModel(
old_name='ShareReceived',
new_name='ReceivedShares',
),
]

View File

@@ -0,0 +1,32 @@
# Generated by Django 2.2.14 on 2021-09-26 15:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ocm_via_webdav', '0002_auto_20210926_1503'),
]
operations = [
migrations.AlterField(
model_name='receivedshares',
name='name',
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name='receivedshares',
name='permissions',
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name='receivedshares',
name='protocol_name',
field=models.CharField(max_length=255),
),
migrations.AlterModelTable(
name='receivedshares',
table='ocm_via_webdav_received_shares',
),
]

View File

@@ -0,0 +1,25 @@
from django.db import models
from django.utils import timezone
class ReceivedShares(models.Model):
# https://cs3org.github.io/OCM-API/docs.html
class Meta:
db_table = 'ocm_via_webdav_received_shares'
description = models.CharField(max_length=255, blank=True, null=True)
name = models.CharField(max_length=255)
owner = models.CharField(max_length=255, db_index=True)
owner_display_name = models.CharField(max_length=255, blank=True, null=True)
protocol_name = models.CharField(max_length=255)
shared_secret = models.CharField(max_length=255, db_index=True)
permissions = models.CharField(max_length=255)
provider_id = models.CharField(max_length=255, db_index=True)
resource_type = models.CharField(max_length=255, db_index=True)
share_type = models.CharField(max_length=255, db_index=True)
share_with = models.CharField(max_length=255, db_index=True)
shared_by = models.CharField(max_length=255, db_index=True)
shared_by_display_name = models.CharField(max_length=255, blank=True, null=True)
ctime = models.DateTimeField(default=timezone.now)

View File

@@ -0,0 +1,373 @@
import base64
import logging
import requests
from constance import config
from django.http import HttpResponse
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.ocm_via_webdav.settings import ENABLE_OCM_VIA_WEBDAV, OCM_VIA_WEBDAV_ENDPOINT
from seahub.ocm_via_webdav.models import ReceivedShares
from seahub.ocm.settings import ENABLE_OCM, OCM_SEAFILE_PROTOCOL, \
OCM_RESOURCE_TYPE_LIBRARY, OCM_API_VERSION, OCM_SHARE_TYPES, \
OCM_ENDPOINT
logger = logging.getLogger(__name__)
class OCMProviderView(APIView):
throttle_classes = (UserRateThrottle,)
def get(self, request):
"""
Return ocm protocol info to remote server
"""
result = {}
if ENABLE_OCM:
result = {
'enabled': True,
'apiVersion': OCM_API_VERSION,
'endPoint': config.SERVICE_URL + '/' + OCM_ENDPOINT,
'resourceTypes': {
'name': OCM_RESOURCE_TYPE_LIBRARY,
'shareTypes': OCM_SHARE_TYPES,
'protocols': {
OCM_SEAFILE_PROTOCOL: OCM_SEAFILE_PROTOCOL,
}
}
}
if ENABLE_OCM_VIA_WEBDAV:
result = {
'apiVersion': '1.0-proposal1',
'enabled': True,
'endPoint': config.SERVICE_URL + '/' + OCM_VIA_WEBDAV_ENDPOINT,
'resourceTypes': {
'name': 'file',
'protocols': {'webdav': 'TODO'},
'shareTypes': ['user'],
}
}
return Response(result)
class SharesView(APIView):
throttle_classes = (UserRateThrottle,)
def post(self, request):
"""
Receive share from other service
"""
if not ENABLE_OCM_VIA_WEBDAV:
error_msg = 'OCM via webdav feature is not enabled.'
return api_error(501, error_msg)
# {'description': '',
# 'name': 'file-3-in-nextcloud-folder.md',
# 'owner': 'lian@https://nextcloud.seafile.top/',
# 'ownerDisplayName': 'lian',
# 'protocol': {'name': 'webdav',
# 'options': {'permissions': '{http://open-cloud-mesh.org/ns}share-permissions',
# 'sharedSecret': 'HdjKpI4o6lamWwN'}},
# 'providerId': 9,
# 'resourceType': 'file',
# 'shareType': 'user',
# 'shareWith': 'lian@lian.com@https://demo.seafile.top', # or 'lian@https://demo.seafile.top',
# 'sharedBy': 'lian@https://nextcloud.seafile.top/',
# 'sharedByDisplayName': 'lian'}
protocol_dict = request.data.get('protocol', {})
protocol_name = protocol_dict.get('name')
shared_secret = protocol_dict.get('options').get('sharedSecret')
permissions = protocol_dict.get('options').get('permissions')
owner = request.data.get('owner')
owner_display_name = request.data.get('owner_display_name')
name = request.data.get('name')
description = request.data.get('description')
provider_id = request.data.get('providerId')
resource_type = request.data.get('resourceType')
share_type = request.data.get('shareType')
share_with = request.data.get('shareWith').split('http')[0].rstrip('@')
shared_by = request.data.get('sharedBy')
shared_by_display_name = request.data.get('sharedByDisplayName')
share = ReceivedShares(description=description,
name=name,
owner=owner,
owner_display_name=owner_display_name,
protocol_name=protocol_name,
shared_secret=shared_secret,
permissions=permissions,
provider_id=provider_id,
resource_type=resource_type,
share_type=share_type,
share_with=share_with,
shared_by=shared_by,
shared_by_display_name=shared_by_display_name)
share.save()
result = {
"recipientDisplayName": email2nickname(share_with)
}
return Response(result, status=status.HTTP_201_CREATED)
class ReceivedSharesView(APIView):
throttle_classes = (UserRateThrottle,)
def get(self, request):
"""
Get items shared from other service.
"""
if not ENABLE_OCM_VIA_WEBDAV:
error_msg = 'OCM via webdav feature is not enabled.'
return api_error(501, error_msg)
username = request.user.username
info_list = []
for share in ReceivedShares.objects.filter(share_with=username):
info = {}
info['id'] = share.id
info['name'] = share.name
info['ctime'] = share.ctime
info['shared_by'] = share.shared_by
info_list.append(info)
result = {
'received_share_list': info_list
}
return Response(result)
class ReceivedShareView(APIView):
throttle_classes = (UserRateThrottle,)
def delete(self, request, share_id):
"""
Delete item shared from other service.
"""
if not ENABLE_OCM_VIA_WEBDAV:
error_msg = 'OCM via webdav feature is not enabled.'
return api_error(501, error_msg)
try:
share = ReceivedShares.objects.get(id=share_id)
except ReceivedShares.DoesNotExist:
error_msg = "OCM share {} not found.".format(share_id)
return api_error(404, error_msg)
username = request.user.username
if share.share_with != username:
error_msg = 'Permission denied.'
return api_error(403, error_msg)
# get remote server endpoint
shared_by = share.shared_by
remote_domain = shared_by.split('@')[-1]
remote_domain = remote_domain.rstrip('/')
ocm_provider_url = remote_domain + '/ocm-provider/'
resp = requests.get(ocm_provider_url)
end_point = resp.json().get('endPoint')
if not end_point:
logger.error('Can not get endPoint from {}'.format(ocm_provider_url))
logger.error(resp.content)
end_point = end_point.rstrip('/')
# send SHARE_DECLINED notification
data = {
"notification": {
"message": "Recipient declined the share",
"sharedSecret": ""
},
"notificationType": "SHARE_DECLINED",
"providerId": "",
"resourceType": ""
}
data['notification']['sharedSecret'] = share.shared_secret
data['providerId'] = share.provider_id
data['resourceType'] = share.resource_type
notifications_url = end_point + '/notifications'
resp = requests.post(notifications_url, json=data)
if resp.status_code != 201:
logger.error('Error occurred when send notification to {}'.format(notifications_url))
logger.error(resp.content)
share.delete()
result = {
'success': True
}
return Response(result)
class DownloadReceivedFileView(APIView):
throttle_classes = (UserRateThrottle,)
def get(self, request):
"""
Download received file.
"""
if not ENABLE_OCM_VIA_WEBDAV:
error_msg = 'OCM via webdav feature is not enabled.'
return api_error(501, error_msg)
share_id = request.GET.get('share_id')
if not share_id:
error_msg = 'share_id invalid.'
return api_error(400, error_msg)
try:
share_id = int(share_id)
except ValueError as e:
logger.error(e)
error_msg = 'share_id invalid.'
return api_error(400, error_msg)
try:
share = ReceivedShares.objects.get(id=share_id)
except ReceivedShares.DoesNotExist:
error_msg = "OCM share {} not found.".format(share_id)
return api_error(404, error_msg)
# get remote server endpoint
shared_by = share.shared_by
remote_domain = shared_by.split('@')[-1]
remote_domain = remote_domain.rstrip('/')
ocm_provider_url = remote_domain + '/ocm-provider/'
resp = requests.get(ocm_provider_url)
# {
# 'apiVersion': '1.0-proposal1',
# 'enabled': True,
# 'endPoint': 'https://nextcloud.seafile.top/index.php/ocm',
# 'resourceTypes': [
# {
# 'name': 'file',
# 'protocols': {'webdav': '/public.php/webdav/'},
# 'shareTypes': ['user', 'group']
# }
# ]
# }
resource_types = resp.json().get('resourceTypes', [])
if not resource_types:
logger.error('Can not get resource_types from {}'.format(ocm_provider_url))
logger.error(resp.content)
error_msg = 'Internal Server Error'
return api_error(501, error_msg)
protocols = resource_types[0].get('protocols')
if not protocols:
logger.error('Can not get protocols from {}'.format(ocm_provider_url))
logger.error(resp.content)
error_msg = 'Internal Server Error'
return api_error(501, error_msg)
webdav_url = protocols.get('webdav')
if not webdav_url:
logger.error('Can not get webdav url from {}'.format(ocm_provider_url))
logger.error(resp.content)
error_msg = 'Internal Server Error'
return api_error(501, error_msg)
# download file via webdav
full_webdav_url = remote_domain + webdav_url
def format_string(string):
return string + (4 - len(string) % 4) * ':'
shared_secret = share.shared_secret
token = base64.b64encode('{}'.format(format_string(shared_secret)).encode('utf-8'))
headers = {"Authorization": "Basic {}".format(token.decode('utf-8'))}
download_file_resp = requests.get(full_webdav_url, headers=headers)
response = HttpResponse(download_file_resp.content, content_type="application/octet-stream")
response['Content-Disposition'] = 'attachment; filename={}'.format(share.name)
return response
class NotificationsView(APIView):
throttle_classes = (UserRateThrottle,)
def post(self, request):
"""
Receive notification from remote server.
"""
if not ENABLE_OCM_VIA_WEBDAV:
error_msg = 'OCM via webdav feature is not enabled.'
return api_error(501, error_msg)
# {'notification': {'messgage': 'file is no longer shared with you',
# 'sharedSecret': 'QoVQuBhqphvVYvz'},
# 'notificationType': 'SHARE_UNSHARED',
# 'providerId': '13',
# 'resourceType': 'file'}
notification_type = request.data.get('notificationType')
notification_dict = request.data.get('notification')
shared_secret = notification_dict.get('sharedSecret')
provider_id = notification_dict.get('providerId')
error_result_not_found = {
"message": "RESOURCE_NOT_FOUND",
"validationErrors": [
{
"name": "",
"message": "NOT_FOUND"
}
]
}
if notification_type == 'SHARE_UNSHARED':
try:
share = ReceivedShares.objects.get(shared_secret=shared_secret)
except ReceivedShares.DoesNotExist:
error_msg = "OCM share with secret {} not found.".format(shared_secret)
error_result_not_found['validationErrors']['name'] = 'sharedSecret'
return Response(error_result_not_found, status=400)
if share.provider_id != provider_id:
error_msg = "OCM share with provider id {} not found.".format(provider_id)
error_result_not_found['validationErrors']['name'] = 'providerID'
return Response(error_result_not_found, status=400)
share.delete()
return Response({}, status=status.HTTP_201_CREATED)

View File

@@ -0,0 +1,4 @@
from django.conf import settings
ENABLE_OCM_VIA_WEBDAV = getattr(settings, 'ENABLE_OCM_VIA_WEBDAV', False)
OCM_VIA_WEBDAV_ENDPOINT = getattr(settings, 'OCM_VIA_WEBDAV_ENDPOINT', 'ocm-via-webdav')

View File

@@ -0,0 +1,17 @@
from django.urls import path
from seahub.views import react_fake_view
from seahub.ocm_via_webdav.ocm_api import SharesView, ReceivedSharesView, \
ReceivedShareView, DownloadReceivedFileView, NotificationsView
urlpatterns = [
path(r'', react_fake_view, name="ocm_via_webdav"),
path('shares', SharesView.as_view(), name='ocm-via-webdav-shares'),
path('notifications', NotificationsView.as_view(), name='ocm-via-webdav-notifications'),
path('received-shares/', ReceivedSharesView.as_view(), name='ocm-via-webdav-received-shares'),
path('received-shares/<int:share_id>/', ReceivedShareView.as_view(), name='ocm-via-webdav-received-share'),
path('download-received-file/', DownloadReceivedFileView.as_view(), name='ocm-via-webdav-download-received-file'),
]

View File

@@ -263,7 +263,7 @@ INSTALLED_APPS = [
'seahub.abuse_reports',
'seahub.repo_auto_delete',
'seahub.ocm',
'seahub.ocm_via_webdav',
'seahub.search',
'seahub.sysadmin_extra',
'seahub.organizations',

View File

@@ -106,6 +106,7 @@
thumbnailSizeForOriginal: {{ thumbnail_size_for_original }},
repoPasswordMinLength: {{repo_password_min_length}},
canAddPublicRepo: {% if can_add_public_repo %} true {% else %} false {% endif %},
enableOCMViaWebdav: {% if enable_ocm_via_webdav %} true {% else %} false {% endif %},
enableOCM: {% if enable_ocm %} true {% else %} false {% endif %},
ocmRemoteServers: (function () {
var servers = [];

View File

@@ -106,6 +106,8 @@ from seahub.api2.endpoints.ocm_repos import OCMReposDirView, OCMReposDownloadLin
OCMReposUploadLinkView
from seahub.api2.endpoints.custom_share_permissions import CustomSharePermissionsView, CustomSharePermissionView
from seahub.ocm_via_webdav.ocm_api import OCMProviderView
from seahub.api2.endpoints.repo_share_links import RepoShareLinks, RepoShareLink
from seahub.api2.endpoints.repo_upload_links import RepoUploadLinks, RepoUploadLink
@@ -194,6 +196,7 @@ urlpatterns = [
url(r'^shib-login/', shib_login, name="shib_login"),
url(r'^oauth/', include('seahub.oauth.urls')),
url(r'^thirdparty-editor/', include('seahub.thirdparty_editor.urls')),
url(r'^ocm-via-webdav/', include('seahub.ocm_via_webdav.urls')),
url(r'^$', react_fake_view, name='libraries'),
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
@@ -474,7 +477,7 @@ urlpatterns = [
## user::ocm
# ocm inter-server api, interact with other server
url(r'ocm-provider/$', OCMProtocolView.as_view(), name='api-v2.1-ocm-protocol'),
url(r'ocm-provider/$', OCMProviderView.as_view(), name='api-v2.1-ocm-protocol'),
url(r'' + OCM_ENDPOINT + 'shares/$', OCMSharesView.as_view(), name='api-v2.1-ocm-shares'),
url(r'' + OCM_ENDPOINT + 'notifications/$', OCMNotificationsView.as_view(), name='api-v2.1-ocm-notifications'),

View File

@@ -61,6 +61,7 @@ from seahub.settings import AVATAR_FILE_STORAGE, \
from seahub.wopi.settings import ENABLE_OFFICE_WEB_APP
from seahub.onlyoffice.settings import ONLYOFFICE_DESKTOP_EDITORS_PORTAL_LOGIN
from seahub.ocm.settings import ENABLE_OCM, OCM_REMOTE_SERVERS
from seahub.ocm_via_webdav.settings import ENABLE_OCM_VIA_WEBDAV
from seahub.constants import HASH_URLS, PERMISSION_READ
from seahub.group.settings import GROUP_IMPORT_MEMBERS_EXTRA_MSG
@@ -1201,6 +1202,7 @@ def react_fake_view(request, **kwargs):
'additional_share_dialog_note': ADDITIONAL_SHARE_DIALOG_NOTE,
'additional_app_bottom_links': ADDITIONAL_APP_BOTTOM_LINKS,
'additional_about_dialog_links': ADDITIONAL_ABOUT_DIALOG_LINKS,
'enable_ocm_via_webdav': ENABLE_OCM_VIA_WEBDAV,
'enable_ocm': ENABLE_OCM,
'ocm_remote_servers': OCM_REMOTE_SERVERS,
'enable_share_to_department': settings.ENABLE_SHARE_TO_DEPARTMENT,