diff --git a/modules/TheFreeNetwork/README.md b/modules/TheFreeNetwork/README.md new file mode 100644 index 0000000000..4e64af7cf6 --- /dev/null +++ b/modules/TheFreeNetwork/README.md @@ -0,0 +1,31 @@ +TheFreeNetwork allows GNU social to handle more than one Federation protocol simultaneously. + +Making this possible essentially consists in not allowing duplication of remote profiles in the profile table, +and to ensure that each profile is handled by one and only one federation protocol at a time. + +Each newly added federation protocol **must** support all the already supported functionalities by the other federation +protocols, otherwise this module will be moving between FullFeaturedFederationProtocolProfile and LackyFederationProtocolProfile all the time. + +You **must** feed this Module with the list of preferences for each federation protocol, more on that in the following section. + +Settings +======== +You can change these settings in `config.php` with `$config['TheFreeNetworkModule'][{setting name}] = {new setting value};`. + +Default values in parenthesis. + +protocols (`['ActivityPub' => 'Activitypub_profile', 'OStatus' => 'Ostatus_profile']`): + +This array follows the following structure: + +`['{PluginName}' => '{Actor_representation_class_name}'`, the latter is the class used to represent the remote profile in +the context of the federation plugin. + +N.B.: Higher Priority/Preference is given to the first entry. I.e., the default value gives preference to ActivityPub over OStatus. + +Scripts +======= + +`./fix_duplicates.php` : Run this script if you have duplicated profiles due to federation issues. +For example, if both ActivityPub and OStatus created different profile entries for the same remote actor. That's something +that shouldn't thank to this module, but if something goes very wrong, there's this script. diff --git a/modules/TheFreeNetwork/scripts/fix_duplicates.php b/modules/TheFreeNetwork/scripts/fix_duplicates.php index 6a9df2ed0c..b9bdf166a1 100644 --- a/modules/TheFreeNetwork/scripts/fix_duplicates.php +++ b/modules/TheFreeNetwork/scripts/fix_duplicates.php @@ -41,11 +41,15 @@ require_once INSTALLDIR . '/scripts/commandline.inc'; /** * Remote profiles are inspected from the most to the least * relevant according to the protocols they belong. - * Doing so while maintaing a global 'seen' array makes it + * Invariants: + * - `seen_local` array: The most recent profile inside of a certain protocol + * - global `seen` array: The most relevant profile (if there were duplicates, the first protocol of the list is the one to have its profile maintained) + * We do so while maintaining a global 'seen' array makes it * easy to satisfy a policy of maintaining only the duplicated * profiles that are either the most relevant or the newest * ones intra-protocol wise. */ + function run(): void { $protocols = common_config('TheFreeNetworkModule', 'protocols'); @@ -73,38 +77,38 @@ function fix_duplicates(string $profile_class, array &$seen): void $id = $db->profile_id; $uri = $db->uri; - // have we seen this profile before? + // Have we seen this profile before? if (array_key_exists($uri, $seen)) { - // yes, mantain previous + // Was it on a previous protocol? Keep the highest preference protocol's one if ($seen[$uri] !== $id) { - printfv("Deleting Profile with id = {$id}"); + printfv("Deleting Profile with id = {$id}\n"); $profile = Profile::getKV('id', $id); - $profile->delete(); // will propagate to federation profile classes + $profile->delete(); } else { - printfv("Deleting {$profile_class} with id = {$id}"); + printfv("Deleting {$profile_class} with id = {$id}\n"); $profile = $profile_class::getKV('profile_id', $id); $profile->delete(); } } elseif (array_key_exists($uri, $seen_local)) { - // yes, mantain current + // Was it in this protocol? Delete the older record. if ($seen_local[$uri] !== $id) { - printfv("Deleting Profile with id = {$id}"); + printfv("Deleting Profile with id = {$seen_local[$uri]}\n"); $profile = Profile::getKV('id', $seen_local[$uri]); - $profile->delete(); // will propagate to federation profile classes + $profile->delete(); } else { - printfv("Deleting {$profile_class} with id = {$seen_local[$uri]}"); + printfv("Deleting {$profile_class} with id = {$seen_local[$uri]}\n"); $profile = $profile_class::getKV('profile_id', $seen_local[$uri]); $profile->delete(); } - + // Update the profile id for this URI. $seen_local[$uri] = $id; } else { - // no, save it + // It's the first time we see this profile _inside_ this protocol! $seen_local[$uri] = $id; } } - // save valid local profiles + // Merge the findings inside this protocol with the global seen to be used on the next protocol of the list. $seen = array_merge($seen, $seen_local); }