Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion example/index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'common.dart';

void main() {
final tokenInput = querySelector('#token') as InputElement;
tokenInput.value = github.auth!.token ?? '';
tokenInput.value = github.auth.token ?? '';
window.sessionStorage['GITHUB_TOKEN'] = tokenInput.value!;
tokenInput.onKeyUp.listen((_) {
window.sessionStorage['GITHUB_TOKEN'] = tokenInput.value!;
Expand Down
4 changes: 2 additions & 2 deletions example/user_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ void loadUser() {
});
});

if (github.auth!.token != null) {
localToken!.value = github.auth!.token;
if (github.auth.token != null) {
localToken!.value = github.auth.token;
loadBtn.click();
}
}
2 changes: 1 addition & 1 deletion lib/src/browser/xplat_browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Authentication findAuthenticationFromEnvironment() {
// search the query string parameters first
var auth = findAuthenticationInMap(_parseQuery(window.location.href));
auth ??= findAuthenticationInMap(window.sessionStorage);
return auth ?? Authentication.anonymous();
return auth ?? const Authentication.anonymous();
}

/// Parse the query string to a parameter `Map`
Expand Down
21 changes: 8 additions & 13 deletions lib/src/common/github.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ class GitHub {
/// [endpoint] is the api endpoint to use
/// [auth] is the authentication information
GitHub({
Authentication? auth,
this.auth = const Authentication.anonymous(),
this.endpoint = 'https://api.github.com',
this.version = '2022-11-28',
http.Client? client,
}) : auth = auth ?? Authentication.anonymous(),
client = client ?? http.Client();
}) : client = client ?? http.Client();

static const _ratelimitLimitHeader = 'x-ratelimit-limit';
static const _ratelimitResetHeader = 'x-ratelimit-reset';
Expand All @@ -34,7 +33,7 @@ class GitHub {
static const versionHeader = 'X-GitHub-Api-Version';

/// Authentication Information
Authentication? auth;
final Authentication auth;

/// API Endpoint
final String endpoint;
Expand Down Expand Up @@ -369,16 +368,16 @@ class GitHub {
headers['Accept'] = preview;
}

if (auth!.isToken) {
headers.putIfAbsent('Authorization', () => 'token ${auth!.token}');
} else if (auth!.isBasic) {
if (auth.isToken) {
headers.putIfAbsent('Authorization', () => 'token ${auth.token}');
} else if (auth.isBasic) {
final userAndPass =
base64Encode(utf8.encode('${auth!.username}:${auth!.password}'));
base64Encode(utf8.encode('${auth.username}:${auth.password}'));
headers.putIfAbsent('Authorization', () => 'basic $userAndPass');
}

// See https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#user-agent-required
headers.putIfAbsent('User-Agent', () => auth?.username ?? 'github.dart');
headers.putIfAbsent('User-Agent', () => auth.username ?? 'github.dart');

if (method == 'PUT' && body == null) {
headers.putIfAbsent('Content-Length', () => '0');
Expand Down Expand Up @@ -493,10 +492,6 @@ class GitHub {
/// Disposes of this GitHub Instance.
/// No other methods on this instance should be called after this method is called.
void dispose() {
// Destroy the Authentication Information
// This is needed for security reasons.
auth = null;

// Closes the HTTP Client
client.close();
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/common/util/auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ class Authentication {
final String? password;

/// Creates an [Authentication] instance that uses the specified OAuth2 [token].
Authentication.withToken(this.token)
const Authentication.withToken(this.token)
: username = null,
password = null;

/// Creates an [Authentication] instance that has no authentication.
Authentication.anonymous()
const Authentication.anonymous()
: token = null,
username = null,
password = null;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/common/xplat_common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:github/src/common.dart';
/// In both contexts it delegates to [findAuthenticationInMap] to find the
/// github token or username and password.
Authentication findAuthenticationFromEnvironment() =>
Authentication.anonymous();
const Authentication.anonymous();

/// Checks the passed in map for keys in [COMMON_GITHUB_TOKEN_ENV_KEYS].
/// The first one that exists is used as the github token to call [Authentication.withToken] with.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/server/xplat_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ Authentication findAuthenticationFromEnvironment() {
}

return findAuthenticationInMap(Platform.environment) ??
Authentication.anonymous();
const Authentication.anonymous();
}
19 changes: 18 additions & 1 deletion test/common/github_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:github/src/common/github.dart';
import 'package:github/src/common.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'package:test/test.dart';
Expand Down Expand Up @@ -38,5 +38,22 @@ void main() {
final userAgent = request!.headers['User-Agent'];
expect(userAgent, 'github.dart');
});

test('anonymous auth passes no authorization header', () async {
Request? request;
final client = MockClient((r) async {
request = r;
return Response('{}', HttpStatus.ok);
});

final github = GitHub(
client: client,
auth: const Authentication.anonymous(),
);
await github.getJSON(''); // Make HTTP request

expect(request, isNotNull);
expect(request!.headers.containsKey('Authorization'), isFalse);
});
});
}
2 changes: 1 addition & 1 deletion test/experiment/crawler.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:github/github.dart';

void main() {
final github = GitHub(auth: Authentication.anonymous());
final github = GitHub(auth: const Authentication.anonymous());

final crawler = RepositoryCrawler(
github,
Expand Down
4 changes: 2 additions & 2 deletions test/git_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const date = '2014-10-02T15:21:29Z';
GitHub createGithub() {
return GitHub(
endpoint: fakeApiUrl,
auth:
Authentication.withToken('0000000000000000000000000000000000000001'));
auth: const Authentication.withToken(
'0000000000000000000000000000000000000001'));
}

void main() {
Expand Down
4 changes: 2 additions & 2 deletions test/scenarios_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ Future<GitHub> createGithubWithScenario(String scenario,
var j = json.decode(resp.body);
return GitHub(
endpoint: j['url'],
auth:
Authentication.withToken('0000000000000000000000000000000000000001'));
auth: const Authentication.withToken(
'0000000000000000000000000000000000000001'));
}

/// Run scenario tests against ockokits fixtures-server
Expand Down