Skip to content

Commit d1bf0be

Browse files
committed
add argument --overwrite-existing-token to preserve additional fields in token file
1 parent 15206ad commit d1bf0be

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,9 @@ in `/etc/sasl-xoauth2.conf`. Set them when setting the initial access token:
585585
}
586586
```
587587

588+
`sasl-xoauth2-tool` has an argument `--overwrite-existing-token` to preserve the content of these additional fields
589+
when manually updating an expired or invalidated token.
590+
588591
## Debugging
589592

590593
### Increasing Verbosity

scripts/sasl-xoauth2-tool.in

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ def url_safe_escape(instring:str) -> str:
3939
return urllib.parse.quote(instring, safe='~-._')
4040

4141

42+
def dump_overwrite(token:dict, output_file:IO[str], input_dict:dict):
43+
# overwrite fields in previous token (represented by input_dict)
44+
# that also have values from new token
45+
input_dict.update(token)
46+
json.dump(input_dict, output_file, indent=4)
47+
48+
4249
def gmail_redirect_uri(local_port:int) -> str:
4350
return 'http://127.0.0.1:%d%s' % (local_port, GOOGLE_OAUTH2_RESULT_PATH)
4451

@@ -63,7 +70,7 @@ def gmail_get_token_from_code(client_id:str, client_secret:str, authorization_co
6370
return json.loads(response)
6471

6572

66-
def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[str]) -> type:
73+
def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[str], input_dict:dict) -> type:
6774
class GMailRequestHandler(http.server.BaseHTTPRequestHandler):
6875
def log_request(self, code:Union[int,str]='-', size:Union[int,str]='-') -> None:
6976
# Silence request logging.
@@ -90,7 +97,7 @@ def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[st
9097
code,
9198
self.server.server_address[1],
9299
)
93-
json.dump(token, output_file)
100+
dump_overwrite(token, output_file, input_dict)
94101
output_file.close()
95102
sys.exit(0)
96103

@@ -104,15 +111,16 @@ def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[st
104111
if len(qs['code']) != 1:
105112
return None
106113
return qs['code'][0]
107-
114+
108115
return GMailRequestHandler
109116

110117

111-
def get_token_gmail(client_id:str, client_secret:str, scope:str, output_file:IO[str]) -> None:
118+
def get_token_gmail(client_id:str, client_secret:str, scope:str, output_file:IO[str], input_dict:dict) -> None:
112119
request_handler_class = gmail_get_RequestHandler(
113120
client_id,
114121
client_secret,
115122
output_file,
123+
input_dict,
116124
)
117125
server = http.server.HTTPServer(('', 0), request_handler_class)
118126
_, port = server.server_address
@@ -199,13 +207,13 @@ def outlook_get_initial_tokens_by_device_flow(client_id:str, tenant:str) -> Dict
199207
}
200208

201209

202-
def get_token_outlook(client_id:str, client_secret:str, tenant:str, use_device_flow:bool, output_file:IO[str]) -> None:
210+
def get_token_outlook(client_id:str, client_secret:str, tenant:str, use_device_flow:bool, output_file:IO[str], input_dict:dict) -> None:
203211
if use_device_flow:
204212
tokens = outlook_get_initial_tokens_by_device_flow(client_id, tenant)
205213
else:
206214
code = outlook_get_authorization_code(client_id, tenant)
207215
tokens = outlook_get_initial_tokens(client_id, client_secret, tenant, code)
208-
json.dump(tokens, output_file, indent=4)
216+
dump_overwrite(tokens, output_file, input_dict)
209217

210218
##########
211219

@@ -219,6 +227,14 @@ def argparse_get_parser() -> argparse.ArgumentParser:
219227

220228

221229
def subcommand_get_token(args:argparse.Namespace) -> None:
230+
input_dict = {}
231+
if args.overwrite_existing_token:
232+
if not os.path.isfile(args.output_file):
233+
raise Exception("Cannot overwrite nonexistent token file {}".format(args.output_file))
234+
else:
235+
with open(args.output_file,'r') as input_file:
236+
input_dict = json.load(input_file)
237+
args.output_file = open(args.output_file,'w')
222238
if args.service == 'outlook':
223239
if not args.tenant:
224240
parser.error("'outlook' service requires 'tenant' argument.")
@@ -230,6 +246,7 @@ def subcommand_get_token(args:argparse.Namespace) -> None:
230246
args.tenant,
231247
args.use_device_flow,
232248
args.output_file,
249+
input_dict,
233250
)
234251
elif args.service == 'gmail':
235252
if not args.client_secret:
@@ -243,6 +260,7 @@ def subcommand_get_token(args:argparse.Namespace) -> None:
243260
args.client_secret,
244261
args.scope,
245262
args.output_file,
263+
input_dict,
246264
)
247265

248266

@@ -275,7 +293,13 @@ sp_get_token.add_argument(
275293
help="use simplified device flow for Outlook/Azure",
276294
)
277295
sp_get_token.add_argument(
278-
'output_file', nargs='?', type=argparse.FileType('w'), default='-',
296+
'--overwrite-existing-token',
297+
default=False,
298+
action='store_true',
299+
help='overwrite existing token file (preserves extra fields)',
300+
)
301+
sp_get_token.add_argument(
302+
'output_file', nargs='?', type=str, default='-',
279303
help="output file, '-' for stdout",
280304
)
281305

0 commit comments

Comments
 (0)