1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-20 10:58:33 +00:00

manage web api auth token on profile page

This commit is contained in:
lian
2021-06-11 14:34:54 +08:00
parent 8f392f1cb3
commit 2b67a6199f
4 changed files with 113 additions and 12 deletions

View File

@@ -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>

View File

@@ -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>
);
}
}

View File

@@ -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})

View File

@@ -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()