Skip to content

Instantly share code, notes, and snippets.

@RobertApikyan
Created March 25, 2024 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobertApikyan/db171576a92371d0544c14c530300339 to your computer and use it in GitHub Desktop.
Save RobertApikyan/db171576a92371d0544c14c530300339 to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'dart:io';
import 'package:raiser/api/API.dart';
import 'package:raiser/api/ApiHeaders.dart';
import 'package:raiser/api/ApiRequestTracker.dart';
import 'package:raiser/repositories/OauthRepo.dart';
import 'package:raiser/repositories/RepoProvider.dart';
import 'package:raiser/rest/RestAbstract.dart';
class AuthorizationResponseMiddleware extends Middleware<RowResponse?> {
OauthRepo _oauth = Repositories.get().getOauthRepo();
static const unauthorizedCode = 401;
@override
Future<RowResponse?> onNext(
RowResponse? row, Middleware nextMiddleware) async {
final hasAuthorizationHeader = row != null &&
(row.request.headers?.containsKey(HttpHeaders.authorizationHeader) ??
false);
final isUnauthorized = row?.code == unauthorizedCode;
if (hasAuthorizationHeader && isUnauthorized) {
await Future.delayed(const Duration(seconds: 3));
if (_oauth.isRefreshTokenLocked()) {
return await _waitForRefreshAndRetry(row, nextMiddleware);
} else {
return await _refreshAndRetry(row, nextMiddleware);
}
}
return await super.onNext(row, nextMiddleware);
}
Future<RowResponse?> _refreshAndRetry(
RowResponse row, Middleware<dynamic> nextMiddleware) async {
final isSuccess = await _oauth.refreshTokenWithLock();
if (isSuccess) {
return await _repeatRequest(row, nextMiddleware);
} else {
throw AppRequestTrackerException(unauthorizedCode);
}
}
Future<RowResponse?> _waitForRefreshAndRetry(
RowResponse row, Middleware nextMiddleware) async {
final isSuccess = await _oauth.joinRefreshTokenLock();
if (isSuccess) {
return await _repeatRequest(row, nextMiddleware);
} else {
throw AppRequestTrackerException(unauthorizedCode);
}
}
Future<RowResponse?> _repeatRequest(
RowResponse row, Middleware nextMiddleware) async {
RestRequest request = row.request;
RestRequest newRequest = RestRequest(
method: request.method,
url: request.url,
headers: ApiHeaders.privateRequestHeaders,
body: request.body,
converterType: request.converterType);
RestResponse response = await apiClient!.execute(newRequest);
return await super.onNext(response.rowResponse, nextMiddleware);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment