Skip to content

Commit

Permalink
Merge pull request #80 from eclipse-thingweb/security-provider
Browse files Browse the repository at this point in the history
feat!: simplify credentials callback usage
  • Loading branch information
JKRhb committed Dec 19, 2023
2 parents f3e39bf + 5caeedf commit d027ca8
Show file tree
Hide file tree
Showing 21 changed files with 164 additions and 170 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ To do so, a Thing Description JSON string is first parsed and turned into a
import 'package:dart_wot/dart_wot.dart';
Future<void> main(List<String> args) async {
final CoapClientFactory coapClientFactory = CoapClientFactory(null);
final CoapClientFactory coapClientFactory = CoapClientFactory();
final servient = Servient()..addClientFactory(coapClientFactory);
final wot = await servient.start();
Expand Down
8 changes: 3 additions & 5 deletions example/coaps_readproperty.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ PskCredentials? _pskCredentialsCallback(

Future<void> main(List<String> args) async {
final CoapClientFactory coapClientFactory = CoapClientFactory(
CoapConfig(
coapConfig: const CoapConfig(
dtlsCiphers: 'PSK-AES128-CCM8',
),
pskCredentialsCallback: _pskCredentialsCallback,
);
final securityProvider =
ClientSecurityProvider(pskCredentialsCallback: _pskCredentialsCallback);
final servient = Servient(clientSecurityProvider: securityProvider)
..addClientFactory(coapClientFactory);
final servient = Servient()..addClientFactory(coapClientFactory);

final wot = await servient.start();

Expand Down
12 changes: 6 additions & 6 deletions example/complex_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ Future<BasicCredentials?> basicCredentialsCallback(
}

Future<void> main() async {
final coapConfig = CoapConfig(blocksize: 64);
final CoapClientFactory coapClientFactory = CoapClientFactory(coapConfig);
final HttpClientFactory httpClientFactory = HttpClientFactory();
final securityProvider = ClientSecurityProvider(
basicCredentialsCallback: basicCredentialsCallback,
const coapConfig = CoapConfig(blocksize: 64);
final CoapClientFactory coapClientFactory = CoapClientFactory(
coapConfig: coapConfig,
);
final servient = Servient(clientSecurityProvider: securityProvider)
final HttpClientFactory httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final servient = Servient()
..addClientFactory(coapClientFactory)
..addClientFactory(httpClientFactory);
final wot = await servient.start();
Expand Down
9 changes: 3 additions & 6 deletions example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ Future<BasicCredentials?> basicCredentialsCallback(

Future<void> main(List<String> args) async {
final CoapClientFactory coapClientFactory = CoapClientFactory();
final HttpClientFactory httpClientFactory = HttpClientFactory();
final HttpClientFactory httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final MqttClientFactory mqttClientFactory = MqttClientFactory();
final servient = Servient(
clientSecurityProvider: ClientSecurityProvider(
basicCredentialsCallback: basicCredentialsCallback,
),
)
final servient = Servient()
..addClientFactory(coapClientFactory)
..addClientFactory(httpClientFactory)
..addClientFactory(mqttClientFactory);
Expand Down
9 changes: 3 additions & 6 deletions example/http_basic_authentication.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,9 @@ Future<BasicCredentials?> basicCredentialsCallback(
/// Illustrates the usage of both the basic and the automatic security scheme,
/// with a server supporting basic authentication.
Future<void> main(List<String> args) async {
final HttpClientFactory httpClientFactory = HttpClientFactory();
final securityProvider = ClientSecurityProvider(
basicCredentialsCallback: basicCredentialsCallback,
);
final servient = Servient(clientSecurityProvider: securityProvider)
..addClientFactory(httpClientFactory);
final HttpClientFactory httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final servient = Servient()..addClientFactory(httpClientFactory);
final wot = await servient.start();

final thingDescription = ThingDescription(thingDescriptionJson);
Expand Down
2 changes: 1 addition & 1 deletion lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ export 'src/core/credentials/ace_credentials.dart';
export 'src/core/credentials/apikey_credentials.dart';
export 'src/core/credentials/basic_credentials.dart';
export 'src/core/credentials/bearer_credentials.dart';
export 'src/core/credentials/callbacks.dart';
export 'src/core/credentials/credentials.dart';
export 'src/core/credentials/digest_credentials.dart';
export 'src/core/credentials/oauth2_credentials.dart';
export 'src/core/credentials/psk_credentials.dart';
export 'src/core/protocol_interfaces/protocol_client.dart';
export 'src/core/protocol_interfaces/protocol_client_factory.dart';
export 'src/core/protocol_interfaces/protocol_server.dart';
export 'src/core/security_provider.dart';
export 'src/core/servient.dart';
37 changes: 23 additions & 14 deletions lib/src/binding_coap/coap_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import 'package:dcaf/dcaf.dart';

import '../core/content.dart';
import '../core/credentials/ace_credentials.dart';
import '../core/credentials/callbacks.dart';
import '../core/credentials/psk_credentials.dart';
import '../core/protocol_interfaces/protocol_client.dart';
import '../core/security_provider.dart';
import '../definitions/form.dart';
import '../definitions/operation_type.dart';
import '../scripting_api/subscription.dart';
Expand Down Expand Up @@ -52,11 +52,10 @@ class _InternalCoapConfig extends CoapConfigDefault {

coap.PskCredentialsCallback? _createPskCallback(
Uri uri,
Form? form,
ClientSecurityProvider? clientSecurityProvider,
) {
Form? form, {
ClientPskCallback? pskCredentialsCallback,
}) {
final usesPskScheme = form?.usesPskScheme ?? false;
final pskCredentialsCallback = clientSecurityProvider?.pskCredentialsCallback;

if (!usesPskScheme || pskCredentialsCallback == null) {
return null;
Expand All @@ -82,11 +81,19 @@ coap.PskCredentialsCallback? _createPskCallback(
/// A [ProtocolClient] for the Constrained Application Protocol (CoAP).
final class CoapClient implements ProtocolClient {
/// Creates a new [CoapClient] based on an optional [CoapConfig].
CoapClient([this._coapConfig, this._clientSecurityProvider]);
CoapClient({
CoapConfig? coapConfig,
ClientPskCallback? pskCredentialsCallback,
AceSecurityCallback? aceSecurityCallback,
}) : _pskCredentialsCallback = pskCredentialsCallback,
_aceSecurityCallback = aceSecurityCallback,
_coapConfig = coapConfig;

final CoapConfig? _coapConfig;

final ClientSecurityProvider? _clientSecurityProvider;
final ClientPskCallback? _pskCredentialsCallback;

final AceSecurityCallback? _aceSecurityCallback;

Future<coap.CoapRequest> _createRequest(
coap.RequestMethod requestMethod,
Expand Down Expand Up @@ -153,9 +160,12 @@ final class CoapClient implements ProtocolClient {
}) async {
final coapClient = coap.CoapClient(
uri,
config: _InternalCoapConfig(_coapConfig ?? CoapConfig()),
pskCredentialsCallback:
_createPskCallback(uri, form, _clientSecurityProvider),
config: _InternalCoapConfig(_coapConfig ?? const CoapConfig()),
pskCredentialsCallback: _createPskCallback(
uri,
form,
pskCredentialsCallback: _pskCredentialsCallback,
),
);

final request = await _createRequest(
Expand All @@ -169,8 +179,7 @@ final class CoapClient implements ProtocolClient {
);

final creationHint = await _obtainAceCreationHintFromForm(form);
final aceCredentialsCallback =
_clientSecurityProvider?.aceCredentialsCallback;
final aceCredentialsCallback = _aceSecurityCallback;

final coap.CoapResponse response;

Expand Down Expand Up @@ -236,7 +245,7 @@ final class CoapClient implements ProtocolClient {

final coapClient = coap.CoapClient(
creationHintUri,
config: _InternalCoapConfig(_coapConfig ?? CoapConfig()),
config: _InternalCoapConfig(_coapConfig ?? const CoapConfig()),
);

final response = await coapClient.send(request);
Expand Down Expand Up @@ -421,7 +430,7 @@ final class CoapClient implements ProtocolClient {

final coapClient = coap.CoapClient(
form.resolvedHref,
config: _InternalCoapConfig(_coapConfig ?? CoapConfig()),
config: _InternalCoapConfig(_coapConfig ?? const CoapConfig()),
);

if (subprotocol == CoapSubprotocol.observe) {
Expand Down
28 changes: 19 additions & 9 deletions lib/src/binding_coap/coap_client_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,43 @@
//
// SPDX-License-Identifier: BSD-3-Clause

import '../core/credentials/callbacks.dart';
import '../core/protocol_interfaces/protocol_client.dart';
import '../core/protocol_interfaces/protocol_client_factory.dart';
import '../core/security_provider.dart';
import 'coap_client.dart';
import 'coap_config.dart';

/// A [ProtocolClientFactory] that produces CoAP clients.
final class CoapClientFactory implements ProtocolClientFactory {
/// Creates a new [CoapClientFactory] based on an optional [CoapConfig].
CoapClientFactory([this.coapConfig]);

@override
Set<String> get schemes => {'coap', 'coaps'};
CoapClientFactory({
this.coapConfig,
ClientPskCallback? pskCredentialsCallback,
AceSecurityCallback? aceSecurityCallback,
}) : _pskCredentialsCallback = pskCredentialsCallback,
_aceSecurityCallback = aceSecurityCallback;

/// The [CoapConfig] used to configure new clients.
final CoapConfig? coapConfig;

final ClientPskCallback? _pskCredentialsCallback;

final AceSecurityCallback? _aceSecurityCallback;

@override
Set<String> get schemes => {'coap', 'coaps'};

@override
bool destroy() {
return true;
}

@override
ProtocolClient createClient([
ClientSecurityProvider? clientSecurityProvider,
]) =>
CoapClient(coapConfig, clientSecurityProvider);
ProtocolClient createClient() => CoapClient(
coapConfig: coapConfig,
pskCredentialsCallback: _pskCredentialsCallback,
aceSecurityCallback: _aceSecurityCallback,
);

@override
bool init() {
Expand Down
5 changes: 4 additions & 1 deletion lib/src/binding_coap/coap_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

import 'dart:typed_data';

import 'package:meta/meta.dart';

/// Allows for configuring the behavior of CoAP clients and servers.
@immutable
class CoapConfig {
/// Creates a new [CoapConfig] object.
CoapConfig({
const CoapConfig({
this.port = 5683,
this.securePort = 5684,
this.blocksize,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/binding_coap/coap_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// SPDX-License-Identifier: BSD-3-Clause

import '../core/credentials/callbacks.dart';
import '../core/protocol_interfaces/protocol_server.dart';
import '../core/security_provider.dart';
import '../scripting_api/exposed_thing.dart';
import 'coap_config.dart';

Expand Down
20 changes: 13 additions & 7 deletions lib/src/binding_http/http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import 'package:http/http.dart';
import '../core/content.dart';
import '../core/credentials/basic_credentials.dart';
import '../core/credentials/bearer_credentials.dart';
import '../core/credentials/callbacks.dart';
import '../core/protocol_interfaces/protocol_client.dart';
import '../core/security_provider.dart';
import '../definitions/form.dart';
import '../definitions/operation_type.dart';
import '../definitions/security/basic_security_scheme.dart';
Expand Down Expand Up @@ -46,11 +46,19 @@ const _authorizationHeader = 'Authorization';
/// [`ComboSecurityScheme`]: https://w3c.github.io/wot-thing-description/#combosecurityscheme
final class HttpClient implements ProtocolClient {
/// Creates a new [HttpClient].
HttpClient(this._clientSecurityProvider);
HttpClient({
AsyncClientSecurityCallback<BasicCredentials>? basicCredentialsCallback,
AsyncClientSecurityCallback<BearerCredentials>? bearerCredentialsCallback,
}) : _basicCredentialsCallback = basicCredentialsCallback,
_bearerCredentialsCallback = bearerCredentialsCallback;

final _client = Client();

final ClientSecurityProvider? _clientSecurityProvider;
final AsyncClientSecurityCallback<BasicCredentials>?
_basicCredentialsCallback;

final AsyncClientSecurityCallback<BearerCredentials>?
_bearerCredentialsCallback;

Future<void> _applyCredentialsFromForm(Request request, Form form) async {
// TODO(JKRhb): Add DigestSecurity back in
Expand Down Expand Up @@ -210,17 +218,15 @@ final class HttpClient implements ProtocolClient {
Form? form, [
BasicCredentials? invalidCredentials,
]) async {
return _clientSecurityProvider?.basicCredentialsCallback
?.call(uri, form, invalidCredentials);
return _basicCredentialsCallback?.call(uri, form, invalidCredentials);
}

Future<BearerCredentials?> _getBearerCredentials(
Uri uri,
Form? form, [
BearerCredentials? invalidCredentials,
]) async {
return _clientSecurityProvider?.bearerCredentialsCallback
?.call(uri, form, invalidCredentials);
return _bearerCredentialsCallback?.call(uri, form, invalidCredentials);
}

static Map<String, String> _getHeadersFromForm(Form form) {
Expand Down
27 changes: 18 additions & 9 deletions lib/src/binding_http/http_client_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,42 @@
//
// SPDX-License-Identifier: BSD-3-Clause

import '../core/credentials/basic_credentials.dart';
import '../core/credentials/bearer_credentials.dart';
import '../core/credentials/callbacks.dart';
import '../core/protocol_interfaces/protocol_client.dart';
import '../core/protocol_interfaces/protocol_client_factory.dart';
import '../core/security_provider.dart';
import 'http_client.dart';
import 'http_config.dart';

/// A [ProtocolClientFactory] that produces HTTP and HTTPS clients.
final class HttpClientFactory implements ProtocolClientFactory {
/// Creates a new [HttpClientFactory] based on an optional [HttpConfig].
HttpClientFactory([this.httpConfig]);
HttpClientFactory({
AsyncClientSecurityCallback<BasicCredentials>? basicCredentialsCallback,
AsyncClientSecurityCallback<BearerCredentials>? bearerCredentialsCallback,
}) : _basicCredentialsCallback = basicCredentialsCallback,
_bearerCredentialsCallback = bearerCredentialsCallback;

final AsyncClientSecurityCallback<BasicCredentials>?
_basicCredentialsCallback;

final AsyncClientSecurityCallback<BearerCredentials>?
_bearerCredentialsCallback;

@override
Set<String> get schemes => {'http', 'https'};

/// The [HttpConfig] used to configure new clients.
final HttpConfig? httpConfig;

@override
bool destroy() {
return true;
}

@override
ProtocolClient createClient([
ClientSecurityProvider? clientSecurityProvider,
]) =>
HttpClient(clientSecurityProvider);
ProtocolClient createClient() => HttpClient(
basicCredentialsCallback: _basicCredentialsCallback,
bearerCredentialsCallback: _bearerCredentialsCallback,
);

@override
bool init() {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/binding_http/http_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// SPDX-License-Identifier: BSD-3-Clause

import '../core/credentials/callbacks.dart';
import '../core/protocol_interfaces/protocol_server.dart';
import '../core/security_provider.dart';
import '../scripting_api/exposed_thing.dart';
import 'http_config.dart';

Expand Down
Loading

0 comments on commit d027ca8

Please sign in to comment.