mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-20 19:08:21 +00:00
manage web api auth token on profile page
This commit is contained in:
@@ -57,7 +57,7 @@ class UpdateWebdavPassword extends Component {
|
||||
<ModalHeader toggle={toggle}>{gettext('WebDav Password')}</ModalHeader>
|
||||
<ModalBody>
|
||||
<InputGroup className="">
|
||||
<Input type={this.state.isPasswordVisible ? 'text' : 'password'} value={this.state.password} onChange={this.handleInputChange} />
|
||||
<Input type={this.state.isPasswordVisible ? 'text' : 'password'} value={this.state.password} onChange={this.handleInputChange} autoComplete="new-password"/>
|
||||
<InputGroupAddon addonType="append">
|
||||
<Button onClick={this.togglePasswordVisible}><i className={`fas ${this.state.isPasswordVisible ? 'fa-eye': 'fa-eye-slash'}`}></i></Button>
|
||||
<Button onClick={this.generatePassword}><i className="fas fa-magic"></i></Button>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import ModalPortal from '../modal-portal';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
@@ -9,10 +10,15 @@ class WebAPIAuthToken extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
authToken: '******'
|
||||
authToken: '',
|
||||
isAuthTokenVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getAuthToken();
|
||||
}
|
||||
|
||||
getAuthToken = () => {
|
||||
seafileAPI.getAuthTokenBySession().then((res) => {
|
||||
this.setState({
|
||||
@@ -24,16 +30,58 @@ class WebAPIAuthToken extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
createAuthToken = () => {
|
||||
seafileAPI.createAuthTokenBySession().then((res) => {
|
||||
this.setState({
|
||||
authToken: res.data.token,
|
||||
isAuthTokenVisible: false
|
||||
});
|
||||
toaster.success(gettext('Success'));
|
||||
}).catch((error) => {
|
||||
let errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
});
|
||||
}
|
||||
|
||||
deleteAuthToken = () => {
|
||||
seafileAPI.deleteAuthTokenBySession().then((res) => {
|
||||
this.setState({
|
||||
authToken: '',
|
||||
isAuthTokenVisible: false
|
||||
});
|
||||
toaster.success(gettext('Success'));
|
||||
}).catch((error) => {
|
||||
let errorMsg = Utils.getErrorMsg(error);
|
||||
toaster.danger(errorMsg);
|
||||
});
|
||||
}
|
||||
|
||||
toggleAuthTokenVisible = () => {
|
||||
this.setState({
|
||||
isAuthTokenVisible: !this.state.isAuthTokenVisible
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { authToken } = this.state;
|
||||
const { authToken, isAuthTokenVisible } = this.state;
|
||||
return (
|
||||
<div id="get-auth-token" className="setting-item">
|
||||
<h3 className="setting-item-heading">{gettext('Web API Auth Token')}</h3>
|
||||
<div className="d-flex align-items-center">
|
||||
<input type="text" readOnly={true} value={authToken} className="form-control mr-2 col-sm-5" />
|
||||
<button className="btn btn-outline-primary" onClick={this.getAuthToken}>{gettext('Get')}</button>
|
||||
<React.Fragment>
|
||||
<div id="get-auth-token" className="setting-item">
|
||||
<h3 className="setting-item-heading">{gettext('Web API Auth Token')}</h3>
|
||||
{authToken ? (
|
||||
<React.Fragment>
|
||||
<div className="d-flex align-items-center">
|
||||
<label className="m-0 mr-2">{gettext('Token:')}</label>
|
||||
<input className="border-0 mr-1" type="text" value={isAuthTokenVisible ? authToken : '****************************************'} readOnly={true} size={Math.max(authToken.length, 10)} />
|
||||
<span onClick={this.toggleAuthTokenVisible} className={`eye-icon fas ${this.state.isAuthTokenVisible ? 'fa-eye': 'fa-eye-slash'}`}></span>
|
||||
</div>
|
||||
<button className="btn btn-outline-primary mt-2" onClick={this.deleteAuthToken}>{gettext('Delete')}</button>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<button className="btn btn-outline-primary" onClick={this.createAuthToken}>{gettext('Generate')}</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,8 @@ from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import get_token_v1, api_error
|
||||
from seahub.api2.utils import api_error
|
||||
from seahub.api2.models import Token
|
||||
|
||||
from seahub.settings import ENABLE_GET_AUTH_TOKEN_BY_SESSION
|
||||
|
||||
@@ -25,6 +26,35 @@ class AuthTokenBySession(APIView):
|
||||
error_msg = 'Feature is not enabled.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
token = get_token_v1(request.user.username)
|
||||
username = request.user.username
|
||||
try:
|
||||
token_obj = Token.objects.get(user=username)
|
||||
token = token_obj.key
|
||||
except Token.DoesNotExist:
|
||||
token = ''
|
||||
|
||||
return Response({'token': token.key})
|
||||
return Response({'token': token})
|
||||
|
||||
def post(self, request):
|
||||
|
||||
if not ENABLE_GET_AUTH_TOKEN_BY_SESSION:
|
||||
error_msg = 'Feature is not enabled.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
if len(Token.objects.filter(user=username)) > 0:
|
||||
return api_error(status.HTTP_409_CONFLICT, 'Token already exists.')
|
||||
|
||||
token_obj = Token.objects.add_or_update(username)
|
||||
return Response({'token': token_obj.key})
|
||||
|
||||
def delete(self, request):
|
||||
|
||||
if not ENABLE_GET_AUTH_TOKEN_BY_SESSION:
|
||||
error_msg = 'Feature is not enabled.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
Token.objects.filter(user=username).delete()
|
||||
|
||||
return Response({'success': True})
|
||||
|
@@ -15,6 +15,27 @@ from seahub.base.fields import LowerCaseCharField
|
||||
DESKTOP_PLATFORMS = ('windows', 'linux', 'mac')
|
||||
MOBILE_PLATFORMS = ('ios', 'android')
|
||||
|
||||
|
||||
class TokenManager(models.Manager):
|
||||
|
||||
def add_or_update(self, username, key=''):
|
||||
|
||||
"""Add or update user auth token.
|
||||
"""
|
||||
try:
|
||||
token_obj = self.get(user=username)
|
||||
except Token.DoesNotExist:
|
||||
token_obj = self.model(user=username)
|
||||
|
||||
if key is not None:
|
||||
token_obj.key = key
|
||||
else:
|
||||
token_obj.key = self.generate_key()
|
||||
|
||||
token_obj.save(using=self._db)
|
||||
return token_obj
|
||||
|
||||
|
||||
class Token(models.Model):
|
||||
"""
|
||||
The default authorization token model.
|
||||
@@ -23,6 +44,8 @@ class Token(models.Model):
|
||||
user = LowerCaseCharField(max_length=255, unique=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
objects = TokenManager()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.key:
|
||||
self.key = self.generate_key()
|
||||
|
Reference in New Issue
Block a user