chore(xep): Move DiscoManager from String to JID

This commit is contained in:
PapaTutuWawa 2023-05-23 17:28:20 +02:00
parent c6552968d5
commit b1da6e5a53
16 changed files with 55 additions and 56 deletions

View File

@ -6,6 +6,9 @@
- The `DiscoManager` now only handled entity capabilities if a `EntityCapabilityManager` is registered. - The `DiscoManager` now only handled entity capabilities if a `EntityCapabilityManager` is registered.
- The `EntityCapabilityManager` now verifies and validates its data before caching. - The `EntityCapabilityManager` now verifies and validates its data before caching.
- **BREAKING**: Added the `resumed` parameter to `StreamNegotiationsDoneEvent`. Use this to check if the current stream is new or resumed instead of using the `ConnectionStateChangedEvent`. - **BREAKING**: Added the `resumed` parameter to `StreamNegotiationsDoneEvent`. Use this to check if the current stream is new or resumed instead of using the `ConnectionStateChangedEvent`.
- **BREAKING**: Remove `DiscoManager.discoInfoCapHashQuery`.
- **BREAKING**: The entity argument of `DiscoManager.discoInfoQuery` and `DiscoManager.discoItemsQuery` are now `JID` instead of `String`.
- **BREAKING**: `PubSubManager` and `UserAvatarManager` now use `JID` instead of `String`.
## 0.3.1 ## 0.3.1

View File

@ -63,6 +63,11 @@ class JID {
/// Converts the JID into one with a resource part of [resource]. /// Converts the JID into one with a resource part of [resource].
JID withResource(String resource) => JID(local, domain, resource); JID withResource(String resource) => JID(local, domain, resource);
/// Convert the JID into the JID of the domain. For example, converts alice@example.org/abc123 to example.org.
JID toDomain() {
return JID('', domain, '');
}
/// Compares the JID with [other]. This function assumes that JID and [other] /// Compares the JID with [other]. This function assumes that JID and [other]
/// are bare, i.e. only the domain- and localparts are compared. If [ensureBare] /// are bare, i.e. only the domain- and localparts are compared. If [ensureBare]
/// is optionally set to true, then [other] MUST be bare. Otherwise, false is returned. /// is optionally set to true, then [other] MUST be bare. Otherwise, false is returned.

View File

@ -45,7 +45,7 @@ abstract class XmppManagerBase {
); );
final result = await dm!.discoInfoQuery( final result = await dm!.discoInfoQuery(
_managerAttributes.getConnectionSettings().jid.domain, _managerAttributes.getConnectionSettings().jid.toDomain(),
shouldEncrypt: false, shouldEncrypt: false,
); );
if (result.isType<DiscoError>()) { if (result.isType<DiscoError>()) {

View File

@ -1,4 +1,5 @@
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:moxxmpp/src/jid.dart';
@internal @internal
@immutable @immutable
@ -6,8 +7,7 @@ class DiscoCacheKey {
const DiscoCacheKey(this.jid, this.node); const DiscoCacheKey(this.jid, this.node);
/// The JID we're requesting disco data from. /// The JID we're requesting disco data from.
// TODO(Unknown): Replace with JID final JID jid;
final String jid;
/// Optionally the node we are requesting from. /// Optionally the node we are requesting from.
final String? node; final String? node;

View File

@ -1,12 +1,13 @@
import 'package:moxxmpp/src/jid.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
// TODO(PapaTutuWawa): Move types into types.dart // TODO(PapaTutuWawa): Move types into types.dart
Stanza buildDiscoInfoQueryStanza(String entity, String? node) { Stanza buildDiscoInfoQueryStanza(JID entity, String? node) {
return Stanza.iq( return Stanza.iq(
to: entity, to: entity.toString(),
type: 'get', type: 'get',
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(
@ -18,9 +19,9 @@ Stanza buildDiscoInfoQueryStanza(String entity, String? node) {
); );
} }
Stanza buildDiscoItemsQueryStanza(String entity, {String? node}) { Stanza buildDiscoItemsQueryStanza(JID entity, {String? node}) {
return Stanza.iq( return Stanza.iq(
to: entity, to: entity.toString(),
type: 'get', type: 'get',
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(

View File

@ -108,13 +108,13 @@ class DiscoInfo {
@immutable @immutable
class DiscoItem { class DiscoItem {
const DiscoItem({required this.jid, this.node, this.name}); const DiscoItem({required this.jid, this.node, this.name});
final String jid; final JID jid;
final String? node; final String? node;
final String? name; final String? name;
XMLNode toXml() { XMLNode toXml() {
final attributes = { final attributes = {
'jid': jid, 'jid': jid.toString(),
}; };
if (node != null) { if (node != null) {
attributes['node'] = node!; attributes['node'] = node!;

View File

@ -253,7 +253,7 @@ class DiscoManager extends XmppManagerBase {
/// [shouldCache] indicates whether the successful result of the disco#info query /// [shouldCache] indicates whether the successful result of the disco#info query
/// should be cached (true) or not(false). /// should be cached (true) or not(false).
Future<Result<DiscoError, DiscoInfo>> discoInfoQuery( Future<Result<DiscoError, DiscoInfo>> discoInfoQuery(
String entity, { JID entity, {
String? node, String? node,
bool shouldEncrypt = true, bool shouldEncrypt = true,
bool shouldCache = true, bool shouldCache = true,
@ -272,7 +272,7 @@ class DiscoManager extends XmppManagerBase {
} else { } else {
// Check if we know entity capabilities // Check if we know entity capabilities
if (ecm != null && node == null) { if (ecm != null && node == null) {
info = await ecm.getCachedDiscoInfoFromJid(JID.fromString(entity)); info = await ecm.getCachedDiscoInfoFromJid(entity);
if (info != null) { if (info != null) {
return null; return null;
} }
@ -312,7 +312,7 @@ class DiscoManager extends XmppManagerBase {
final result = Result<DiscoError, DiscoInfo>( final result = Result<DiscoError, DiscoInfo>(
DiscoInfo.fromQuery( DiscoInfo.fromQuery(
query, query,
JID.fromString(entity), entity,
), ),
); );
await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache); await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
@ -321,7 +321,7 @@ class DiscoManager extends XmppManagerBase {
/// Sends a disco items query to the (full) jid [entity], optionally with node=[node]. /// Sends a disco items query to the (full) jid [entity], optionally with node=[node].
Future<Result<DiscoError, List<DiscoItem>>> discoItemsQuery( Future<Result<DiscoError, List<DiscoItem>>> discoItemsQuery(
String entity, { JID entity, {
String? node, String? node,
bool shouldEncrypt = true, bool shouldEncrypt = true,
}) async { }) async {
@ -357,7 +357,7 @@ class DiscoManager extends XmppManagerBase {
.findTags('item') .findTags('item')
.map( .map(
(node) => DiscoItem( (node) => DiscoItem(
jid: node.attributes['jid']! as String, jid: JID.fromString(node.attributes['jid']! as String),
node: node.attributes['node'] as String?, node: node.attributes['node'] as String?,
name: node.attributes['name'] as String?, name: node.attributes['name'] as String?,
), ),
@ -369,18 +369,9 @@ class DiscoManager extends XmppManagerBase {
return result; return result;
} }
/// Queries information about a jid based on its node and capability hash.
Future<Result<DiscoError, DiscoInfo>> discoInfoCapHashQuery(
String jid,
String node,
String ver,
) async {
return discoInfoQuery(jid, node: '$node#$ver');
}
Future<Result<DiscoError, List<DiscoInfo>>> performDiscoSweep() async { Future<Result<DiscoError, List<DiscoInfo>>> performDiscoSweep() async {
final attrs = getAttributes(); final attrs = getAttributes();
final serverJid = attrs.getConnectionSettings().jid.domain; final serverJid = attrs.getConnectionSettings().jid.toDomain();
final infoResults = List<DiscoInfo>.empty(growable: true); final infoResults = List<DiscoInfo>.empty(growable: true);
final result = await discoInfoQuery(serverJid); final result = await discoInfoQuery(serverJid);
if (result.isType<DiscoInfo>()) { if (result.isType<DiscoInfo>()) {
@ -423,7 +414,7 @@ class DiscoManager extends XmppManagerBase {
/// A wrapper function around discoInfoQuery: Returns true if the entity with JID /// A wrapper function around discoInfoQuery: Returns true if the entity with JID
/// [entity] supports the disco feature [feature]. If not, returns false. /// [entity] supports the disco feature [feature]. If not, returns false.
Future<bool> supportsFeature(JID entity, String feature) async { Future<bool> supportsFeature(JID entity, String feature) async {
final info = await discoInfoQuery(entity.toString()); final info = await discoInfoQuery(entity);
if (info.isType<DiscoError>()) return false; if (info.isType<DiscoError>()) return false;
return info.get<DiscoInfo>().features.contains(feature); return info.get<DiscoInfo>().features.contains(feature);

View File

@ -117,7 +117,7 @@ class PubSubManager extends XmppManagerBase {
return state.copyWith(done: true); return state.copyWith(done: true);
} }
Future<int> _getNodeItemCount(String jid, String node) async { Future<int> _getNodeItemCount(JID jid, String node) async {
final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!; final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!;
final response = await dm.discoItemsQuery(jid, node: node); final response = await dm.discoItemsQuery(jid, node: node);
var count = 0; var count = 0;
@ -136,7 +136,7 @@ class PubSubManager extends XmppManagerBase {
// with the requested configuration. // with the requested configuration.
@visibleForTesting @visibleForTesting
Future<PubSubPublishOptions> preprocessPublishOptions( Future<PubSubPublishOptions> preprocessPublishOptions(
String jid, JID jid,
String node, String node,
PubSubPublishOptions options, PubSubPublishOptions options,
) async { ) async {
@ -264,7 +264,7 @@ class PubSubManager extends XmppManagerBase {
/// Publish [payload] to the PubSub node [node] on JID [jid]. Returns true if it /// Publish [payload] to the PubSub node [node] on JID [jid]. Returns true if it
/// was successful. False otherwise. /// was successful. False otherwise.
Future<Result<PubSubError, bool>> publish( Future<Result<PubSubError, bool>> publish(
String jid, JID jid,
String node, String node,
XMLNode payload, { XMLNode payload, {
String? id, String? id,
@ -280,7 +280,7 @@ class PubSubManager extends XmppManagerBase {
} }
Future<Result<PubSubError, bool>> _publish( Future<Result<PubSubError, bool>> _publish(
String jid, JID jid,
String node, String node,
XMLNode payload, { XMLNode payload, {
String? id, String? id,
@ -296,7 +296,7 @@ class PubSubManager extends XmppManagerBase {
final result = await getAttributes().sendStanza( final result = await getAttributes().sendStanza(
Stanza.iq( Stanza.iq(
type: 'set', type: 'set',
to: jid, to: jid.toString(),
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(
tag: 'pubsub', tag: 'pubsub',
@ -481,7 +481,7 @@ class PubSubManager extends XmppManagerBase {
} }
Future<Result<PubSubError, bool>> configure( Future<Result<PubSubError, bool>> configure(
String jid, JID jid,
String node, String node,
PubSubPublishOptions options, PubSubPublishOptions options,
) async { ) async {
@ -491,7 +491,7 @@ class PubSubManager extends XmppManagerBase {
final form = await attrs.sendStanza( final form = await attrs.sendStanza(
Stanza.iq( Stanza.iq(
type: 'get', type: 'get',
to: jid, to: jid.toString(),
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(
tag: 'pubsub', tag: 'pubsub',
@ -515,7 +515,7 @@ class PubSubManager extends XmppManagerBase {
final submit = await attrs.sendStanza( final submit = await attrs.sendStanza(
Stanza.iq( Stanza.iq(
type: 'set', type: 'set',
to: jid, to: jid.toString(),
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(
tag: 'pubsub', tag: 'pubsub',

View File

@ -1,4 +1,5 @@
import 'package:moxxmpp/src/events.dart'; import 'package:moxxmpp/src/events.dart';
import 'package:moxxmpp/src/jid.dart';
import 'package:moxxmpp/src/managers/base.dart'; import 'package:moxxmpp/src/managers/base.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';
@ -106,7 +107,7 @@ class UserAvatarManager extends XmppManagerBase {
) async { ) async {
final pubsub = _getPubSubManager(); final pubsub = _getPubSubManager();
final result = await pubsub.publish( final result = await pubsub.publish(
getAttributes().getFullJID().toBare().toString(), getAttributes().getFullJID().toBare(),
userAvatarDataXmlns, userAvatarDataXmlns,
XMLNode.xmlns( XMLNode.xmlns(
tag: 'data', tag: 'data',
@ -133,7 +134,7 @@ class UserAvatarManager extends XmppManagerBase {
) async { ) async {
final pubsub = _getPubSubManager(); final pubsub = _getPubSubManager();
final result = await pubsub.publish( final result = await pubsub.publish(
getAttributes().getFullJID().toBare().toString(), getAttributes().getFullJID().toBare(),
userAvatarMetadataXmlns, userAvatarMetadataXmlns,
XMLNode.xmlns( XMLNode.xmlns(
tag: 'metadata', tag: 'metadata',
@ -178,7 +179,7 @@ class UserAvatarManager extends XmppManagerBase {
/// Returns the PubSub Id of an avatar after doing a disco#items query. /// Returns the PubSub Id of an avatar after doing a disco#items query.
/// Note that this assumes that there is only one (1) item published on /// Note that this assumes that there is only one (1) item published on
/// the node. /// the node.
Future<Result<AvatarError, String>> getAvatarId(String jid) async { Future<Result<AvatarError, String>> getAvatarId(JID jid) async {
final disco = getAttributes().getManagerById(discoManager)! as DiscoManager; final disco = getAttributes().getManagerById(discoManager)! as DiscoManager;
final response = await disco.discoItemsQuery( final response = await disco.discoItemsQuery(
jid, jid,

View File

@ -181,7 +181,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!; final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!;
final discoRequest = await dm.discoInfoQuery( final discoRequest = await dm.discoInfoQuery(
event.jid.toString(), event.jid,
node: capabilityNode, node: capabilityNode,
); );
if (discoRequest.isType<DiscoError>()) { if (discoRequest.isType<DiscoError>()) {
@ -194,7 +194,7 @@ class EntityCapabilitiesManager extends XmppManagerBase {
await dm.addCachedDiscoInfo( await dm.addCachedDiscoInfo(
MapEntry<DiscoCacheKey, DiscoInfo>( MapEntry<DiscoCacheKey, DiscoInfo>(
DiscoCacheKey( DiscoCacheKey(
event.jid.toString(), event.jid,
null, null,
), ),
discoInfo, discoInfo,

View File

@ -68,7 +68,7 @@ class StableIdManager extends XmppManagerBase {
logger.finest('Found stanza Id tag'); logger.finest('Found stanza Id tag');
final attrs = getAttributes(); final attrs = getAttributes();
final disco = attrs.getManagerById<DiscoManager>(discoManager)!; final disco = attrs.getManagerById<DiscoManager>(discoManager)!;
final result = await disco.discoInfoQuery(from.toString()); final result = await disco.discoInfoQuery(from);
if (result.isType<DiscoInfo>()) { if (result.isType<DiscoInfo>()) {
final info = result.get<DiscoInfo>(); final info = result.get<DiscoInfo>();
logger.finest('Got info for ${from.toString()}'); logger.finest('Got info for ${from.toString()}');

View File

@ -609,7 +609,7 @@ abstract class BaseOmemoManager extends XmppManagerBase {
); );
final deviceListPublish = await pm.publish( final deviceListPublish = await pm.publish(
bareJid.toString(), bareJid,
omemoDevicesXmlns, omemoDevicesXmlns,
newDeviceList, newDeviceList,
id: 'current', id: 'current',
@ -621,7 +621,7 @@ abstract class BaseOmemoManager extends XmppManagerBase {
} }
final deviceBundlePublish = await pm.publish( final deviceBundlePublish = await pm.publish(
bareJid.toString(), bareJid,
omemoBundlesXmlns, omemoBundlesXmlns,
bundleToXML(bundle), bundleToXML(bundle),
id: '${bundle.id}', id: '${bundle.id}',
@ -646,7 +646,7 @@ abstract class BaseOmemoManager extends XmppManagerBase {
/// On failure, returns an OmemoError. /// On failure, returns an OmemoError.
Future<Result<OmemoError, bool>> supportsOmemo(JID jid) async { Future<Result<OmemoError, bool>> supportsOmemo(JID jid) async {
final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!; final dm = getAttributes().getManagerById<DiscoManager>(discoManager)!;
final items = await dm.discoItemsQuery(jid.toBare().toString()); final items = await dm.discoItemsQuery(jid.toBare());
if (items.isType<DiscoError>()) return Result(UnknownOmemoError()); if (items.isType<DiscoError>()) return Result(UnknownOmemoError());
@ -686,7 +686,7 @@ abstract class BaseOmemoManager extends XmppManagerBase {
.toList(), .toList(),
); );
final publishResult = await pm.publish( final publishResult = await pm.publish(
jid.toString(), jid,
omemoDevicesXmlns, omemoDevicesXmlns,
newPayload, newPayload,
id: 'current', id: 'current',

View File

@ -267,7 +267,7 @@ class StickersManager extends XmppManagerBase {
final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!; final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!;
return pm.publish( return pm.publish(
jid.toBare().toString(), jid.toBare(),
stickersXmlns, stickersXmlns,
pack.toXML(), pack.toXML(),
id: pack.id, id: pack.id,

View File

@ -95,14 +95,12 @@ void main() {
await Future<void>.delayed(const Duration(seconds: 3)); await Future<void>.delayed(const Duration(seconds: 3));
final jid = JID.fromString('romeo@montague.lit/orchard'); final jid = JID.fromString('romeo@montague.lit/orchard');
final result1 = disco.discoInfoQuery(jid.toString()); final result1 = disco.discoInfoQuery(jid);
final result2 = disco.discoInfoQuery(jid.toString()); final result2 = disco.discoInfoQuery(jid);
await Future<void>.delayed(const Duration(seconds: 1)); await Future<void>.delayed(const Duration(seconds: 1));
expect( expect(
disco.infoTracker disco.infoTracker.getRunningTasks(DiscoCacheKey(jid, null)).length,
.getRunningTasks(DiscoCacheKey(jid.toString(), null))
.length,
1, 1,
); );
fakeSocket.injectRawXml( fakeSocket.injectRawXml(
@ -140,7 +138,7 @@ void main() {
); );
// Query Alice's device // Query Alice's device
final result = await dm.discoInfoQuery(aliceJid.toString()); final result = await dm.discoInfoQuery(aliceJid);
expect(result.isType<DiscoError>(), false); expect(result.isType<DiscoError>(), false);
expect(tm.sentStanzas, 0); expect(tm.sentStanzas, 0);
}); });

View File

@ -12,7 +12,7 @@ class StubbedDiscoManager extends DiscoManager {
@override @override
Future<Result<DiscoError, DiscoInfo>> discoInfoQuery( Future<Result<DiscoError, DiscoInfo>> discoInfoQuery(
String entity, { JID entity, {
String? node, String? node,
bool shouldEncrypt = true, bool shouldEncrypt = true,
bool shouldCache = true, bool shouldCache = true,
@ -32,7 +32,7 @@ class StubbedDiscoManager extends DiscoManager {
@override @override
Future<Result<DiscoError, List<DiscoItem>>> discoItemsQuery( Future<Result<DiscoError, List<DiscoItem>>> discoItemsQuery(
String entity, { JID entity, {
String? node, String? node,
bool shouldEncrypt = true, bool shouldEncrypt = true,
}) async { }) async {
@ -59,7 +59,7 @@ void main() {
await tm.register(manager); await tm.register(manager);
final result = await manager.preprocessPublishOptions( final result = await manager.preprocessPublishOptions(
'pubsub.server.example.org', JID.fromString('pubsub.server.example.org'),
'urn:xmpp:omemo:2:bundles', 'urn:xmpp:omemo:2:bundles',
const PubSubPublishOptions(maxItems: 'max'), const PubSubPublishOptions(maxItems: 'max'),
); );
@ -76,7 +76,7 @@ void main() {
await tm.register(manager); await tm.register(manager);
final result = await manager.preprocessPublishOptions( final result = await manager.preprocessPublishOptions(
'pubsub.server.example.org', JID.fromString('pubsub.server.example.org'),
'urn:xmpp:omemo:2:bundles', 'urn:xmpp:omemo:2:bundles',
const PubSubPublishOptions(maxItems: 'max'), const PubSubPublishOptions(maxItems: 'max'),
); );
@ -182,7 +182,7 @@ void main() {
final item = XMLNode(tag: 'test-item'); final item = XMLNode(tag: 'test-item');
final result = final result =
await connection.getManagerById<PubSubManager>(pubsubManager)!.publish( await connection.getManagerById<PubSubManager>(pubsubManager)!.publish(
'pubsub.server.example.org', JID.fromString('pubsub.server.example.org'),
'princely_musings', 'princely_musings',
item, item,
id: 'current', id: 'current',

View File

@ -27,7 +27,7 @@ class StubbedDiscoManager extends DiscoManager {
@override @override
Future<Result<DiscoError, DiscoInfo>> discoInfoQuery( Future<Result<DiscoError, DiscoInfo>> discoInfoQuery(
String entity, { JID entity, {
String? node, String? node,
bool shouldEncrypt = true, bool shouldEncrypt = true,
bool shouldCache = true, bool shouldCache = true,