mirror of
https://github.com/haiwen/seahub.git
synced 2025-05-13 10:25:46 +00:00
Merge branch 'master' into 13.0
This commit is contained in:
commit
71966dd729
frontend/src
components
css
pages
org-admin/statistic
sys-admin
logs-page
repos
statistic
users
seahub
@ -17,7 +17,7 @@ function EmptyTip({ className = '', title, text, children }) {
|
||||
EmptyTip.propTypes = {
|
||||
className: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
text: PropTypes.any,
|
||||
children: PropTypes.any,
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,7 @@ const propTypes = {
|
||||
repoID: PropTypes.string,
|
||||
onDirentItemClick: PropTypes.func,
|
||||
onRepoItemClick: PropTypes.func,
|
||||
mode: PropTypes.string.isRequired,
|
||||
mode: PropTypes.string,
|
||||
fileSuffixes: PropTypes.arrayOf(PropTypes.string),
|
||||
currentPath: PropTypes.string,
|
||||
searchResults: PropTypes.array,
|
||||
|
@ -2,10 +2,10 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import TreeListView from './tree-list-view';
|
||||
import TreeNode from '../../components/tree-view/tree-node';
|
||||
import Dirent from '../../models/dirent';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import treeHelper from '../../components/tree-view/tree-helper';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import Dirent from '../../models/dirent';
|
||||
import toaster from '../toast';
|
||||
|
||||
const propTypes = {
|
||||
@ -54,7 +54,7 @@ class RepoListItem extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
if (repo && repo.repo_id === this.props.selectedRepo.repo_id || isCurrentRepo) {
|
||||
if (this.props.selectedRepo && repo && repo.repo_id === this.props.selectedRepo.repo_id || isCurrentRepo) {
|
||||
this.loadRepoDirentList(repo);
|
||||
this.loadRepoTimer = setTimeout(() => {
|
||||
const repoID = repo.repo_id;
|
||||
@ -69,7 +69,7 @@ class RepoListItem extends React.Component {
|
||||
componentDidUpdate(prevProps) {
|
||||
const { repo, selectedRepo, selectedPath, newFolderName } = this.props;
|
||||
// create new folder in selected repo or folder
|
||||
if (repo.repo_id === selectedRepo.repo_id && prevProps.selectedRepo !== selectedRepo) {
|
||||
if (repo && selectedRepo && repo.repo_id === selectedRepo.repo_id && prevProps.selectedRepo !== selectedRepo) {
|
||||
seafileAPI.listDir(repo.repo_id, selectedPath).then(res => {
|
||||
if (!this.isComponentMounted) return;
|
||||
const direntData = res.data.dirent_list.find(item => item.type === 'dir' && item.name === newFolderName);
|
||||
|
@ -136,3 +136,7 @@ body {
|
||||
border-radius: 3px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sf-save-file .file-chooser-scroll-wrapper .file-chooser-list-view-header {
|
||||
display: none;
|
||||
}
|
||||
|
@ -98,8 +98,9 @@
|
||||
}
|
||||
|
||||
.system-statistic-button {
|
||||
height: 31px;
|
||||
margin-left: 1rem;
|
||||
height: 30px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.rc-calendar table {
|
||||
|
@ -125,7 +125,7 @@ class StatisticCommonTool extends React.Component {
|
||||
value={endValue}
|
||||
onChange={this.onChange.bind(this, 'endValue')}
|
||||
/>
|
||||
<Button color="primary" className="operation-item system-statistic-button" onClick={this.onSubmit}>{gettext('Submit')}</Button>
|
||||
<Button color="primary" size="sm" className="system-statistic-button" onClick={this.onSubmit}>{gettext('Submit')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
@ -93,25 +93,6 @@ Content.propTypes = {
|
||||
|
||||
class Item extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isOpIconShown: false,
|
||||
};
|
||||
}
|
||||
|
||||
handleMouseOver = () => {
|
||||
this.setState({
|
||||
isOpIconShown: true
|
||||
});
|
||||
};
|
||||
|
||||
handleMouseOut = () => {
|
||||
this.setState({
|
||||
isOpIconShown: false
|
||||
});
|
||||
};
|
||||
|
||||
getActionTextByEType = (etype) => {
|
||||
if (etype.indexOf('add') != -1) {
|
||||
return gettext('Add');
|
||||
@ -129,9 +110,8 @@ class Item extends Component {
|
||||
case 'user':
|
||||
return <UserLink email={item.to_user_email} name={item.to_user_name} />;
|
||||
case 'group':
|
||||
return <Link to={`${siteRoot}sys/groups/${item.to_group_id}/libraries/`}>{item.to_group_name}</Link>;
|
||||
case 'department':
|
||||
return <Link to={`${siteRoot}sys/departments/${item.to_group_id}/`}>{item.to_group_name}</Link>;
|
||||
return <Link to={`${siteRoot}sys/groups/${item.to_group_id}/libraries/`}>{item.to_group_name}</Link>;
|
||||
case 'all':
|
||||
return <Link to={`${siteRoot}org/`}>{gettext('All')}</Link>;
|
||||
default:
|
||||
@ -142,7 +122,7 @@ class Item extends Component {
|
||||
render() {
|
||||
let { item } = this.props;
|
||||
return (
|
||||
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
|
||||
<tr>
|
||||
<td><UserLink email={item.from_user_email} name={item.from_user_name} /></td>
|
||||
<td>{this.getShareTo(item)}</td>
|
||||
<td>{this.getActionTextByEType(item.etype)}</td>
|
||||
|
@ -334,7 +334,7 @@ class Item extends Component {
|
||||
<td>{repo.id}</td>
|
||||
<td>
|
||||
{isGroupOwnedRepo ?
|
||||
<Link to={`${siteRoot}sys/departments/${departmentID}/`}>{repo.owner_name}</Link> :
|
||||
<Link to={`${siteRoot}sys/groups/${departmentID}/libraries/`}>{repo.owner_name}</Link> :
|
||||
<UserLink email={repo.owner_email} name={repo.owner_name} />
|
||||
}
|
||||
</td>
|
||||
|
@ -125,7 +125,7 @@ class StatisticCommonTool extends React.Component {
|
||||
value={endValue}
|
||||
onChange={this.onChange.bind(this, 'endValue')}
|
||||
/>
|
||||
<Button color="primary" className="operation-item system-statistic-button" onClick={this.onSubmit}>{gettext('Submit')}</Button>
|
||||
<Button color="primary" size="sm" className="system-statistic-button" onClick={this.onSubmit}>{gettext('Submit')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
@ -79,7 +79,6 @@ class Item extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isOpIconShown: false,
|
||||
highlight: false,
|
||||
};
|
||||
}
|
||||
@ -87,7 +86,6 @@ class Item extends Component {
|
||||
handleMouseEnter = () => {
|
||||
if (!this.props.isItemFreezed) {
|
||||
this.setState({
|
||||
isOpIconShown: true,
|
||||
highlight: true
|
||||
});
|
||||
}
|
||||
@ -96,7 +94,6 @@ class Item extends Component {
|
||||
handleMouseLeave = () => {
|
||||
if (!this.props.isItemFreezed) {
|
||||
this.setState({
|
||||
isOpIconShown: false,
|
||||
highlight: false
|
||||
});
|
||||
}
|
||||
@ -129,9 +126,7 @@ class Item extends Component {
|
||||
|
||||
render() {
|
||||
const { item } = this.props;
|
||||
const url = item.parent_group_id == 0 ?
|
||||
`${siteRoot}sys/groups/${item.id}/libraries/` :
|
||||
`${siteRoot}sys/departments/${item.id}/`;
|
||||
const url = `${siteRoot}sys/groups/${item.id}/libraries/`;
|
||||
return (
|
||||
<Fragment>
|
||||
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
||||
|
@ -5,7 +5,7 @@ import { siteRoot, gettext } from '../../../utils/constants';
|
||||
|
||||
const propTypes = {
|
||||
email: PropTypes.string,
|
||||
userName: PropTypes.string.isRequired,
|
||||
userName: PropTypes.string,
|
||||
currentItem: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
|
@ -24,27 +24,25 @@ class Content extends Component {
|
||||
return <p className="error text-center mt-4">{errorMsg}</p>;
|
||||
} else {
|
||||
const table = (
|
||||
<Fragment>
|
||||
<table className="table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%"></th>
|
||||
<th width="35%">{gettext('Name')}</th>
|
||||
<th width="20%">{gettext('Share From')}</th>
|
||||
<th width="20%">{gettext('Size')}</th>
|
||||
<th width="20%">{gettext('Last Update')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((item, index) => {
|
||||
return (<Item
|
||||
key={index}
|
||||
item={item}
|
||||
/>);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</Fragment>
|
||||
<table className="table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%"></th>
|
||||
<th width="35%">{gettext('Name')}</th>
|
||||
<th width="20%">{gettext('Share From')}</th>
|
||||
<th width="20%">{gettext('Size')}</th>
|
||||
<th width="20%">{gettext('Last Update')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items.map((item, index) => {
|
||||
return (<Item
|
||||
key={index}
|
||||
item={item}
|
||||
/>);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
return items.length ? table : <EmptyTip text={gettext('No libraries')} />;
|
||||
}
|
||||
@ -82,7 +80,7 @@ class Item extends Component {
|
||||
link = <UserLink email={item.owner_email} name={item.owner_name} />;
|
||||
} else {
|
||||
const groupID = item.owner_email.substring(0, index);
|
||||
link = <Link to={`${siteRoot}sys/departments/${groupID}/`}>{item.owner_name}</Link>;
|
||||
link = <Link to={`${siteRoot}sys/groups/${groupID}/libraries/`}>{item.owner_name}</Link>;
|
||||
}
|
||||
return link;
|
||||
};
|
||||
@ -92,15 +90,13 @@ class Item extends Component {
|
||||
const iconUrl = Utils.getLibIconUrl(item);
|
||||
const iconTitle = Utils.getLibIconTitle(item);
|
||||
return (
|
||||
<Fragment>
|
||||
<tr>
|
||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||
<td>{this.renderRepoName()}</td>
|
||||
<td>{this.getOwnerLink()}</td>
|
||||
<td>{Utils.bytesToSize(item.size)}</td>
|
||||
<td>{dayjs(item.last_modify).fromNow()}</td>
|
||||
</tr>
|
||||
</Fragment>
|
||||
<tr>
|
||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||
<td>{this.renderRepoName()}</td>
|
||||
<td>{this.getOwnerLink()}</td>
|
||||
<td>{Utils.bytesToSize(item.size)}</td>
|
||||
<td>{dayjs(item.last_modify).fromNow()}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +197,7 @@ def login(request, template_name='registration/login.html',
|
||||
getattr(settings, 'ENABLE_KRB5_LOGIN', False) or \
|
||||
getattr(settings, 'ENABLE_ADFS_LOGIN', False) or \
|
||||
getattr(settings, 'ENABLE_OAUTH', False) or \
|
||||
getattr(settings, 'ENABLE_CUSTOM_OAUTH', False) or \
|
||||
getattr(settings, 'ENABLE_CAS', False) or \
|
||||
getattr(settings, 'ENABLE_REMOTE_USER_AUTHENTICATION', False)
|
||||
|
||||
@ -296,7 +297,7 @@ def logout(request, next_page=None,
|
||||
# Local logout for ouath user.
|
||||
via_oauth = request.COOKIES.get('via_oauth', '')
|
||||
oauth_logout_url = getattr(settings, 'OAUTH_LOGOUT_URL', '')
|
||||
if getattr(settings, 'ENABLE_OAUTH', False) and via_oauth and oauth_logout_url:
|
||||
if (getattr(settings, 'ENABLE_OAUTH', False) or getattr(settings, 'ENABLE_CUSTOM_OAUTH', False)) and via_oauth and oauth_logout_url:
|
||||
response = HttpResponseRedirect(oauth_logout_url)
|
||||
response.delete_cookie('via_oauth')
|
||||
response.delete_cookie('seahub_auth')
|
||||
|
@ -1,9 +1,20 @@
|
||||
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||
|
||||
from django.urls import path
|
||||
from seahub.oauth.views import oauth_login, oauth_callback
|
||||
from seahub.oauth.views import oauth_login, oauth_callback, \
|
||||
custom_oauth_login_view, custom_oauth_callback_view
|
||||
|
||||
import seahub.settings as settings
|
||||
ENABLE_CUSTOM_OAUTH = getattr(settings, 'ENABLE_CUSTOM_OAUTH', False)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('login/', oauth_login, name='oauth_login'),
|
||||
path('callback/', oauth_callback, name='oauth_callback'),
|
||||
]
|
||||
|
||||
if ENABLE_CUSTOM_OAUTH:
|
||||
urlpatterns = [
|
||||
path('login/', custom_oauth_login_view, name='oauth_login'),
|
||||
path('callback/', custom_oauth_callback_view, name='oauth_callback'),
|
||||
]
|
||||
|
@ -58,6 +58,17 @@ if ENABLE_OAUTH:
|
||||
OAUTH_PROVIDER = getattr(settings, 'OAUTH_PROVIDER_DOMAIN', '')
|
||||
OAUTH_ATTRIBUTE_MAP = getattr(settings, 'OAUTH_ATTRIBUTE_MAP', {})
|
||||
|
||||
ENABLE_CUSTOM_OAUTH = getattr(settings, 'ENABLE_CUSTOM_OAUTH', False)
|
||||
if ENABLE_CUSTOM_OAUTH:
|
||||
try:
|
||||
current_path = os.path.dirname(os.path.abspath(__file__))
|
||||
conf_dir = os.path.join(current_path, '../../../../conf')
|
||||
sys.path.append(conf_dir)
|
||||
from seahub_custom_functions import custom_oauth_login, custom_oauth_callback
|
||||
ENABLE_CUSTOM_OAUTH = True
|
||||
except ImportError:
|
||||
ENABLE_CUSTOM_OAUTH = False
|
||||
|
||||
|
||||
def oauth_check(func):
|
||||
""" Decorator for check if OAuth valid.
|
||||
@ -260,3 +271,22 @@ def oauth_callback(request):
|
||||
response.set_cookie('seahub_auth', email + '@' + api_token.key)
|
||||
response.set_cookie('via_oauth', 'true')
|
||||
return response
|
||||
|
||||
|
||||
def custom_oauth_login_view(request):
|
||||
if not ENABLE_CUSTOM_OAUTH:
|
||||
return render_error(request, _('Feature is not enabled.'))
|
||||
|
||||
if request.user.is_authenticated:
|
||||
# already authenticated
|
||||
redirect_url = request.GET.get(auth.REDIRECT_FIELD_NAME, settings.LOGIN_REDIRECT_URL)
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
||||
return custom_oauth_login(request)
|
||||
|
||||
|
||||
def custom_oauth_callback_view(request):
|
||||
if not ENABLE_CUSTOM_OAUTH:
|
||||
return render_error(request, _('Feature is not enabled.'))
|
||||
|
||||
return custom_oauth_callback(request)
|
||||
|
@ -319,6 +319,8 @@ DISABLE_ADFS_USER_PWD_LOGIN = False
|
||||
ENABLE_OAUTH = False
|
||||
ENABLE_WATERMARK = False
|
||||
|
||||
ENABLE_CUSTOM_OAUTH = False
|
||||
|
||||
ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER = False
|
||||
ENABLE_SHOW_LOGIN_ID_WHEN_SEARCH_USER = False
|
||||
|
||||
@ -1217,7 +1219,7 @@ if ENABLE_REMOTE_USER_AUTHENTICATION:
|
||||
MIDDLEWARE.append('seahub.auth.middleware.SeafileRemoteUserMiddleware')
|
||||
AUTHENTICATION_BACKENDS += ('seahub.auth.backends.SeafileRemoteUserBackend',)
|
||||
|
||||
if ENABLE_OAUTH or ENABLE_WORK_WEIXIN or ENABLE_WEIXIN or ENABLE_DINGTALK:
|
||||
if ENABLE_OAUTH or ENABLE_CUSTOM_OAUTH or ENABLE_WORK_WEIXIN or ENABLE_WEIXIN or ENABLE_DINGTALK:
|
||||
AUTHENTICATION_BACKENDS += ('seahub.oauth.backends.OauthRemoteUserBackend',)
|
||||
|
||||
if ENABLE_CAS:
|
||||
|
@ -57,6 +57,9 @@ def sso(request):
|
||||
if getattr(settings, 'ENABLE_OAUTH', False):
|
||||
return HttpResponseRedirect(reverse('oauth_login') + next_param)
|
||||
|
||||
if getattr(settings, 'ENABLE_CUSTOM_OAUTH', False):
|
||||
return HttpResponseRedirect(reverse('oauth_login') + next_param)
|
||||
|
||||
if getattr(settings, 'ENABLE_CAS', False):
|
||||
return HttpResponseRedirect(reverse('cas_ng_login') + next_param)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user