def post(self): # pylint:disable-msg=invalid-name """Handles HTTP POST requests.""" repo_url = self.request.data.get('repo_url') if not repo_url: Abort(httplib.BAD_REQUEST, 'repo_url required') repo = model.GetRepo(repo_url) if not repo: html_url = name = description = repo_url repo = model.CreateRepoAsync(owner=model.GetManualTemplateOwner(), repo_url=repo_url, html_url=html_url, name=name, description=description, show_files=[], read_only_files=[], read_only_demo_url=None) template_project = repo.project.get() if not template_project or template_project.in_progress_task_name: Abort( httplib.REQUEST_TIMEOUT, 'Sorry. Requested template is not yet available. ' 'Please try again in 30 seconds.') expiration_seconds = self.request.data.get('expiration_seconds') project = model.CopyProject( self.user, template_project, expiration_seconds, new_project_name=template_project.project_name) return self.DictOfProject(project)
def __init__(self, namespace, access_key): if not namespace: Abort(httplib.FORBIDDEN, 'Missing namespace') if not access_key: Abort(httplib.FORBIDDEN, 'Missing access key') super(UrlFetchTree, self).__init__(namespace) self.namespace = namespace self.access_key = access_key
def _AssertCollaboratingAppIdAccessCheck(self, environ): if environ['PATH_INFO'] in common.CONTROL_PATHS_REQUIRING_TREE: if not shared.ThisIsPlaygroundApp(): Abort(httplib.FORBIDDEN, 'playground service is not available in this app id') else: if shared.ThisIsPlaygroundApp(): Abort( httplib.NOT_FOUND, 'mimic execution playground is not available in this app id' )
def _PerformCsrfRequestValidation(session, environ): session_xsrf = session['xsrf'] client_xsrf = environ.get(_XSRF_TOKEN_HEADER) if not client_xsrf: Abort(httplib.UNAUTHORIZED, 'Missing client XSRF token.') if client_xsrf != session_xsrf: # do not log tokens in production if common.IsDevMode(): logging.error( 'Client XSRF token={0!r}, session XSRF token={1!r}'.format( client_xsrf, session_xsrf)) Abort(httplib.UNAUTHORIZED, 'Client XSRF token does not match session XSRF token.')
def __call__(self, environ, start_response): if appids.TWO_COLLABORATING_APP_IDS: self._AssertCollaboratingAppIdAccessCheck(environ) if environ['PATH_INFO'] in common.CONTROL_PATHS_REQUIRING_TREE: if shared.IsHttpReadMethod(environ): if not shared.HasProjectReadAccess(environ): Abort(httplib.UNAUTHORIZED, 'no project read access to mimic control') else: if not shared.HasProjectWriteAccess(environ): Abort(httplib.UNAUTHORIZED, 'no project write access to mimic control') return self.app(environ, start_response)
def HasProjectReadAccess(environ): """Assert that the current user has project read permissions. Args: environ: the current WSGI environ Returns: True if the current user as read access to the current project. When deployed as two collaborating app ids, as determined by settings.TWO_COLLABORATING_APP_IDS, always returns True. """ project = environ['playground.project'] if not project: Abort(httplib.NOT_FOUND, 'requested read access to non-existent project') access_key = environ.get('mimic.access_key') if access_key and access_key == project.access_key: return True if users.is_current_user_admin(): return True user = environ.get('playground.user', None) if user and user.key.id() in project.writers: return True if settings.PROJECT_TEMPLATE_OWNER in project.writers: return True return False
def HasProjectReadAccess(environ): """Assert that the current user has project read permissions. Args: environ: the current WSGI environ Returns: True if the current user has read access to the current project. """ project = environ['playground.project'] if not project: Abort(httplib.NOT_FOUND, 'requested read access to non-existent project') access_key = environ.get('mimic.access_key') if access_key and access_key == project.access_key: return True if users.is_current_user_admin(): return True user = environ.get('playground.user', None) if user and user.key.id() in project.writers: return True if settings.PUBLIC_PROJECT_TEMPLATE_OWNER in project.writers: return True if settings.MANUAL_PROJECT_TEMPLATE_OWNER in project.writers: return True return False
def __call__(self, environ, start_response): project_id = mimic.GetProjectId(environ, False) if project_id and shared.ThisIsPlaygroundApp(): project = model.GetProject(project_id) if self._assert_project_existence: if not project: Abort(httplib.NOT_FOUND, 'project_id {} not found'.format(project_id)) environ['playground.project'] = project or settings.NO_SUCH_PROJECT return self._app(environ, start_response)
def post(self): # pylint:disable-msg=invalid-name """Handles HTTP POST requests.""" tp = self.request.environ['playground.project'] if not tp or tp.in_progress_task_name: Abort( httplib.REQUEST_TIMEOUT, 'Sorry. Requested template is not yet available. ' 'Please try again in 30 seconds.') expiration_seconds = self.request.data.get('expiration_seconds') project = model.CopyProject(self.user, tp, expiration_seconds) return self.DictOfProject(project)
def dispatch(self): # pylint:disable-msg=invalid-name """WSGI request dispatch with automatic JSON parsing.""" try: if not shared.ThisIsPlaygroundApp(): Abort(httplib.FORBIDDEN, 'playground handlers are not available in this app id') self.PerformAccessCheck() except error.PlaygroundError, e: # Manually dispatch to handle_exception self.handle_exception(e, self.app.debug) return
def post(self): # pylint:disable-msg=invalid-name """Handles HTTP POST requests.""" if not users.is_current_user_admin(): self.response.set_status(httplib.UNAUTHORIZED) return project_id = self.request.data['project_id'] if not project_id: Abort(httplib.BAD_REQUEST, 'project_id required') project = model.GetProject(project_id) if not project: Abort(httplib.NOT_FOUND, 'failed to retrieve project {}'.format(project_id)) repo_url = project.template_url repo = model.GetRepo(repo_url) model.CreateRepoAsync(owner=model.GetOrCreateUser(repo.owner), repo_url=repo.key.id(), html_url=repo.html_url, name=repo.name, description=repo.description, show_files=repo.show_files, read_only_files=repo.read_only_files, read_only_demo_url=repo.read_only_demo_url)
def __init__(self, namespace, access_key): if not namespace: Abort(httplib.FORBIDDEN, 'Missing namespace') if not access_key: Abort(httplib.FORBIDDEN, 'Missing access key') super(ZipUrlFetchTree, self).__init__(namespace, access_key) self.namespace = namespace self.access_key = access_key path_info = '{}/zip'.format(common.CONTROL_PREFIX) query_params = '{}={}&use_basepath=false'.format( common.config.PROJECT_ID_QUERY_PARAM, namespace) playground_hostname = (settings.PLAYGROUND_USER_CONTENT_HOST or settings.PLAYGROUND_HOSTS[0]) url = 'https://{}{}?{}'.format(playground_hostname, path_info, query_params) result = shared.Fetch(access_key, url, method='GET', deadline=30, retries=3) buf = cStringIO.StringIO(result.content) self._zipfile = zipfile.ZipFile(buf)
def HasProjectWriteAccess(environ): """Assert that the current user has project write permissions. Args: environ: the current WSGI environ Returns: True if the current user as write access to the current project. """ project = environ['playground.project'] if not project: Abort(httplib.NOT_FOUND, 'requested write access to non-existent project') if users.is_current_user_admin(): return True user = environ.get('playground.user') if user and user.key.id() in project.writers: return True return False
def AssertIsAdmin(): if not users.is_current_user_admin(): Abort(403, 'Admin only function')
def PerformAccessCheck(self): if not shared.HasProjectWriteAccess(self.request.environ): Abort(httplib.UNAUTHORIZED, 'no project write access')