Browse Source

enforce that the board is reserved by correct user..

main
John-Mark Gurney 4 years ago
parent
commit
61bb076be2
1 changed files with 39 additions and 8 deletions
  1. +39
    -8
      bitelab/__init__.py

+ 39
- 8
bitelab/__init__.py View File

@@ -320,7 +320,7 @@ def get_authorized_board_parms(board_id, token: str = Depends(oauth2_scheme),
return dict(board_id=board_id, token=token, data=data, brdmgr=brdmgr) return dict(board_id=board_id, token=token, data=data, brdmgr=brdmgr)


@contextlib.asynccontextmanager @contextlib.asynccontextmanager
async def validate_board_params(board_id, token, data, brdmgr):
async def validate_board_params(board_id, data, brdmgr, user=None, token=None):
'''This context manager checks to see if the request is authorized '''This context manager checks to see if the request is authorized
for the board_id. This requires that the board is reserved by for the board_id. This requires that the board is reserved by
the user, or the connection came from the board's jail (TBI). the user, or the connection came from the board's jail (TBI).
@@ -329,7 +329,8 @@ async def validate_board_params(board_id, token, data, brdmgr):
brd = brdmgr.boards[board_id] brd = brdmgr.boards[board_id]


async with brd.lock: async with brd.lock:
user = await lookup_user(token, data)
if user is None:
user = await lookup_user(token, data)


try: try:
brduser = await data.BoardStatus.objects.get(board=board_id) brduser = await data.BoardStatus.objects.get(board=board_id)
@@ -448,11 +449,12 @@ async def reserve_board(board_id_or_class,
return brd return brd


class HandleExec(WSFWDServer): class HandleExec(WSFWDServer):
def __init__(self, *args, board_id, data, **kwargs):
def __init__(self, *args, board_id, data, brdmgr, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)


self._board_id = board_id self._board_id = board_id
self._data = data self._data = data
self._brdmgr = brdmgr
self._auth_user = None self._auth_user = None
self._did_exec = False self._did_exec = False


@@ -514,9 +516,16 @@ class HandleExec(WSFWDServer):
if self._auth_user is None: if self._auth_user is None:
raise RuntimeError('not authenticated') raise RuntimeError('not authenticated')


self._proc = await asyncio.create_subprocess_exec(
'jexec', self._board_id, *msg['args'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
try:
async with validate_board_params(self._board_id, self._data,
self._brdmgr, user=self._auth_user) as brd:
self._proc = await \
asyncio.create_subprocess_exec('jexec',
self._board_id, *msg['args'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
except BITEError as e:
raise RuntimeError(e.errobj.error)


self._did_exec = True self._did_exec = True


@@ -547,7 +556,7 @@ async def board_exec_ws(
try: try:
async with HandleExec(websocket.receive_bytes, async with HandleExec(websocket.receive_bytes,
websocket.send_bytes, data=data, websocket.send_bytes, data=data,
board_id=board_id) as server:
board_id=board_id, brdmgr=brdmgr) as server:
await server.get_finish_handler() await server.get_finish_handler()
finally: finally:
await websocket.close() await websocket.close()
@@ -773,7 +782,29 @@ class TestWebSocket(TestCommon):
# that a valid auth token works # that a valid auth token works
await client.auth(dict(bearer='thisisanapikey')) await client.auth(dict(bearer='thisisanapikey'))


# XXX - enforce board reservation and correct user
# That since the board isn't reserved, it fails
with self.assertRaisesRegex(RuntimeError,
'Board not reserved.'):
await client.exec([ 'sshd', '-i' ], stdin=1,
stdout=2)

# that when the board is reserved by the wrong user
brd = self.brdmgr.boards['cora-1']
obrdreq = await self.data.BoardStatus.objects.create(
board='cora-1', user='bar')
async with brd.lock:
await brd.reserve()

# that it fails
with self.assertRaisesRegex(RuntimeError, 'Board reserved by \'bar\'.'):
await client.exec([ 'sshd', '-i' ], stdin=1, stdout=2)

brduser = await self.data.BoardStatus.objects.get(board='cora-1')
obrdreq = await self.data.BoardStatus.delete(brduser)

# that when the board is reserved by the correct user
obrdreq = await self.data.BoardStatus.objects.create(
board='cora-1', user='foo')


echodata = b'somedata' echodata = b'somedata'
wrap_subprocess_exec(cse, stdout=echodata, retcode=0) wrap_subprocess_exec(cse, stdout=echodata, retcode=0)


Loading…
Cancel
Save