perlsky is a Perl 5 implementation of an AT Protocol Personal Data Server.
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

Align sync repo status semantics

alice 597788f2 e54b0a07

+129 -7
+12 -6
lib/ATProto/PDS/API/Sync.pm
··· 17 17 EVENT_TYPE_SYNC 18 18 ); 19 19 use ATProto::PDS::Identity qw(service_host); 20 - use ATProto::PDS::Moderation qw(assert_blob_readable assert_repo_readable); 20 + use ATProto::PDS::Moderation qw(assert_blob_readable assert_repo_readable is_repo_takedown); 21 21 use ATProto::PDS::Repo::CAR qw(write_car); 22 22 use ATProto::PDS::Repo::CID; 23 23 use ATProto::PDS::Repo::Bytes; ··· 55 55 }); 56 56 57 57 $registry->register('com.atproto.sync.getRepoStatus', sub ($c, $endpoint) { 58 - my $account = _readable_repo_by_did($c); 58 + my $account = _repo_by_did_or_error($c); 59 + my $active = (!defined($account->{deleted_at}) && !defined($account->{deactivated_at}) && !is_repo_takedown($c, $account->{did})) 60 + ? JSON::PP::true 61 + : JSON::PP::false; 62 + my $status = defined($account->{deleted_at}) ? 'deleted' 63 + : is_repo_takedown($c, $account->{did}) ? 'takendown' 64 + : defined($account->{deactivated_at}) ? 'deactivated' 65 + : undef; 59 66 return { 60 67 did => $account->{did}, 61 - active => defined($account->{deactivated_at}) ? JSON::PP::false : JSON::PP::true, 62 - (defined($account->{repo_rev}) ? (rev => $account->{repo_rev}) : ()), 63 - (defined($account->{deactivated_at}) ? (status => 'deactivated') : ()), 64 - (defined($account->{deleted_at}) ? (status => 'deleted') : ()), 68 + active => $active, 69 + ($active ? (defined($account->{repo_rev}) ? (rev => $account->{repo_rev}) : ()) : ()), 70 + (defined($status) ? (status => $status) : ()), 65 71 }; 66 72 }); 67 73
+100
script/differential-validate
··· 986 986 'record takedown sync proof semantics match the official reference PDS', 987 987 ); 988 988 989 + note('Comparing sync.getRepoStatus status semantics'); 990 + for my $name (sort keys %server) { 991 + my $active = get_form($server{$name}{origin}, 'com.atproto.sync.getRepoStatus', { 992 + did => $server{$name}{did}, 993 + }); 994 + check($active->is_success, "$name active getRepoStatus succeeds"); 995 + 996 + my $deactivate = post_json( 997 + $server{$name}{origin}, 998 + 'com.atproto.server.deactivateAccount', 999 + {}, 1000 + auth_header($server{$name}{access}), 1001 + ); 1002 + check($deactivate->is_success, "$name deactivateAccount succeeds for repo status comparison"); 1003 + 1004 + my $deactivated = get_form($server{$name}{origin}, 'com.atproto.sync.getRepoStatus', { 1005 + did => $server{$name}{did}, 1006 + }); 1007 + check($deactivated->is_success, "$name deactivated getRepoStatus succeeds"); 1008 + 1009 + my $deactivated_session = post_json($server{$name}{origin}, 'com.atproto.server.createSession', { 1010 + identifier => $server{$name}{renamed_handle} || $server{$name}{handle}, 1011 + password => 'hunter22', 1012 + }); 1013 + check($deactivated_session->is_success, "$name deactivated createSession succeeds for repo status comparison"); 1014 + 1015 + my $reactivate = post_json( 1016 + $server{$name}{origin}, 1017 + 'com.atproto.admin.updateSubjectStatus', 1018 + { 1019 + subject => { 1020 + '$type' => 'com.atproto.admin.defs#repoRef', 1021 + did => $server{$name}{did}, 1022 + }, 1023 + deactivated => { applied => false }, 1024 + }, 1025 + admin_auth_header($server{$name}{admin_password}), 1026 + ); 1027 + check($reactivate->is_success, "$name repo reactivation succeeds for repo status comparison"); 1028 + 1029 + my $takedown = post_json( 1030 + $server{$name}{origin}, 1031 + 'com.atproto.admin.updateSubjectStatus', 1032 + { 1033 + subject => { 1034 + '$type' => 'com.atproto.admin.defs#repoRef', 1035 + did => $server{$name}{did}, 1036 + }, 1037 + takedown => { applied => true }, 1038 + }, 1039 + admin_auth_header($server{$name}{admin_password}), 1040 + ); 1041 + check($takedown->is_success, "$name repo takedown succeeds for repo status comparison"); 1042 + 1043 + my $takendown = get_form($server{$name}{origin}, 'com.atproto.sync.getRepoStatus', { 1044 + did => $server{$name}{did}, 1045 + }); 1046 + check($takendown->is_success, "$name takendown getRepoStatus succeeds"); 1047 + 1048 + my $restore = post_json( 1049 + $server{$name}{origin}, 1050 + 'com.atproto.admin.updateSubjectStatus', 1051 + { 1052 + subject => { 1053 + '$type' => 'com.atproto.admin.defs#repoRef', 1054 + did => $server{$name}{did}, 1055 + }, 1056 + takedown => { applied => false }, 1057 + }, 1058 + admin_auth_header($server{$name}{admin_password}), 1059 + ); 1060 + check($restore->is_success, "$name repo takedown restore succeeds for repo status comparison"); 1061 + 1062 + $server{$name}{repo_status_surface} = { 1063 + active => { 1064 + ok => $active->is_success ? 1 : 0, 1065 + active => ($active->json || {})->{active} ? 1 : 0, 1066 + status => ($active->json || {})->{status}, 1067 + has_rev => defined(($active->json || {})->{rev}) ? 1 : 0, 1068 + }, 1069 + deactivated => { 1070 + ok => $deactivated->is_success ? 1 : 0, 1071 + active => ($deactivated->json || {})->{active} ? 1 : 0, 1072 + status => ($deactivated->json || {})->{status}, 1073 + has_rev => defined(($deactivated->json || {})->{rev}) ? 1 : 0, 1074 + }, 1075 + takendown => { 1076 + ok => $takendown->is_success ? 1 : 0, 1077 + active => ($takendown->json || {})->{active} ? 1 : 0, 1078 + status => ($takendown->json || {})->{status}, 1079 + has_rev => defined(($takendown->json || {})->{rev}) ? 1 : 0, 1080 + }, 1081 + }; 1082 + } 1083 + 1084 + check( 1085 + same_hash($server{reference}{repo_status_surface}, $server{perlsky}{repo_status_surface}), 1086 + 'sync.getRepoStatus active, deactivated, and takendown semantics match the official reference PDS', 1087 + ); 1088 + 989 1089 note('Comparing describeRepo'); 990 1090 for my $name (sort keys %server) { 991 1091 my $res = get_form($server{$name}{origin}, 'com.atproto.repo.describeRepo', {
+7
t/moderation.t
··· 105 105 takedown => { applied => JSON::PP::true }, 106 106 })->status_is(200); 107 107 108 + $t->get_ok("/xrpc/com.atproto.sync.getRepoStatus?did=$did") 109 + ->status_is(200) 110 + ->json_is('/did' => $did) 111 + ->json_is('/active' => JSON::PP::false) 112 + ->json_is('/status' => 'takendown') 113 + ->json_hasnt('/rev'); 114 + 108 115 $t->post_ok('/xrpc/com.atproto.server.createSession' => json => { 109 116 identifier => 'alice.example.test', 110 117 password => 'hunter22',
+3 -1
t/repo-api.t
··· 338 338 $t->get_ok("/xrpc/com.atproto.sync.getRepoStatus?did=$did") 339 339 ->status_is(200) 340 340 ->json_is('/did' => $did) 341 - ->json_has('/active'); 341 + ->json_is('/active' => JSON::PP::true) 342 + ->json_has('/rev') 343 + ->json_hasnt('/status'); 342 344 343 345 $t->get_ok('/xrpc/com.atproto.sync.listRepos') 344 346 ->status_is(200)
+7
t/server-auth.t
··· 324 324 Authorization => "Bearer $replacement_access", 325 325 } => json => {})->status_is(200); 326 326 327 + $t->get_ok("/xrpc/com.atproto.sync.getRepoStatus?did=$did") 328 + ->status_is(200) 329 + ->json_is('/did' => $did) 330 + ->json_is('/active' => JSON::PP::false) 331 + ->json_is('/status' => 'deactivated') 332 + ->json_hasnt('/rev'); 333 + 327 334 $t->post_ok('/xrpc/com.atproto.server.createSession' => json => { 328 335 identifier => 'alice.localhost', 329 336 password => 'password123',