kopia lustrzana https://gitlab.com/mysocialportal/relatica
Add FediverseServiceValidator
rodzic
80a55af4c4
commit
c5a64a8691
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
Ładowanie…
Reference in New Issue