@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

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

at upstream/main 195 lines 6.0 kB view raw
1<?php 2 3final class PhabricatorAuthManagementRevokeWorkflow 4 extends PhabricatorAuthManagementWorkflow { 5 6 protected function didConstruct() { 7 $this 8 ->setName('revoke') 9 ->setExamples( 10 "**revoke** --list\n". 11 "**revoke** --type __type__ --from __@user__\n". 12 "**revoke** --everything --everywhere") 13 ->setSynopsis( 14 pht( 15 'Revoke credentials which may have been leaked or disclosed.')) 16 ->setArguments( 17 array( 18 array( 19 'name' => 'from', 20 'param' => 'object', 21 'help' => pht( 22 'Revoke credentials for the specified object. To revoke '. 23 'credentials for a user, use "@username".'), 24 ), 25 array( 26 'name' => 'type', 27 'param' => 'type', 28 'help' => pht('Revoke credentials of the given type.'), 29 ), 30 array( 31 'name' => 'list', 32 'help' => pht( 33 'List information about available credential revokers.'), 34 ), 35 array( 36 'name' => 'everything', 37 'help' => pht('Revoke all credentials types.'), 38 ), 39 array( 40 'name' => 'everywhere', 41 'help' => pht('Revoke from all credential owners.'), 42 ), 43 array( 44 'name' => 'force', 45 'help' => pht('Revoke credentials without prompting.'), 46 ), 47 )); 48 } 49 50 public function execute(PhutilArgumentParser $args) { 51 $viewer = $this->getViewer(); 52 53 $all_types = PhabricatorAuthRevoker::getAllRevokers(); 54 $is_force = $args->getArg('force'); 55 56 // The "--list" flag is compatible with revoker selection flags like 57 // "--type" to filter the list, but not compatible with target selection 58 // flags like "--from". 59 $is_list = $args->getArg('list'); 60 61 $type = $args->getArg('type'); 62 $is_everything = $args->getArg('everything'); 63 if ($type === null && !$is_everything) { 64 if ($is_list) { 65 // By default, "bin/auth revoke --list" implies "--everything". 66 $types = $all_types; 67 } else { 68 throw new PhutilArgumentUsageException( 69 pht( 70 'Specify the credential type to revoke with "--type" or specify '. 71 '"--everything". Use "--list" to list available credential '. 72 'types.')); 73 } 74 } else if (phutil_nonempty_string($type) && $is_everything) { 75 throw new PhutilArgumentUsageException( 76 pht( 77 'Specify the credential type to revoke with "--type" or '. 78 '"--everything", but not both.')); 79 } else if ($is_everything) { 80 $types = $all_types; 81 } else { 82 if (empty($all_types[$type])) { 83 throw new PhutilArgumentUsageException( 84 pht( 85 'Credential type "%s" is not valid. Valid credential types '. 86 'are: %s.', 87 $type, 88 implode(', ', array_keys($all_types)))); 89 } 90 $types = array($all_types[$type]); 91 } 92 93 $is_everywhere = $args->getArg('everywhere'); 94 $from = $args->getArg('from'); 95 96 if ($is_list) { 97 if ($from !== null || $is_everywhere) { 98 throw new PhutilArgumentUsageException( 99 pht( 100 'You can not "--list" and revoke credentials (with "--from" or '. 101 '"--everywhere") in the same operation.')); 102 } 103 } 104 105 if ($is_list) { 106 $last_key = last_key($types); 107 foreach ($types as $key => $type) { 108 echo tsprintf( 109 "**%s** (%s)\n\n", 110 $type->getRevokerKey(), 111 $type->getRevokerName()); 112 113 id(new PhutilConsoleBlock()) 114 ->addParagraph(tsprintf('%B', $type->getRevokerDescription())) 115 ->draw(); 116 } 117 118 return 0; 119 } 120 121 $target = null; 122 if (!phutil_nonempty_string($from) && !$is_everywhere) { 123 throw new PhutilArgumentUsageException( 124 pht( 125 'Specify the target to revoke credentials from with "--from" or '. 126 'specify "--everywhere".')); 127 } else if (phutil_nonempty_string($from) && $is_everywhere) { 128 throw new PhutilArgumentUsageException( 129 pht( 130 'Specify the target to revoke credentials from with "--from" or '. 131 'specify "--everywhere", but not both.')); 132 } else if ($is_everywhere) { 133 // Just carry the flag through. 134 } else { 135 $target = id(new PhabricatorObjectQuery()) 136 ->setViewer($viewer) 137 ->withNames(array($from)) 138 ->executeOne(); 139 if (!$target) { 140 throw new PhutilArgumentUsageException( 141 pht( 142 'Target "%s" is not a valid target to revoke credentials from. '. 143 'Usually, revoke from "@username".', 144 $from)); 145 } 146 } 147 148 if ($is_everywhere && !$is_force) { 149 echo id(new PhutilConsoleBlock()) 150 ->addParagraph( 151 pht( 152 'You are destroying an entire class of credentials. This may be '. 153 'very disruptive to users. You should normally do this only if '. 154 'you suspect there has been a widespread compromise which may '. 155 'have impacted everyone.')) 156 ->drawConsoleString(); 157 158 $prompt = pht('Really destroy credentials everywhere?'); 159 if (!phutil_console_confirm($prompt)) { 160 throw new PhutilArgumentUsageException( 161 pht('Aborted workflow.')); 162 } 163 } 164 165 foreach ($types as $type) { 166 $type->setViewer($viewer); 167 if ($is_everywhere) { 168 $count = $type->revokeAllCredentials(); 169 } else { 170 $count = $type->revokeCredentialsFrom($target); 171 } 172 173 echo tsprintf( 174 "%s\n", 175 pht( 176 'Destroyed %s credential(s) of type "%s".', 177 new PhutilNumber($count), 178 $type->getRevokerKey())); 179 180 $guidance = $type->getRevokerNextSteps(); 181 if ($guidance !== null) { 182 echo tsprintf( 183 "%s\n", 184 $guidance); 185 } 186 } 187 188 echo tsprintf( 189 "%s\n", 190 pht('Done.')); 191 192 return 0; 193 } 194 195}