..
Viewing
auth.dart
102 lines (94 loc) • 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 | import 'package:http/http.dart' as http;
import 'package:oauth2/oauth2.dart' as oauth2;
import 'package:url_launcher/url_launcher.dart';
import 'dart:io';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/services.dart' show rootBundle;
const githubScopes = [
'repo',
'admin:repo_hook',
'admin:org',
'admin:public_key',
'admin:org_hook',
'gist',
'notifications',
'user',
'project',
'delete_repo',
'admin:gpg_key',
'workflow',
'write:discussion',
'write:packages',
'read:packages',
'delete:packages',
'codespace'
];
final authorizationEndpoint =
Uri.parse('https://github.com/login/oauth/authorize');
final tokenEndpoint = Uri.parse('https://github.com/login/oauth/access_token');
class _JSONAcceptingHttpClient extends http.BaseClient {
final _httpClient = http.Client();
@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
request.headers['Accept'] = 'application/json';
return _httpClient.send(request);
}
}
// If there is no token, hide the main window and open the browser to get the token
Future<oauth2.Client> _getOAuth2Client(
Uri redirectUri, HttpServer redirectServer) async {
await dotenv.load(fileName: ".env");
var grant = oauth2.AuthorizationCodeGrant(
dotenv.env['GITHUB_CLIENT_ID']!,
authorizationEndpoint,
tokenEndpoint,
secret: dotenv.env['GITHUB_CLIENT_SECRET']!,
httpClient: _JSONAcceptingHttpClient(),
);
var authorizationUrl =
grant.getAuthorizationUrl(redirectUri, scopes: githubScopes);
await _redirect(authorizationUrl);
var responseQueryParameters = await _listen(redirectServer);
try {
var client =
await grant.handleAuthorizationResponse(responseQueryParameters);
return client;
} catch (e) {
return oauth2.Client(oauth2.Credentials('null'));
}
}
Future<void> _redirect(Uri authorizationUrl) async {
if (await canLaunchUrl(authorizationUrl)) {
await launchUrl(authorizationUrl);
} else {
throw 'Could not launch ${authorizationUrl.toString()}.';
}
}
Future<Map<String, String>> _listen(redirectServer) async {
var request = await redirectServer.first;
var params = request.uri.queryParameters;
request.response.statusCode = 200;
request.response.headers.set('content-type', 'text/html');
var error = params['error'];
if (error != null) {
// request.response.write('Error: ${params.error}');
String failedHtml = await rootBundle.loadString('html/failed.html');
request.response.write(failedHtml);
} else {
// request.response.write('Success! You can close this window now.');
String successHtml = await rootBundle.loadString('html/success.html');
request.response.write(successHtml);
}
await request.response.close();
await redirectServer.close();
redirectServer = null;
return params;
}
class GithubAuth {
static Future<oauth2.Client> getOAuth2Client() async {
var redirectServer = await HttpServer.bind('localhost', 51691);
var authenticatedHttpClient = await _getOAuth2Client(
Uri.parse('http://localhost:${redirectServer.port}'), redirectServer);
return authenticatedHttpClient;
}
}
|
|