Skip to content

Commit 41b27db

Browse files
authored
Merge pull request #78 from kpedro88/overwrite
add argument --overwrite-existing-token to preserve additional fields in token file
2 parents 15206ad + 098b556 commit 41b27db

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
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: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ def url_safe_escape(instring:str) -> str:
3939
return urllib.parse.quote(instring, safe='~-._')
4040

4141

42+
def dump_overwrite(token:dict, output_filename: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+
with open(output_filename,'w') as output_file:
47+
json.dump(input_dict, output_file, indent=4)
48+
49+
4250
def gmail_redirect_uri(local_port:int) -> str:
4351
return 'http://127.0.0.1:%d%s' % (local_port, GOOGLE_OAUTH2_RESULT_PATH)
4452

@@ -63,7 +71,7 @@ def gmail_get_token_from_code(client_id:str, client_secret:str, authorization_co
6371
return json.loads(response)
6472

6573

66-
def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[str]) -> type:
74+
def gmail_get_RequestHandler(client_id:str, client_secret:str, output_filename:str, input_dict:dict) -> type:
6775
class GMailRequestHandler(http.server.BaseHTTPRequestHandler):
6876
def log_request(self, code:Union[int,str]='-', size:Union[int,str]='-') -> None:
6977
# Silence request logging.
@@ -90,8 +98,7 @@ def gmail_get_RequestHandler(client_id:str, client_secret:str, output_file:IO[st
9098
code,
9199
self.server.server_address[1],
92100
)
93-
json.dump(token, output_file)
94-
output_file.close()
101+
dump_overwrite(token, output_filename, input_dict)
95102
sys.exit(0)
96103

97104
def ExtractCodeFromResponse(self) -> Optional[str]:
@@ -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_filename:str, input_dict:dict) -> None:
112119
request_handler_class = gmail_get_RequestHandler(
113120
client_id,
114121
client_secret,
115-
output_file,
122+
output_filename,
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_filename: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_filename, input_dict)
209217

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

@@ -219,6 +227,13 @@ 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)
222237
if args.service == 'outlook':
223238
if not args.tenant:
224239
parser.error("'outlook' service requires 'tenant' argument.")
@@ -230,6 +245,7 @@ def subcommand_get_token(args:argparse.Namespace) -> None:
230245
args.tenant,
231246
args.use_device_flow,
232247
args.output_file,
248+
input_dict,
233249
)
234250
elif args.service == 'gmail':
235251
if not args.client_secret:
@@ -243,6 +259,7 @@ def subcommand_get_token(args:argparse.Namespace) -> None:
243259
args.client_secret,
244260
args.scope,
245261
args.output_file,
262+
input_dict,
246263
)
247264

248265

@@ -275,7 +292,13 @@ sp_get_token.add_argument(
275292
help="use simplified device flow for Outlook/Azure",
276293
)
277294
sp_get_token.add_argument(
278-
'output_file', nargs='?', type=argparse.FileType('w'), default='-',
295+
'--overwrite-existing-token',
296+
default=False,
297+
action='store_true',
298+
help='overwrite existing token file (preserves extra fields)',
299+
)
300+
sp_get_token.add_argument(
301+
'output_file', nargs='?', type=str, default='-',
279302
help="output file, '-' for stdout",
280303
)
281304

0 commit comments

Comments
 (0)