From 233c040d0ee4b4a8ea7c0758a4c38deac9a3cffc Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 10 Jan 2024 18:32:07 +0530 Subject: [PATCH 01/18] feat: add new method fetchEnrollmentRequests() to AtClientImpl --- .../at_client/lib/src/client/at_client_impl.dart | 14 ++++++++++++++ .../at_client/lib/src/client/at_client_spec.dart | 3 +++ 2 files changed, 17 insertions(+) diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index 4a8927e05..16ee1a578 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -673,6 +673,20 @@ class AtClientImpl implements AtClient, AtSignChangeListener { return AtChopsImpl(atChopsKeys); } + @override + Future> fetchEnrollmentRequests( + {String? appName, String? deviceName}) async { + EnrollVerbBuilder enrollBuilder = EnrollVerbBuilder() + ..operation = EnrollOperationEnum.list + ..appName = appName + ..deviceName = deviceName; + + var response = await getRemoteSecondary()?.executeCommand(enrollBuilder.buildCommand(), auth: true); + response = response?.replaceFirst('data:', ''); + Map enrollRequests = jsonDecode(response!); + return enrollRequests; + } + @override Future stream(String sharedWith, String filePath, {String? namespace}) async { diff --git a/packages/at_client/lib/src/client/at_client_spec.dart b/packages/at_client/lib/src/client/at_client_spec.dart index d04ec9424..f3ee463b4 100644 --- a/packages/at_client/lib/src/client/at_client_spec.dart +++ b/packages/at_client/lib/src/client/at_client_spec.dart @@ -572,4 +572,7 @@ abstract class AtClient { String? getCurrentAtSign(); EncryptionService? get encryptionService; + + /// Fetches all enrollment requests from the corresponding atServer + Future> fetchEnrollmentRequests({String? appName, String? deviceName}); } From 07ef40fc41243752207ce46d306018f01286ec1d Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 10 Jan 2024 18:32:19 +0530 Subject: [PATCH 02/18] test: add unit test --- .../at_client/test/at_client_impl_test.dart | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/at_client/test/at_client_impl_test.dart b/packages/at_client/test/at_client_impl_test.dart index 39f9a16a6..8d5d0794c 100644 --- a/packages/at_client/test/at_client_impl_test.dart +++ b/packages/at_client/test/at_client_impl_test.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:at_client/at_client.dart'; import 'package:at_client/src/compaction/at_commit_log_compaction.dart'; import 'package:at_client/src/service/notification_service_impl.dart'; @@ -20,6 +22,8 @@ class MockAtCompactionJob extends Mock implements AtCompactionJob { } } +class MockRemoteSecondary extends Mock implements RemoteSecondary {} + void main() { group('A group of at client impl create tests', () { final String atSign = '@alice'; @@ -251,7 +255,7 @@ void main() { }); }); - group('A group of tests related to setting enrollmentId', () { + group('A group of tests related to apkam/enrollments', () { test( 'A test to verify enrollmentId is set in atClient after calling setCurrentAtSign', () async { @@ -261,5 +265,39 @@ void main() { enrollmentId: testEnrollmentId); expect(atClientManager.atClient.enrollmentId, testEnrollmentId); }); + + MockRemoteSecondary mockRemoteSecondary = MockRemoteSecondary(); + + test('verify behaviour of fetchEnrollmentRequests()', () async { + String currentAtsign = '@apkam'; + String enrollKey1 = + '0acdeb4d-1a2e-43e4-93bd-378f1d366ea7.new.enrollments.__manage$currentAtsign'; + String enrollValue1 = + '{"appName":"buzz","deviceName":"pixel","namespace":{"buzz":"rw"}}'; + String enrollKey2 = + '9beefa26-3384-4f10-81a6-0deaa4332669.new.enrollments.__manage$currentAtsign'; + String enrollValue2 = + '{"appName":"buzz","deviceName":"pixel","namespace":{"buzz":"rw"}}'; + String enrollKey3 = + 'a6bbef17-c7bf-46f4-a172-1ed7b3b443bc.new.enrollments.__manage$currentAtsign'; + String enrollValue3 = + '{"appName":"buzz","deviceName":"pixel","namespace":{"buzz":"rw"}}'; + when(() => + mockRemoteSecondary.executeCommand('enroll:list\n', auth: true)) + .thenAnswer((_) => Future.value('data:{"$enrollKey1":' + '$enrollValue1,"$enrollKey2":$enrollValue2,"$enrollKey3":$enrollValue3}')); + + AtClient? client = await AtClientImpl.create( + currentAtsign, 'buzz', AtClientPreference(), + remoteSecondary: mockRemoteSecondary); + AtClientImpl? clientImpl = client as AtClientImpl; + + Map? requests = + await clientImpl.fetchEnrollmentRequests(); + expect(requests.length, 3); + expect(requests[enrollKey1], jsonDecode(enrollValue1)); + expect(requests[enrollKey2], jsonDecode(enrollValue2)); + expect(requests[enrollKey3], jsonDecode(enrollValue3)); + }); }); } From 5a724a824aada2a29d135dcca79652cd1e293087 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 10 Jan 2024 18:32:45 +0530 Subject: [PATCH 03/18] refactor: minor refactoring in RemoteSecondary --- .../at_client/lib/src/client/remote_secondary.dart | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/at_client/lib/src/client/remote_secondary.dart b/packages/at_client/lib/src/client/remote_secondary.dart index 4110f2675..56b768c0c 100644 --- a/packages/at_client/lib/src/client/remote_secondary.dart +++ b/packages/at_client/lib/src/client/remote_secondary.dart @@ -33,10 +33,10 @@ class RemoteSecondary implements Secondary { logger = AtSignLogger('RemoteSecondary ($_atSign)'); _preference = preference; privateKey ??= preference.privateKey; - SecureSocketConfig secureSocketConfig = SecureSocketConfig(); - secureSocketConfig.decryptPackets = preference.decryptPackets; - secureSocketConfig.pathToCerts = preference.pathToCerts; - secureSocketConfig.tlsKeysSavePath = preference.tlsKeysSavePath; + SecureSocketConfig secureSocketConfig = SecureSocketConfig() + ..decryptPackets = preference.decryptPackets + ..pathToCerts = preference.pathToCerts + ..tlsKeysSavePath = preference.tlsKeysSavePath; atLookUp = AtLookupImpl(atSign, preference.rootDomain, preference.rootPort, privateKey: privateKey, cramSecret: preference.cramSecret, @@ -107,14 +107,8 @@ class RemoteSecondary implements Secondary { // ignore: prefer_typing_uninitialized_variables var verbResult; try { - logger.finer(logger.getLogMessageWithClientParticulars( - _preference.atClientParticulars, - 'Command sent to server: ${builder.buildCommand()}')); verbResult = await executeVerb(builder); verbResult = verbResult.replaceFirst('data:', ''); - logger.finer(logger.getLogMessageWithClientParticulars( - _preference.atClientParticulars, - 'Response from server: $verbResult')); } on AtException catch (e) { throw e ..stack(AtChainedException(Intent.fetchData, From dfa6750e4b6990c59e1c7edbe334dc7643efa979 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 12:56:25 +0530 Subject: [PATCH 04/18] refactor: run dart formatter --- packages/at_client/lib/src/client/at_client_impl.dart | 3 ++- packages/at_client/lib/src/client/at_client_spec.dart | 3 ++- packages/at_client/test/at_client_impl_test.dart | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index 16ee1a578..bd8052f31 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -681,7 +681,8 @@ class AtClientImpl implements AtClient, AtSignChangeListener { ..appName = appName ..deviceName = deviceName; - var response = await getRemoteSecondary()?.executeCommand(enrollBuilder.buildCommand(), auth: true); + var response = await getRemoteSecondary() + ?.executeCommand(enrollBuilder.buildCommand(), auth: true); response = response?.replaceFirst('data:', ''); Map enrollRequests = jsonDecode(response!); return enrollRequests; diff --git a/packages/at_client/lib/src/client/at_client_spec.dart b/packages/at_client/lib/src/client/at_client_spec.dart index f3ee463b4..ba8616ecd 100644 --- a/packages/at_client/lib/src/client/at_client_spec.dart +++ b/packages/at_client/lib/src/client/at_client_spec.dart @@ -574,5 +574,6 @@ abstract class AtClient { EncryptionService? get encryptionService; /// Fetches all enrollment requests from the corresponding atServer - Future> fetchEnrollmentRequests({String? appName, String? deviceName}); + Future> fetchEnrollmentRequests( + {String? appName, String? deviceName}); } diff --git a/packages/at_client/test/at_client_impl_test.dart b/packages/at_client/test/at_client_impl_test.dart index 8d5d0794c..e80030e3d 100644 --- a/packages/at_client/test/at_client_impl_test.dart +++ b/packages/at_client/test/at_client_impl_test.dart @@ -283,9 +283,9 @@ void main() { String enrollValue3 = '{"appName":"buzz","deviceName":"pixel","namespace":{"buzz":"rw"}}'; when(() => - mockRemoteSecondary.executeCommand('enroll:list\n', auth: true)) - .thenAnswer((_) => Future.value('data:{"$enrollKey1":' - '$enrollValue1,"$enrollKey2":$enrollValue2,"$enrollKey3":$enrollValue3}')); + mockRemoteSecondary.executeCommand('enroll:list\n', + auth: true)).thenAnswer((_) => Future.value('data:{"$enrollKey1":' + '$enrollValue1,"$enrollKey2":$enrollValue2,"$enrollKey3":$enrollValue3}')); AtClient? client = await AtClientImpl.create( currentAtsign, 'buzz', AtClientPreference(), From bda846a2e656956ef67a2597183928549bdf72b9 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 17:18:26 +0530 Subject: [PATCH 05/18] test: add functional test --- .../test/enrollment_test.dart | 54 ++++++++++++++++++- tests/at_functional_test/test/test_utils.dart | 13 +++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index 806f84a41..722700b5b 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -26,7 +26,7 @@ void main() { await setLastReceivedNotificationDateTime(); }); - void _stopSubscriptions() { + void stopSubscriptions() { atClientManager.atClient.notificationService.stopAllSubscriptions(); print('subscriptions stopped'); } @@ -87,9 +87,59 @@ void main() { print('got enrollment notification: $enrollNotification'); expect(enrollNotification.key, '$enrollmentIdFromServer.new.enrollments.__manage'); - _stopSubscriptions(); + stopSubscriptions(); }, count: 1, max: 1)); }); + + test( + 'validate client functionality to fetch pending enrollments on legacy pkam authenticated client', + () async { + AtClient? client = atClientManager.atClient; + // fetch first otp + String? otp = + await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); + expect(otp, isNotNull); + // create first enrollment request + RemoteSecondary? secondRemoteSecondary = + RemoteSecondary(atSign, getClient2Preferences()); + var publicKey = + at_demos.pkamPublicKeyMap['@bob🛠']; // can be any random public key + var newEnrollRequest = TestUtils.formatCommand( + 'enroll:request:{"appName":"buzz","deviceName":"pixel","namespaces":{"buzz":"rw"},"otp":"$otp","apkamPublicKey":"$publicKey"}'); + var enrollResponse = await TestUtils.executeCommandAndParse( + null, newEnrollRequest, + remoteSecondary: secondRemoteSecondary); + Map enrollResponse1JsonDecoded = + jsonDecode(enrollResponse!); + expect(enrollResponse1JsonDecoded['enrollmentId'], isNotNull); + expect(enrollResponse1JsonDecoded['status'], 'pending'); + + // fetch second otp + otp = await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); + expect(otp, isNotNull); + // create second enrollment request + newEnrollRequest = TestUtils.formatCommand( + 'enroll:request:{"appName":"wavi","deviceName":"pixel7","namespaces":{"buzz":"rw", "wavi":"r"},"otp":"$otp","apkamPublicKey":"$publicKey"}'); + enrollResponse = await TestUtils.executeCommandAndParse( + null, newEnrollRequest, + remoteSecondary: secondRemoteSecondary); + var enrollResponse2JsonDecoded = jsonDecode(enrollResponse!); + expect(enrollResponse2JsonDecoded['enrollmentId'], isNotNull); + expect(enrollResponse2JsonDecoded['status'], 'pending'); + + // fetch enrollment requests through client + Map enrollmentRequests = + await client.fetchEnrollmentRequests(); + print(enrollmentRequests.entries); + expect(enrollmentRequests.length, 2); + + String firstEnrollmentKey = enrollmentRequests.keys.toList()[0]; + String secondEnrollmentKey = enrollmentRequests.keys.toList()[1]; + + expect((enrollmentRequests[firstEnrollmentKey]['namespace'] as Map)['buzz'], 'rw'); + expect((enrollmentRequests[secondEnrollmentKey]['namespace'] as Map)['buzz'], 'rw'); + expect((enrollmentRequests[secondEnrollmentKey]['namespace'] as Map)['wavi'], 'r'); + }); } Future setLastReceivedNotificationDateTime() async { diff --git a/tests/at_functional_test/test/test_utils.dart b/tests/at_functional_test/test/test_utils.dart index 6984b1128..cf7b31d0a 100644 --- a/tests/at_functional_test/test/test_utils.dart +++ b/tests/at_functional_test/test/test_utils.dart @@ -8,6 +8,7 @@ import 'package:at_client/at_client.dart'; import 'package:at_functional_test/src/at_demo_credentials.dart' as demo_credentials; + class TestUtils { static AtClientPreference getPreference(String atsign) { var preference = AtClientPreference(); @@ -52,4 +53,16 @@ class TestUtils { atClientManager.atClient, currentAtSign); return atClientManager; } + + static String formatCommand(String command){ + if(!command.contains('\n')) return '$command\n'; + return command; + } + + static Future executeCommandAndParse(AtClient? client, command, {bool auth = false, RemoteSecondary? remoteSecondary}) async { + remoteSecondary ??= client?.getRemoteSecondary(); + String? response = await remoteSecondary?.executeCommand(formatCommand(command), auth: auth); + print('Command: $command -> Response: $response'); + return response?.replaceFirst('data:', ''); + } } From 3d16f433c46284b6fff4e7cb042de9558b0edc4e Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 18:08:41 +0530 Subject: [PATCH 06/18] test: fix functional tests --- .../test/enrollment_test.dart | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index 722700b5b..ce921aef4 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -14,9 +14,11 @@ void main() { late String aliceDefaultEncryptionPrivateKey; late String aliceSelfEncryptionKey; late String alicePkamPublicKey; + late String secondAtsign; setUp(() async { atSign = ConfigUtil.getYaml()['atSign']['firstAtSign']; + secondAtsign = ConfigUtil.getYaml()['atSign']['secondAtSign']; atClientManager = await TestUtils.initAtClient(atSign, namespace); aliceApkamSymmetricKey = at_demos.apkamSymmetricKeyMap[atSign]!; aliceDefaultEncryptionPrivateKey = @@ -94,6 +96,64 @@ void main() { test( 'validate client functionality to fetch pending enrollments on legacy pkam authenticated client', () async { + atClientManager = await TestUtils.initAtClient(secondAtsign, 'buzz'); + AtClient? client = atClientManager.atClient; + // fetch first otp + String? otp = + await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); + expect(otp, isNotNull); + // create first enrollment request + RemoteSecondary? secondRemoteSecondary = + RemoteSecondary(secondAtsign, getClient2Preferences()); + var apkamPublicKey = + at_demos.pkamPublicKeyMap['@eve🛠']; // can be any random public key + var newEnrollRequest = TestUtils.formatCommand( + 'enroll:request:{"appName":"buzz","deviceName":"pixel","namespaces":{"buzz":"rw"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); + var enrollResponse = await TestUtils.executeCommandAndParse( + null, newEnrollRequest, + remoteSecondary: secondRemoteSecondary); + Map enrollResponse1JsonDecoded = + jsonDecode(enrollResponse!); + expect(enrollResponse1JsonDecoded['enrollmentId'], isNotNull); + expect(enrollResponse1JsonDecoded['status'], 'pending'); + + // fetch second otp + otp = await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); + expect(otp, isNotNull); + // create second enrollment request + newEnrollRequest = TestUtils.formatCommand( + 'enroll:request:{"appName":"wavi","deviceName":"pixel7","namespaces":{"buzz":"rw", "wavi":"r"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); + enrollResponse = await TestUtils.executeCommandAndParse( + null, newEnrollRequest, + remoteSecondary: secondRemoteSecondary); + var enrollResponse2JsonDecoded = jsonDecode(enrollResponse!); + expect(enrollResponse2JsonDecoded['enrollmentId'], isNotNull); + expect(enrollResponse2JsonDecoded['status'], 'pending'); + + // fetch enrollment requests through client + Map enrollmentRequests = + await client.fetchEnrollmentRequests(); + print(enrollmentRequests.entries); + expect(enrollmentRequests.length, 2); + + String firstEnrollmentKey = enrollmentRequests.keys.toList()[0]; + String secondEnrollmentKey = enrollmentRequests.keys.toList()[1]; + + expect( + (enrollmentRequests[firstEnrollmentKey]['namespace'] + as Map)['buzz'], + 'rw'); + expect( + (enrollmentRequests[secondEnrollmentKey]['namespace'] + as Map)['buzz'], + 'rw'); + expect( + (enrollmentRequests[secondEnrollmentKey]['namespace'] + as Map)['wavi'], + 'r'); + }); + + test('validate client functionality to fetch pending enrollments', () async { AtClient? client = atClientManager.atClient; // fetch first otp String? otp = @@ -113,6 +173,9 @@ void main() { jsonDecode(enrollResponse!); expect(enrollResponse1JsonDecoded['enrollmentId'], isNotNull); expect(enrollResponse1JsonDecoded['status'], 'pending'); + // approve first enrollment request + enrollResponse = await TestUtils.executeCommandAndParse(client, + 'enroll:approve:{"enrollmentId":"${enrollResponse1JsonDecoded['enrollmentId']}"}'); // fetch second otp otp = await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); @@ -136,9 +199,18 @@ void main() { String firstEnrollmentKey = enrollmentRequests.keys.toList()[0]; String secondEnrollmentKey = enrollmentRequests.keys.toList()[1]; - expect((enrollmentRequests[firstEnrollmentKey]['namespace'] as Map)['buzz'], 'rw'); - expect((enrollmentRequests[secondEnrollmentKey]['namespace'] as Map)['buzz'], 'rw'); - expect((enrollmentRequests[secondEnrollmentKey]['namespace'] as Map)['wavi'], 'r'); + expect( + (enrollmentRequests[firstEnrollmentKey]['namespace'] + as Map)['buzz'], + 'rw'); + expect( + (enrollmentRequests[secondEnrollmentKey]['namespace'] + as Map)['buzz'], + 'rw'); + expect( + (enrollmentRequests[secondEnrollmentKey]['namespace'] + as Map)['wavi'], + 'r'); }); } From 3dfaaff90421fbc0ea7329981f01d7daf87b00b7 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 18:33:30 +0530 Subject: [PATCH 07/18] test: fix functional tests --- .../test/enrollment_test.dart | 70 +++---------------- 1 file changed, 8 insertions(+), 62 deletions(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index ce921aef4..10ee24160 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -136,68 +136,10 @@ void main() { print(enrollmentRequests.entries); expect(enrollmentRequests.length, 2); - String firstEnrollmentKey = enrollmentRequests.keys.toList()[0]; - String secondEnrollmentKey = enrollmentRequests.keys.toList()[1]; - - expect( - (enrollmentRequests[firstEnrollmentKey]['namespace'] - as Map)['buzz'], - 'rw'); - expect( - (enrollmentRequests[secondEnrollmentKey]['namespace'] - as Map)['buzz'], - 'rw'); - expect( - (enrollmentRequests[secondEnrollmentKey]['namespace'] - as Map)['wavi'], - 'r'); - }); - - test('validate client functionality to fetch pending enrollments', () async { - AtClient? client = atClientManager.atClient; - // fetch first otp - String? otp = - await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); - expect(otp, isNotNull); - // create first enrollment request - RemoteSecondary? secondRemoteSecondary = - RemoteSecondary(atSign, getClient2Preferences()); - var publicKey = - at_demos.pkamPublicKeyMap['@bob🛠']; // can be any random public key - var newEnrollRequest = TestUtils.formatCommand( - 'enroll:request:{"appName":"buzz","deviceName":"pixel","namespaces":{"buzz":"rw"},"otp":"$otp","apkamPublicKey":"$publicKey"}'); - var enrollResponse = await TestUtils.executeCommandAndParse( - null, newEnrollRequest, - remoteSecondary: secondRemoteSecondary); - Map enrollResponse1JsonDecoded = - jsonDecode(enrollResponse!); - expect(enrollResponse1JsonDecoded['enrollmentId'], isNotNull); - expect(enrollResponse1JsonDecoded['status'], 'pending'); - // approve first enrollment request - enrollResponse = await TestUtils.executeCommandAndParse(client, - 'enroll:approve:{"enrollmentId":"${enrollResponse1JsonDecoded['enrollmentId']}"}'); - - // fetch second otp - otp = await TestUtils.executeCommandAndParse(client, 'otp:get', auth: true); - expect(otp, isNotNull); - // create second enrollment request - newEnrollRequest = TestUtils.formatCommand( - 'enroll:request:{"appName":"wavi","deviceName":"pixel7","namespaces":{"buzz":"rw", "wavi":"r"},"otp":"$otp","apkamPublicKey":"$publicKey"}'); - enrollResponse = await TestUtils.executeCommandAndParse( - null, newEnrollRequest, - remoteSecondary: secondRemoteSecondary); - var enrollResponse2JsonDecoded = jsonDecode(enrollResponse!); - expect(enrollResponse2JsonDecoded['enrollmentId'], isNotNull); - expect(enrollResponse2JsonDecoded['status'], 'pending'); - - // fetch enrollment requests through client - Map enrollmentRequests = - await client.fetchEnrollmentRequests(); - print(enrollmentRequests.entries); - expect(enrollmentRequests.length, 2); - - String firstEnrollmentKey = enrollmentRequests.keys.toList()[0]; - String secondEnrollmentKey = enrollmentRequests.keys.toList()[1]; + String firstEnrollmentKey = getEnrollmentKey( + enrollResponse1JsonDecoded['enrollmentId'], secondAtsign); + String secondEnrollmentKey = getEnrollmentKey( + enrollResponse2JsonDecoded['enrollmentId'], secondAtsign); expect( (enrollmentRequests[firstEnrollmentKey]['namespace'] @@ -237,6 +179,10 @@ Future setLastReceivedNotificationDateTime() async { .put(lastReceivedNotificationAtKey, jsonEncode(atNotification.toJson())); } +String getEnrollmentKey(String enrollmentId, String atsign) { + return '$enrollmentId.new.enrollments.__manage$atsign'; +} + AtClientPreference getClient2Preferences() { return AtClientPreference() ..commitLogPath = 'test/hive/client_2/commit' From d751c8433071b1c2ebe8cc021543eecc03d86dbc Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 19:06:34 +0530 Subject: [PATCH 08/18] test: change the atsign used in the new test --- .../test/enrollment_test.dart | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index 10ee24160..533f65dfd 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -14,11 +14,9 @@ void main() { late String aliceDefaultEncryptionPrivateKey; late String aliceSelfEncryptionKey; late String alicePkamPublicKey; - late String secondAtsign; setUp(() async { atSign = ConfigUtil.getYaml()['atSign']['firstAtSign']; - secondAtsign = ConfigUtil.getYaml()['atSign']['secondAtSign']; atClientManager = await TestUtils.initAtClient(atSign, namespace); aliceApkamSymmetricKey = at_demos.apkamSymmetricKeyMap[atSign]!; aliceDefaultEncryptionPrivateKey = @@ -96,7 +94,7 @@ void main() { test( 'validate client functionality to fetch pending enrollments on legacy pkam authenticated client', () async { - atClientManager = await TestUtils.initAtClient(secondAtsign, 'buzz'); + atClientManager = await TestUtils.initAtClient(atSign, 'new_app'); AtClient? client = atClientManager.atClient; // fetch first otp String? otp = @@ -104,11 +102,11 @@ void main() { expect(otp, isNotNull); // create first enrollment request RemoteSecondary? secondRemoteSecondary = - RemoteSecondary(secondAtsign, getClient2Preferences()); + RemoteSecondary(atSign, getClient2Preferences()); var apkamPublicKey = at_demos.pkamPublicKeyMap['@eve🛠']; // can be any random public key var newEnrollRequest = TestUtils.formatCommand( - 'enroll:request:{"appName":"buzz","deviceName":"pixel","namespaces":{"buzz":"rw"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); + 'enroll:request:{"appName":"new_app","deviceName":"pixel","namespaces":{"new_app":"rw"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); var enrollResponse = await TestUtils.executeCommandAndParse( null, newEnrollRequest, remoteSecondary: secondRemoteSecondary); @@ -122,7 +120,7 @@ void main() { expect(otp, isNotNull); // create second enrollment request newEnrollRequest = TestUtils.formatCommand( - 'enroll:request:{"appName":"wavi","deviceName":"pixel7","namespaces":{"buzz":"rw", "wavi":"r"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); + 'enroll:request:{"appName":"new_app","deviceName":"pixel7","namespaces":{"new_app":"rw", "wavi":"r"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}'); enrollResponse = await TestUtils.executeCommandAndParse( null, newEnrollRequest, remoteSecondary: secondRemoteSecondary); @@ -137,17 +135,17 @@ void main() { expect(enrollmentRequests.length, 2); String firstEnrollmentKey = getEnrollmentKey( - enrollResponse1JsonDecoded['enrollmentId'], secondAtsign); + enrollResponse1JsonDecoded['enrollmentId'], atSign); String secondEnrollmentKey = getEnrollmentKey( - enrollResponse2JsonDecoded['enrollmentId'], secondAtsign); + enrollResponse2JsonDecoded['enrollmentId'], atSign); expect( (enrollmentRequests[firstEnrollmentKey]['namespace'] - as Map)['buzz'], + as Map)['new_app'], 'rw'); expect( (enrollmentRequests[secondEnrollmentKey]['namespace'] - as Map)['buzz'], + as Map)['new_app'], 'rw'); expect( (enrollmentRequests[secondEnrollmentKey]['namespace'] From 68b566295bb5603a94334a849bec82d978970b22 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 19:23:41 +0530 Subject: [PATCH 09/18] test: fix functional tests --- tests/at_functional_test/test/enrollment_test.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index 533f65dfd..b92c11332 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -132,7 +132,8 @@ void main() { Map enrollmentRequests = await client.fetchEnrollmentRequests(); print(enrollmentRequests.entries); - expect(enrollmentRequests.length, 2); + expect(enrollmentRequests.length, 4); // 4 entries - 2 entries from this test + // + 2 entries from the other test in this file. String firstEnrollmentKey = getEnrollmentKey( enrollResponse1JsonDecoded['enrollmentId'], atSign); From c4cca0c6936540b01b1c900949a86c39e3c4771f Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 11 Jan 2024 19:24:05 +0530 Subject: [PATCH 10/18] test: run dart formatter --- tests/at_functional_test/test/enrollment_test.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index b92c11332..be60140ad 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -132,13 +132,14 @@ void main() { Map enrollmentRequests = await client.fetchEnrollmentRequests(); print(enrollmentRequests.entries); - expect(enrollmentRequests.length, 4); // 4 entries - 2 entries from this test + expect( + enrollmentRequests.length, 4); // 4 entries - 2 entries from this test // + 2 entries from the other test in this file. - String firstEnrollmentKey = getEnrollmentKey( - enrollResponse1JsonDecoded['enrollmentId'], atSign); - String secondEnrollmentKey = getEnrollmentKey( - enrollResponse2JsonDecoded['enrollmentId'], atSign); + String firstEnrollmentKey = + getEnrollmentKey(enrollResponse1JsonDecoded['enrollmentId'], atSign); + String secondEnrollmentKey = + getEnrollmentKey(enrollResponse2JsonDecoded['enrollmentId'], atSign); expect( (enrollmentRequests[firstEnrollmentKey]['namespace'] From 17f342af6e4ad3728c14f2a5dc0175f3c60f50d0 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Tue, 16 Jan 2024 19:32:09 +0530 Subject: [PATCH 11/18] feat: introduced two classes for input and output of fetchEnrollmentRequests() --- packages/at_client/lib/at_client.dart | 2 ++ .../lib/src/client/at_client_impl.dart | 24 +++++++++++++++---- .../lib/src/client/at_client_spec.dart | 11 ++++++--- .../src/util/enroll_list_request_param.dart | 6 +++++ .../lib/src/util/enrollment_request.dart | 11 +++++++++ 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 packages/at_client/lib/src/util/enroll_list_request_param.dart create mode 100644 packages/at_client/lib/src/util/enrollment_request.dart diff --git a/packages/at_client/lib/at_client.dart b/packages/at_client/lib/at_client.dart index 8ddc869de..598abef56 100644 --- a/packages/at_client/lib/at_client.dart +++ b/packages/at_client/lib/at_client.dart @@ -12,6 +12,8 @@ export 'package:at_client/src/preference/at_client_preference.dart'; export 'package:at_client/src/response/at_notification.dart'; export 'package:at_client/src/util/at_client_util.dart'; export 'package:at_client/src/util/encryption_util.dart'; +export 'package:at_client/src/util/enrollment_request.dart'; +export 'package:at_client/src/util/enroll_list_request_param.dart'; export 'package:at_client/src/service/notification_service.dart'; export 'package:at_client/src/service/sync_service.dart'; export 'package:at_client/src/service/sync/sync_result.dart'; diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index bd8052f31..f910cb788 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -674,18 +674,32 @@ class AtClientImpl implements AtClient, AtSignChangeListener { } @override - Future> fetchEnrollmentRequests( - {String? appName, String? deviceName}) async { + Future> fetchEnrollmentRequests( + {EnrollListRequestParam? enrollmentListRequest}) async { EnrollVerbBuilder enrollBuilder = EnrollVerbBuilder() ..operation = EnrollOperationEnum.list - ..appName = appName - ..deviceName = deviceName; + ..appName = enrollmentListRequest?.appName + ..deviceName = enrollmentListRequest?.deviceName; var response = await getRemoteSecondary() ?.executeCommand(enrollBuilder.buildCommand(), auth: true); response = response?.replaceFirst('data:', ''); Map enrollRequests = jsonDecode(response!); - return enrollRequests; + stdout.writeln('enrollment lis req response: $response'); + return _formatEnrollListResponse(enrollRequests); + } + + List _formatEnrollListResponse( + Map enrollRequests) { + List enrollRequestsFormatted = []; + for (var request in enrollRequests.entries) { + enrollRequestsFormatted.add(EnrollmentRequest() + ..enrollmentKey = request.key + ..appName = request.value['appName'] + ..deviceName = request.value['deviceName'] + ..namespace = request.value['namespace']); + } + return enrollRequestsFormatted; } @override diff --git a/packages/at_client/lib/src/client/at_client_spec.dart b/packages/at_client/lib/src/client/at_client_spec.dart index ba8616ecd..f8361cd55 100644 --- a/packages/at_client/lib/src/client/at_client_spec.dart +++ b/packages/at_client/lib/src/client/at_client_spec.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:at_client/at_client.dart'; import 'package:at_client/src/client/local_secondary.dart'; import 'package:at_client/src/client/remote_secondary.dart'; import 'package:at_client/src/manager/sync_manager.dart'; @@ -573,7 +574,11 @@ abstract class AtClient { EncryptionService? get encryptionService; - /// Fetches all enrollment requests from the corresponding atServer - Future> fetchEnrollmentRequests( - {String? appName, String? deviceName}); + /// Fetches all enrollment requests from the corresponding atServer; Formats the requests into a + /// List<[EnrollmentResponse]> + /// + /// The optional param [EnrollListRequestParam] is present to avoid future compatibility issues over backwards compatibility + /// [enrollListRequest] for now does not have any functionality + Future> fetchEnrollmentRequests( + {EnrollListRequestParam? enrollmentListRequest}); } diff --git a/packages/at_client/lib/src/util/enroll_list_request_param.dart b/packages/at_client/lib/src/util/enroll_list_request_param.dart new file mode 100644 index 000000000..b41f94617 --- /dev/null +++ b/packages/at_client/lib/src/util/enroll_list_request_param.dart @@ -0,0 +1,6 @@ +/// class to store request parameters while fetching a list of enrollments +class EnrollListRequestParam { + String? appName; + String? deviceName; + String? namespace; +} diff --git a/packages/at_client/lib/src/util/enrollment_request.dart b/packages/at_client/lib/src/util/enrollment_request.dart new file mode 100644 index 000000000..783e5fd3e --- /dev/null +++ b/packages/at_client/lib/src/util/enrollment_request.dart @@ -0,0 +1,11 @@ +class EnrollmentRequest { + late String enrollmentKey; + late String appName; + late String deviceName; + late Map namespace; + + @override + String toString() { + return 'Enrollment Request: enrollmentKey: $enrollmentKey | appName: $appName | deviceName: $deviceName | namespace: ${namespace.toString()}'; + } +} From 1816b390161ba5837e1f8a2e2452486d2f21d5db Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Tue, 16 Jan 2024 19:33:02 +0530 Subject: [PATCH 12/18] tests: updated tests w.r.t. EnrollRequestParam and EnrollmentRequest classes --- .../at_client/test/at_client_impl_test.dart | 14 +++++--- .../test/enrollment_test.dart | 34 +++++++++++-------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/packages/at_client/test/at_client_impl_test.dart b/packages/at_client/test/at_client_impl_test.dart index e80030e3d..00df63c64 100644 --- a/packages/at_client/test/at_client_impl_test.dart +++ b/packages/at_client/test/at_client_impl_test.dart @@ -292,12 +292,18 @@ void main() { remoteSecondary: mockRemoteSecondary); AtClientImpl? clientImpl = client as AtClientImpl; - Map? requests = + List requests = await clientImpl.fetchEnrollmentRequests(); expect(requests.length, 3); - expect(requests[enrollKey1], jsonDecode(enrollValue1)); - expect(requests[enrollKey2], jsonDecode(enrollValue2)); - expect(requests[enrollKey3], jsonDecode(enrollValue3)); + expect(requests[0].appName, jsonDecode(enrollValue1)['appName']); + expect(requests[0].deviceName, jsonDecode(enrollValue1)['deviceName']); + expect(requests[0].namespace, jsonDecode(enrollValue1)['namespace']); + expect(requests[1].appName, jsonDecode(enrollValue2)['appName']); + expect(requests[1].deviceName, jsonDecode(enrollValue2)['deviceName']); + expect(requests[1].namespace, jsonDecode(enrollValue2)['namespace']); + expect(requests[2].appName, jsonDecode(enrollValue3)['appName']); + expect(requests[2].deviceName, jsonDecode(enrollValue3)['deviceName']); + expect(requests[2].namespace, jsonDecode(enrollValue3)['namespace']); }); }); } diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index be60140ad..cf3417e2c 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -129,9 +129,11 @@ void main() { expect(enrollResponse2JsonDecoded['status'], 'pending'); // fetch enrollment requests through client - Map enrollmentRequests = + List enrollmentRequests = await client.fetchEnrollmentRequests(); - print(enrollmentRequests.entries); + for(var request in enrollmentRequests){ + print(request); + } expect( enrollmentRequests.length, 4); // 4 entries - 2 entries from this test // + 2 entries from the other test in this file. @@ -140,19 +142,21 @@ void main() { getEnrollmentKey(enrollResponse1JsonDecoded['enrollmentId'], atSign); String secondEnrollmentKey = getEnrollmentKey(enrollResponse2JsonDecoded['enrollmentId'], atSign); - - expect( - (enrollmentRequests[firstEnrollmentKey]['namespace'] - as Map)['new_app'], - 'rw'); - expect( - (enrollmentRequests[secondEnrollmentKey]['namespace'] - as Map)['new_app'], - 'rw'); - expect( - (enrollmentRequests[secondEnrollmentKey]['namespace'] - as Map)['wavi'], - 'r'); + int matchCount = 0; + for (var request in enrollmentRequests){ + if(request.enrollmentKey == firstEnrollmentKey){ + expect(request.namespace['new_app'], 'rw'); + expect(request.deviceName, 'pixel'); + matchCount ++; + } else if (request.enrollmentKey == secondEnrollmentKey){ + expect(request.namespace['new_app'], 'rw'); + expect(request.namespace['wavi'], 'r'); + expect(request.deviceName, 'pixel7'); + matchCount++; + } + } + // this counter is to assert that the list of requests has exactly two request matches + expect(matchCount, 2); }); } From 17863dab6f2ff06ece40bc131c49b02c5714d293 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 17 Jan 2024 14:31:46 +0530 Subject: [PATCH 13/18] fix: introduce toJson(), fromJson() and get enrollmentId for EnrollmentRequest; --- .../lib/src/client/at_client_spec.dart | 13 +++++-- .../lib/src/util/enrollment_request.dart | 39 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/packages/at_client/lib/src/client/at_client_spec.dart b/packages/at_client/lib/src/client/at_client_spec.dart index f8361cd55..ff7936b32 100644 --- a/packages/at_client/lib/src/client/at_client_spec.dart +++ b/packages/at_client/lib/src/client/at_client_spec.dart @@ -577,8 +577,13 @@ abstract class AtClient { /// Fetches all enrollment requests from the corresponding atServer; Formats the requests into a /// List<[EnrollmentResponse]> /// - /// The optional param [EnrollListRequestParam] is present to avoid future compatibility issues over backwards compatibility - /// [enrollListRequest] for now does not have any functionality - Future> fetchEnrollmentRequests( - {EnrollListRequestParam? enrollmentListRequest}); + /// Responses can be filtered using params provided through [EnrollListRequestParam] + /// ``` + /// e.g. + /// List enrollmentRequests = fetchEnrollmentRequests(EnrollRequestParams()); + /// enrollmentRequests now contains all the enrollment requests fetched from the server in the for of + /// EnrollmentRequest objects + /// ``` + @experimental + Future> fetchEnrollmentRequests(EnrollListRequestParam enrollmentListRequest); } diff --git a/packages/at_client/lib/src/util/enrollment_request.dart b/packages/at_client/lib/src/util/enrollment_request.dart index 783e5fd3e..471c5e7fc 100644 --- a/packages/at_client/lib/src/util/enrollment_request.dart +++ b/packages/at_client/lib/src/util/enrollment_request.dart @@ -1,11 +1,50 @@ +import 'dart:collection'; +import 'dart:convert'; + +import 'package:at_client/at_client.dart'; + class EnrollmentRequest { late String enrollmentKey; late String appName; late String deviceName; late Map namespace; + String get enrollmentId { + return extractEnrollmentId(enrollmentKey); + } + @override String toString() { return 'Enrollment Request: enrollmentKey: $enrollmentKey | appName: $appName | deviceName: $deviceName | namespace: ${namespace.toString()}'; } + + String toJson() { + Map jsonMap = HashMap(); + jsonMap['enrollmentKey'] = enrollmentKey; + jsonMap['appName'] = appName; + jsonMap['deviceName'] = deviceName; + jsonMap['namespace'] = jsonEncode(namespace); + + return jsonEncode(jsonMap); + } + + static EnrollmentRequest fromJson(Map json, + {bool jsonIncludesKey = true, String? enrollmentKey}) { + EnrollmentRequest enrollmentRequest = EnrollmentRequest(); + if (jsonIncludesKey) { + enrollmentRequest.enrollmentKey = json['enrollmentKey']; + } else if (!jsonIncludesKey && enrollmentKey != null) { + enrollmentRequest.enrollmentKey = enrollmentKey; + } else { + throw IllegalArgumentException('enrollment key not set'); + } + return enrollmentRequest + ..appName = json['appName'] + ..deviceName = json['deviceName'] + ..namespace = json['namespace']; + } + + static String extractEnrollmentId(String enrollmentKey) { + return enrollmentKey.split('.')[0]; + } } From 3e015572ee951a81da0ab1aa22755b1599df6760 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 17 Jan 2024 14:31:57 +0530 Subject: [PATCH 14/18] fix: make enrollRequestParams mandatory; and update tests --- .../lib/src/client/at_client_impl.dart | 27 ++++++++++--------- .../at_client/test/at_client_impl_test.dart | 13 ++++++++- .../test/enrollment_test.dart | 18 ++++++------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index f910cb788..aae085d69 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -675,29 +675,30 @@ class AtClientImpl implements AtClient, AtSignChangeListener { @override Future> fetchEnrollmentRequests( - {EnrollListRequestParam? enrollmentListRequest}) async { + EnrollListRequestParam enrollmentListRequestParams) async { + // enrollmentListRequestParams for now is not used + // A server side enhancement request is created. https://github.com/atsign-foundation/at_server/issues/1748 + // On implementation of this enhancement/feature, the enrollListRequestParam object can be made use of EnrollVerbBuilder enrollBuilder = EnrollVerbBuilder() ..operation = EnrollOperationEnum.list - ..appName = enrollmentListRequest?.appName - ..deviceName = enrollmentListRequest?.deviceName; + ..appName = enrollmentListRequestParams.appName + ..deviceName = enrollmentListRequestParams.deviceName; var response = await getRemoteSecondary() ?.executeCommand(enrollBuilder.buildCommand(), auth: true); - response = response?.replaceFirst('data:', ''); - Map enrollRequests = jsonDecode(response!); - stdout.writeln('enrollment lis req response: $response'); - return _formatEnrollListResponse(enrollRequests); + + return _formatEnrollListResponse(response); } List _formatEnrollListResponse( - Map enrollRequests) { + response) { + response = response?.replaceFirst('data:', ''); + Map enrollRequests = jsonDecode(response!); List enrollRequestsFormatted = []; + for (var request in enrollRequests.entries) { - enrollRequestsFormatted.add(EnrollmentRequest() - ..enrollmentKey = request.key - ..appName = request.value['appName'] - ..deviceName = request.value['deviceName'] - ..namespace = request.value['namespace']); + enrollRequestsFormatted.add(EnrollmentRequest.fromJson(request.value, + jsonIncludesKey: false, enrollmentKey: request.key)); } return enrollRequestsFormatted; } diff --git a/packages/at_client/test/at_client_impl_test.dart b/packages/at_client/test/at_client_impl_test.dart index 00df63c64..5a986df0a 100644 --- a/packages/at_client/test/at_client_impl_test.dart +++ b/packages/at_client/test/at_client_impl_test.dart @@ -293,17 +293,28 @@ void main() { AtClientImpl? clientImpl = client as AtClientImpl; List requests = - await clientImpl.fetchEnrollmentRequests(); + await clientImpl.fetchEnrollmentRequests(EnrollListRequestParam()); expect(requests.length, 3); expect(requests[0].appName, jsonDecode(enrollValue1)['appName']); expect(requests[0].deviceName, jsonDecode(enrollValue1)['deviceName']); expect(requests[0].namespace, jsonDecode(enrollValue1)['namespace']); + expect(requests[1].appName, jsonDecode(enrollValue2)['appName']); expect(requests[1].deviceName, jsonDecode(enrollValue2)['deviceName']); expect(requests[1].namespace, jsonDecode(enrollValue2)['namespace']); + expect(requests[2].appName, jsonDecode(enrollValue3)['appName']); expect(requests[2].deviceName, jsonDecode(enrollValue3)['deviceName']); expect(requests[2].namespace, jsonDecode(enrollValue3)['namespace']); }); + + test('validate EnrollRequest.extractEnrollmentId()', () { + String enrollmentKey = + '0acdeb4d-1a2e-43e4-93bd-378f1d366ea7.new.enrollments.__manage@random'; + String enrollmentId = '0acdeb4d-1a2e-43e4-93bd-378f1d366ea7'; + + expect( + EnrollmentRequest.extractEnrollmentId(enrollmentKey), enrollmentId); + }); }); } diff --git a/tests/at_functional_test/test/enrollment_test.dart b/tests/at_functional_test/test/enrollment_test.dart index cf3417e2c..3f4017c0b 100644 --- a/tests/at_functional_test/test/enrollment_test.dart +++ b/tests/at_functional_test/test/enrollment_test.dart @@ -130,12 +130,10 @@ void main() { // fetch enrollment requests through client List enrollmentRequests = - await client.fetchEnrollmentRequests(); - for(var request in enrollmentRequests){ - print(request); - } - expect( - enrollmentRequests.length, 4); // 4 entries - 2 entries from this test + await client.fetchEnrollmentRequests(EnrollListRequestParam()); + + expect(enrollmentRequests.length, 4); + // 4 entries - 2 entries from this test // + 2 entries from the other test in this file. String firstEnrollmentKey = @@ -143,12 +141,12 @@ void main() { String secondEnrollmentKey = getEnrollmentKey(enrollResponse2JsonDecoded['enrollmentId'], atSign); int matchCount = 0; - for (var request in enrollmentRequests){ - if(request.enrollmentKey == firstEnrollmentKey){ + for (var request in enrollmentRequests) { + if (request.enrollmentKey == firstEnrollmentKey) { expect(request.namespace['new_app'], 'rw'); expect(request.deviceName, 'pixel'); - matchCount ++; - } else if (request.enrollmentKey == secondEnrollmentKey){ + matchCount++; + } else if (request.enrollmentKey == secondEnrollmentKey) { expect(request.namespace['new_app'], 'rw'); expect(request.namespace['wavi'], 'r'); expect(request.deviceName, 'pixel7'); From d6accd71bacbc149422555db3d184f6ab6f0ef0d Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 17 Jan 2024 14:40:57 +0530 Subject: [PATCH 15/18] reformat: run the dart formatter --- packages/at_client/lib/src/client/at_client_impl.dart | 3 +-- packages/at_client/lib/src/client/at_client_spec.dart | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index d75a114d1..411e22847 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -666,8 +666,7 @@ class AtClientImpl implements AtClient, AtSignChangeListener { return _formatEnrollListResponse(response); } - List _formatEnrollListResponse( - response) { + List _formatEnrollListResponse(response) { response = response?.replaceFirst('data:', ''); Map enrollRequests = jsonDecode(response!); List enrollRequestsFormatted = []; diff --git a/packages/at_client/lib/src/client/at_client_spec.dart b/packages/at_client/lib/src/client/at_client_spec.dart index ff7936b32..f21646dec 100644 --- a/packages/at_client/lib/src/client/at_client_spec.dart +++ b/packages/at_client/lib/src/client/at_client_spec.dart @@ -585,5 +585,6 @@ abstract class AtClient { /// EnrollmentRequest objects /// ``` @experimental - Future> fetchEnrollmentRequests(EnrollListRequestParam enrollmentListRequest); + Future> fetchEnrollmentRequests( + EnrollListRequestParam enrollmentListRequest); } From ffa9aec950d46a63d3a777c71f55fd8300c2ee91 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 17 Jan 2024 17:36:28 +0530 Subject: [PATCH 16/18] reformat: address review comments --- .../lib/src/client/at_client_impl.dart | 7 ++++--- .../lib/src/util/enrollment_request.dart | 17 ++++------------- .../at_client/test/at_client_impl_test.dart | 7 +++++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/at_client/lib/src/client/at_client_impl.dart b/packages/at_client/lib/src/client/at_client_impl.dart index 411e22847..487d3fa42 100644 --- a/packages/at_client/lib/src/client/at_client_impl.dart +++ b/packages/at_client/lib/src/client/at_client_impl.dart @@ -670,10 +670,11 @@ class AtClientImpl implements AtClient, AtSignChangeListener { response = response?.replaceFirst('data:', ''); Map enrollRequests = jsonDecode(response!); List enrollRequestsFormatted = []; - + EnrollmentRequest? enrollment; for (var request in enrollRequests.entries) { - enrollRequestsFormatted.add(EnrollmentRequest.fromJson(request.value, - jsonIncludesKey: false, enrollmentKey: request.key)); + enrollment = EnrollmentRequest.fromJson(request.value); + enrollment.enrollmentKey = request.key; + enrollRequestsFormatted.add(enrollment); } return enrollRequestsFormatted; } diff --git a/packages/at_client/lib/src/util/enrollment_request.dart b/packages/at_client/lib/src/util/enrollment_request.dart index 471c5e7fc..ed943d19f 100644 --- a/packages/at_client/lib/src/util/enrollment_request.dart +++ b/packages/at_client/lib/src/util/enrollment_request.dart @@ -1,7 +1,6 @@ import 'dart:collection'; import 'dart:convert'; -import 'package:at_client/at_client.dart'; class EnrollmentRequest { late String enrollmentKey; @@ -18,26 +17,18 @@ class EnrollmentRequest { return 'Enrollment Request: enrollmentKey: $enrollmentKey | appName: $appName | deviceName: $deviceName | namespace: ${namespace.toString()}'; } - String toJson() { - Map jsonMap = HashMap(); + Map toJson() { + Map jsonMap = HashMap(); jsonMap['enrollmentKey'] = enrollmentKey; jsonMap['appName'] = appName; jsonMap['deviceName'] = deviceName; jsonMap['namespace'] = jsonEncode(namespace); - return jsonEncode(jsonMap); + return jsonMap; } - static EnrollmentRequest fromJson(Map json, - {bool jsonIncludesKey = true, String? enrollmentKey}) { + static EnrollmentRequest fromJson(Map json) { EnrollmentRequest enrollmentRequest = EnrollmentRequest(); - if (jsonIncludesKey) { - enrollmentRequest.enrollmentKey = json['enrollmentKey']; - } else if (!jsonIncludesKey && enrollmentKey != null) { - enrollmentRequest.enrollmentKey = enrollmentKey; - } else { - throw IllegalArgumentException('enrollment key not set'); - } return enrollmentRequest ..appName = json['appName'] ..deviceName = json['deviceName'] diff --git a/packages/at_client/test/at_client_impl_test.dart b/packages/at_client/test/at_client_impl_test.dart index 5a986df0a..750a163b7 100644 --- a/packages/at_client/test/at_client_impl_test.dart +++ b/packages/at_client/test/at_client_impl_test.dart @@ -295,17 +295,24 @@ void main() { List requests = await clientImpl.fetchEnrollmentRequests(EnrollListRequestParam()); expect(requests.length, 3); + expect(requests[0].enrollmentKey, enrollKey1); expect(requests[0].appName, jsonDecode(enrollValue1)['appName']); expect(requests[0].deviceName, jsonDecode(enrollValue1)['deviceName']); expect(requests[0].namespace, jsonDecode(enrollValue1)['namespace']); + // the following statement asserts that the enrollment.enrollmentId getter fetches the correct enrollment id + expect(requests[0].enrollmentKey.contains(enrollKey1), true); + expect(requests[1].enrollmentKey, enrollKey2); expect(requests[1].appName, jsonDecode(enrollValue2)['appName']); expect(requests[1].deviceName, jsonDecode(enrollValue2)['deviceName']); expect(requests[1].namespace, jsonDecode(enrollValue2)['namespace']); + expect(requests[1].enrollmentKey.contains(enrollKey2), true); + expect(requests[2].enrollmentKey, enrollKey3); expect(requests[2].appName, jsonDecode(enrollValue3)['appName']); expect(requests[2].deviceName, jsonDecode(enrollValue3)['deviceName']); expect(requests[2].namespace, jsonDecode(enrollValue3)['namespace']); + expect(requests[2].enrollmentKey.contains(enrollKey3), true); }); test('validate EnrollRequest.extractEnrollmentId()', () { From a6f3d28d0dfd306c89512a95c989bc4918d987f8 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Wed, 17 Jan 2024 17:59:45 +0530 Subject: [PATCH 17/18] reformat: run dart formatter --- packages/at_client/lib/src/util/enrollment_request.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/at_client/lib/src/util/enrollment_request.dart b/packages/at_client/lib/src/util/enrollment_request.dart index ed943d19f..6e25f561c 100644 --- a/packages/at_client/lib/src/util/enrollment_request.dart +++ b/packages/at_client/lib/src/util/enrollment_request.dart @@ -1,7 +1,6 @@ import 'dart:collection'; import 'dart:convert'; - class EnrollmentRequest { late String enrollmentKey; late String appName; From decb70601fe61b70aa58639600adc5377b5ea0e6 Mon Sep 17 00:00:00 2001 From: Srie Teja Date: Thu, 18 Jan 2024 14:07:19 +0530 Subject: [PATCH 18/18] docs: updated changelog --- packages/at_client/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/at_client/CHANGELOG.md b/packages/at_client/CHANGELOG.md index e6060efb8..0106107fb 100644 --- a/packages/at_client/CHANGELOG.md +++ b/packages/at_client/CHANGELOG.md @@ -6,6 +6,7 @@ - at_chops to v1.0.7 - at_persistence_secondary_server to v3.0.60 - feat: Replace encryption methods from EncryptionUtils with AtChops method +- feat: Introduce feature to fetch all enrollment requests from the server ## 3.0.72 - chore: Minor change to allow us to support dart versions both before and after 3.2.0 specifically for this