Exemplo n.º 1
0
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
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
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"}
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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"
Exemplo n.º 10
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)
Exemplo n.º 11
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')

        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)
Exemplo n.º 12
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")

        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)
Exemplo n.º 13
0
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()
Exemplo n.º 14
0
    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)