Skip to content

Commit 7899282

Browse files
author
serverpod_cloud
committed
feat(scloud): 10cc2babefeb2b766af70f64256fde2ac2a5d666
1 parent 9eb3ca1 commit 7899282

15 files changed

Lines changed: 150 additions & 99 deletions

serverpod_cloud_cli/lib/command_runner/cloud_cli_command_runner.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ To update to the latest version, run "dart pub global activate serverpod_cloud_c
293293
}
294294

295295
Directory _getDefaultStorageDir() {
296-
return ResourceManager.localStorageDirectory;
296+
return ResourceManager.localCloudStorageDirectory;
297297
}
298298

299299
/// The global configuration options for the Serverpod Cloud CLI.

serverpod_cloud_cli/lib/command_runner/commands/auth_command.dart

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'dart:async';
33
import 'package:config/config.dart';
44
import 'package:serverpod_cloud_cli/command_runner/cloud_cli_command.dart';
55
import 'package:serverpod_cloud_cli/shared/exceptions/exit_exceptions.dart';
6-
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_data.dart';
6+
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_auth_data.dart';
77
import 'package:serverpod_cloud_cli/persistent_storage/resource_manager.dart';
88
import 'package:serverpod_cloud_cli/util/browser_launcher.dart';
99
import 'package:serverpod_cloud_cli/util/listener_server.dart';
@@ -92,7 +92,8 @@ class CloudLoginCommand extends CloudCliCommand<LoginCommandOption> {
9292
final localStoragePath = globalConfiguration.scloudDir;
9393
final serverAddress = globalConfiguration.consoleServer;
9494

95-
final storedCloudData = await ResourceManager.tryFetchServerpodCloudData(
95+
final storedCloudData =
96+
await ResourceManager.tryFetchServerpodCloudAuthData(
9697
localStoragePath: localStoragePath.path,
9798
logger: logger,
9899
);
@@ -153,8 +154,8 @@ class CloudLoginCommand extends CloudCliCommand<LoginCommandOption> {
153154
}
154155

155156
if (persistent) {
156-
await ResourceManager.storeServerpodCloudData(
157-
cloudData: ServerpodCloudData(token),
157+
await ResourceManager.storeServerpodCloudAuthData(
158+
authData: ServerpodCloudAuthData(token),
158159
localStoragePath: localStoragePath.path,
159160
);
160161
}
@@ -180,7 +181,7 @@ class CloudLogoutCommand extends CloudCliCommand {
180181
Future<void> runWithConfig(final Configuration commandConfig) async {
181182
final localStoragePath = globalConfiguration.scloudDir;
182183

183-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
184+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
184185
localStoragePath: localStoragePath.path,
185186
logger: logger,
186187
);
@@ -201,7 +202,7 @@ class CloudLogoutCommand extends CloudCliCommand {
201202
}
202203

203204
try {
204-
await ResourceManager.removeServerpodCloudData(
205+
await ResourceManager.removeServerpodCloudAuthData(
205206
localStoragePath: localStoragePath.path,
206207
);
207208
} on Exception catch (e) {

serverpod_cloud_cli/lib/command_runner/helpers/cloud_cli_service_provider.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:serverpod_cloud_cli/command_logger/command_logger.dart';
22
import 'package:serverpod_cloud_cli/command_runner/cloud_cli_command_runner.dart';
3-
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_data.dart';
3+
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_auth_data.dart';
44
import 'package:serverpod_cloud_cli/util/cli_authentication_key_manager.dart';
55
import 'package:ground_control_client/ground_control_client.dart';
66

@@ -58,7 +58,7 @@ class CloudCliServiceProvider {
5858

5959
final authTokenOverride = _globalConfiguration.authToken;
6060
final cloudDataOverride = authTokenOverride != null
61-
? ServerpodCloudData(authTokenOverride)
61+
? ServerpodCloudAuthData(authTokenOverride)
6262
: null;
6363

6464
cloudApiClient = Client(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class ServerpodCloudAuthData {
2+
late final String token;
3+
4+
ServerpodCloudAuthData(this.token);
5+
6+
factory ServerpodCloudAuthData.fromJson(final Map<String, dynamic> json) {
7+
return ServerpodCloudAuthData(json['token'] as String);
8+
}
9+
10+
Map<String, dynamic> toJson() => {
11+
'token': token,
12+
};
13+
}

serverpod_cloud_cli/lib/persistent_storage/models/serverpod_cloud_data.dart

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

serverpod_cloud_cli/lib/persistent_storage/resource_manager.dart

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@ import 'dart:io';
33
import 'package:cli_tools/cli_tools.dart';
44
import 'package:path/path.dart' as p;
55
import 'package:serverpod_cloud_cli/command_logger/command_logger.dart';
6-
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_data.dart';
6+
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_auth_data.dart';
77

88
abstract class ResourceManager {
9-
static Directory get localStorageDirectory => Directory(
10-
p.join(LocalStorageManager.homeDirectory.path, '.serverpod_cloud'));
9+
/// The directory where Serverpod tools store local data.
10+
static Directory get _localStorageDirectory =>
11+
Directory(p.join(LocalStorageManager.homeDirectory.path, '.serverpod'));
1112

12-
static Future<void> removeServerpodCloudData({
13+
/// The directory where Serverpod Cloud CLI stores its local data.
14+
static Directory get localCloudStorageDirectory =>
15+
Directory(p.join(_localStorageDirectory.path, 'cloud'));
16+
17+
static Future<void> removeServerpodCloudAuthData({
1318
required final String localStoragePath,
1419
}) async {
1520
try {
1621
await LocalStorageManager.removeFile(
17-
fileName: ResourceManagerConstants.serverpodCloudDataFilePath,
22+
fileName: ResourceManagerConstants.serverpodCloudAuthFilePath,
1823
localStoragePath: localStoragePath,
1924
);
2025
} on DeleteException catch (e) {
@@ -24,14 +29,14 @@ abstract class ResourceManager {
2429
}
2530
}
2631

27-
static Future<void> storeServerpodCloudData({
28-
required final ServerpodCloudData cloudData,
32+
static Future<void> storeServerpodCloudAuthData({
33+
required final ServerpodCloudAuthData authData,
2934
required final String localStoragePath,
3035
}) async {
3136
try {
3237
await LocalStorageManager.storeJsonFile(
33-
fileName: ResourceManagerConstants.serverpodCloudDataFilePath,
34-
json: cloudData.toJson(),
38+
fileName: ResourceManagerConstants.serverpodCloudAuthFilePath,
39+
json: authData.toJson(),
3540
localStoragePath: localStoragePath,
3641
);
3742
} on CreateException catch (e) {
@@ -49,34 +54,78 @@ abstract class ResourceManager {
4954
}
5055
}
5156

52-
static Future<ServerpodCloudData?> tryFetchServerpodCloudData({
57+
static Future<ServerpodCloudAuthData?> tryFetchServerpodCloudAuthData({
5358
required final String localStoragePath,
5459
required final CommandLogger logger,
5560
}) async {
5661
try {
57-
return await LocalStorageManager.tryFetchAndDeserializeJsonFile(
58-
fileName: ResourceManagerConstants.serverpodCloudDataFilePath,
62+
final authData = await LocalStorageManager.tryFetchAndDeserializeJsonFile(
63+
fileName: ResourceManagerConstants.serverpodCloudAuthFilePath,
5964
localStoragePath: localStoragePath,
60-
fromJson: ServerpodCloudData.fromJson,
65+
fromJson: ServerpodCloudAuthData.fromJson,
6166
);
67+
if (authData != null) {
68+
return authData;
69+
}
6270
} on ReadException catch (_) {
6371
logger.error(
64-
'Could not read file at location ${ResourceManagerConstants.serverpodCloudDataFilePath}.',
72+
'Could not read file ${ResourceManagerConstants.serverpodCloudAuthFilePath}.',
6573
hint:
6674
'Please check that the Serverpod Cloud CLI has the correct permissions to '
6775
'read the file. If the problem persists, try deleting the file.');
6876
return null;
6977
} on DeserializationException catch (_) {
7078
return null;
7179
}
80+
81+
// Transparently migrate old local auth data to new file path.
82+
// TODO: Remove this code when users have had time to run scloud which
83+
// automatically executes this.
84+
return await _tryMigrateAuthData(localStoragePath: localStoragePath);
85+
}
86+
87+
static Future<ServerpodCloudAuthData?> _tryMigrateAuthData({
88+
required final String localStoragePath,
89+
}) async {
90+
const oldServerpodCloudStorageDir = '.serverpod_cloud';
91+
const oldServerpodCloudDataFilePath = 'serverpod_cloud_data.yaml';
92+
93+
final oldAuthDirPath = p.join(
94+
LocalStorageManager.homeDirectory.path,
95+
oldServerpodCloudStorageDir,
96+
);
97+
98+
// try to read the auth data from the old location
99+
final authData = await LocalStorageManager.tryFetchAndDeserializeJsonFile(
100+
localStoragePath: oldAuthDirPath,
101+
fileName: oldServerpodCloudDataFilePath,
102+
fromJson: ServerpodCloudAuthData.fromJson,
103+
);
104+
if (authData == null) {
105+
return null;
106+
}
107+
108+
// store the auth data to the new location
109+
await storeServerpodCloudAuthData(
110+
authData: authData,
111+
localStoragePath: localStoragePath,
112+
);
113+
114+
// remove the old file
115+
await LocalStorageManager.removeFile(
116+
localStoragePath: oldAuthDirPath,
117+
fileName: oldServerpodCloudDataFilePath,
118+
);
119+
120+
return authData;
72121
}
73122

74123
static Future<void> storeLatestCliVersion({
75124
required final CommandLogger logger,
76125
required final PackageVersionData cliVersionData,
77126
String? localStoragePath,
78127
}) async {
79-
localStoragePath ??= localStorageDirectory.path;
128+
localStoragePath ??= localCloudStorageDirectory.path;
80129

81130
try {
82131
await LocalStorageManager.storeJsonFile(
@@ -96,7 +145,7 @@ abstract class ResourceManager {
96145
String? localStoragePath,
97146
required final CommandLogger logger,
98147
}) async {
99-
localStoragePath ??= localStorageDirectory.path;
148+
localStoragePath ??= localCloudStorageDirectory.path;
100149

101150
void deleteFile(final File file) {
102151
try {
@@ -126,6 +175,6 @@ abstract class ResourceManager {
126175
}
127176

128177
abstract class ResourceManagerConstants {
129-
static const serverpodCloudDataFilePath = 'serverpod_cloud_data.yaml';
178+
static const serverpodCloudAuthFilePath = 'serverpod_cloud_auth.json';
130179
static const latestVersionFilePath = 'latest_cli_version.json';
131180
}

serverpod_cloud_cli/lib/util/cli_authentication_key_manager.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:serverpod_cloud_cli/command_logger/command_logger.dart';
2-
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_data.dart';
2+
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_auth_data.dart';
33
import 'package:serverpod_cloud_cli/persistent_storage/resource_manager.dart';
44
import 'package:ground_control_client/ground_control_client.dart';
55

@@ -10,12 +10,12 @@ extension IsAuthenticated on AuthenticationKeyManager {
1010
class CliAuthenticationKeyManager extends AuthenticationKeyManager {
1111
final CommandLogger _logger;
1212
final String _localStoragePath;
13-
ServerpodCloudData? _cloudData;
13+
ServerpodCloudAuthData? _cloudData;
1414

1515
CliAuthenticationKeyManager({
1616
required final CommandLogger logger,
1717
required final String localStoragePath,
18-
final ServerpodCloudData? cloudDataOverride,
18+
final ServerpodCloudAuthData? cloudDataOverride,
1919
}) : _localStoragePath = localStoragePath,
2020
_logger = logger,
2121
_cloudData = cloudDataOverride;
@@ -27,7 +27,7 @@ class CliAuthenticationKeyManager extends AuthenticationKeyManager {
2727
return cloudData.token;
2828
}
2929

30-
_cloudData = await ResourceManager.tryFetchServerpodCloudData(
30+
_cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
3131
localStoragePath: _localStoragePath,
3232
logger: _logger,
3333
);
@@ -38,16 +38,16 @@ class CliAuthenticationKeyManager extends AuthenticationKeyManager {
3838
@override
3939
Future<void> put(final String key) async {
4040
_cloudData = null;
41-
return ResourceManager.storeServerpodCloudData(
42-
cloudData: ServerpodCloudData(key),
41+
return ResourceManager.storeServerpodCloudAuthData(
42+
authData: ServerpodCloudAuthData(key),
4343
localStoragePath: _localStoragePath,
4444
);
4545
}
4646

4747
@override
4848
Future<void> remove() async {
4949
_cloudData = null;
50-
return ResourceManager.removeServerpodCloudData(
50+
return ResourceManager.removeServerpodCloudAuthData(
5151
localStoragePath: _localStoragePath,
5252
);
5353
}

serverpod_cloud_cli/test_integration/cli_authentication_key_manager_test.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'dart:io';
33
import 'package:cli_tools/cli_tools.dart';
44
import 'package:path/path.dart' as p;
55
import 'package:serverpod_cloud_cli/command_logger/command_logger.dart';
6-
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_data.dart';
6+
import 'package:serverpod_cloud_cli/persistent_storage/models/serverpod_cloud_auth_data.dart';
77
import 'package:serverpod_cloud_cli/persistent_storage/resource_manager.dart';
88
import 'package:serverpod_cloud_cli/util/cli_authentication_key_manager.dart';
99
import 'package:test/test.dart';
@@ -26,9 +26,9 @@ void main() {
2626
late String testKey;
2727
setUp(() async {
2828
testKey = 'my-key-${const Uuid().v4()}';
29-
final cloudData = ServerpodCloudData(testKey);
30-
await ResourceManager.storeServerpodCloudData(
31-
cloudData: cloudData,
29+
final cloudData = ServerpodCloudAuthData(testKey);
30+
await ResourceManager.storeServerpodCloudAuthData(
31+
authData: cloudData,
3232
localStoragePath: testCacheFolderPath,
3333
);
3434
});
@@ -60,7 +60,7 @@ void main() {
6060
});
6161

6262
test('then new key is stored on disk.', () async {
63-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
63+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
6464
localStoragePath: testCacheFolderPath,
6565
logger: logger,
6666
);
@@ -85,7 +85,7 @@ void main() {
8585
});
8686

8787
test('then key is removed from disk.', () async {
88-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
88+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
8989
localStoragePath: testCacheFolderPath,
9090
logger: logger,
9191
);
@@ -119,7 +119,7 @@ void main() {
119119
});
120120

121121
test('then the key is stored on disk.', () async {
122-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
122+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
123123
localStoragePath: testCacheFolderPath,
124124
logger: logger,
125125
);
@@ -148,7 +148,7 @@ void main() {
148148
late CliAuthenticationKeyManager keyManager;
149149
setUp(() async {
150150
testKey = 'my-key-${const Uuid().v4()}';
151-
final cloudData = ServerpodCloudData(testKey);
151+
final cloudData = ServerpodCloudAuthData(testKey);
152152
keyManager = CliAuthenticationKeyManager(
153153
logger: logger,
154154
localStoragePath: testCacheFolderPath,
@@ -164,7 +164,7 @@ void main() {
164164
test('when getting the authentication key then no key is stored on disk.',
165165
() async {
166166
await keyManager.get();
167-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
167+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
168168
localStoragePath: testCacheFolderPath,
169169
logger: logger,
170170
);
@@ -178,7 +178,7 @@ void main() {
178178
final newKey = 'new-key-${const Uuid().v4()}';
179179
await keyManager.put(newKey);
180180

181-
final cloudData = await ResourceManager.tryFetchServerpodCloudData(
181+
final cloudData = await ResourceManager.tryFetchServerpodCloudAuthData(
182182
localStoragePath: testCacheFolderPath,
183183
logger: logger,
184184
);

0 commit comments

Comments
 (0)