def check_bot_code_access(self, bot_id, generate_token): """Raises AuthorizationError if caller is not authorized to access bot code. Four variants here: 1. A valid bootstrap token is passed as '?tok=...' parameter. 2. An user, allowed to do a bootstrap, is using their credentials. 3. An IP whitelisted machine is making this call. 4. A bot (with given bot_id) is using it's own machine credentials. In later three cases we optionally generate and return a new bootstrap token, that can be used to authorize /bot_code calls. """ existing_token = self.request.get('tok') if existing_token: payload = bot_code.validate_bootstrap_token(existing_token) if payload is None: raise auth.AuthorizationError('Invalid bootstrap token') logging.debug('Using bootstrap token %r', payload) return existing_token machine_type = None if bot_id: bot_info = bot_management.get_info_key(bot_id).get() if bot_info: machine_type = bot_info.machine_type # TODO(vadimsh): Remove is_ip_whitelisted_machine check once all bots are # using auth for bootstrap and updating. if (not acl.can_create_bot() and not acl.is_ip_whitelisted_machine() and not (bot_id and bot_auth.is_authenticated_bot( bot_id, machine_type))): raise auth.AuthorizationError('Not allowed to access the bot code') return bot_code.generate_bootstrap_token() if generate_token else None
def token(self, _request): """Returns a token to bootstrap a new bot. This may seem strange to be a POST and not a GET, but it's very important to make sure GET requests are idempotent and safe to be pre-fetched; generating a token is neither of those things. """ return swarming_rpcs.BootstrapToken( bootstrap_token=bot_code.generate_bootstrap_token(), )
def get(self): params = { 'host_url': self.request.host_url, 'is_admin': acl.is_admin(), 'is_privileged_user': acl.is_privileged_user(), 'is_user': acl.is_user(), 'is_bootstrapper': acl.is_bootstrapper(), 'bootstrap_token': '...', 'mapreduce_jobs': [], 'user_type': acl.get_user_type(), 'xsrf_token': '', } if acl.is_admin(): params['mapreduce_jobs'] = [ {'id': job_id, 'name': job_def['job_name']} for job_id, job_def in mapreduce_jobs.MAPREDUCE_JOBS.iteritems() ] params['xsrf_token'] = self.generate_xsrf_token() if acl.is_bootstrapper(): params['bootstrap_token'] = bot_code.generate_bootstrap_token() self.response.write(template.render('swarming/root.html', params))
def test_bootstrap_token(self): tok = bot_code.generate_bootstrap_token() self.assertEqual({'for': 'user:joe@localhost'}, bot_code.validate_bootstrap_token(tok))
def test_bot_code_with_token(self): self.set_as_anonymous() tok = bot_code.generate_bootstrap_token() self.app.get('/bot_code?tok=%s' % tok, status=200)