Skip to content

Commit

Permalink
Merge #1251: feat: validate auth header in session request if provided
Browse files Browse the repository at this point in the history
a04fb60 add tests of /session auth-ed and not (Adam Gibson)
7e4d2b1 docs: clarify handling of optional auth token in session endpoint (theborakompanioni)
c7a2612 feat: validate auth header in session request if provided (theborakompanioni)
  • Loading branch information
AdamISZ committed Apr 22, 2022
2 parents e7ff098 + a04fb60 commit 5bf64ed
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
7 changes: 6 additions & 1 deletion docs/api/wallet-rpc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,17 @@ paths:
$ref: '#/components/responses/404-NotFound'
/session:
get:
security:
- {}
- bearerAuth: []
summary: get current status of backend
operationId: session
description: get whether a wallet is loaded and whether coinjoin/maker are happening.
description: get whether a wallet is loaded and whether coinjoin/maker are happening. if an auth token is provided, which is optional, it will be validated.
responses:
'200':
$ref: "#/components/responses/Session-200-OK"
'401':
$ref: '#/components/responses/401-Unauthorized'
'404':
$ref: '#/components/responses/404-NotFound'
/wallet/all:
Expand Down
9 changes: 9 additions & 0 deletions jmclient/jmclient/wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ def check_cookie(self, request):
jlog.warn("Invalid cookie: " + str(
request_cookie) + ", request rejected.")
raise NotAuthorized()

def check_cookie_if_present(self, request):
auth_header = request.getHeader('Authorization')
if auth_header is not None:
self.check_cookie(request)

def set_token(self, wallet_name):
""" This function creates a new JWT token and sets it as our
Expand Down Expand Up @@ -502,6 +507,10 @@ def session(self, request):
to the client what the current status of the wallet
and services is. TODO: add more data to send to client.
"""
#validate auth header if provided
#this lets caller know if cookie is invalid or outdated
self.check_cookie_if_present(request)

#if no wallet loaded then clear frontend session info
#when no wallet status is false
session = not self.cookie==None
Expand Down
35 changes: 35 additions & 0 deletions jmclient/test/test_wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,27 @@ def response_handler(self, response, handler):
yield handler(body, response.code)
return True

@defer.inlineCallbacks
def do_session_request(self, agent, addr, handler=None, token=None):
""" A `None` value for handler is reserved for the case
where we expect an Unauthorized request because we provided a token,
but it is not valid.
For other cases, provide the url prefix before `/session' as addr,
and we expect a 200 if token is valid *or* token is None, but contents
are to be checked by provided response handler callback.
"""
if handler is None:
assert token is not None
handler = self.unauthorized_session_request_handler
yield self.do_request(agent, b"GET", (addr+"/session").encode(),
None, handler, token)

def authorized_session_request_handler(self, response, code):
assert code == 200

def unauthorized_session_request_handler(self, response, code):
assert code == 401

@defer.inlineCallbacks
def test_create_list_lock_unlock(self):
""" A batch of tests in sequence here,
Expand Down Expand Up @@ -195,13 +216,27 @@ def test_create_list_lock_unlock(self):
yield self.do_request(agent, b"POST", addr, body,
self.process_create_wallet_response)

# 1a. Session request with valid token; should succeed
yield self.do_session_request(agent, root,
self.authorized_session_request_handler, token=self.jwt_token)
# 1b. Session request without token, even though one is active; should succeed
yield self.do_session_request(agent, root,
self.authorized_session_request_handler)

# 2. now *lock*
addr = root + "/wallet/" + wfn1 + "/lock"
addr = addr.encode()
jlog.info("Using address: {}".format(addr))
yield self.do_request(agent, b"GET", addr, None,
self.process_lock_response, token=self.jwt_token)

# 2a. Session request with now invalid token; should fail
yield self.do_session_request(agent, root,
self.unauthorized_session_request_handler, token=self.jwt_token)
# 2b. Session request without token, should still succeed.
yield self.do_session_request(agent, root,
self.authorized_session_request_handler)

# 3. Create this secondary wallet (so we can test re-unlock)
addr = root + "/wallet/create"
addr = addr.encode()
Expand Down

0 comments on commit 5bf64ed

Please sign in to comment.