def dispatch( self, path: str, method: str, data: dict = None, files: Mapping[str, BinaryIO] = None, json: dict = None, params: dict = None, request=None, tenant=True, ) -> Response: if request: assert not json assert not data assert not files data = request.data files = request.files json = None params = request.args if tenant is True: tenant = auth.get_current_tenant() if json: assert not data data = dumps(json) content_type = 'application/json' elif files: if not data: data = {} for key, value in request.form.items(): data[key] = value for key, value in files.items(): data[key] = value content_type = 'multipart/form-data' else: content_type = None with current_app.test_client() as client: response = client.open(path='/api/{}'.format(path.lstrip('/')), query_string=params, method=method, content_type=content_type, data=data, environ_overrides={ 'zeus.tenant': tenant, }) if not (200 <= response.status_code < 300): raise ApiError( text=response.get_data(as_text=True), code=response.status_code, ) if response.headers['Content-Type'] != 'application/json': raise ApiError( text='Request returned invalid content type: {}'.format( response.headers['Content-Type']), code=response.status_code, ) return response
def get(self): """ Return a list of repositories. """ tenant = auth.get_current_tenant() if not tenant.repository_ids: return self.respond([]) query = (Repository.query.filter( Repository.id.in_(tenant.repository_ids)).order_by( Repository.owner_name.asc(), Repository.name.asc()).limit(100)) schema = RepositorySchema(many=True, context={"user": auth.get_current_user()}) return self.paginate_with_schema(schema, query)
def dispatch_request(self, hook_id: str, *args, **kwargs) -> Response: queryset = Hook.query.filter(Hook.id == hook_id) if self.select_resource_for_update(): queryset = queryset.with_for_update() hook = queryset.first() if not hook: return self.not_found() tenant = auth.get_current_tenant() required_permission = self.permission_overrides.get( request.method, PERMISSION_MAP[request.method]) if not tenant.has_permission(hook.repository_id, required_permission): return self.error("permission denied", 400) return Resource.dispatch_request(self, hook, *args, **kwargs)
def constrained(self): from zeus.auth import get_current_tenant if not self.current_constrained: return self mzero = self._mapper_zero() if mzero is not None: tenant = get_current_tenant() if tenant.repository_ids: return self.enable_assertions(False).filter( mzero.class_.id.in_(tenant.repository_ids)) else: return self.enable_assertions(False).filter( sqlalchemy.sql.false()) return self
def get(self): """ Return a list of builds. """ # tenants automatically restrict this query but we dont want # to include public repos tenant = auth.get_current_tenant() if not tenant.repository_ids: return self.respond([]) query = ( Build.query.options( joinedload("repository"), joinedload("revision"), subqueryload_all("revision.authors"), subqueryload_all("stats"), subqueryload_all("authors"), ) .filter(Build.repository_id.in_(tenant.repository_ids)) .order_by(Build.date_created.desc()) ) user = request.args.get("user") if user: if user == "me": user = auth.get_current_user() else: user = User.query.get(user) if not user: return self.respond([]) query = query.filter( Build.authors.any( Author.email.in_( db.session.query(Email.email).filter( Email.user_id == user.id, Email.verified == True # NOQA ) ) ) ) repository = request.args.get("repository") if repository: repo = Repository.from_full_name(repository) if not repo: return self.respond([]) query = query.filter(Build.repository_id == repo.id) return self.paginate_with_schema(builds_schema, query)
def dispatch( self, path: str, method: str, data: dict = None, files: Mapping[str, BinaryIO] = None, json: dict = None, request=None, tenant=True, ) -> Response: if request: assert not json assert not data assert not files data = request.data files = request.files json = None if tenant is True: tenant = auth.get_current_tenant() if json: assert not data data = dumps(json) elif files: if not data: data = {} for key, value in files.items(): data[key] = value with current_app.test_client() as client: response = client.open( path='/api/{}'.format(path.lstrip('/')), method=method, content_type=(request.content_type if request else ('application/json' if json else None)), data=data, environ_overrides={ 'zeus.tenant': tenant, }) if not (200 <= response.status_code < 300): raise APIError.from_response(response) if response.headers['Content-Type'] != 'application/json': raise APIError('Request returned invalid content type: %s' % (response.headers['Content-Type'], )) return response
def constrained(self): from zeus.auth import get_current_tenant if not self.current_constrained: return self mzero = self._mapper_zero() if mzero is not None: cls = mzero.class_ tenant = get_current_tenant() if tenant.repository_ids: return self.enable_assertions(False).filter( or_(cls.id.in_(tenant.repository_ids), cls.public == True) # NOQA ) else: return self.enable_assertions(False).filter(cls.public == True) # NOQA return self
def get(self): """ Return a list of builds. """ # tenants automatically restrict this query but we dont want # to include public repos tenant = auth.get_current_tenant() if not tenant.repository_ids: return self.respond([]) query = (Build.query.options( joinedload("repository"), joinedload("source"), joinedload("source").joinedload("author"), joinedload("source").joinedload("revision"), subqueryload_all("stats"), ).filter(Build.repository_id.in_(tenant.repository_ids)).order_by( Build.date_created.desc())) return self.paginate_with_schema(builds_schema, query)
def get(self): """ Return a list of change requests. """ tenant = auth.get_current_tenant() if not tenant.repository_ids: return self.respond([]) query = (ChangeRequest.query.options( joinedload("head_revision"), joinedload("parent_revision", innerjoin=True), joinedload("author"), ).filter(ChangeRequest.repository_id.in_( tenant.repository_ids)).order_by( ChangeRequest.date_created.desc())) user = request.args.get("user") if user: if user == "me": user = auth.get_current_user() else: user = User.query.get(user) if not user: return self.respond([]) query = query.filter( ChangeRequest.author_id.in_( db.session.query(Author.id).filter( Author.email.in_( db.session.query(Email.email).filter( Email.user_id == user.id, Email.verified == True # NOQA ))))) repository = request.args.get("repository") if repository: repo = Repository.from_full_name(repository) if not repo: return self.respond([]) query = query.filter(ChangeRequest.repository_id == repo.id) schema = ChangeRequestWithBuildSchema(many=True, strict=True) return self.paginate_with_schema(schema, query)
def dispatch_request(self, provider, owner_name: str, repo_name: str, *args, **kwargs) -> Response: queryset = Repository.query.filter( Repository.provider == RepositoryProvider(provider), Repository.owner_name == owner_name, Repository.name == repo_name, ) if self.select_resource_for_update(): queryset = queryset.with_for_update() repo = queryset.first() if not repo: return self.not_found() tenant = auth.get_current_tenant() required_permission = self.permission_overrides.get( request.method, PERMISSION_MAP[request.method]) if not tenant.has_permission(repo.id, required_permission): return self.error("permission denied", 400) return Resource.dispatch_request(self, repo, *args, **kwargs)
def dispatch_request(self, provider, owner_name: str, repo_name: str, revision_sha: str, *args, **kwargs) -> Response: queryset = Revision.query.join( Repository, Repository.id == Revision.repository_id).filter( Repository.provider == RepositoryProvider(provider), Repository.owner_name == owner_name, Repository.name == repo_name, Revision.sha == revision_sha, ) if self.select_resource_for_update(): queryset = queryset.with_for_update() revision = queryset.first() if not revision: return self.not_found() tenant = auth.get_current_tenant() if not tenant.has_permission(revision.repository_id, PERMISSION_MAP[request.method]): return self.error("permission denied", 400) return Resource.dispatch_request(self, revision, *args, **kwargs)
def dispatch( self, path: str, method: str, data: dict = None, files: Mapping[str, BinaryIO] = None, json: dict = None, params: dict = None, request=None, tenant=True, raise_errors=True, ) -> Response: if request: assert not json assert not data assert not files data = request.data files = request.files json = None params = request.args if tenant is True: tenant = auth.get_current_tenant() if json: assert not data data = dumps(json, default=json_encoder) content_type = "application/json" elif files: if not data: data = {} for key, value in request.form.items(): data[key] = value for key, value in files.items(): data[key] = value content_type = "multipart/form-data" else: content_type = None path = "/api/{}".format(path.lstrip("/")) from sentry_sdk import Hub hub = Hub.current with hub.start_span(op="api", description=f"{method} {path}" ), current_app.test_client() as client: response = client.open( path=path, query_string=params, method=method, content_type=content_type, data=data, environ_overrides={"zeus.tenant": tenant}, ) if raise_errors and not (200 <= response.status_code < 300): raise ApiError(text=response.get_data(as_text=True), code=response.status_code) if raise_errors and response.headers[ "Content-Type"] != "application/json": raise ApiError( text="Request returned invalid content type: {}".format( response.headers["Content-Type"]), code=response.status_code, ) return response
def get_constraints(self, mzero): from zeus import auth tenant = auth.get_current_tenant() if tenant.repository_ids: return mzero.class_.id.in_(tenant.repository_ids) return sqlalchemy.sql.false()