mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-30 22:34:53 +00:00
wikis permission set (#2799)
This commit is contained in:
parent
c6cd6bb2c4
commit
1c4f48eef3
6
frontend/package-lock.json
generated
6
frontend/package-lock.json
generated
@ -10793,9 +10793,9 @@
|
||||
}
|
||||
},
|
||||
"seafile-js": {
|
||||
"version": "0.2.55",
|
||||
"resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.55.tgz",
|
||||
"integrity": "sha512-Q9qE/RE0rg3wmXlYENO8mcEhu+OHC3emK9/+Fq3k3u38z6iy/Kc/1ntJjNpHYI5VS4oipum/Lc8gIvPL/FZQAQ==",
|
||||
"version": "0.2.56",
|
||||
"resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.56.tgz",
|
||||
"integrity": "sha512-Stm5Xa3OmXZ8beNVftS2OPU5nZlGGSIL7JazD2R4KrOtxQElfUWA5XsGsFnfbuAFv25mUxABzteWpYsMPVtOqg==",
|
||||
"requires": {
|
||||
"axios": "^0.18.0",
|
||||
"form-data": "^2.3.2",
|
||||
|
@ -31,7 +31,7 @@
|
||||
"react-moment": "^0.7.9",
|
||||
"react-select": "^2.1.1",
|
||||
"reactstrap": "^6.4.0",
|
||||
"seafile-js": "^0.2.55",
|
||||
"seafile-js": "^0.2.56",
|
||||
"seafile-ui": "^0.1.10",
|
||||
"socket.io-client": "^2.2.0",
|
||||
"sw-precache-webpack-plugin": "0.11.4",
|
||||
|
@ -5,7 +5,7 @@ import Select from 'react-select';
|
||||
import makeAnimated from 'react-select/lib/animated';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api.js';
|
||||
import PermissionEditor from '../select-editor/permission-editor';
|
||||
import SharePermissionEditor from '../select-editor/share-permission-editor';
|
||||
|
||||
class GroupItem extends React.Component {
|
||||
|
||||
@ -40,7 +40,7 @@ class GroupItem extends React.Component {
|
||||
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||
<td className='name'>{item.group_info.name}</td>
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={true}
|
||||
isEditIconShow={this.state.isOperationShow}
|
||||
currentPermission={item.permission}
|
||||
@ -270,7 +270,7 @@ class ShareToGroup extends React.Component {
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={false}
|
||||
isEditIconShow={false}
|
||||
currentPermission={this.state.permission}
|
||||
|
@ -4,7 +4,7 @@ import AsyncSelect from 'react-select/lib/Async';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { Button } from 'reactstrap';
|
||||
import { seafileAPI } from '../../utils/seafile-api.js';
|
||||
import PermissionEditor from '../select-editor/permission-editor';
|
||||
import SharePermissionEditor from '../select-editor/share-permission-editor';
|
||||
|
||||
class UserItem extends React.Component {
|
||||
|
||||
@ -40,7 +40,7 @@ class UserItem extends React.Component {
|
||||
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||
<td className="name">{item.user_info.nickname}</td>
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={true}
|
||||
isEditIconShow={this.state.isOperationShow}
|
||||
currentPermission={currentPermission}
|
||||
@ -292,7 +292,7 @@ class ShareToUser extends React.Component {
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={false}
|
||||
isEditIconShow={false}
|
||||
currentPermission={this.state.permission}
|
||||
|
@ -11,7 +11,7 @@ const propTypes = {
|
||||
onPermissionChangedHandler: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class PermissionEditor extends React.Component {
|
||||
class SharePermissionEditor extends React.Component {
|
||||
|
||||
translatePermission = (permission) => {
|
||||
return Utils.sharePerms(permission);
|
||||
@ -31,6 +31,6 @@ class PermissionEditor extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
PermissionEditor.propTypes = propTypes;
|
||||
SharePermissionEditor.propTypes = propTypes;
|
||||
|
||||
export default PermissionEditor;
|
||||
export default SharePermissionEditor;
|
@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import SelectEditor from './select-editor';
|
||||
|
||||
const propTypes = {
|
||||
isTextMode: PropTypes.bool.isRequired,
|
||||
isEditIconShow: PropTypes.bool.isRequired,
|
||||
permissions: PropTypes.array.isRequired,
|
||||
currentPermission: PropTypes.string.isRequired,
|
||||
onPermissionChangedHandler: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class WikiPermissionEditor extends React.Component {
|
||||
|
||||
translatePermission = (permission) => {
|
||||
if (permission === 'private') {
|
||||
return gettext('Private');
|
||||
}
|
||||
|
||||
if (permission === 'public') {
|
||||
return gettext('Public');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SelectEditor
|
||||
isTextMode={this.props.isTextMode}
|
||||
isEditIconShow={this.props.isEditIconShow}
|
||||
options={this.props.permissions}
|
||||
currentOption={this.props.currentPermission}
|
||||
onOptionChangedHandler={this.props.onPermissionChangedHandler}
|
||||
translateOption={this.translatePermission}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WikiPermissionEditor.propTypes = propTypes;
|
||||
|
||||
export default WikiPermissionEditor;
|
@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||
import { gettext, siteRoot } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import WikiPermissionEditor from '../select-editor/wiki-permission-editor.js';
|
||||
import Toast from '../toast';
|
||||
import ModalPortal from '../modal-portal';
|
||||
import WikiDeleteDialog from '../dialog/wiki-delete-dialog';
|
||||
@ -26,7 +28,10 @@ class WikiListItem extends Component {
|
||||
isShowMenuControl: false,
|
||||
isRenameing: false,
|
||||
highlight: false,
|
||||
permission: this.props.wiki.permission,
|
||||
showOpIcon: false,
|
||||
};
|
||||
this.permissions = ['private', 'public'];
|
||||
}
|
||||
|
||||
clickMenuToggle = (e) => {
|
||||
@ -58,6 +63,7 @@ class WikiListItem extends Component {
|
||||
this.setState({
|
||||
isShowMenuControl: true,
|
||||
highlight: true,
|
||||
showOpIcon: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -67,10 +73,23 @@ class WikiListItem extends Component {
|
||||
this.setState({
|
||||
isShowMenuControl: false,
|
||||
highlight: false,
|
||||
showOpIcon: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
changePerm = (permission) => {
|
||||
let wiki = this.props.wiki;
|
||||
seafileAPI.updateWikiPermission(wiki.slug, permission).then(() => {
|
||||
this.setState({permission: permission});
|
||||
}).catch((error) => {
|
||||
if(error.response) {
|
||||
let errorMsg = error.response.data.error_msg;
|
||||
Toast.danger(errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onRenameToggle = (e) => {
|
||||
this.props.onFreezedItem();
|
||||
this.setState({
|
||||
@ -150,6 +169,15 @@ class WikiListItem extends Component {
|
||||
</td>
|
||||
<td><a href={userProfileURL} target='_blank'>{gettext(wiki.owner_nickname)}</a></td>
|
||||
<td>{moment(wiki.updated_at).fromNow()}</td>
|
||||
<td>
|
||||
<WikiPermissionEditor
|
||||
isTextMode={true}
|
||||
isEditIconShow={this.state.showOpIcon}
|
||||
currentPermission={this.state.permission}
|
||||
permissions={this.permissions}
|
||||
onPermissionChangedHandler={this.changePerm}
|
||||
/>
|
||||
</td>
|
||||
<td className="text-center cursor-pointer">
|
||||
{this.state.isShowMenuControl && (
|
||||
<Dropdown isOpen={this.state.isShowWikiMenu} toggle={this.onMenuToggle}>
|
||||
|
@ -38,9 +38,10 @@ class WikiListView extends Component {
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="50%">{gettext('Name')}</th>
|
||||
<th width="40%">{gettext('Name')}</th>
|
||||
<th width="20%">{gettext('Owner')}</th>
|
||||
<th width="20%">{gettext('Last Update')}</th>
|
||||
<th width="10%">{gettext('Permission')}</th>
|
||||
<th width="10%">{/* operation */}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -3,7 +3,7 @@ import { Link } from '@reach/router';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import { gettext, siteRoot, loginUrl, isPro } from '../../utils/constants';
|
||||
import PermissionEditor from '../../components/select-editor/permission-editor';
|
||||
import SharePermissionEditor from '../../components/select-editor/share-permission-editor';
|
||||
import SharedFolderInfo from '../../models/shared-folder-info';
|
||||
|
||||
class Content extends Component {
|
||||
@ -153,7 +153,7 @@ class Item extends Component {
|
||||
<td><Link to={folderUrl}>{item.folder_name}</Link></td>
|
||||
{shareTo}
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={true}
|
||||
isEditIconShow={this.state.showOpIcon}
|
||||
currentPermission={this.state.share_permission}
|
||||
|
@ -3,7 +3,7 @@ import { Link } from '@reach/router';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import { gettext, siteRoot, loginUrl, isPro } from '../../utils/constants';
|
||||
import PermissionEditor from '../../components/select-editor/permission-editor';
|
||||
import SharePermissionEditor from '../../components/select-editor/share-permission-editor';
|
||||
import SharedRepoInfo from '../../models/shared-repo-info';
|
||||
|
||||
class Content extends Component {
|
||||
@ -173,7 +173,7 @@ class Item extends Component {
|
||||
<td><Link to={repoUrl}>{item.repo_name}</Link></td>
|
||||
{shareTo}
|
||||
<td>
|
||||
<PermissionEditor
|
||||
<SharePermissionEditor
|
||||
isTextMode={true}
|
||||
isEditIconShow={this.state.showOpIcon}
|
||||
currentPermission={share_permission}
|
||||
|
@ -5,6 +5,7 @@ import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||
import MarkdownViewer from '../../components/markdown-viewer';
|
||||
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
|
||||
|
||||
let loginUser = window.app.pageOptions.username;
|
||||
const propTypes = {
|
||||
content: PropTypes.string,
|
||||
lastModified: PropTypes.string,
|
||||
@ -88,11 +89,13 @@ class MainPanel extends Component {
|
||||
<button className="btn btn-secondary operation-item" title="Edit File" onClick={this.onEditClick}>{gettext('Edit Page')}</button>
|
||||
}
|
||||
</div>
|
||||
<CommonToolbar
|
||||
repoID={repoID}
|
||||
onSearchedClick={this.props.onSearchedClick}
|
||||
searchPlaceholder={gettext('Search files in this library')}
|
||||
/>
|
||||
{loginUser &&
|
||||
<CommonToolbar
|
||||
repoID={repoID}
|
||||
onSearchedClick={this.props.onSearchedClick}
|
||||
searchPlaceholder={gettext('Search files in this library')}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<div className="cur-view-container">
|
||||
<div className="cur-view-path">
|
||||
|
@ -225,7 +225,7 @@ class WikiPagesDirView(APIView):
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# perm check
|
||||
if not wiki.check_access_wiki(request):
|
||||
if not wiki.has_read_perm(request.user):
|
||||
error_msg = "Permission denied"
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -266,7 +266,7 @@ class WikiPageContentView(APIView):
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# perm check
|
||||
if not wiki.check_access_wiki(request):
|
||||
if not wiki.has_read_perm(request.user):
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
|
@ -54,11 +54,11 @@ def slug(request, slug, file_path="home.md"):
|
||||
# perm check
|
||||
req_user = request.user.username
|
||||
|
||||
if not req_user:
|
||||
if not req_user and not wiki.has_read_perm(request.user):
|
||||
return redirect('auth_login')
|
||||
|
||||
if not wiki.check_access_wiki(request):
|
||||
return render_permission_error(request, _(u'Permission denied.'))
|
||||
else:
|
||||
if not wiki.has_read_perm(request.user):
|
||||
return render_permission_error(request, _(u'Unable to view Wiki'))
|
||||
|
||||
file_type, ext = get_file_type_and_ext(posixpath.basename(file_path))
|
||||
if file_type == IMAGE:
|
||||
|
Loading…
Reference in New Issue
Block a user