Skip to content
Snippets Groups Projects
Commit fac49a9b authored by Simon Künzel's avatar Simon Künzel
Browse files

Adjust OAuth to fix some problems where OAuth didn't finish (probably some...

Adjust OAuth to fix some problems where OAuth didn't finish (probably some race condition, RWTH servers caching problem)
parent 4b3bab05
Branches main
Tags v1.0.9
No related merge requests found
Pipeline #7710 passed
...@@ -214,7 +214,8 @@ ui.video_player.login_moodle.description = "Für Teilnehmer der Veranstaltung ve ...@@ -214,7 +214,8 @@ ui.video_player.login_moodle.description = "Für Teilnehmer der Veranstaltung ve
ui.video_player.login_moodle.not_in_course = "Du bist kein Teilnehmer des Moodle-Kurses!" ui.video_player.login_moodle.not_in_course = "Du bist kein Teilnehmer des Moodle-Kurses!"
ui.video_player.login_moodle.refresh_course = "Kurse aktualisieren" ui.video_player.login_moodle.refresh_course = "Kurse aktualisieren"
ui.video_player.login_oauth.finished_no_access = "OAuth erfolgreich allerdings hast Du keine Berechtigung für diese Vorlesung" ui.video_player.login_oauth.finished_no_access = "OAuth erfolgreich allerdings hast Du keine Berechtigung für diese Vorlesung"
ui.video_player.login_oauth.unfinished_popup_closed = "Popup wurde geschlossen bevor der OAuth fertig war" ui.video_player.login_oauth.waiting_popup_closed = "Popup wurde geschlossen. Warten auf Bestätigung des OAuth Anbieter..."
ui.video_player.login_oauth.unfinished_popup_closed = "Popup wurde geschlossen aber der OAuth wurde nicht erfolgreich abgeschlossen"
ui.video_player.login_oauth.waiting_for_finish = """ ui.video_player.login_oauth.waiting_for_finish = """
Bitte schließe den OAuth in dem neuen Fenster ab, welches sich geöffnet hat, und schließe es dann. Bitte schließe den OAuth in dem neuen Fenster ab, welches sich geöffnet hat, und schließe es dann.
""" """
......
...@@ -214,7 +214,8 @@ ui.video_player.login_moodle.description = "Available to participants of the Moo ...@@ -214,7 +214,8 @@ ui.video_player.login_moodle.description = "Available to participants of the Moo
ui.video_player.login_moodle.not_in_course = "You are not enrolled in the Moodle course" ui.video_player.login_moodle.not_in_course = "You are not enrolled in the Moodle course"
ui.video_player.login_moodle.refresh_course = "Refresh course" ui.video_player.login_moodle.refresh_course = "Refresh course"
ui.video_player.login_oauth.finished_no_access = "OAuth finished but you don't have permissions to access this lecture" ui.video_player.login_oauth.finished_no_access = "OAuth finished but you don't have permissions to access this lecture"
ui.video_player.login_oauth.unfinished_popup_closed = "Popup closed without finishing OAuth" ui.video_player.login_oauth.waiting_popup_closed = "Popup was closed. Waiting for OAuth Provider to confirm login..."
ui.video_player.login_oauth.unfinished_popup_closed = "Popup was closed but OAuth was completed successfully"
ui.video_player.login_oauth.waiting_for_finish = "Please finish the OAuth in the new window which has opened, then close it." ui.video_player.login_oauth.waiting_for_finish = "Please finish the OAuth in the new window which has opened, then close it."
ui.video_player.login_oauth.error_start = "Error while starting OAuth" ui.video_player.login_oauth.error_start = "Error while starting OAuth"
ui.video_player.login_oauth.error_finish = "Error while finishing OAuth" ui.video_player.login_oauth.error_finish = "Error while finishing OAuth"
......
...@@ -163,6 +163,11 @@ function PasswordAuthComponent({ course, lecture }: { course: course; lecture: l ...@@ -163,6 +163,11 @@ function PasswordAuthComponent({ course, lecture }: { course: course; lecture: l
); );
} }
const _OAUTH_FINISH_PERIODIC_CHECK_INTERVAL_SECONDS = 3;
const _OAUTH_FINISH_PERIODIC_CHECK_MAX_ATTEMPTS = Math.ceil(
30 / _OAUTH_FINISH_PERIODIC_CHECK_INTERVAL_SECONDS,
);
function OAuthComponent({ function OAuthComponent({
type, type,
course, course,
...@@ -178,7 +183,6 @@ function OAuthComponent({ ...@@ -178,7 +183,6 @@ function OAuthComponent({
const { language } = useLanguage(); const { language } = useLanguage();
const [isOAuthRunning, setIsOAuthRunning] = useState(false); const [isOAuthRunning, setIsOAuthRunning] = useState(false);
const [waitingForFinish, setWaitingForFinish] = useState(false);
const remainingFinishAttempts = useRef<number>(0); const remainingFinishAttempts = useRef<number>(0);
const popupClosed = useRef<boolean>(false); const popupClosed = useRef<boolean>(false);
...@@ -188,21 +192,25 @@ function OAuthComponent({ ...@@ -188,21 +192,25 @@ function OAuthComponent({
useEffect(() => { useEffect(() => {
return () => { return () => {
remainingFinishAttempts.current = 0; remainingFinishAttempts.current = 0;
popupClosed.current = true;
}; };
}, []); }, []);
const [fetchStatusDeferred, fetchStatusNow] = useDebouncedCall<void>(1000, () => // We had a periodic check in here, however, this caused some problems as the RWTH OAuth servers didn't always
// return the new logged in status immediately (there seems to be some caching of at least 20 seconds)
// Instead we now only rely on someone closing the popup, and then start a periodic timer for a few attempts.
const [fetchStatusDeferred, fetchStatusNow] = useDebouncedCall<void>(
_OAUTH_FINISH_PERIODIC_CHECK_INTERVAL_SECONDS * 1000,
() =>
api api
.getAuthenticationStatus({ lecture_id: lecture.id }) .getAuthenticationStatus({ lecture_id: lecture.id })
.then((res) => { .then((res) => {
if (res.is_lecture_authenticated) { if (res.is_lecture_authenticated) {
setIsOAuthRunning(false); setIsOAuthRunning(false);
setWaitingForFinish(false);
authStatus.addAuthenticatedMethod(type); authStatus.addAuthenticatedMethod(type);
authStatus.setCurrentlyAuthenticatedLectureId(lecture.id); authStatus.setCurrentlyAuthenticatedLectureId(lecture.id);
} else if (res.in_progress_authentication !== type) { } else if (res.in_progress_authentication !== type) {
setIsOAuthRunning(false); setIsOAuthRunning(false);
setWaitingForFinish(false);
setOauthInfo( setOauthInfo(
<span className="text-warning"> <span className="text-warning">
{language.get("ui.video_player.login_oauth.finished_no_access")} {language.get("ui.video_player.login_oauth.finished_no_access")}
...@@ -211,10 +219,19 @@ function OAuthComponent({ ...@@ -211,10 +219,19 @@ function OAuthComponent({
} else { } else {
if (remainingFinishAttempts.current > 0) { if (remainingFinishAttempts.current > 0) {
remainingFinishAttempts.current--; remainingFinishAttempts.current--;
if (
remainingFinishAttempts.current <=
_OAUTH_FINISH_PERIODIC_CHECK_MAX_ATTEMPTS - 2
) {
setOauthInfo(
language.get(
"ui.video_player.login_oauth.waiting_popup_closed",
),
);
}
fetchStatusDeferred(); fetchStatusDeferred();
} else if (popupClosed.current) { } else {
setIsOAuthRunning(false); setIsOAuthRunning(false);
setWaitingForFinish(false);
setOauthInfo( setOauthInfo(
<span className="text-warning"> <span className="text-warning">
{language.get( {language.get(
...@@ -222,8 +239,6 @@ function OAuthComponent({ ...@@ -222,8 +239,6 @@ function OAuthComponent({
)} )}
</span>, </span>,
); );
} else if (remainingFinishAttempts.current <= 0) {
console.log("Stopping automatic authentication status fetching");
} }
} }
}) })
...@@ -232,26 +247,27 @@ function OAuthComponent({ ...@@ -232,26 +247,27 @@ function OAuthComponent({
remainingFinishAttempts.current = 0; remainingFinishAttempts.current = 0;
if (popupClosed.current) { if (popupClosed.current) {
setIsOAuthRunning(false); setIsOAuthRunning(false);
setWaitingForFinish(false);
setOauthInfo(undefined); setOauthInfo(undefined);
} }
}), }),
); );
const startFinishListener = (popup: any) => { const startFinishListener = (popup: any) => {
setWaitingForFinish(true); setOauthInfo(language.get("ui.video_player.login_oauth.waiting_for_finish"));
setOauthInfo(undefined);
popupClosed.current = false; popupClosed.current = false;
remainingFinishAttempts.current = 120;
fetchStatusDeferred();
let popInterval = setInterval(() => { let popInterval = setInterval(() => {
if (popup.closed) { if (!popup.closed) {
remainingFinishAttempts.current = 1; return;
popupClosed.current = true; }
fetchStatusNow();
clearInterval(popInterval); clearInterval(popInterval);
if (popupClosed.current) {
// Also set on unmounting. Don't start a new timer then.
return;
} }
remainingFinishAttempts.current = _OAUTH_FINISH_PERIODIC_CHECK_MAX_ATTEMPTS;
popupClosed.current = true;
fetchStatusNow();
}, 100); }, 100);
}; };
...@@ -305,9 +321,6 @@ function OAuthComponent({ ...@@ -305,9 +321,6 @@ function OAuthComponent({
{isOAuthRunning && ( {isOAuthRunning && (
<div className="flex-shrink-0 spinner-border text-primary" role="status" /> <div className="flex-shrink-0 spinner-border text-primary" role="status" />
)} )}
{waitingForFinish && (
<span>{language.get("ui.video_player.login_oauth.waiting_for_finish")}</span>
)}
{oauthInfo && <span>{oauthInfo}</span>} {oauthInfo && <span>{oauthInfo}</span>}
</div> </div>
</> </>
......
...@@ -84,6 +84,7 @@ export function useDebouncedProcessing<D, R>( ...@@ -84,6 +84,7 @@ export function useDebouncedProcessing<D, R>(
function doProcessing(): Promise<R> | undefined { function doProcessing(): Promise<R> | undefined {
if (processingPromiseRef.current !== undefined) { if (processingPromiseRef.current !== undefined) {
// TODO this is wrong as it might return a promise for a processor which started before now() was called
return processingPromiseRef.current; return processingPromiseRef.current;
} }
if (unprocessedDataRef.current instanceof NoDataMarker) { if (unprocessedDataRef.current instanceof NoDataMarker) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment