Skip to content

Commit b7a63a9

Browse files
authored
Migrate publisher-member-invite to action (#8616)
1 parent 728a2cc commit b7a63a9

File tree

5 files changed

+72
-57
lines changed

5 files changed

+72
-57
lines changed

app/lib/admin/actions/actions.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import 'package_version_retraction.dart';
3232
import 'publisher_create.dart';
3333
import 'publisher_delete.dart';
3434
import 'publisher_info.dart';
35+
import 'publisher_member_invite.dart';
3536
import 'publisher_members_list.dart';
3637
import 'publisher_package_remove.dart';
3738
import 'task_bump_priority.dart';
@@ -120,6 +121,7 @@ final class AdminAction {
120121
publisherCreate,
121122
publisherDelete,
122123
publisherInfo,
124+
publisherMemberInvite,
123125
publisherMembersList,
124126
publisherPackageRemove,
125127
taskBumpPriority,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:_pub_shared/data/publisher_api.dart';
6+
7+
import '../../account/backend.dart';
8+
import '../../account/consent_backend.dart';
9+
import '../../publisher/backend.dart';
10+
import '../../shared/configuration.dart';
11+
import 'actions.dart';
12+
13+
final publisherMemberInvite = AdminAction(
14+
name: 'publisher-member-invite',
15+
summary: 'Invite a new member to a publisher',
16+
description: '''
17+
Sends an invite to <email> to become a member of <publisher>.
18+
''',
19+
options: {
20+
'publisher': 'Publisher for which to list members, eg `dart.dev`',
21+
'email': 'email to send invitation to',
22+
},
23+
invoke: (options) async {
24+
final publisherId = options['publisher'] ??
25+
(throw InvalidInputException('Missing --publisher argument.'));
26+
27+
final invitedEmail = options['email'] ??
28+
(throw InvalidInputException('Missing --email argument.'));
29+
30+
final publisher = await publisherBackend.lookupPublisher(publisherId);
31+
if (publisher == null) {
32+
throw NotFoundException.resource(publisherId);
33+
}
34+
35+
final authenticatedAgent =
36+
await requireAuthenticatedAdmin(AdminPermission.removePackage);
37+
38+
await publisherBackend.verifyPublisherMemberInvite(
39+
publisherId, InviteMemberRequest(email: invitedEmail));
40+
await consentBackend.invitePublisherMember(
41+
authenticatedAgent: authenticatedAgent,
42+
publisherId: publisherId,
43+
invitedUserEmail: invitedEmail,
44+
);
45+
46+
return {
47+
'message': 'Sent invitation',
48+
'publisher': publisher.publisherId,
49+
'email': invitedEmail,
50+
};
51+
},
52+
);

app/lib/admin/backend.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import 'tools/delete_all_staging.dart';
3838
import 'tools/list_tools.dart';
3939
import 'tools/notify_service.dart';
4040
import 'tools/package_publisher.dart';
41-
import 'tools/publisher_member.dart';
4241
import 'tools/recent_uploaders.dart';
4342
import 'tools/user_merger.dart';
4443

@@ -59,8 +58,6 @@ final Map<String, Tool> availableTools = {
5958
'notify-service': executeNotifyService,
6059
'package-publisher': executeSetPackagePublisher,
6160
'recent-uploaders': executeRecentUploaders,
62-
'publisher-member': executePublisherMember,
63-
'publisher-invite-member': executePublisherInviteMember,
6461
'user-merger': executeUserMergerTool,
6562
'list-tools': executeListTools,
6663
};

app/lib/admin/tools/publisher_member.dart

Lines changed: 0 additions & 44 deletions
This file was deleted.

app/test/admin/api_tool_test.dart

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,27 @@ void main() {
7575
});
7676

7777
group('publisher member invite', () {
78-
setupTestsWithAdminTokenIssues((client) =>
79-
client.adminExecuteTool('publisher-invite-member', 'example.com'));
78+
setupTestsWithAdminTokenIssues((client) => client.adminInvokeAction(
79+
'publisher-member-invite',
80+
AdminInvokeActionArguments(arguments: {
81+
'publisher': 'example.com',
82+
'email': '[email protected]'
83+
})));
8084

8185
testWithProfile('invite + accept', fn: () async {
8286
final adminClient = createPubApiClient(authToken: siteAdminToken);
83-
final adminOutput = await adminClient.adminExecuteTool(
84-
'publisher-invite-member',
85-
Uri(pathSegments: [
86-
'example.com',
87-
88-
]).toString(),
89-
);
90-
expect(utf8.decode(adminOutput), '[email protected] has been invited.');
87+
final adminOutput = await adminClient.adminInvokeAction(
88+
'publisher-member-invite',
89+
AdminInvokeActionArguments(arguments: {
90+
'publisher': 'example.com',
91+
'email': '[email protected]'
92+
}));
93+
94+
expect(adminOutput.output, {
95+
'message': 'Sent invitation',
96+
'publisher': 'example.com',
97+
'email': '[email protected]'
98+
});
9199

92100
final email = fakeEmailSender.sentMessages.first;
93101
expect(

0 commit comments

Comments
 (0)