Add FediverseServiceValidator

codemagic-setup
Hank Grabowski 2023-03-21 21:15:14 -04:00
rodzic 80a55af4c4
commit c5a64a8691
2 zmienionych plików z 142 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,86 @@
import 'dart:convert';
import 'package:result_monad/result_monad.dart';
import '../models/exec_error.dart';
import '../models/server_data.dart';
import '../utils/network_utils.dart';
class FediverseServiceValidator {
final knownServers = <String, ServerData>{};
FutureResult<bool, ExecError> checkIfFediverseLink(String url) async {
final uri = Uri.tryParse(url);
if (uri == null) {
return buildErrorResult(
type: ErrorType.parsingError,
message: 'Invalid URL: $url',
);
}
final domain = uri.host;
ServerData? data = knownServers[domain];
if (data != null) {
return Result.ok(data.isFediverse);
}
final updateResult = await refreshServerData(domain);
return updateResult.andThenSuccess((sd) {
knownServers[sd.domainName] = sd;
return sd.isFediverse;
}).execErrorCast();
}
static FutureResult<ServerData, ExecError> refreshServerData(
String domainName) async {
final uri = Uri.https(
domainName,
'/.well-known/nodeinfo',
);
final result = await getUrl(uri)
.andThenSuccessAsync((page) async {
return jsonDecode(page.data);
})
.andThenAsync(
(json) async => json is Map<String, dynamic>
? Result.ok(json)
: Result.error('Unknown response type for well-know/nodeinfo'),
)
.andThenSuccessAsync((json) async => json['links'] ?? [])
.andThenAsync(
(nodeInfos) async => nodeInfos.isNotEmpty
? Result.ok(nodeInfos.last)
: Result.error('Unknown response type for well-know/nodeinfo'),
)
.andThenAsync((nodeInfo) async {
final rel = nodeInfo['rel']?.toString() ?? '';
if (!rel.startsWith('http://nodeinfo.diaspora.software/ns/schema/')) {
return Result.error('Unknown response type for well-know/nodeinfo');
}
final nodeInfoUrl = Uri.tryParse(nodeInfo['href'] ?? '');
if (nodeInfoUrl == null) {
return Result.error('Unknown response type for well-know/nodeinfo');
}
return await getUrl(nodeInfoUrl);
})
.andThenSuccessAsync(
(nodeInfoData) async => jsonDecode(nodeInfoData.data))
.andThenSuccessAsync((nodeInfoJson) async {
final softwareName =
nodeInfoJson['software']?['name']?.toString() ?? '';
final softwareVersion =
nodeInfoJson['software']?['version']?.toString() ?? '';
final isFediverse =
softwareName.isNotEmpty && softwareVersion.isNotEmpty;
return ServerData(
domainName: domainName,
isFediverse: isFediverse,
softwareName: softwareName,
softwareVersion: softwareVersion,
);
});
return result.execErrorCast();
}
}

Wyświetl plik

@ -0,0 +1,56 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:relatica/services/fediverse_server_validator.dart';
void main() {
test('Test against Diaspora Server', () async {
await testDomain('diasp.org', 'diaspora');
});
test('Test against Friendica Server', () async {
await testDomain('friendica.myportal.social', 'friendica');
});
test('Test against Mastodon Server', () async {
await testDomain('mastodon.social', 'mastodon');
});
test('Test against GNUSocial Server', () async {
await testDomain('gnusocial.net', 'gnusocial');
});
test('Test against MissKey Server', () async {
await testDomain('misskey.io', 'misskey');
});
test('Test against HubZilla Server', () async {
await testDomain('hub.hubzilla.de', 'redmatrix');
});
test('Test against PeerTube Server', () async {
await testDomain('tilvids.com', 'peertube');
});
test('Test against PixelFed Server', () async {
await testDomain('pixels.gsi.li', 'pixelfed');
});
test('Test against Funkwhale Server', () async {
await testDomain('open.audio', 'funkwhale');
});
test('Test against Akkoma Server', () async {
await testDomain('social.kernel.org', 'akkoma');
});
test('Test against Pleroma Server', () async {
await testDomain('stereophonic.space', 'pleroma');
});
}
Future<void> testDomain(String domain, String softwareName) async {
final result = await FediverseServiceValidator.refreshServerData(domain);
expect(result.isSuccess, equals(true));
expect(result.value.isFediverse, equals(true));
expect(result.value.domainName, equals(domain));
expect(result.value.softwareName, equals(softwareName));
}