Verify token characters when added and when used (#3732)
diff --git a/doc/repository-spec-v2.md b/doc/repository-spec-v2.md
index 06ad714..9104428 100644
--- a/doc/repository-spec-v2.md
+++ b/doc/repository-spec-v2.md
@@ -133,6 +133,10 @@
authentication can only be used when `<hosted-url>` uses HTTPS. For further
details on token management see: `dart pub token --help`.
+The tokens are inserted verbatim in the header, therefore they have to adhere to
+ https://www.rfc-editor.org/rfc/rfc6750#section-2.1. This means they must match
+ the regex: `^[a-zA-Z0-9._~+/=-]+$`.
+
### Missing Authentication or Invalid Token
If the server requires authentication and the request does not carry an
diff --git a/lib/src/authentication/credential.dart b/lib/src/authentication/credential.dart
index 9f7ce0d..a59c1d0 100644
--- a/lib/src/authentication/credential.dart
+++ b/lib/src/authentication/credential.dart
@@ -6,6 +6,7 @@
import '../exceptions.dart';
import '../source/hosted.dart';
+import '../utils.dart';
/// Token is a structure for storing authentication credentials for third-party
/// pub registries. A token holds registry [url], credential [kind] and [token]
@@ -116,19 +117,26 @@
);
}
+ final String tokenValue;
final environment = env;
if (environment != null) {
final value = Platform.environment[environment];
if (value == null) {
- throw DataException(
+ dataError(
'Saved credential for "$url" pub repository requires environment '
'variable named "$env" but not defined.',
);
}
- return Future.value('Bearer $value');
+ tokenValue = value;
+ } else {
+ tokenValue = token!;
+ }
+ if (!isValidBearerToken(tokenValue)) {
+ dataError('Credential token for $url is not a valid Bearer token. '
+ 'It should match `^[a-zA-Z0-9._~+/=-]+\$`');
}
- return Future.value('Bearer $token');
+ return Future.value('Bearer $tokenValue');
}
/// Returns whether or not given [url] could be authenticated using this
@@ -144,6 +152,14 @@
// Either [token] or [env] should be defined to be valid.
bool isValid() => (token == null) ^ (env == null);
+ /// Whether [candidate] can be used as a bearer token.
+ ///
+ /// We limit tokens to be valid bearer tokens according to
+ /// https://www.rfc-editor.org/rfc/rfc6750#section-2.1
+ static bool isValidBearerToken(String candidate) {
+ return RegExp(r'^[a-zA-Z0-9._~+/=-]+$').hasMatch(candidate);
+ }
+
static String _normalizeUrl(String url) {
return (url.endsWith('/') ? url : '$url/').toLowerCase();
}
diff --git a/lib/src/command/token_add.dart b/lib/src/command/token_add.dart
index be9d406..86f032f 100644
--- a/lib/src/command/token_add.dart
+++ b/lib/src/command/token_add.dart
@@ -11,6 +11,7 @@
import '../io.dart';
import '../log.dart' as log;
import '../source/hosted.dart';
+import '../utils.dart';
/// Handles the `token add` pub command.
class TokenAddCommand extends PubCommand {
@@ -69,6 +70,11 @@
usageException('Token is not provided.');
}
+ if (!Credential.isValidBearerToken(token)) {
+ dataError('The entered token is not a valid Bearer token. '
+ 'A token may only contain `a-zA-Z0-9._~+/=-`');
+ }
+
tokenStore.addCredential(Credential.token(hostedUrl, token));
log.message(
'Requests to "$hostedUrl" will now be authenticated using the secret '
diff --git a/test/directory_option_test.dart b/test/directory_option_test.dart
index ac61887..5bc1cfd 100644
--- a/test/directory_option_test.dart
+++ b/test/directory_option_test.dart
@@ -18,7 +18,7 @@
..serve('foo', '1.0.0')
..serve('foo', '0.1.2')
..serve('bar', '1.2.3');
- await credentialsFile(globalServer, 'access token').create();
+ await credentialsFile(globalServer, 'access-token').create();
globalServer.handle(
RegExp('/api/packages/test_pkg/uploaders'),
(request) {
diff --git a/test/lish/archives_and_uploads_a_package_test.dart b/test/lish/archives_and_uploads_a_package_test.dart
index ffad2ea..dcd66cc 100644
--- a/test/lish/archives_and_uploads_a_package_test.dart
+++ b/test/lish/archives_and_uploads_a_package_test.dart
@@ -18,7 +18,7 @@
test('archives and uploads a package', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
@@ -44,7 +44,7 @@
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': globalServer.url, 'token': 'access token'},
+ {'url': globalServer.url, 'token': 'access-token'},
]
}).create();
var pub = await startPublish(globalServer);
@@ -79,7 +79,7 @@
globalServer,
path: '/sub/folder',
overrideDefaultHostedServer: false,
- environment: {'TOKEN': 'access token'},
+ environment: {'TOKEN': 'access-token'},
);
await confirmPublish(pub);
@@ -124,7 +124,7 @@
await d.dir(p.join(appPath, 'empty')).create();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
index 19b8761..fd14f85 100644
--- a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
+++ b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
@@ -13,7 +13,7 @@
test("cloud storage upload doesn't redirect", () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/cloud_storage_upload_provides_an_error_test.dart b/test/lish/cloud_storage_upload_provides_an_error_test.dart
index fa3a783..78b783e 100644
--- a/test/lish/cloud_storage_upload_provides_an_error_test.dart
+++ b/test/lish/cloud_storage_upload_provides_an_error_test.dart
@@ -13,7 +13,7 @@
test('cloud storage upload provides an error', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/does_not_include_dot_file.dart b/test/lish/does_not_include_dot_file.dart
index ab0b8a8..2699c81 100644
--- a/test/lish/does_not_include_dot_file.dart
+++ b/test/lish/does_not_include_dot_file.dart
@@ -30,7 +30,7 @@
test('Check if package doesn\'t include dot-files', () async {
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/does_not_include_pubspec_overrides_file.dart b/test/lish/does_not_include_pubspec_overrides_file.dart
index 9ff584b..126eeb1 100644
--- a/test/lish/does_not_include_pubspec_overrides_file.dart
+++ b/test/lish/does_not_include_pubspec_overrides_file.dart
@@ -31,7 +31,7 @@
test('Check if package doesn\'t include pubspec_overrides.yaml', () async {
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart b/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
index c287c31..882fbf0 100644
--- a/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
+++ b/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
@@ -16,7 +16,7 @@
test('--force publishes if there are no warnings or errors', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer, args: ['--force']);
handleUploadForm(globalServer);
diff --git a/test/lish/force_publishes_if_there_are_warnings_test.dart b/test/lish/force_publishes_if_there_are_warnings_test.dart
index 62e8754..cfc4567 100644
--- a/test/lish/force_publishes_if_there_are_warnings_test.dart
+++ b/test/lish/force_publishes_if_there_are_warnings_test.dart
@@ -27,7 +27,7 @@
(await servePackages()).serve('foo', '1.0.0');
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer, args: ['--force']);
handleUploadForm(globalServer);
diff --git a/test/lish/many_files_test.dart b/test/lish/many_files_test.dart
index d3805d1..7d9940e 100644
--- a/test/lish/many_files_test.dart
+++ b/test/lish/many_files_test.dart
@@ -40,7 +40,7 @@
],
).create();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
pub.stdin.writeln('y');
handleUploadForm(globalServer);
@@ -107,7 +107,7 @@
}
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/package_creation_provides_a_malformed_error_test.dart b/test/lish/package_creation_provides_a_malformed_error_test.dart
index cb18e56..491fb6e 100644
--- a/test/lish/package_creation_provides_a_malformed_error_test.dart
+++ b/test/lish/package_creation_provides_a_malformed_error_test.dart
@@ -15,7 +15,7 @@
test('package creation provides a malformed error', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/package_creation_provides_a_malformed_success_test.dart b/test/lish/package_creation_provides_a_malformed_success_test.dart
index b65317c..3166285 100644
--- a/test/lish/package_creation_provides_a_malformed_success_test.dart
+++ b/test/lish/package_creation_provides_a_malformed_success_test.dart
@@ -15,7 +15,7 @@
test('package creation provides a malformed success', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/package_creation_provides_an_error_test.dart b/test/lish/package_creation_provides_an_error_test.dart
index c1d8bba..e7dbda4 100644
--- a/test/lish/package_creation_provides_an_error_test.dart
+++ b/test/lish/package_creation_provides_an_error_test.dart
@@ -15,7 +15,7 @@
test('package creation provides an error', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/package_creation_provides_invalid_json_test.dart b/test/lish/package_creation_provides_invalid_json_test.dart
index 124e01a..39c8e45 100644
--- a/test/lish/package_creation_provides_invalid_json_test.dart
+++ b/test/lish/package_creation_provides_invalid_json_test.dart
@@ -13,7 +13,7 @@
test('package creation provides invalid JSON', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/package_validation_has_a_warning_and_continues_test.dart b/test/lish/package_validation_has_a_warning_and_continues_test.dart
index 5355434..a5c083b 100644
--- a/test/lish/package_validation_has_a_warning_and_continues_test.dart
+++ b/test/lish/package_validation_has_a_warning_and_continues_test.dart
@@ -22,7 +22,7 @@
File(d.path(p.join(appPath, 'README.md'))).deleteSync();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
expect(pub.stdout, emitsThrough(startsWith('Package has 1 warning.')));
pub.stdin.writeln('y');
diff --git a/test/lish/upload_form_fields_has_a_non_string_value_test.dart b/test/lish/upload_form_fields_has_a_non_string_value_test.dart
index 8758bca..7793863 100644
--- a/test/lish/upload_form_fields_has_a_non_string_value_test.dart
+++ b/test/lish/upload_form_fields_has_a_non_string_value_test.dart
@@ -14,7 +14,7 @@
test('upload form fields has a non-string value', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_fields_is_not_a_map_test.dart b/test/lish/upload_form_fields_is_not_a_map_test.dart
index dc41511..d0efb0d 100644
--- a/test/lish/upload_form_fields_is_not_a_map_test.dart
+++ b/test/lish/upload_form_fields_is_not_a_map_test.dart
@@ -14,7 +14,7 @@
test('upload form fields is not a map', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_is_missing_fields_test.dart b/test/lish/upload_form_is_missing_fields_test.dart
index e909c0a..fc494ca 100644
--- a/test/lish/upload_form_is_missing_fields_test.dart
+++ b/test/lish/upload_form_is_missing_fields_test.dart
@@ -14,7 +14,7 @@
test('upload form is missing fields', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_is_missing_url_test.dart b/test/lish/upload_form_is_missing_url_test.dart
index 418813f..e4f0291 100644
--- a/test/lish/upload_form_is_missing_url_test.dart
+++ b/test/lish/upload_form_is_missing_url_test.dart
@@ -14,7 +14,7 @@
test('upload form is missing url', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_provides_an_error_test.dart b/test/lish/upload_form_provides_an_error_test.dart
index 048ca17..2eacb24 100644
--- a/test/lish/upload_form_provides_an_error_test.dart
+++ b/test/lish/upload_form_provides_an_error_test.dart
@@ -14,7 +14,7 @@
test('upload form provides an error', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_provides_invalid_json_test.dart b/test/lish/upload_form_provides_invalid_json_test.dart
index 03f1551..14862bd 100644
--- a/test/lish/upload_form_provides_invalid_json_test.dart
+++ b/test/lish/upload_form_provides_invalid_json_test.dart
@@ -13,7 +13,7 @@
await servePackages();
await d.validPackage.create();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/upload_form_url_is_not_a_string_test.dart b/test/lish/upload_form_url_is_not_a_string_test.dart
index b37d24f..45e9aa8 100644
--- a/test/lish/upload_form_url_is_not_a_string_test.dart
+++ b/test/lish/upload_form_url_is_not_a_string_test.dart
@@ -14,7 +14,7 @@
test('upload form url is not a string', () async {
await servePackages();
await d.validPackage.create();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/lish/utils.dart b/test/lish/utils.dart
index 03766a4..10d21e5 100644
--- a/test/lish/utils.dart
+++ b/test/lish/utils.dart
@@ -13,7 +13,7 @@
server.expect('GET', '$path/api/packages/versions/new', (request) {
expect(
request.headers,
- containsPair('authorization', 'Bearer access token'),
+ containsPair('authorization', 'Bearer access-token'),
);
body ??= {
diff --git a/test/oauth2/logout_test.dart b/test/oauth2/logout_test.dart
index f5c8619..6c835a9 100644
--- a/test/oauth2/logout_test.dart
+++ b/test/oauth2/logout_test.dart
@@ -13,7 +13,7 @@
await d
.credentialsFile(
globalServer,
- 'access token',
+ 'access-token',
refreshToken: 'refresh token',
expiration: DateTime.now().add(Duration(hours: 1)),
)
@@ -31,7 +31,7 @@
await d
.credentialsFile(
globalServer,
- 'access token',
+ 'access-token',
refreshToken: 'refresh token',
expiration: DateTime.now().add(Duration(hours: 1)),
)
@@ -40,7 +40,7 @@
await d
.legacyCredentialsFile(
globalServer,
- 'access token',
+ 'access-token',
refreshToken: 'refresh token',
expiration: DateTime.now().add(Duration(hours: 1)),
)
diff --git a/test/oauth2/utils.dart b/test/oauth2/utils.dart
index f7043a0..05636e2 100644
--- a/test/oauth2/utils.dart
+++ b/test/oauth2/utils.dart
@@ -16,7 +16,7 @@
Future authorizePub(
TestProcess pub,
PackageServer server, [
- String accessToken = 'access token',
+ String accessToken = 'access-token',
]) async {
await expectLater(
pub.stdout,
diff --git a/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart b/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
index 3c22994..516204c 100644
--- a/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
+++ b/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
@@ -12,7 +12,7 @@
await d.validPackage.create();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
index 7e38887..2237814 100644
--- a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
+++ b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
@@ -23,7 +23,7 @@
await d
.credentialsFile(
globalServer,
- 'access token',
+ 'access-token',
refreshToken: 'bad refresh token',
expiration: DateTime.now().subtract(Duration(hours: 1)),
)
diff --git a/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart b/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart
index c4a54e1..bca9feb 100644
--- a/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart
+++ b/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart
@@ -20,7 +20,7 @@
await d
.credentialsFile(
globalServer,
- 'access token',
+ 'access-token',
refreshToken: 'refresh token',
expiration: DateTime.now().subtract(Duration(hours: 1)),
)
diff --git a/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart b/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
index ac22d7f..b21b496 100644
--- a/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
+++ b/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
@@ -19,7 +19,7 @@
await d
.credentialsFile(
globalServer,
- 'access token',
+ 'access-token',
expiration: DateTime.now().subtract(Duration(hours: 1)),
)
.create();
diff --git a/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart b/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
index c4d61ed..abe365f 100644
--- a/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
+++ b/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
@@ -32,6 +32,6 @@
// do so rather than killing it so it'll write out the credentials file.
await pub.shouldExit(1);
- await d.credentialsFile(globalServer, 'access token').validate();
+ await d.credentialsFile(globalServer, 'access-token').validate();
});
}
diff --git a/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart b/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
index 03468cf..c4b8d5b 100644
--- a/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
+++ b/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
@@ -16,7 +16,7 @@
'credentials.json', () async {
await d.validPackage.create();
await servePackages();
- await d.credentialsFile(globalServer, 'access token').create();
+ await d.credentialsFile(globalServer, 'access-token').create();
var pub = await startPublish(globalServer);
await confirmPublish(pub);
diff --git a/test/token/add_token_test.dart b/test/token/add_token_test.dart
index dd5d690..4321d90 100644
--- a/test/token/add_token_test.dart
+++ b/test/token/add_token_test.dart
@@ -129,6 +129,19 @@
await d.dir(configPath, [d.nothing('pub-tokens.json')]).validate();
});
+ test('with invalid token returns error', () async {
+ await d.dir(configPath).create();
+
+ await runPub(
+ args: ['token', 'add', 'https://pub.dev'],
+ error: contains('The entered token is not a valid Bearer token.'),
+ input: ['auth-token@'], // '@' is not allowed in bearer tokens
+ exitCode: exit_codes.DATA,
+ );
+
+ await d.dir(configPath, [d.nothing('pub-tokens.json')]).validate();
+ });
+
test('with non-secure server url returns error', () async {
await d.dir(configPath).create();
await runPub(
diff --git a/test/token/error_message_test.dart b/test/token/error_message_test.dart
index 0ccce60..5ed36dc 100644
--- a/test/token/error_message_test.dart
+++ b/test/token/error_message_test.dart
@@ -34,7 +34,7 @@
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': globalServer.url, 'token': 'access token'},
+ {'url': globalServer.url, 'token': 'access-token'},
]
}).create();
});
diff --git a/test/token/token_authentication_test.dart b/test/token/token_authentication_test.dart
index d0b89c9..7bd74f1 100644
--- a/test/token/token_authentication_test.dart
+++ b/test/token/token_authentication_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:pub/src/exit_codes.dart' as exit_codes;
import 'package:test/test.dart';
import '../descriptor.dart' as d;
@@ -21,7 +22,7 @@
var pub = await startPublish(
globalServer,
overrideDefaultHostedServer: false,
- environment: {'TOKEN': 'access token'},
+ environment: {'TOKEN': 'access-token'},
);
await confirmPublish(pub);
@@ -30,13 +31,60 @@
await pub.shouldExit(1);
});
+ test('with a invalid environment token fails with error', () async {
+ await servePackages();
+ await d.validPackage.create();
+ await d.tokensFile({
+ 'version': 1,
+ 'hosted': [
+ {'url': globalServer.url, 'env': 'TOKEN'},
+ ]
+ }).create();
+ await runPub(
+ args: ['publish'],
+ environment: {
+ 'TOKEN': 'access-token@' // '@' is not allowed in bearer tokens
+ },
+ error: contains(
+ 'Credential token for ${globalServer.url} is not a valid Bearer token.',
+ ),
+ exitCode: exit_codes.DATA,
+ );
+ });
+
+ test('with a pre existing invalid opaque token fails with error', () async {
+ await servePackages();
+ await d.validPackage.create();
+ await d.tokensFile({
+ 'version': 1,
+ 'hosted': [
+ // Corrupted files can be created by earlier pub versions that did not
+ // validate, or by manual edits.
+ {
+ 'url': globalServer.url,
+ 'token': 'access-token@', // '@' is not allowed in bearer tokens
+ },
+ ]
+ }).create();
+ await runPub(
+ args: ['publish'],
+ environment: {
+ 'TOKEN': 'access-token@' // '@' is not allowed in bearer tokens
+ },
+ error: contains(
+ 'Credential token for ${globalServer.url} is not a valid Bearer token.',
+ ),
+ exitCode: exit_codes.DATA,
+ );
+ });
+
test('with a pre existing opaque token authenticates', () async {
await servePackages();
await d.validPackage.create();
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': globalServer.url, 'token': 'access token'},
+ {'url': globalServer.url, 'token': 'access-token'},
]
}).create();
var pub = await startPublish(
diff --git a/test/token/when_receives_401_removes_token_test.dart b/test/token/when_receives_401_removes_token_test.dart
index 6ab0700..9e4d187 100644
--- a/test/token/when_receives_401_removes_token_test.dart
+++ b/test/token/when_receives_401_removes_token_test.dart
@@ -15,7 +15,7 @@
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': server.url, 'token': 'access token'},
+ {'url': server.url, 'token': 'access-token'},
]
}).create();
var pub = await startPublish(server, overrideDefaultHostedServer: false);
diff --git a/test/token/when_receives_403_persists_saved_token_test.dart b/test/token/when_receives_403_persists_saved_token_test.dart
index 3fef9a5..2141173 100644
--- a/test/token/when_receives_403_persists_saved_token_test.dart
+++ b/test/token/when_receives_403_persists_saved_token_test.dart
@@ -15,7 +15,7 @@
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': server.url, 'token': 'access token'},
+ {'url': server.url, 'token': 'access-token'},
]
}).create();
var pub = await startPublish(server, overrideDefaultHostedServer: false);
@@ -30,7 +30,7 @@
await d.tokensFile({
'version': 1,
'hosted': [
- {'url': server.url, 'token': 'access token'},
+ {'url': server.url, 'token': 'access-token'},
]
}).validate();
});