Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new method to fetch enrollment requests #1200

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
233c040
feat: add new method fetchEnrollmentRequests() to AtClientImpl
srieteja Jan 10, 2024
07ef40f
test: add unit test
srieteja Jan 10, 2024
5a724a8
refactor: minor refactoring in RemoteSecondary
srieteja Jan 10, 2024
dfa6750
refactor: run dart formatter
srieteja Jan 11, 2024
d4bc099
Merge branch 'trunk' into enroll_list_client
srieteja Jan 11, 2024
bda846a
test: add functional test
srieteja Jan 11, 2024
d557101
Merge remote-tracking branch 'origin/enroll_list_client' into enroll_…
srieteja Jan 11, 2024
3d16f43
test: fix functional tests
srieteja Jan 11, 2024
3dfaaff
test: fix functional tests
srieteja Jan 11, 2024
d751c84
test: change the atsign used in the new test
srieteja Jan 11, 2024
68b5662
test: fix functional tests
srieteja Jan 11, 2024
c4cca0c
test: run dart formatter
srieteja Jan 11, 2024
17f342a
feat: introduced two classes for input and output of fetchEnrollmentR…
srieteja Jan 16, 2024
1816b39
tests: updated tests w.r.t. EnrollRequestParam and EnrollmentRequest …
srieteja Jan 16, 2024
3c669f7
Merge branch 'trunk' into enroll_list_client
srieteja Jan 16, 2024
17863da
fix: introduce toJson(), fromJson() and get enrollmentId for Enrollme…
srieteja Jan 17, 2024
3e01557
fix: make enrollRequestParams mandatory; and update tests
srieteja Jan 17, 2024
27081c1
Merge remote-tracking branch 'origin/enroll_list_client' into enroll_…
srieteja Jan 17, 2024
265f306
Merge branch 'trunk' into enroll_list_client
srieteja Jan 17, 2024
d6accd7
reformat: run the dart formatter
srieteja Jan 17, 2024
ff55915
Merge remote-tracking branch 'origin/enroll_list_client' into enroll_…
srieteja Jan 17, 2024
ffa9aec
reformat: address review comments
srieteja Jan 17, 2024
d0a0f0a
Merge branch 'trunk' into enroll_list_client
srieteja Jan 17, 2024
a6f3d28
reformat: run dart formatter
srieteja Jan 17, 2024
e20d2eb
Merge remote-tracking branch 'origin/enroll_list_client' into enroll_…
srieteja Jan 17, 2024
decb706
docs: updated changelog
srieteja Jan 18, 2024
adb23f2
Merge branch 'trunk' into enroll_list_client
srieteja Jan 22, 2024
8a17438
Merge branch 'trunk' into enroll_list_client
srieteja Jan 24, 2024
8f1b820
Merge branch 'trunk' into enroll_list_client
murali-shris Jan 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/at_client/lib/src/client/at_client_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,21 @@ class AtClientImpl implements AtClient, AtSignChangeListener {
return AtChopsImpl(atChopsKeys);
}

@override
Future<Map<String, dynamic>> 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);
srieteja marked this conversation as resolved.
Show resolved Hide resolved
response = response?.replaceFirst('data:', '');
Map<String, dynamic> enrollRequests = jsonDecode(response!);
return enrollRequests;
}

@override
Future<AtStreamResponse> stream(String sharedWith, String filePath,
{String? namespace}) async {
Expand Down
4 changes: 4 additions & 0 deletions packages/at_client/lib/src/client/at_client_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -572,4 +572,8 @@ abstract class AtClient {
String? getCurrentAtSign();

EncryptionService? get encryptionService;

/// Fetches all enrollment requests from the corresponding atServer
Future<Map<String, dynamic>> fetchEnrollmentRequests(
{String? appName, String? deviceName});
srieteja marked this conversation as resolved.
Show resolved Hide resolved
srieteja marked this conversation as resolved.
Show resolved Hide resolved
}
14 changes: 4 additions & 10 deletions packages/at_client/lib/src/client/remote_secondary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -107,14 +107,8 @@ class RemoteSecondary implements Secondary {
// ignore: prefer_typing_uninitialized_variables
var verbResult;
try {
logger.finer(logger.getLogMessageWithClientParticulars(
srieteja marked this conversation as resolved.
Show resolved Hide resolved
_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,
Expand Down
40 changes: 39 additions & 1 deletion packages/at_client/test/at_client_impl_test.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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 {
Expand All @@ -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<String, dynamic>? requests =
await clientImpl.fetchEnrollmentRequests();
expect(requests.length, 3);
expect(requests[enrollKey1], jsonDecode(enrollValue1));
expect(requests[enrollKey2], jsonDecode(enrollValue2));
expect(requests[enrollKey3], jsonDecode(enrollValue3));
});
});
}
72 changes: 70 additions & 2 deletions tests/at_functional_test/test/enrollment_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void main() {
await setLastReceivedNotificationDateTime();
});

void _stopSubscriptions() {
void stopSubscriptions() {
atClientManager.atClient.notificationService.stopAllSubscriptions();
print('subscriptions stopped');
}
Expand Down Expand Up @@ -87,9 +87,73 @@ 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 {
atClientManager = await TestUtils.initAtClient(atSign, 'new_app');
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 apkamPublicKey =
at_demos.pkamPublicKeyMap['@eve🛠']; // can be any random public key
var newEnrollRequest = TestUtils.formatCommand(
'enroll:request:{"appName":"new_app","deviceName":"pixel","namespaces":{"new_app":"rw"},"otp":"$otp","apkamPublicKey":"$apkamPublicKey"}');
var enrollResponse = await TestUtils.executeCommandAndParse(
null, newEnrollRequest,
remoteSecondary: secondRemoteSecondary);
Map<String, dynamic> 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":"new_app","deviceName":"pixel7","namespaces":{"new_app":"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<String, dynamic> enrollmentRequests =
await client.fetchEnrollmentRequests();
print(enrollmentRequests.entries);
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);

expect(
(enrollmentRequests[firstEnrollmentKey]['namespace']
as Map<String, dynamic>)['new_app'],
'rw');
expect(
(enrollmentRequests[secondEnrollmentKey]['namespace']
as Map<String, dynamic>)['new_app'],
'rw');
expect(
(enrollmentRequests[secondEnrollmentKey]['namespace']
as Map<String, dynamic>)['wavi'],
'r');
});
}

Future<void> setLastReceivedNotificationDateTime() async {
Expand All @@ -115,6 +179,10 @@ Future<void> 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'
Expand Down
13 changes: 13 additions & 0 deletions tests/at_functional_test/test/test_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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<String?> 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:', '');
}
}