All checks were successful
continuous-integration/drone/push Build is passing
295 lines
8.1 KiB
Dart
295 lines
8.1 KiB
Dart
// Copyright (C) 2022 WYATT GROUP
|
|
// Please see the AUTHORS file for details.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:wyatt_http_client/wyatt_http_client.dart';
|
|
|
|
String lastToken = '';
|
|
int token = 0;
|
|
|
|
void printAuth(HttpRequest req) {
|
|
print(
|
|
'Authorization => '
|
|
"${req.headers.value('Authorization') ?? 'no authorization header'}",
|
|
);
|
|
}
|
|
|
|
Future<void> handleBasic(HttpRequest req) async {
|
|
printAuth(req);
|
|
}
|
|
|
|
Future<void> handleBasicNegotiate(HttpRequest req) async {
|
|
if (req.headers.value('Authorization') == null) {
|
|
req.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
req.response.headers.set(HeaderKeys.wwwAuthenticate, 'Basic realm="Wyatt"');
|
|
print(req.response.headers.value('WWW-Authenticate'));
|
|
return req.response.close();
|
|
}
|
|
printAuth(req);
|
|
}
|
|
|
|
Future<void> handleBearer(HttpRequest req) async {
|
|
printAuth(req);
|
|
}
|
|
|
|
Future<void> handleDigest(HttpRequest req) async {
|
|
if (req.headers.value('Authorization') == null) {
|
|
req.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
req.response.headers.set(
|
|
'WWW-Authenticate',
|
|
'Digest realm="Wyatt", '
|
|
'qop="auth,auth-int", '
|
|
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", '
|
|
'opaque="5ccc069c403ebaf9f0171e9517f40e41"',
|
|
);
|
|
print(req.response.headers.value('WWW-Authenticate'));
|
|
return req.response.close();
|
|
}
|
|
printAuth(req);
|
|
}
|
|
|
|
Future<void> handleUnsafe(HttpRequest req) async {
|
|
print(
|
|
'Query parameters => '
|
|
'${req.uri.queryParameters}',
|
|
);
|
|
}
|
|
|
|
Future<void> handleOauth2RefreshToken(HttpRequest req) async {
|
|
final action = req.uri.queryParameters['action'];
|
|
if (action == null) {
|
|
printAuth(req);
|
|
}
|
|
|
|
switch (action) {
|
|
case 'login':
|
|
if (req.method == 'POST') {
|
|
token++;
|
|
req.response.write(
|
|
'{"accessToken": "access-token-awesome$token", '
|
|
'"refreshToken": "refresh-token-awesome$token"}',
|
|
);
|
|
}
|
|
break;
|
|
case 'refresh':
|
|
printAuth(req);
|
|
if (req.method == 'GET') {
|
|
token++;
|
|
req.response.write('{"accessToken": "access-token-refreshed$token"}');
|
|
}
|
|
break;
|
|
case 'access-denied':
|
|
final String receivedToken = req.headers.value('Authorization') ?? '';
|
|
if (receivedToken != '' &&
|
|
lastToken != '' &&
|
|
receivedToken != lastToken) {
|
|
lastToken = receivedToken;
|
|
printAuth(req);
|
|
return req.response.close();
|
|
} else {
|
|
lastToken = receivedToken;
|
|
req.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
return req.response.close();
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
Future<void> server() async {
|
|
final server = await HttpServer.bind(InternetAddress.anyIPv6, 8080);
|
|
var error = 0;
|
|
var token = 0;
|
|
await server.forEach((request) {
|
|
print('[${request.method}] ${request.uri}');
|
|
switch (request.uri.path) {
|
|
case '/test/basic-test':
|
|
handleBasic(request);
|
|
break;
|
|
case '/test/basic-test-with-negotiate':
|
|
handleBasicNegotiate(request);
|
|
break;
|
|
case '/test/digest-test':
|
|
handleDigest(request);
|
|
break;
|
|
case '/test/apikey-test':
|
|
handleBearer(request);
|
|
break;
|
|
case '/test/bearer-test':
|
|
handleBearer(request);
|
|
break;
|
|
case '/test/unsafe-test':
|
|
handleUnsafe(request);
|
|
break;
|
|
case '/test/oauth2-test':
|
|
handleOauth2RefreshToken(request);
|
|
break;
|
|
|
|
case '/test/bearer-login':
|
|
if (request.method == 'POST') {
|
|
request.response.write('{"token": "access-token-test"}');
|
|
}
|
|
break;
|
|
|
|
case '/test/oauth2-test-error':
|
|
error++;
|
|
print('Error $error');
|
|
if (error >= 3) {
|
|
print('Authorized');
|
|
error = 0;
|
|
} else {
|
|
request.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
}
|
|
break;
|
|
case '/test/oauth2-test-timeout':
|
|
error++;
|
|
print('Error $error');
|
|
request.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
break;
|
|
case '/test/oauth2-login':
|
|
if (request.method == 'POST') {
|
|
token++;
|
|
request.response.write(
|
|
'{"accessToken": "access-token-awesome$token", '
|
|
'"refreshToken": "refresh-token-awesome$token"}',
|
|
);
|
|
}
|
|
break;
|
|
case '/test/oauth2-refresh':
|
|
print(
|
|
'Authorization => '
|
|
"${request.headers.value('Authorization') ?? 'no refresh token'}",
|
|
);
|
|
if (request.method == 'GET') {
|
|
token++;
|
|
request.response
|
|
.write('{"accessToken": "access-token-refreshed$token"}');
|
|
}
|
|
break;
|
|
case '/test/oauth2-refresh-error':
|
|
request.response.statusCode = HttpStatus.unauthorized.statusCode;
|
|
break;
|
|
|
|
default:
|
|
print(' => Unknown path or method');
|
|
request.response.statusCode = HttpStatus.notFound.statusCode;
|
|
}
|
|
request.response.close();
|
|
print('====================');
|
|
});
|
|
}
|
|
|
|
Future<void> main() async {
|
|
unawaited(server());
|
|
const base = 'localhost:8080';
|
|
final uriPrefix = UriPrefixMiddleware(
|
|
protocol: Protocols.http,
|
|
authority: base,
|
|
);
|
|
final jsonEncoder = BodyToJsonMiddleware();
|
|
final logger = SimpleLoggerMiddleware();
|
|
|
|
// Basic
|
|
final basicAuth = BasicAuthMiddleware(
|
|
username: 'username',
|
|
password: 'password',
|
|
);
|
|
final basic = MiddlewareClient(
|
|
pipeline: Pipeline.fromIterable([
|
|
uriPrefix,
|
|
basicAuth,
|
|
logger,
|
|
]),
|
|
);
|
|
await basic.get(Uri.parse('/test/basic-test'));
|
|
|
|
// Digest
|
|
final digestAuth = DigestAuthMiddleware(
|
|
username: 'Mufasa',
|
|
password: 'Circle Of Life',
|
|
);
|
|
final digest = MiddlewareClient(
|
|
pipeline: Pipeline.fromIterable([
|
|
uriPrefix,
|
|
digestAuth,
|
|
logger,
|
|
]),
|
|
);
|
|
await digest.get(Uri.parse('/test/digest-test'));
|
|
|
|
// // Bearer
|
|
// final bearer = BearerAuthenticationClient(
|
|
// token: 'access-token-test',
|
|
// inner: restClient,
|
|
// );
|
|
// await bearer.get(Uri.parse('/test/bearer-test'));
|
|
|
|
// // API Key
|
|
// final apiKey = BearerAuthenticationClient(
|
|
// token: 'awesome-api-key',
|
|
// authenticationMethod: 'ApiKey',
|
|
// inner: restClient,
|
|
// );
|
|
// await apiKey.get(Uri.parse('/test/apikey-test'));
|
|
|
|
// Unsafe URL
|
|
final unsafeAuth = UnsafeAuthMiddleware(
|
|
username: 'Mufasa',
|
|
password: 'Circle Of Life',
|
|
);
|
|
final unsafe = MiddlewareClient(
|
|
pipeline: Pipeline.fromIterable([
|
|
uriPrefix,
|
|
unsafeAuth,
|
|
logger,
|
|
]),
|
|
);
|
|
await unsafe.get(Uri.parse('/test/unsafe-test'));
|
|
|
|
// OAuth2
|
|
final refreshTokenAuth = RefreshTokenAuthMiddleware(
|
|
authorizationEndpoint: '/test/oauth2-test?action=login',
|
|
tokenEndpoint: '/test/oauth2-test?action=refresh',
|
|
accessTokenParser: (body) => body['accessToken']! as String,
|
|
refreshTokenParser: (body) => body['refreshToken']! as String,
|
|
);
|
|
final refreshToken = MiddlewareClient(
|
|
pipeline: Pipeline.fromIterable([
|
|
uriPrefix,
|
|
jsonEncoder,
|
|
refreshTokenAuth,
|
|
logger,
|
|
]),
|
|
);
|
|
await refreshToken.get(Uri.parse('/test/oauth2-test'));
|
|
// Login
|
|
await refreshToken.post(
|
|
Uri.parse('/test/oauth2-test'),
|
|
body: <String, String>{
|
|
'username': 'username',
|
|
'password': 'password',
|
|
},
|
|
);
|
|
await refreshToken.get(Uri.parse('/test/oauth2-test'));
|
|
// await refreshToken.refresh();
|
|
// await refreshToken.get(Uri.parse('/test/oauth2-test'));
|
|
// await refreshToken.get(Uri.parse('/test/oauth2-test?action=access-denied'));
|
|
|
|
exit(0);
|
|
}
|