@@ -145,6 +145,29 @@ def logout(origin: Origin):
145145 print (f"Not logged in to { origin } ." , file = stderr )
146146
147147
148+ def logout_all ():
149+ """
150+ Remove **all** locally-saved credentials.
151+
152+ Equivalent to calling :func:`logout` on all origins found in the secrets
153+ file.
154+ """
155+ with config .write_lock ():
156+ secrets = config .load (config .SECRETS )
157+
158+ sections = [
159+ (section , _parse_section (section ))
160+ for section in secrets
161+ if _parse_section (section ) ]
162+
163+ for section , origin in sections :
164+ del secrets [section ]
165+ print (f"Credentials for { origin } removed from { config .SECRETS } ." , file = stderr )
166+ print (f"Logged out of { origin } ." , file = stderr )
167+
168+ config .save (secrets , config .SECRETS )
169+
170+
148171def current_user (origin : Origin ) -> Optional [User ]:
149172 """
150173 Information about the currently logged in user for *origin*, if any.
@@ -237,3 +260,12 @@ def _config_section(origin: Origin) -> str:
237260 if origin == "https://nextstrain.org" :
238261 return CONFIG_SECTION
239262 return f"{ CONFIG_SECTION } { origin } "
263+
264+
265+ def _parse_section (section : str ) -> Optional [Origin ]:
266+ if section == CONFIG_SECTION :
267+ return Origin ("https://nextstrain.org" )
268+ elif section .startswith (CONFIG_SECTION + " " ):
269+ return Origin (section .split (" " , 1 )[1 ])
270+ else :
271+ return None
0 commit comments