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 `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**: 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
|
- **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
|
## 0.1.6+1
|
||||||
|
|
||||||
|
@ -133,9 +133,6 @@ class XmppConnection {
|
|||||||
StreamController.broadcast();
|
StreamController.broadcast();
|
||||||
final Map<String, XmppManagerBase> _xmppManagers = {};
|
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
|
/// The buffer object to keep split up stanzas together
|
||||||
final XmlStreamBuffer _streamBuffer = XmlStreamBuffer();
|
final XmlStreamBuffer _streamBuffer = XmlStreamBuffer();
|
||||||
|
|
||||||
@ -150,6 +147,7 @@ class XmppConnection {
|
|||||||
|
|
||||||
/// The currently bound resource or '' if none has been bound yet.
|
/// The currently bound resource or '' if none has been bound yet.
|
||||||
String _resource = '';
|
String _resource = '';
|
||||||
|
String get resource => _resource;
|
||||||
|
|
||||||
/// True if we are authenticated. False if not.
|
/// True if we are authenticated. False if not.
|
||||||
bool _isAuthenticated = false;
|
bool _isAuthenticated = false;
|
||||||
@ -201,8 +199,6 @@ class XmppConnection {
|
|||||||
|
|
||||||
ReconnectionPolicy get reconnectionPolicy => _reconnectionPolicy;
|
ReconnectionPolicy get reconnectionPolicy => _reconnectionPolicy;
|
||||||
|
|
||||||
List<String> get serverFeatures => _serverFeatures;
|
|
||||||
|
|
||||||
bool get isAuthenticated => _isAuthenticated;
|
bool get isAuthenticated => _isAuthenticated;
|
||||||
|
|
||||||
/// Return the registered feature negotiator that has id [id]. Returns null if
|
/// Return the registered feature negotiator that has id [id]. Returns null if
|
||||||
@ -221,7 +217,6 @@ class XmppConnection {
|
|||||||
sendEvent: _sendEvent,
|
sendEvent: _sendEvent,
|
||||||
getConnectionSettings: () => _connectionSettings,
|
getConnectionSettings: () => _connectionSettings,
|
||||||
getManagerById: getManagerById,
|
getManagerById: getManagerById,
|
||||||
isFeatureSupported: _serverFeatures.contains,
|
|
||||||
getFullJID: () => _connectionSettings.jid.withResource(_resource),
|
getFullJID: () => _connectionSettings.jid.withResource(_resource),
|
||||||
getSocket: () => _socket,
|
getSocket: () => _socket,
|
||||||
getConnection: () => this,
|
getConnection: () => this,
|
||||||
@ -283,6 +278,7 @@ class XmppConnection {
|
|||||||
() => _socket,
|
() => _socket,
|
||||||
() => _isAuthenticated,
|
() => _isAuthenticated,
|
||||||
_setAuthenticated,
|
_setAuthenticated,
|
||||||
|
_setResource,
|
||||||
_removeNegotiatingFeature,
|
_removeNegotiatingFeature,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -678,9 +674,13 @@ class XmppConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the resource of the connection
|
/// Sets the resource of the connection
|
||||||
void setResource(String resource) {
|
void _setResource(String resource, {bool triggerEvent = true}) {
|
||||||
_log.finest('Updating _resource to $resource');
|
_log.finest('Updating _resource to $resource');
|
||||||
_resource = resource;
|
_resource = resource;
|
||||||
|
|
||||||
|
if (triggerEvent) {
|
||||||
|
_sendEvent(ResourceBoundEvent(resource));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the connection's events as a stream.
|
/// Returns the connection's events as a stream.
|
||||||
@ -1028,17 +1028,6 @@ class XmppConnection {
|
|||||||
Future<void> _sendEvent(XmppEvent event) async {
|
Future<void> _sendEvent(XmppEvent event) async {
|
||||||
_log.finest('Event: ${event.toString()}');
|
_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) {
|
for (final manager in _xmppManagers.values) {
|
||||||
await manager.onXmppEvent(event);
|
await manager.onXmppEvent(event);
|
||||||
}
|
}
|
||||||
@ -1151,7 +1140,7 @@ class XmppConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastResource != null) {
|
if (lastResource != null) {
|
||||||
setResource(lastResource);
|
_setResource(lastResource, triggerEvent: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_enableReconnectOnSuccess = enableReconnectOnSuccess;
|
_enableReconnectOnSuccess = enableReconnectOnSuccess;
|
||||||
|
@ -160,8 +160,10 @@ class StreamManagementEnabledEvent extends XmppEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Triggered when we bound a resource
|
/// Triggered when we bound a resource
|
||||||
class ResourceBindingSuccessEvent extends XmppEvent {
|
class ResourceBoundEvent extends XmppEvent {
|
||||||
ResourceBindingSuccessEvent({required this.resource});
|
ResourceBoundEvent(this.resource);
|
||||||
|
|
||||||
|
/// The resource that was just bound.
|
||||||
final String resource;
|
final String resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ class XmppManagerAttributes {
|
|||||||
required this.getManagerById,
|
required this.getManagerById,
|
||||||
required this.sendEvent,
|
required this.sendEvent,
|
||||||
required this.getConnectionSettings,
|
required this.getConnectionSettings,
|
||||||
required this.isFeatureSupported,
|
|
||||||
required this.getFullJID,
|
required this.getFullJID,
|
||||||
required this.getSocket,
|
required this.getSocket,
|
||||||
required this.getConnection,
|
required this.getConnection,
|
||||||
@ -45,9 +44,6 @@ class XmppManagerAttributes {
|
|||||||
/// (Maybe) Get a Manager attached to the connection by its Id.
|
/// (Maybe) Get a Manager attached to the connection by its Id.
|
||||||
final T? Function<T extends XmppManagerBase>(String) getManagerById;
|
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
|
/// Returns the full JID of the current account
|
||||||
final JID Function() getFullJID;
|
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/handlers.dart';
|
||||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||||
import 'package:moxxmpp/src/stringxml.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/types.dart';
|
||||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
||||||
import 'package:moxxmpp/src/xeps/xep_0198/xep_0198.dart';
|
import 'package:moxxmpp/src/xeps/xep_0198/xep_0198.dart';
|
||||||
@ -31,6 +32,29 @@ abstract class XmppManagerBase {
|
|||||||
return _managerAttributes;
|
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
|
/// 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
|
/// send. These are run before the stanza is sent. The higher the value of the
|
||||||
/// handler's priority, the earlier it is run.
|
/// handler's priority, the earlier it is run.
|
||||||
|
@ -36,6 +36,7 @@ class NegotiatorAttributes {
|
|||||||
this.getSocket,
|
this.getSocket,
|
||||||
this.isAuthenticated,
|
this.isAuthenticated,
|
||||||
this.setAuthenticated,
|
this.setAuthenticated,
|
||||||
|
this.setResource,
|
||||||
this.removeNegotiatingFeature,
|
this.removeNegotiatingFeature,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -64,6 +65,10 @@ class NegotiatorAttributes {
|
|||||||
/// Returns true if the stream is authenticated. Returns false if not.
|
/// Returns true if the stream is authenticated. Returns false if not.
|
||||||
final bool Function() isAuthenticated;
|
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.
|
/// Sets the authentication state of the connection to true.
|
||||||
final void Function() setAuthenticated;
|
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/managers/namespaces.dart';
|
||||||
import 'package:moxxmpp/src/namespaces.dart';
|
import 'package:moxxmpp/src/namespaces.dart';
|
||||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||||
@ -65,11 +65,9 @@ class ResourceBindingNegotiator extends XmppFeatureNegotiatorBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final bind = nonza.firstTag('bind')!;
|
final bind = nonza.firstTag('bind')!;
|
||||||
final jid = bind.firstTag('jid')!;
|
final rawJid = bind.firstTag('jid')!.innerText();
|
||||||
final resource = jid.innerText().split('/')[1];
|
final resource = JID.fromString(rawJid).resource;
|
||||||
|
attributes.setResource(resource);
|
||||||
await attributes
|
|
||||||
.sendEvent(ResourceBindingSuccessEvent(resource: resource));
|
|
||||||
return const Result(NegotiatorState.done);
|
return const Result(NegotiatorState.done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ class TestingManagerHolder {
|
|||||||
sendNonza: (_) {},
|
sendNonza: (_) {},
|
||||||
sendEvent: (_) {},
|
sendEvent: (_) {},
|
||||||
getSocket: () => _socket,
|
getSocket: () => _socket,
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getNegotiatorById: getNegotiatorNullStub,
|
getNegotiatorById: getNegotiatorNullStub,
|
||||||
getFullJID: () => jid,
|
getFullJID: () => jid,
|
||||||
getManagerById: _getManagerById,
|
getManagerById: _getManagerById,
|
||||||
|
@ -58,6 +58,7 @@ void main() {
|
|||||||
() => fakeSocket,
|
() => fakeSocket,
|
||||||
() => false,
|
() => false,
|
||||||
() {},
|
() {},
|
||||||
|
(_, {bool triggerEvent = true}) {},
|
||||||
(_) {},
|
(_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -153,6 +154,7 @@ void main() {
|
|||||||
() => fakeSocket,
|
() => fakeSocket,
|
||||||
() => false,
|
() => false,
|
||||||
() {},
|
() {},
|
||||||
|
(_, {bool triggerEvent = true}) {},
|
||||||
(_) {},
|
(_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -203,6 +205,7 @@ void main() {
|
|||||||
() => fakeSocket,
|
() => fakeSocket,
|
||||||
() => false,
|
() => false,
|
||||||
() {},
|
() {},
|
||||||
|
(_, {bool triggerEvent = true}) {},
|
||||||
(_) {},
|
(_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -243,6 +246,7 @@ void main() {
|
|||||||
() => fakeSocket,
|
() => fakeSocket,
|
||||||
() => false,
|
() => false,
|
||||||
() {},
|
() {},
|
||||||
|
(_, {bool triggerEvent = true}) {},
|
||||||
(_) {},
|
(_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -286,6 +290,7 @@ void main() {
|
|||||||
() => fakeSocket,
|
() => fakeSocket,
|
||||||
() => false,
|
() => false,
|
||||||
() {},
|
() {},
|
||||||
|
(_, {bool triggerEvent = true}) {},
|
||||||
(_) {},
|
(_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -63,7 +63,6 @@ XmppManagerAttributes mkAttributes(void Function(Stanza) callback) {
|
|||||||
password: 'password',
|
password: 'password',
|
||||||
useDirectTLS: true,
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
|
@ -27,7 +27,6 @@ void main() {
|
|||||||
password: 'password',
|
password: 'password',
|
||||||
useDirectTLS: true,
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('bob@xmpp.example/uwu'),
|
getFullJID: () => JID.fromString('bob@xmpp.example/uwu'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
|
@ -55,7 +55,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getUnsupportedCSINegotiator,
|
getNegotiatorById: getUnsupportedCSINegotiator,
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
@ -99,7 +98,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getSupportedCSINegotiator,
|
getNegotiatorById: getSupportedCSINegotiator,
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
|
@ -35,7 +35,6 @@ Future<bool> testRosterManager(
|
|||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getNegotiatorNullStub,
|
getNegotiatorById: getNegotiatorNullStub,
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('$bareJid/$resource'),
|
getFullJID: () => JID.fromString('$bareJid/$resource'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
@ -151,6 +150,7 @@ void main() {
|
|||||||
waitUntilLogin: true,
|
waitUntilLogin: true,
|
||||||
);
|
);
|
||||||
expect(fakeSocket.getState(), /*6*/ 5);
|
expect(fakeSocket.getState(), /*6*/ 5);
|
||||||
|
expect(conn.resource, 'MU29eEZn');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test a failed SASL auth', () async {
|
test('Test a failed SASL auth', () async {
|
||||||
@ -296,7 +296,6 @@ void main() {
|
|||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getNegotiatorNullStub,
|
getNegotiatorById: getNegotiatorNullStub,
|
||||||
isFeatureSupported: (_) => false,
|
|
||||||
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
getFullJID: () => JID.fromString('some.user@example.server/aaaaa'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
getConnection: () => XmppConnection(
|
getConnection: () => XmppConnection(
|
||||||
|
Loading…
Reference in New Issue
Block a user