def test_disabled(mocker, db_session, default_user, default_repo, default_repo_access, default_source, outbox): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, failed=True) db_session.add(build) db_session.add( ItemOption(item_id=default_user.id, name='mail.notify_author', value='0')) db_session.flush() send_email_notification(build) assert len(outbox) == 0
def test_invalid_public_key(mocker, db_session, default_repo): option = ItemOption(item_id=default_repo.id, name="auth.private-key", value="foo") db_session.add(option) db_session.flush() mock_vcs_backend = mocker.MagicMock(spec=Vcs) mocker.patch.object(Repository, "get_vcs", return_value=mock_vcs_backend) mock_vcs_backend.exists.return_value = False mock_vcs_backend.clone.side_effect = InvalidPublicKey(["git", "clone"], 1) sync_repo(repo_id=default_repo.id) assert default_repo.status == RepositoryStatus.inactive assert not ItemOption.query.get(option.id)
def test_deactivate_repo(db_session, default_repo, default_repo_access, default_user, outbox): db_session.add( ItemOption(item_id=default_repo.id, name="auth.private-key", value="")) db_session.flush() deactivate_repo(default_repo.id, DeactivationReason.invalid_pubkey) assert not ItemOption.query.filter(ItemOption.item_id == default_repo.id, ItemOption.name == "auth.private-key").first() assert default_repo.status == RepositoryStatus.inactive assert len(outbox) == 1 msg = outbox[0] assert msg.subject == "Repository Disabled - getsentry/zeus" assert msg.recipients == [default_user.email]
def test_disabled( mocker, db_session, default_user, default_repo, default_repo_access, default_source, default_tenant, outbox, ): build = factories.BuildFactory(source=default_source, failed=True) db_session.add(build) db_session.add( ItemOption(item_id=default_user.id, name="mail.notify_author", value="0")) db_session.flush() send_email_notification(build) assert len(outbox) == 0
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 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)