Skip to content

Commit

Permalink
417-two-loading-indicators (#418)
Browse files Browse the repository at this point in the history
* nullcheck disabledFeatures

* Refresh push tokens manually fix

* 4.4.0 patchnotes

* update versionnumber

* fix folder issue

* fix folder issue

* fix folder issue

* changed warning to info

* fix tokenfolder issue

* fix folder issue

* fixed mutex

* show only 2 newest patchnotes

* Update pubspec.yaml

* fixed translation error

* fixed some translations

* update versionnumber

* more tests and minor optimizations

* more tests and minor optimizations

* fixed test

* fix tests

* fixed minor import issues

* added sortable test

* fix test

* removed prints

* show error qr scanner messanges

* fix issue that widget did not rebuild

* update buildnumber

* can now handle lowercase written algorithms

* SendErrorDialog popUntil

* renamed file and class of PrivacyideaIOClient

* hid RefreshIndicator

* ios

* test fix

* fix tests

* fix tests

* fix test
  • Loading branch information
frankmer authored Jul 12, 2024
1 parent 5211cb9 commit 6219ad3
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 179 deletions.
4 changes: 2 additions & 2 deletions integration_test/views_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void main() {
late final MockTokenFolderRepository mockTokenFolderRepository;
late final MockRsaUtils mockRsaUtils;
late final MockFirebaseUtils mockFirebaseUtils;
late final MockPrivacyIdeaIOClient mockIOClient;
late final MockPrivacyideaIOClient mockIOClient;
late final MockIntroductionRepository mockIntroductionRepository;
setUp(() {
mockSettingsRepository = MockSettingsRepository();
Expand Down Expand Up @@ -63,7 +63,7 @@ void main() {
mockFirebaseUtils = MockFirebaseUtils();
when(mockFirebaseUtils.getFBToken()).thenAnswer((_) => Future.value('fbToken'));
when(mockRsaUtils.deserializeRSAPublicKeyPKCS1('publicKey')).thenAnswer((_) => RSAPublicKey(BigInt.one, BigInt.one));
mockIOClient = MockPrivacyIdeaIOClient();
mockIOClient = MockPrivacyideaIOClient();
when(mockIOClient.doPost(
url: anyNamed('url'),
body: anyNamed('body'),
Expand Down
180 changes: 90 additions & 90 deletions ios/Runner.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions lib/state_notifiers/push_request_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import '../repo/secure_push_request_repository.dart';
import '../utils/custom_int_buffer.dart';
import '../utils/globals.dart';
import '../utils/logger.dart';
import '../utils/network_utils.dart';
import '../utils/privacyidea_io_client.dart';
import '../utils/push_provider.dart';
import '../utils/riverpod_providers.dart';
import '../utils/rsa_utils.dart';
Expand All @@ -48,19 +48,19 @@ class PushRequestNotifier extends StateNotifier<PushRequestState> {

PushProvider _pushProvider;
PushProvider get pushProvider => _pushProvider;
final PrivacyIdeaIOClient _ioClient;
final PrivacyideaIOClient _ioClient;
final RsaUtils _rsaUtils;

final Map<String, Timer> _expirationTimers = {};

PushRequestNotifier({
PushRequestState? initState,
PrivacyIdeaIOClient? ioClient,
PrivacyideaIOClient? ioClient,
required PushProvider pushProvider,
required this.ref,
RsaUtils? rsaUtils,
PushRequestRepository? pushRepo,
}) : _ioClient = ioClient ?? const PrivacyIdeaIOClient(),
}) : _ioClient = ioClient ?? const PrivacyideaIOClient(),
_pushProvider = pushProvider,
_rsaUtils = rsaUtils ?? const RsaUtils(),
_pushRepo = pushRepo ?? const SecurePushRequestRepository(),
Expand Down
24 changes: 5 additions & 19 deletions lib/state_notifiers/token_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import '../utils/globals.dart';
import '../utils/identifiers.dart';
import '../utils/lock_auth.dart';
import '../utils/logger.dart';
import '../utils/network_utils.dart';
import '../utils/privacyidea_io_client.dart';
import '../utils/riverpod_providers.dart';
import '../utils/rsa_utils.dart';
import '../utils/utils.dart';
Expand All @@ -47,19 +47,19 @@ class TokenNotifier extends StateNotifier<TokenState> {
final _updatingTokensMutex = Mutex();
final TokenRepository _repo;
final RsaUtils _rsaUtils;
final PrivacyIdeaIOClient _ioClient;
final PrivacyideaIOClient _ioClient;
final FirebaseUtils _firebaseUtils;

TokenNotifier({
required this.ref,
TokenState? initialState,
TokenRepository? repository,
RsaUtils? rsaUtils,
PrivacyIdeaIOClient? ioClient,
PrivacyideaIOClient? ioClient,
FirebaseUtils? firebaseUtils,
}) : _rsaUtils = rsaUtils ?? const RsaUtils(),
_repo = repository ?? const SecureTokenRepository(),
_ioClient = ioClient ?? const PrivacyIdeaIOClient(),
_ioClient = ioClient ?? const PrivacyideaIOClient(),
_firebaseUtils = firebaseUtils ?? FirebaseUtils(),
super(
initialState ?? TokenState(tokens: const [], lastlyUpdatedTokens: const []),
Expand Down Expand Up @@ -282,23 +282,9 @@ class TokenNotifier extends StateNotifier<TokenState> {
/// There is no need to use mutexes because the updating functions are always using the latest version of the updating tokens.
*/

/// Adds a new token and returns true if successful, false if not.
Future<bool> addNewToken(Token token) async {
final success = await _addOrReplaceToken(token);
await _handlePushTokensIfExist();
return success;
}

/// Adds or replaces a token and returns true if successful, false if not.
Future<bool> addOrReplaceToken(Token token) => _addOrReplaceToken(token);

/// Adds new tokens and returns the tokens that could not be added.
Future<List<Token>> addTokens(List<Token> tokens) async {
final failedTokens = await _addOrReplaceTokens(tokens);
await _handlePushTokensIfExist();
return failedTokens;
}

/// Adds or replaces a list of tokens and returns the tokens that could not be added or replaced.
Future<List<Token>> addOrReplaceTokens(List<Token> tokens) => _addOrReplaceTokens(tokens);

Expand Down Expand Up @@ -758,7 +744,7 @@ class TokenNotifier extends StateNotifier<TokenState> {
Future<void> _handlePushTokensIfExist() async {
Logger.info('Handling push tokens if they exist.', name: 'token_notifier.dart#_handlePushTokensIfExist');
final pushTokens = state.pushTokens;
if (pushTokens.isNotEmpty || state.hasOTPTokens == false) {
if (pushTokens.isEmpty || state.pushTokens.isEmpty) {
if (ref.read(settingsProvider).hidePushTokens == true) {
ref.read(settingsProvider.notifier).setHidePushTokens(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import '../utils/logger.dart';
import '../utils/riverpod_providers.dart';
import '../utils/view_utils.dart';

class PrivacyIdeaIOClient {
const PrivacyIdeaIOClient();
class PrivacyideaIOClient {
const PrivacyideaIOClient();

/// Dummy network request can be used to trigger the network access permission
/// on iOS devices. Doing this at an appropriate place in the code can prevent
Expand Down Expand Up @@ -113,11 +113,19 @@ class PrivacyIdeaIOClient {
Response response;
try {
response = await ioClient.post(url, body: body).timeout(const Duration(seconds: 15));
} on HandshakeException catch (e, s) {
response = Response('${e.runtimeType} : $s', 525);
} catch (e, s) {
if (e is! TimeoutException && e is! SocketException && e is! ClientException) rethrow;
response = Response('${e.runtimeType} : $s', 404);
} on HandshakeException catch (e, _) {
Logger.info('Handshake failed. sslVerify: $sslVerify', name: 'utils.dart#doPost');
showMessage(message: 'Handshake failed, please check the server certificate and try again.');
response = Response('${e.runtimeType}', 525);
} on TimeoutException catch (e, _) {
Logger.info('TimeoutException', name: 'utils.dart#doPost');
response = Response('${e.runtimeType}', 408);
} on SocketException catch (e, _) {
Logger.info('SocketException', name: 'utils.dart#doPost');
response = Response('${e.runtimeType}', 404);
} catch (e, _) {
Logger.info('Unknown exception', name: 'utils.dart#doPost');
response = Response('${e.runtimeType}', 404);
}

if (response.statusCode != 200) {
Expand Down Expand Up @@ -165,13 +173,19 @@ class PrivacyIdeaIOClient {
Uri uri = Uri.parse(buffer.toString());
try {
response = await ioClient.get(uri).timeout(const Duration(seconds: 15));
} on HandshakeException catch (e, s) {
Logger.warning('Handshake failed. sslVerify: $sslVerify', name: 'utils.dart#doGet', error: e, stackTrace: s);
} on HandshakeException catch (e, _) {
Logger.info('Handshake failed. sslVerify: $sslVerify', name: 'utils.dart#doGet');
showMessage(message: 'Handshake failed, please check the server certificate and try again.');
rethrow;
} catch (e, s) {
if (e is! TimeoutException && e is! SocketException) rethrow;
response = Response('${e.runtimeType} : $s', 404);
response = Response('${e.runtimeType}', 525);
} on TimeoutException catch (e, _) {
Logger.info('TimeoutException', name: 'utils.dart#doGet');
response = Response('${e.runtimeType}', 408);
} on SocketException catch (e, _) {
Logger.info('SocketException', name: 'utils.dart#doGet');
response = Response('${e.runtimeType}', 404);
} catch (e, _) {
Logger.info('Unknown exception', name: 'utils.dart#doGet');
response = Response('${e.runtimeType}', 404);
}

if (response.statusCode != 200) {
Expand Down
18 changes: 9 additions & 9 deletions lib/utils/push_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import '../repo/secure_token_repository.dart';
import 'firebase_utils.dart';
import 'globals.dart';
import 'logger.dart';
import 'network_utils.dart';
import 'privacyidea_io_client.dart';
import 'riverpod_providers.dart';
import 'rsa_utils.dart';
import 'utils.dart';
Expand All @@ -58,19 +58,19 @@ class PushProvider {
FirebaseUtils _firebaseUtils;
FirebaseUtils get firebaseUtils => _firebaseUtils;
bool _firebaseInitialized = false;
PrivacyIdeaIOClient _ioClient;
PrivacyIdeaIOClient get ioClient => _ioClient;
PrivacyideaIOClient _ioClient;
PrivacyideaIOClient get ioClient => _ioClient;
RsaUtils _rsaUtils;
RsaUtils get rsaUtils => _rsaUtils;
LegacyUtils _legacyUtils;

PushProvider._({
FirebaseUtils? firebaseUtils,
PrivacyIdeaIOClient? ioClient,
PrivacyideaIOClient? ioClient,
RsaUtils? rsaUtils,
LegacyUtils? legacyUtils,
}) : _firebaseUtils = firebaseUtils ?? FirebaseUtils(),
_ioClient = ioClient ?? const PrivacyIdeaIOClient(),
_ioClient = ioClient ?? const PrivacyideaIOClient(),
_rsaUtils = rsaUtils ?? const RsaUtils(),
_legacyUtils = legacyUtils ?? const LegacyUtils() {
_initFirebase();
Expand Down Expand Up @@ -103,7 +103,7 @@ class PushProvider {

factory PushProvider({
bool? pollingEnabled,
PrivacyIdeaIOClient? ioClient,
PrivacyideaIOClient? ioClient,
RsaUtils? rsaUtils,
FirebaseUtils? firebaseUtils,
}) {
Expand Down Expand Up @@ -355,7 +355,7 @@ class PushProvider {
try {
response = instance != null
? await instance!._ioClient.doGet(url: token.url!, parameters: parameters, sslVerify: token.sslVerify)
: await const PrivacyIdeaIOClient().doGet(url: token.url!, parameters: parameters, sslVerify: token.sslVerify);
: await const PrivacyideaIOClient().doGet(url: token.url!, parameters: parameters, sslVerify: token.sslVerify);
} catch (e) {
if (isManually) {
globalRef?.read(statusMessageProvider.notifier).state = (
Expand Down Expand Up @@ -428,9 +428,9 @@ class PlaceholderPushProvider implements PushProvider {
@override
FirebaseUtils get firebaseUtils => _firebaseUtils;
@override
PrivacyIdeaIOClient _ioClient = const PrivacyIdeaIOClient();
PrivacyideaIOClient _ioClient = const PrivacyideaIOClient();
@override
PrivacyIdeaIOClient get ioClient => _ioClient;
PrivacyideaIOClient get ioClient => _ioClient;
@override
LegacyUtils _legacyUtils = const LegacyUtils();
@override
Expand Down
4 changes: 3 additions & 1 deletion lib/widgets/deactivateable_refresh_indicator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class DeactivateableRefreshIndicator extends StatelessWidget {
Widget build(BuildContext context) {
return allowToRefresh
? RefreshIndicator(
onRefresh: onRefresh,
onRefresh: () async {
onRefresh();
},
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
triggerMode: RefreshIndicatorTriggerMode.anywhere,
child: child,
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ publish_to: none
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 4.4.0+404007 # TODO Set the right version number
version: 4.4.0+404008 # TODO Set the right version number

# version: major.minor.build + 2x major|2x minor|3x build
# version: version number + build number (optional)
# android: build-name + versionCode
Expand Down
4 changes: 2 additions & 2 deletions test/tests_app_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import 'package:privacyidea_authenticator/interfaces/repo/settings_repository.da
import 'package:privacyidea_authenticator/interfaces/repo/token_folder_repository.dart';
import 'package:privacyidea_authenticator/interfaces/repo/token_repository.dart';
import 'package:privacyidea_authenticator/utils/firebase_utils.dart';
import 'package:privacyidea_authenticator/utils/network_utils.dart';
import 'package:privacyidea_authenticator/utils/privacyidea_io_client.dart';
import 'package:privacyidea_authenticator/utils/rsa_utils.dart';

@GenerateNiceMocks([
MockSpec<TokenRepository>(),
MockSpec<SettingsRepository>(),
MockSpec<TokenFolderRepository>(),
MockSpec<PrivacyIdeaIOClient>(),
MockSpec<PrivacyideaIOClient>(),
MockSpec<RsaUtils>(),
MockSpec<FirebaseUtils>(),
MockSpec<IntroductionRepository>(),
Expand Down
9 changes: 5 additions & 4 deletions test/tests_app_wrapper.mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import 'package:privacyidea_authenticator/model/token_folder.dart' as _i11;
import 'package:privacyidea_authenticator/model/tokens/push_token.dart' as _i16;
import 'package:privacyidea_authenticator/model/tokens/token.dart' as _i8;
import 'package:privacyidea_authenticator/utils/firebase_utils.dart' as _i17;
import 'package:privacyidea_authenticator/utils/network_utils.dart' as _i12;
import 'package:privacyidea_authenticator/utils/privacyidea_io_client.dart'
as _i12;
import 'package:privacyidea_authenticator/utils/rsa_utils.dart' as _i13;

// ignore_for_file: type=lint
Expand Down Expand Up @@ -244,11 +245,11 @@ class MockTokenFolderRepository extends _i1.Mock
) as _i7.Future<List<_i11.TokenFolder>>);
}

/// A class which mocks [PrivacyIdeaIOClient].
/// A class which mocks [PrivacyideaIOClient].
///
/// See the documentation for Mockito's code generation for more information.
class MockPrivacyIdeaIOClient extends _i1.Mock
implements _i12.PrivacyIdeaIOClient {
class MockPrivacyideaIOClient extends _i1.Mock
implements _i12.PrivacyideaIOClient {
@override
_i7.Future<bool> triggerNetworkAccessPermission({
required Uri? url,
Expand Down
12 changes: 6 additions & 6 deletions test/unit_test/state_notifiers/push_request_notifier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import 'package:privacyidea_authenticator/model/states/push_request_state.dart';
import 'package:privacyidea_authenticator/model/tokens/push_token.dart';
import 'package:privacyidea_authenticator/state_notifiers/push_request_notifier.dart';
import 'package:privacyidea_authenticator/utils/custom_int_buffer.dart';
import 'package:privacyidea_authenticator/utils/network_utils.dart';
import 'package:privacyidea_authenticator/utils/privacyidea_io_client.dart';
import 'package:privacyidea_authenticator/utils/push_provider.dart';
import 'package:privacyidea_authenticator/utils/rsa_utils.dart';
import 'package:mockito/annotations.dart';

import 'push_request_notifier_test.mocks.dart';

@GenerateMocks([RsaUtils, PrivacyIdeaIOClient, PushProvider, PushRequestRepository])
@GenerateMocks([RsaUtils, PrivacyideaIOClient, PushProvider, PushRequestRepository])
void main() {
_testPushRequestNotifier();
}
Expand All @@ -24,7 +24,7 @@ void _testPushRequestNotifier() {
group('PushRequestNotifier', () {
test('accept', () async {
final container = ProviderContainer();
final mockIoClient = MockPrivacyIdeaIOClient();
final mockIoClient = MockPrivacyideaIOClient();
final mockPushProvider = MockPushProvider();
final mockRsaUtils = MockRsaUtils();
final mockPushRepo = MockPushRequestRepository();
Expand Down Expand Up @@ -82,7 +82,7 @@ void _testPushRequestNotifier() {
});
test('decline', () async {
final container = ProviderContainer();
final mockIoClient = MockPrivacyIdeaIOClient();
final mockIoClient = MockPrivacyideaIOClient();
final mockPushProvider = MockPushProvider();
final mockRsaUtils = MockRsaUtils();
final mockPushRepo = MockPushRequestRepository();
Expand Down Expand Up @@ -139,7 +139,7 @@ void _testPushRequestNotifier() {

test('add', () async {
final container = ProviderContainer();
final mockIoClient = MockPrivacyIdeaIOClient();
final mockIoClient = MockPrivacyideaIOClient();
final mockPushProvider = MockPushProvider();
final mockRsaUtils = MockRsaUtils();
final mockPushRepo = MockPushRequestRepository();
Expand Down Expand Up @@ -175,7 +175,7 @@ void _testPushRequestNotifier() {
});
test('remove', () async {
final container = ProviderContainer();
final mockIoClient = MockPrivacyIdeaIOClient();
final mockIoClient = MockPrivacyideaIOClient();
final mockPushProvider = MockPushProvider();
final mockRsaUtils = MockRsaUtils();
final mockPushRepo = MockPushRequestRepository();
Expand Down
Loading

0 comments on commit 6219ad3

Please sign in to comment.