diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index bd4bbbe..f31b10b 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -10,6 +10,7 @@ from rest_auth.registration.serializers import RegisterSerializer from rest_auth.serializers import PasswordChangeSerializer, PasswordResetSerializer, PasswordResetConfirmSerializer, LoginSerializer from rest_auth.serializers import UserDetailsSerializer import re +import time from . import models, fields, utils, utils_ldap, utils_auth, utils_stats from .. import settings, secrets @@ -556,12 +557,15 @@ class MyRegisterSerializer(RegisterSerializer): class MyPasswordChangeSerializer(PasswordChangeSerializer): def save(self): + request_id = self.request.data.get('request_id', '') + data = dict( username=self.user.username, password1=self.request.data['new_password1'], ) if utils_ldap.is_configured(): + if request_id: utils_stats.set_progress(request_id, 'Changing LDAP password...') if utils_ldap.set_password(data) != 200: msg = 'Problem connecting to LDAP server: set.' utils.alert_tanner(msg) @@ -576,6 +580,7 @@ class MyPasswordChangeSerializer(PasswordChangeSerializer): ) if utils_auth.wiki_is_configured(): + if request_id: utils_stats.set_progress(request_id, 'Changing Wiki password...') if utils_auth.set_wiki_password(data) != 200: msg = 'Problem connecting to Wiki Auth server: set.' utils.alert_tanner(msg) @@ -583,12 +588,16 @@ class MyPasswordChangeSerializer(PasswordChangeSerializer): raise ValidationError(dict(non_field_errors=msg)) if utils_auth.discourse_is_configured(): + if request_id: utils_stats.set_progress(request_id, 'Changing Discourse password...') if utils_auth.set_discourse_password(data) != 200: msg = 'Problem connecting to Discourse Auth server: set.' utils.alert_tanner(msg) logger.info(msg) raise ValidationError(dict(non_field_errors=msg)) + if request_id: utils_stats.set_progress(request_id, 'Done!') + time.sleep(1) + super().save() class MyPasswordResetSerializer(PasswordResetSerializer): diff --git a/webclient/src/Account.js b/webclient/src/Account.js index fe28b90..1a7d01b 100644 --- a/webclient/src/Account.js +++ b/webclient/src/Account.js @@ -5,7 +5,7 @@ import ReactCrop from 'react-image-crop'; import 'react-image-crop/dist/ReactCrop.css'; import './light.css'; import { Button, Container, Checkbox, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react'; -import { BasicTable, staticUrl, requester } from './utils.js'; +import { BasicTable, staticUrl, requester, randomString } from './utils.js'; import { LoginForm, SignupForm } from './LoginSignup.js'; function LogoutEverywhere(props) { @@ -54,6 +54,7 @@ function ChangePasswordForm(props) { const { token } = props; const [input, setInput] = useState({}); const [error, setError] = useState({}); + const [progress, setProgress] = useState([]); const [loading, setLoading] = useState(false); const history = useHistory(); @@ -64,12 +65,28 @@ function ChangePasswordForm(props) { const handleSubmit = (e) => { if (loading) return; setLoading(true); - requester('/password/change/', 'POST', token, input) + + const request_id = randomString(); + const getStatus = () => { + requester('/stats/progress/?request_id='+request_id, 'GET') + .then(res => { + setProgress(res); + }) + .catch(err => { + console.log(err); + }); + }; + const interval = setInterval(getStatus, 500); + + const data = { ...input, request_id: request_id }; + requester('/password/change/', 'POST', token, data) .then(res => { + clearInterval(interval); setError({}); history.push('/'); }) .catch(err => { + clearInterval(interval); setLoading(false); console.log(err); setError(err.data); @@ -106,6 +123,10 @@ function ChangePasswordForm(props) { {...makeProps('new_password2')} /> +

+ {progress.map(x => <>{x}
)} +

+ Submit