| @@ -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) | ||||