feat(core): Handle less resource binding in the core connection class
This commit is contained in:
parent
af8bc606d6
commit
f460e5ebe9
@ -3,6 +3,8 @@
|
||||
- **BREAKING**: Removed `connectAwaitable` and merged it with `connect`.
|
||||
- **BREAKING**: Removed `allowPlainAuth` from `ConnectionSettings`. If you don't want to use SASL PLAIN, don't register the negotiator. If you want to only conditionally use SASL PLAIN, extend the `SaslPlainNegotiator` and override its `matchesFeature` method to only call the super method when SASL PLAIN should be used.
|
||||
- **BREAKING**: The user avatar's `subscribe` and `unsubscribe` no longer subscribe to the `:data` PubSub nodes
|
||||
- Renamed `ResourceBindingSuccessEvent` to `ResourceBoundEvent`
|
||||
- **BREAKING**: Removed `isFeatureSupported` from the manager attributes. The managers now all have a method `isFeatureSupported` that works the same
|
||||
|
||||
## 0.1.6+1
|
||||
|
||||
|
@ -133,9 +133,6 @@ class XmppConnection {
|
||||
StreamController.broadcast();
|
||||
final Map<String, XmppManagerBase> _xmppManagers = {};
|
||||
|
||||
/// Disco info we got after binding a resource (xmlns)
|
||||
final List<String> _serverFeatures = List.empty(growable: true);
|
||||
|
||||
/// The buffer object to keep split up stanzas together
|
||||
final XmlStreamBuffer _streamBuffer = XmlStreamBuffer();
|
||||
|
||||
@ -150,6 +147,7 @@ class XmppConnection {
|
||||
|
||||
/// The currently bound resource or '' if none has been bound yet.
|
||||
String _resource = '';
|
||||
String get resource => _resource;
|
||||
|
||||
/// True if we are authenticated. False if not.
|
||||
bool _isAuthenticated = false;
|
||||
@ -201,8 +199,6 @@ class XmppConnection {
|
||||
|
||||
ReconnectionPolicy get reconnectionPolicy => _reconnectionPolicy;
|
||||
|
||||
List<String> get serverFeatures => _serverFeatures;
|
||||
|
||||
bool get isAuthenticated => _isAuthenticated;
|
||||
|
||||
/// Return the registered feature negotiator that has id [id]. Returns null if
|
||||
@ -221,7 +217,6 @@ class XmppConnection {
|
||||
sendEvent: _sendEvent,
|
||||
getConnectionSettings: () => _connectionSettings,
|
||||
getManagerById: getManagerById,
|
||||
isFeatureSupported: _serverFeatures.contains,
|
||||
getFullJID: () => _connectionSettings.jid.withResource(_resource),
|
||||
getSocket: () => _socket,
|
||||
getConnection: () => this,
|
||||
@ -283,6 +278,7 @@ class XmppConnection {
|
||||
() => _socket,
|
||||
() => _isAuthenticated,
|
||||
_setAuthenticated,
|
||||
_setResource,
|
||||
_removeNegotiatingFeature,
|
||||
),
|
||||
);
|
||||
@ -678,9 +674,13 @@ class XmppConnection {
|
||||
}
|
||||
|
||||
/// Sets the resource of the connection
|
||||
void setResource(String resource) {
|
||||
void _setResource(String resource, {bool triggerEvent = true}) {
|
||||
_log.finest('Updating _resource to $resource');
|
||||
_resource = resource;
|
||||
|
||||
if (triggerEvent) {
|
||||
_sendEvent(ResourceBoundEvent(resource));
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the connection's events as a stream.
|
||||
@ -1028,17 +1028,6 @@ class XmppConnection {
|
||||
Future<void> _sendEvent(XmppEvent event) async {
|
||||
_log.finest('Event: ${event.toString()}');
|
||||
|
||||
// Specific event handling
|
||||
if (event is ResourceBindingSuccessEvent) {
|
||||
_log.finest(
|
||||
'Received ResourceBindingSuccessEvent. Setting _resource to ${event.resource}',
|
||||
);
|
||||
setResource(event.resource);
|
||||
|
||||
_log.finest('Resetting _serverFeatures');
|
||||
_serverFeatures.clear();
|
||||
}
|
||||
|
||||
for (final manager in _xmppManagers.values) {
|
||||
await manager.onXmppEvent(event);
|
||||
}
|
||||
@ -1151,7 +1140,7 @@ class XmppConnection {
|
||||
}
|
||||
|
||||
if (lastResource != null) {
|
||||
setResource(lastResource);
|
||||
_setResource(lastResource, triggerEvent: false);
|
||||
}
|
||||
|
||||
_enableReconnectOnSuccess = enableReconnectOnSuccess;
|
||||
|
@ -160,8 +160,10 @@ class StreamManagementEnabledEvent extends XmppEvent {
|
||||
}
|
||||
|
||||
/// Triggered when we bound a resource
|
||||
class ResourceBindingSuccessEvent extends XmppEvent {
|
||||
ResourceBindingSuccessEvent({required this.resource});
|
||||
class ResourceBoundEvent extends XmppEvent {
|
||||
ResourceBoundEvent(this.resource);
|
||||
|
||||
/// The resource that was just bound.
|
||||
final String resource;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ class XmppManagerAttributes {
|
||||
required this.getManagerById,
|
||||
required this.sendEvent,
|
||||
required this.getConnectionSettings,
|
||||
required this.isFeatureSupported,
|
||||
required this.getFullJID,
|
||||
required this.getSocket,
|
||||
required this.getConnection,
|
||||
@ -45,9 +44,6 @@ class XmppManagerAttributes {
|
||||
/// (Maybe) Get a Manager attached to the connection by its Id.
|
||||
final T? Function<T extends XmppManagerBase>(String) getManagerById;
|
||||
|
||||
/// Returns true if a server feature is supported
|
||||
final bool Function(String) isFeatureSupported;
|
||||
|
||||
/// Returns the full JID of the current account
|
||||
final JID Function() getFullJID;
|
||||
|
||||
|
@ -6,6 +6,7 @@ import 'package:moxxmpp/src/managers/data.dart';
|
||||
import 'package:moxxmpp/src/managers/handlers.dart';
|
||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0198/xep_0198.dart';
|
||||
@ -31,6 +32,29 @@ abstract class XmppManagerBase {
|
||||
return _managerAttributes;
|
||||
}
|
||||
|
||||
/// Resolves to true when the server supports the disco feature [xmlns]. Resolves
|
||||
/// to false when either the disco request fails or the server does not
|
||||
/// support [xmlns].
|
||||
/// Note that this function requires a registered DiscoManager.
|
||||
@protected
|
||||
Future<bool> isFeatureSupported(String xmlns) async {
|
||||
final dm = _managerAttributes.getManagerById<DiscoManager>(discoManager);
|
||||
assert(
|
||||
dm != null,
|
||||
'The DiscoManager must be registered for isFeatureSupported to work',
|
||||
);
|
||||
|
||||
final result = await dm!.discoInfoQuery(
|
||||
_managerAttributes.getConnectionSettings().jid.domain,
|
||||
shouldEncrypt: false,
|
||||
);
|
||||
if (result.isType<DiscoError>()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result.get<DiscoInfo>().features.contains(xmlns);
|
||||
}
|
||||
|
||||
/// Return the StanzaHandlers associated with this manager that deal with stanzas we
|
||||
/// send. These are run before the stanza is sent. The higher the value of the
|
||||
/// handler's priority, the earlier it is run.
|
||||
|
@ -36,6 +36,7 @@ class NegotiatorAttributes {
|
||||
this.getSocket,
|
||||
this.isAuthenticated,
|
||||
this.setAuthenticated,
|
||||
this.setResource,
|
||||
this.removeNegotiatingFeature,
|
||||
);
|
||||
|
||||
@ -64,6 +65,10 @@ class NegotiatorAttributes {
|
||||
/// Returns true if the stream is authenticated. Returns false if not.
|
||||
final bool Function() isAuthenticated;
|
||||
|
||||
/// Sets the resource of the connection. If triggerEvent is true, then a
|
||||
/// [ResourceBoundEvent] is triggered.
|
||||
final void Function(String, {bool triggerEvent}) setResource;
|
||||
|
||||
/// Sets the authentication state of the connection to true.
|
||||
final void Function() setAuthenticated;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:moxxmpp/src/events.dart';
|
||||
import 'package:moxxmpp/src/jid.dart';
|
||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||
import 'package:moxxmpp/src/namespaces.dart';
|
||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||
@ -65,11 +65,9 @@ class ResourceBindingNegotiator extends XmppFeatureNegotiatorBase {
|
||||
}
|
||||
|
||||
final bind = nonza.firstTag('bind')!;
|
||||
final jid = bind.firstTag('jid')!;
|
||||
final resource = jid.innerText().split('/')[1];
|
||||
|
||||
await attributes
|
||||
.sendEvent(ResourceBindingSuccessEvent(resource: resource));
|
||||
final rawJid = bind.firstTag('jid')!.innerText();
|
||||
final resource = JID.fromString(rawJid).resource;
|
||||
attributes.setResource(resource);
|
||||
return const Result(NegotiatorState.done);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ class TestingManagerHolder {
|
||||
sendNonza: (_) {},
|
||||
sendEvent: (_) {},
|
||||
getSocket: () => _socket,
|
||||
isFeatureSupported: (_) => false,
|
||||
getNegotiatorById: getNegotiatorNullStub,
|
||||
getFullJID: () => jid,
|
||||
getManagerById: _getManagerById,
|
||||
|
@ -58,6 +58,7 @@ void main() {
|
||||
() => fakeSocket,
|
||||
() => false,
|
||||
() {},
|
||||
(_, {bool triggerEvent = true}) {},
|
||||
(_) {},
|
||||
),
|
||||
);
|
||||
@ -153,6 +154,7 @@ void main() {
|
||||
() => fakeSocket,
|
||||
() => false,
|
||||
() {},
|
||||
(_, {bool triggerEvent = true}) {},
|
||||
(_) {},
|
||||
),
|
||||
);
|
||||
@ -203,6 +205,7 @@ void main() {
|
||||
() => fakeSocket,
|
||||
() => false,
|
||||
() {},
|
||||
(_, {bool triggerEvent = true}) {},
|
||||
(_) {},
|
||||
),
|
||||
);
|
||||
@ -243,6 +246,7 @@ void main() {
|
||||
() => fakeSocket,
|
||||
() => false,
|
||||
() {},
|
||||
(_, {bool triggerEvent = true}) {},
|
||||
(_) {},
|
||||
),
|
||||
);
|
||||
@ -286,6 +290,7 @@ void main() {
|
||||
() => fakeSocket,
|
||||
() => false,
|
||||
() {},
|
||||
(_, {bool triggerEvent = true}) {},
|
||||
(_) {},
|
||||
),
|
||||
);
|
||||
|
@ -63,7 +63,6 @@ XmppManagerAttributes mkAttributes(void Function(Stanza) callback) {
|
||||
password: 'password',
|
||||
useDirectTLS: true,
|
||||
),
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
|
@ -27,7 +27,6 @@ void main() {
|
||||
password: 'password',
|
||||
useDirectTLS: true,
|
||||
),
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('bob@xmpp.example/uwu'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
|
@ -55,7 +55,6 @@ void main() {
|
||||
),
|
||||
getManagerById: getManagerNullStub,
|
||||
getNegotiatorById: getUnsupportedCSINegotiator,
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
@ -99,7 +98,6 @@ void main() {
|
||||
),
|
||||
getManagerById: getManagerNullStub,
|
||||
getNegotiatorById: getSupportedCSINegotiator,
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
|
@ -35,7 +35,6 @@ Future<bool> testRosterManager(
|
||||
),
|
||||
getManagerById: getManagerNullStub,
|
||||
getNegotiatorById: getNegotiatorNullStub,
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('$bareJid/$resource'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
@ -151,6 +150,7 @@ void main() {
|
||||
waitUntilLogin: true,
|
||||
);
|
||||
expect(fakeSocket.getState(), /*6*/ 5);
|
||||
expect(conn.resource, 'MU29eEZn');
|
||||
});
|
||||
|
||||
test('Test a failed SASL auth', () async {
|
||||
@ -296,7 +296,6 @@ void main() {
|
||||
),
|
||||
getManagerById: getManagerNullStub,
|
||||
getNegotiatorById: getNegotiatorNullStub,
|
||||
isFeatureSupported: (_) => false,
|
||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||
getSocket: () => StubTCPSocket([]),
|
||||
getConnection: () => XmppConnection(
|
||||
|
Loading…
Reference in New Issue
Block a user