def test_repo_revision_list(client, db_session, default_login, default_user, git_repo_config): repo = factories.RepositoryFactory.create( backend=RepositoryBackend.git, provider=RepositoryProvider.github, url=git_repo_config.url, ) db_session.add(RepositoryAccess(user=default_user, repository=repo)) db_session.flush() revision = factories.RevisionFactory.create(sha=git_repo_config.commits[0], repository=repo) source = factories.SourceFactory.create(revision=revision) factories.BuildFactory.create(source=source, date_created=timezone.now() - timedelta(minutes=1)) factories.BuildFactory.create(source=source, passed=True) resp = client.get("/api/repos/{}/revisions".format(repo.get_full_name())) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]["sha"] == git_repo_config.commits[0] assert data[0]["latest_build"]["status"] == "finished" assert data[1]["sha"] == git_repo_config.commits[1] assert data[1]["latest_build"] is None
def test_revision_artifacts(client, db_session, default_login, default_user, git_repo_config): repo = factories.RepositoryFactory.create( backend=RepositoryBackend.git, provider=RepositoryProvider.github, url=git_repo_config.url, ) db_session.add(RepositoryAccess(user=default_user, repository=repo)) db_session.flush() revision = factories.RevisionFactory.create(sha=git_repo_config.commits[0], repository=repo) source = factories.SourceFactory.create(revision=revision) factories.BuildFactory.create(source=source, date_created=timezone.now() - timedelta(minutes=1)) build = factories.BuildFactory.create(source=source, date_created=timezone.now()) job = factories.JobFactory.create(build=build) artifact = factories.ArtifactFactory.create(job=job) resp = client.get("/api/repos/{}/revisions/{}/artifacts".format( repo.get_full_name(), revision.sha)) assert resp.status_code == 200 data = resp.json() assert len(data) == 1 assert data[0]["id"] == str(artifact.id)
def access_add(repository_url, email): repo = Repository.query.unrestricted_unsafe().filter( Repository.url == repository_url, ).first() user = User.query.filter(User.email == email).first() assert repo assert email access = RepositoryAccess(user=user, repository=repo) db.session.add(access) db.session.commit()
def access_add(repository_full_name, email): owner_name, repo_name = repository_full_name.split('/', 1) repo = Repository.query.unrestricted_unsafe().filter( Repository.owner_name == owner_name, Repository.name == repo_name, ).first() user = User.query.filter(User.email == email).first() assert repo assert email access = RepositoryAccess(user=user, repository=repo) db.session.add(access) db.session.commit()
def access_add(repository, email): provider, owner_name, repo_name = repository.split("/", 2) repo = Repository.query.unrestricted_unsafe().filter( Repository.provider == RepositoryProvider(provider), Repository.owner_name == owner_name, Repository.name == repo_name, ).first() user = User.query.filter(User.email == email).first() assert repo assert email access = RepositoryAccess(user=user, repository=repo) db.session.add(access) db.session.commit()
def test_repo_branch_list(client, db_session, default_login, default_user, git_repo_config, mock_vcs_server): repo = factories.RepositoryFactory.create( backend=RepositoryBackend.git, provider=RepositoryProvider.github, url=git_repo_config.url, ) db_session.add(RepositoryAccess(user=default_user, repository=repo)) db_session.flush() resp = client.get("/api/repos/{}/branches".format(repo.get_full_name())) assert resp.status_code == 200 data = resp.json() assert len(data) == 1 assert data[0] == {"name": "master"}
def test_revision_artifacts_no_build(client, db_session, default_login, default_user, git_repo_config): repo = factories.RepositoryFactory.create( backend=RepositoryBackend.git, provider=RepositoryProvider.github, url=git_repo_config.url, ) db_session.add(RepositoryAccess(user=default_user, repository=repo)) db_session.flush() revision = factories.RevisionFactory.create(sha=git_repo_config.commits[0], repository=repo) resp = client.get("/api/repos/{}/revisions/{}/artifacts".format( repo.get_full_name(), revision.sha)) assert resp.status_code == 404
def grant_access_to_existing_repos(user): provider = GitHubRepositoryProvider(cache=True) owner_list = [o['name'] for o in provider.get_owners(user)] if owner_list: matching_repos = Repository.query.unrestricted_unsafe().filter( Repository.provider == RepositoryProvider.github, Repository.owner_name.in_(owner_list), ~Repository.id.in_( db.session.query(RepositoryAccess.repository_id, ).filter( RepositoryAccess.user_id == user.id, ))) for repo in matching_repos: if provider.has_access(auth.get_current_user(), repo): try: with db.session.begin_nested(): db.session.add( RepositoryAccess( repository_id=repo.id, user_id=user.id, )) db.session.flush() except IntegrityError: pass db.session.commit()
def test_revision_details(client, db_session, default_login, default_user, git_repo_config): repo = factories.RepositoryFactory.create( backend=RepositoryBackend.git, provider=RepositoryProvider.github, url=git_repo_config.url, ) db_session.add(RepositoryAccess(user=default_user, repository=repo)) db_session.flush() revision = factories.RevisionFactory.create(sha=git_repo_config.commits[0], repository=repo) factories.BuildFactory.create(revision=revision, date_created=timezone.now() - timedelta(minutes=1)) factories.BuildFactory.create(revision=revision, passed=True) resp = client.get("/api/repos/{}/revisions/{}".format( repo.get_full_name(), revision.sha)) assert resp.status_code == 200 data = resp.json() assert data["status"] == "finished"
def post(self): """ Activate a GitHub repository. """ repo_name = (request.get_json() or {}).get('name') if not repo_name: return self.error('missing repo_name parameter') user = auth.get_current_user() try: github, _ = self.get_github_client(user) except IdentityNeedsUpgrade as exc: return self.respond( { 'error': 'identity_needs_upgrade', 'url': exc.get_upgrade_url(), }, 401) # fetch repository details using their credentials repo_data = github.get('/repos/{}'.format(repo_name)) owner_name, repo_name = repo_data['full_name'].split('/', 1) repo = Repository.query.filter( Repository.provider == RepositoryProvider.github, Repository.external_id == str(repo_data['id']), ).first() if repo is None: # bind various github specific attributes repo = Repository( backend=RepositoryBackend.git, provider=RepositoryProvider.github, status=RepositoryStatus.active, external_id=str(repo_data['id']), owner_name=owner_name, name=repo_name, url=repo_data['clone_url'], data={'github': { 'full_name': repo_data['full_name'] }}, ) db.session.add(repo) # generate a new private key for use on github key = ssh.generate_key() db.session.add( ItemOption( item_id=repo.id, name='auth.private-key', value=key.private_key, )) # register key with github github.post('/repos/{}/keys'.format( repo.data['github']['full_name']), json={ 'title': 'zeus', 'key': key.public_key, 'read_only': True, }) # we need to commit before firing off the task db.session.commit() import_repo.delay(repo_id=repo.id) try: with db.session.begin_nested(): db.session.add( RepositoryAccess( repository_id=repo.id, user_id=user.id, )) db.session.flush() except IntegrityError: pass db.session.commit() return self.respond_with_schema(repo_schema, repo, 201)
def post(self): """ Activate a GitHub repository. """ repo_name = (request.get_json() or {}).get('name') if not repo_name: return self.error('missing repo_name parameter') owner_name, repo_name = repo_name.split('/', 1) user = auth.get_current_user() provider = GitHubRepositoryProvider(cache=False) try: repo_data = provider.get_repo(user=user, owner_name=owner_name, repo_name=repo_name) except IdentityNeedsUpgrade as exc: return self.respond( { 'provider': 'github', 'error': 'identity_needs_upgrade', 'url': exc.get_upgrade_url(), }, 401) if not repo_data['admin']: return self.respond( { 'message': 'Insufficient permissions to activate repository', }, 403) lock_key = 'repo:{provider}/{owner_name}/{repo_name}'.format( provider='github', owner_name=owner_name, repo_name=repo_name, ) with redis.lock(lock_key): try: with db.session.begin_nested(): # bind various github specific attributes repo = Repository( backend=RepositoryBackend.git, provider=RepositoryProvider.github, status=RepositoryStatus.active, external_id=str(repo_data['id']), owner_name=owner_name, name=repo_name, url=repo_data['url'], data=repo_data['config'], ) db.session.add(repo) db.session.flush() except IntegrityError: repo = Repository.query.unrestricted_unsafe().filter( Repository.provider == RepositoryProvider.github, Repository.external_id == str(repo_data['id']), ).first() # it's possible to get here if the "full name" already exists assert repo needs_configured = repo.status == RepositoryStatus.inactive if needs_configured: repo.status = RepositoryStatus.active db.session.add(repo) else: needs_configured = True if needs_configured: # generate a new private key for use on github key = ssh.generate_key() db.session.add( ItemOption( item_id=repo.id, name='auth.private-key', value=key.private_key, )) # register key with github provider.add_key( user=user, repo_name=repo_name, owner_name=owner_name, key=key, ) # we need to commit before firing off the task db.session.commit() import_repo.delay(repo_id=repo.id) try: with db.session.begin_nested(): db.session.add( RepositoryAccess( repository_id=repo.id, user_id=user.id, )) db.session.flush() except IntegrityError: pass db.session.commit() return self.respond_with_schema(repo_schema, repo, 201)
def post(self): """ Activate a GitHub repository. """ repo_name = (request.get_json() or {}).get("name") if not repo_name: return self.error("missing repo_name parameter") owner_name, repo_name = repo_name.split("/", 1) user = auth.get_current_user() provider = GitHubRepositoryProvider(cache=False) try: repo_data = provider.get_repo(user=user, owner_name=owner_name, repo_name=repo_name) except IdentityNeedsUpgrade as exc: return self.respond( { "provider": "github", "error": "identity_needs_upgrade", "url": exc.get_upgrade_url(), }, 401, ) if Permission.admin not in repo_data["permission"]: return self.respond( {"message": "Insufficient permissions to activate repository"}, 403) lock_key = Repository.get_lock_key(RepositoryProvider.github, owner_name, repo_name) with redis.lock(lock_key): try: with db.session.begin_nested(): # bind various github specific attributes repo = Repository( backend=RepositoryBackend.git, provider=RepositoryProvider.github, status=RepositoryStatus.active, external_id=str(repo_data["id"]), owner_name=owner_name, name=repo_name, url=repo_data["url"], data=repo_data["config"], ) db.session.add(repo) db.session.flush() except IntegrityError: repo = (Repository.query.unrestricted_unsafe().filter( Repository.provider == RepositoryProvider.github, Repository.external_id == str(repo_data["id"]), ).first()) # it's possible to get here if the "full name" already exists assert repo needs_configured = repo.status == RepositoryStatus.inactive if needs_configured: repo.status = RepositoryStatus.active db.session.add(repo) else: needs_configured = True if needs_configured: # generate a new private key for use on github key = ssh.generate_key() db.session.add( ItemOption(item_id=repo.id, name="auth.private-key", value=key.private_key)) # register key with github # TODO(dcramer): we should store this key reference so we can delete it # when the user deactivates the repo provider.add_key(user=user, repo_name=repo_name, owner_name=owner_name, key=key) db.session.commit() try: with db.session.begin_nested(): db.session.add( RepositoryAccess( repository_id=repo.id, user_id=user.id, permission=repo_data["permission"], )) db.session.flush() except IntegrityError: pass db.session.commit() return self.respond_with_schema(repo_schema, repo, 201)
def access_add(repository, email): user = User.query.filter(User.email == email).first() assert email access = RepositoryAccess(user=user, repository=repository) db.session.add(access) db.session.commit()
def post(self, org: Organization): """ Create a new repository. """ provider = (request.get_json() or {}).get('provider', 'native') if provider == 'github': schema = github_repo_schema elif provider == 'native': schema = repo_schema else: raise NotImplementedError result = self.schema_from_request(schema, partial=True) if result.errors: return self.respond(result.errors, 403) data = result.data if provider == 'github': # get their credentials identity = Identity.query.filter( Identity.provider == 'github', Identity.user_id == auth.get_current_user().id ).first() if 'repo' not in identity.config['scopes']: return self.respond( { 'needUpgrade': True, 'upgradeUrl': '/auth/github/upgrade' }, 401 ) assert identity # fetch repository details using their credentials github = GitHubClient(token=identity.config['access_token']) repo_data = github.get('/repos/{}'.format(data['github_name'])) repo, created = Repository.query.filter( Repository.provider == RepositoryProvider.github, Repository.external_id == str(repo_data['id']), ).first(), False if repo is None: # bind various github specific attributes repo, created = Repository( organization=org, backend=RepositoryBackend.git, provider=RepositoryProvider.github, status=RepositoryStatus.active, external_id=str(repo_data['id']), url=repo_data['clone_url'], data={'github': { 'full_name': repo_data['full_name'] }}, ), True db.session.add(repo) # generate a new private key for use on github key = ssh.generate_key() db.session.add( ItemOption( item_id=repo.id, name='auth.private-key', value=key.private_key, ) ) # register key with github github.post( '/repos/{}/keys'.format(repo.data['github']['full_name']), json={ 'title': 'zeus', 'key': key.public_key, 'read_only': True, } ) elif provider == 'native': repo, created = Repository( organization=org, status=RepositoryStatus.active, **data, ), True db.session.add(repo) db.session.flush() try: with db.session.begin_nested(): db.session.add( RepositoryAccess( organization=org, repository=repo, user=auth.get_current_user(), ) ) db.session.flush() except IntegrityError: raise pass db.session.commit() if created: import_repo.delay(repo_id=repo.id) return self.respond_with_schema(repo_schema, repo)