Skip to content

Commit 25e5cde

Browse files
adejanovskimichaelsembwever
authored andcommitted
Save the JWT locally to avoid passing it for each call
1 parent b1099d9 commit 25e5cde

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

src/packaging/bin/spreaper

+40-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
#
33
# Copyright 2014-2017 Spotify AB
4-
# Copyright 2016-2018 The Last Pickle Ltd
4+
# Copyright 2016-2019 The Last Pickle Ltd
55
#
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import getpass
2020
import json
2121
import logging
2222
import os
23+
import subprocess
2324
import urllib
2425
import urlparse
2526

@@ -88,7 +89,8 @@ class ReaperCaller(object):
8889
http_method, r.status_code, len(str(r.text)))
8990
log.debug("Response content:\n%s", r.text)
9091
if str(r.status_code) == "403":
91-
printq("Access to this operation seems to be restricted. You may need to login and pass a JWT to access it.")
92+
printq("Access to this operation seems to be restricted. Please login before making any call to the API:")
93+
printq("spreaper login <username>")
9294
if not str(r.status_code).startswith("2"):
9395
print r.text
9496
r.raise_for_status()
@@ -147,7 +149,7 @@ def _global_arguments(parser, command):
147149
action="store_true")
148150
group.add_argument("-vv", help="extra output verbosity", action="store_true")
149151
group.add_argument("-q", "--quiet", help="unix mode", action="store_true")
150-
group.add_argument("--jwt", default=None, help="Session JSON Web Token obtained at login")
152+
group.add_argument("--jwt", default=None, help="JSON Web Token (JWT) to authenticate with")
151153
parser.add_argument(command)
152154

153155

@@ -329,7 +331,7 @@ def _arguments_for_delete_snapshots(parser):
329331

330332
def _arguments_for_login(parser):
331333
"""Arguments needed to login"""
332-
parser.add_argument("--username", help="Username to login with")
334+
parser.add_argument("username", help="Username to login with")
333335

334336
def _parse_arguments(command, description, usage=None, extra_arguments=None):
335337
"""Generic argument parsing done by every command"""
@@ -418,24 +420,49 @@ class ReaperCLI(object):
418420
def prepare_reaper(command, description, usage=None, extra_arguments=None):
419421
args = _parse_arguments(command, description, usage, extra_arguments)
420422
reaper = ReaperCaller(args.reaper_host, args.reaper_port, args.reaper_use_ssl)
421-
ReaperCLI.addJwtHeader(args)
423+
jwt = ReaperCLI.get_jwt(args)
424+
ReaperCLI.addJwtHeader(jwt)
422425
return reaper, args
423426

424427
@staticmethod
425-
def addJwtHeader(args):
426-
if (args.jwt != None):
427-
HEADERS['Authorization'] = 'Bearer ' + args.jwt
428+
def addJwtHeader(jwt):
429+
if (jwt != None):
430+
HEADERS['Authorization'] = 'Bearer ' + jwt
428431

429432
@staticmethod
430433
def get_password():
431434
password = None
432435
# Use the password from the file if it exists or prompt the user for it
433-
if (os.path.exists(os.path.expanduser('~/.reaper'))):
434-
password = file(os.path.expanduser('~/.reaper'),'rU').readline().rstrip("\r\n")
436+
if (os.path.exists(os.path.expanduser('~/.reaper/credentials'))):
437+
password = file(os.path.expanduser('~/.reaper/credentials'),'rU').readline().rstrip("\r\n")
435438
else:
436439
password = getpass.getpass()
437440

438441
return password
442+
443+
@staticmethod
444+
def get_jwt(args):
445+
jwt = None
446+
if args.jwt == None:
447+
# Use the password from the file if it exists or prompt the user for it
448+
if (os.path.exists(os.path.expanduser('~/.reaper/jwt'))):
449+
jwt = file(os.path.expanduser('~/.reaper/jwt'),'rU').readline().rstrip("\r\n")
450+
else:
451+
jwt = args.jwt
452+
453+
return jwt
454+
455+
@staticmethod
456+
def save_jwt(jwt):
457+
try:
458+
os.makedirs(os.path.expanduser('~/.reaper'))
459+
os.chmod(os.path.expanduser('~/.reaper'),0700)
460+
except OSError:
461+
pass
462+
with open(os.path.expanduser('~/.reaper/jwt'),'w+') as f:
463+
f.write(jwt)
464+
os.chmod(os.path.expanduser('~/.reaper/jwt'),0600)
465+
printq("# JWT saved")
439466

440467
def login(self):
441468
reaper, args = ReaperCLI.prepare_reaper(
@@ -451,7 +478,8 @@ class ReaperCLI(object):
451478
# Use shiro's session id to request a JWT
452479
COOKIES["JSESSIONID"] = reply.cookies["JSESSIONID"]
453480
jwt = reaper.get("jwt")
454-
printq("Add the following flag to all subsequent spreaper calls to use your authenticated session : --jwt {}".format(jwt))
481+
printq("You are now authenticated to Reaper.")
482+
ReaperCLI.save_jwt(jwt)
455483

456484
# remove the session id and set the auth header with the JWT
457485
COOKIES.pop("JSESSIONID", None)
@@ -461,6 +489,7 @@ class ReaperCLI(object):
461489
"ping",
462490
"Test connectivity to the Reaper service."
463491
)
492+
printq("# JWT: {}".format(os.environ.get("REAPER_JWT")))
464493
printq("# Sending PING to Reaper...")
465494
answer = reaper.get("ping")
466495
printq("# [Reply] {}".format(answer))

0 commit comments

Comments
 (0)