예제 #1
0
    def setUp(self):
        super(EditProjectMappingTests, self).setUp()

        # Set up a mapping to edit
        session = Session()
        self.user = models.User(
            email='*****@*****.**',
            username='******',
        )
        user_social_auth = social_models.UserSocialAuth(user_id=self.user.id,
                                                        user=self.user)

        self.session.add(self.user)
        self.session.add(user_social_auth)
        self.distro1 = models.Distro(name='CentOS')
        self.distro2 = models.Distro(name='Fedora')
        self.project = models.Project(
            name='python_project',
            homepage='https://example.com/python_project',
            backend='PyPI',
            ecosystem_name='pypi',
        )
        self.package = models.Packages(package_name='python_project',
                                       distro=self.distro1.name,
                                       project=self.project)
        session.add_all(
            [self.distro1, self.distro2, self.project, self.package])
        session.commit()
        self.client = self.flask_app.test_client()
예제 #2
0
def delete_distro(distro_name):
    """ Delete a distro """

    distro = models.Distro.by_name(Session, distro_name)
    if not distro:
        flask.abort(404)

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.ConfirmationForm()

    if form.validate_on_submit():
        utilities.log(
            Session,
            distro=distro.__json__(),
            topic="distro.remove",
            message=dict(agent=flask.g.user.username, distro=distro.name),
        )

        Session.delete(distro)
        Session.commit()
        flask.flash("Distro %s has been removed" % distro_name)
        return flask.redirect(flask.url_for("anitya_ui.distros"))

    return flask.render_template("distro_delete.html",
                                 current="distros",
                                 distro=distro,
                                 form=form)
    def setUp(self):
        super(DeleteProjectVersionTests, self).setUp()
        session = Session()

        # Add a project with a version to delete.
        self.project = models.Project(
            name='test_project',
            homepage='https://example.com/test_project',
            backend='PyPI',
        )
        self.project_version = models.ProjectVersion(project=self.project, version='1.0.0')

        # Add a regular user and an admin user
        self.user = models.User(email='*****@*****.**', username='******')
        self.admin = models.User(email='*****@*****.**', username='******')

        session.add_all([self.user, self.admin, self.project, self.project_version])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
예제 #4
0
    def setUp(self):
        super(LoadUserFromSessionTests, self).setUp()

        session = Session()
        self.user = User(email='*****@*****.**', username='******')
        session.add(self.user)
        session.commit()
예제 #5
0
def add_distro():

    form = anitya.forms.DistroForm()

    if form.validate_on_submit():
        name = form.name.data

        distro = models.Distro(name)

        utilities.log(Session,
                      distro=distro,
                      topic='distro.add',
                      message=dict(
                          agent=flask.g.user.username,
                          distro=distro.name,
                      ))

        try:
            Session.add(distro)
            Session.commit()
            flask.flash('Distribution added')
        except SQLAlchemyError:
            Session.rollback()
            flask.flash('Could not add this distro, already exists?', 'error')
        return flask.redirect(flask.url_for('anitya_ui.distros'))

    return flask.render_template('distro_add_edit.html',
                                 context='Add',
                                 current='distros',
                                 form=form)
예제 #6
0
    def test_list_packages_items_per_page_with_page(self):
        """Assert retrieving other pages works."""
        project = models.Project(
            name="requests", homepage="https://pypi.io/project/requests", backend="PyPI"
        )
        fedora_package = models.Packages(
            distro_name="Fedora", project=project, package_name="python-requests"
        )
        debian_package = models.Packages(
            distro_name="Debian", project=project, package_name="python-requests"
        )
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        output = self.app.get("/api/v2/packages/?items_per_page=1&page=2")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            "page": 2,
            "items_per_page": 1,
            "total_items": 2,
            "items": [
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                }
            ],
        }

        self.assertEqual(data, exp)
예제 #7
0
    def test_list_packages_items_per_page_with_page(self):
        """Assert retrieving other pages works."""
        project = models.Project(name="requests",
                                 homepage="https://pypi.io/project/requests",
                                 backend="PyPI")
        fedora_package = models.Packages(distro_name="Fedora",
                                         project=project,
                                         package_name="python-requests")
        debian_package = models.Packages(distro_name="Debian",
                                         project=project,
                                         package_name="python-requests")
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        output = self.app.get("/api/v2/packages/?items_per_page=1&page=2")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            "page":
            2,
            "items_per_page":
            1,
            "total_items":
            2,
            "items": [{
                "distribution": "Debian",
                "name": "python-requests",
                "project": "requests",
                "ecosystem": "pypi",
            }],
        }

        self.assertEqual(data, exp)
예제 #8
0
파일: app.py 프로젝트: odra/anitya
def integrity_error_handler(error):
    """
    Flask error handler for unhandled IntegrityErrors.

    Args:
        error (IntegrityError): The exception to be handled.

    Returns:
        tuple: A tuple of (message, HTTP error code).
    """
    # Because social auth provides the route and raises the exception, this is
    # the simplest way to turn the error into a nicely formatted error message
    # for the user.
    if 'email' in error.params:
        Session.rollback()
        other_user = models.User.query.filter_by(email=error.params['email']).one()
        try:
            social_auth_user = other_user.social_auth.filter_by(user_id=other_user.id).one()
            msg = ("Error: There's already an account associated with your email, "
                   "authenticate with {}.".format(social_auth_user.provider))
            return msg, 400
        # This error happens only if there is account without provider info
        except NoResultFound:
            Session.delete(other_user)
            Session.commit()
            msg = (
                "Error: There was already an existing account with missing provider. "
                "So we removed it. "
                "Please try to log in again.")
            return msg, 500

    return 'The server encountered an unexpected error', 500
예제 #9
0
    def setUp(self):
        super(EditDistroTests, self).setUp()

        # Add a regular user and an admin user
        session = Session()
        self.user = models.User(
            email='*****@*****.**',
            username='******',
        )
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id,
            user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.admin = models.User(email='*****@*****.**', username='******')
        admin_social_auth = social_models.UserSocialAuth(
            user_id=self.admin.id,
            user=self.admin
        )

        # Add distributions to edit
        self.fedora = models.Distro(name='Fedora')
        self.centos = models.Distro(name='CentOS')

        session.add_all([admin_social_auth, self.admin, self.fedora, self.centos])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
예제 #10
0
def delete_distro(distro_name):
    """ Delete a distro """

    distro = models.Distro.by_name(Session, distro_name)
    if not distro:
        flask.abort(404)

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.ConfirmationForm()

    if form.validate_on_submit():
        utilities.log(
            Session,
            distro=distro.__json__(),
            topic="distro.remove",
            message=dict(agent=flask.g.user.username, distro=distro.name),
        )

        Session.delete(distro)
        Session.commit()
        flask.flash("Distro %s has been removed" % distro_name)
        return flask.redirect(flask.url_for("anitya_ui.distros"))

    return flask.render_template(
        "distro_delete.html", current="distros", distro=distro, form=form
    )
예제 #11
0
    def setUp(self):
        super(DeleteProjectMappingTests, self).setUp()
        self.project = models.Project(
            name='test_project',
            homepage='https://example.com/test_project',
            backend='PyPI',
        )
        self.distro = models.Distro(name='Fedora')
        self.package = models.Packages(
            distro=self.distro.name, project=self.project, package_name='test-project')

        # Add a regular user and an admin user
        session = Session()
        self.user = models.User(email='*****@*****.**', username='******')
        self.admin = models.User(email='*****@*****.**', username='******')

        session.add_all([self.user, self.admin, self.distro, self.project, self.package])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
예제 #12
0
    def setUp(self):
        super(IsAdminTests, self).setUp()

        # Add a regular user and an admin user
        session = Session()
        self.user = models.User(
            email='*****@*****.**',
            username='******',
        )
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id,
            user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.admin = models.User(email='*****@*****.**', username='******')
        admin_social_auth = social_models.UserSocialAuth(
            user_id=self.admin.id,
            user=self.admin
        )
        session.add_all([admin_social_auth, self.admin])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)
예제 #13
0
    def setUp(self):
        super(BrowseLogsTests, self).setUp()
        session = Session()

        # Add a regular user and an admin user
        self.user = models.User(email='*****@*****.**', username='******')
        self.admin = models.User(email='*****@*****.**', username='******')

        self.user_log = models.Log(
            user='******',
            project='relational_db',
            distro='Fedora',
            description='This is a log',
        )
        self.admin_log = models.Log(
            user='******',
            project='best_project',
            distro='CentOS',
            description='This is also a log',
        )

        session.add_all([self.user, self.admin, self.user_log, self.admin_log])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
예제 #14
0
    def setUp(self):
        super(SetFlagStateTests, self).setUp()
        session = Session()

        # Add a regular user and an admin user
        self.user = models.User(email='*****@*****.**', username='******')
        self.admin = models.User(email='*****@*****.**', username='******')

        self.project1 = models.Project(
            name='test_project', homepage='https://example.com/test_project', backend='PyPI')
        self.project2 = models.Project(
            name='project2', homepage='https://example.com/project2', backend='PyPI')
        self.flag1 = models.ProjectFlag(
            reason='I wanted to flag it', user='******', project=self.project1)
        self.flag2 = models.ProjectFlag(
            reason='This project is wrong', user='******', project=self.project2)

        session.add_all(
            [self.user, self.admin, self.project1, self.project2, self.flag1, self.flag2])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
예제 #15
0
def add_distro():

    form = anitya.forms.DistroForm()

    if form.validate_on_submit():
        name = form.name.data

        distro = models.Distro(name)

        utilities.publish_message(
            distro=distro.__json__(),
            topic="distro.add",
            message=dict(agent=flask.g.user.username, distro=distro.name),
        )

        try:
            Session.add(distro)
            Session.commit()
            flask.flash("Distribution added")
        except SQLAlchemyError:
            Session.rollback()
            flask.flash("Could not add this distro, already exists?", "error")
        return flask.redirect(flask.url_for("anitya_ui.distros"))

    return flask.render_template("distro_add_edit.html",
                                 context="Add",
                                 current="distros",
                                 form=form)
예제 #16
0
    def test_delete_token(self):
        """Assert a user can delete an API token."""
        session = Session()
        token = models.ApiToken(user=self.user, description='Test token')
        session.add(token)
        session.commit()

        with login_user(self.flask_app, self.user):
            with self.flask_app.test_client() as c:
                output = c.get('/settings/', follow_redirects=False)
                self.assertEqual(output.status_code, 200)
                self.assertTrue(b'Test token' in output.data)
                csrf_token = output.data.split(
                    b'name="csrf_token" type="hidden" value="')[1].split(
                        b'">')[0]
                data = {'csrf_token': csrf_token}

                output = c.post('/settings/tokens/delete/{}/'.format(
                    token.token),
                                data=data,
                                follow_redirects=True)

                self.assertEqual(output.status_code, 200)
                self.assertFalse(b'Test token' in output.data)
                self.assertEqual(
                    0,
                    models.ApiToken.query.filter_by(user=self.user).count())
예제 #17
0
    def test_list_projects_with_same_name(self):
        """Assert two projects with the same name are sorted by the ecosystem."""
        self.maxDiff = None
        session = Session()
        project1 = models.Project(
            name="zlib",
            homepage="https://hackage.haskell.org/package/zlib",
            backend="GitHub",
            ecosystem_name="https://hackage.haskell.org/package/zlib",
        )
        project2 = models.Project(
            name="zlib",
            homepage="http://www.zlib.net/",
            backend="custom",
            regex="DEFAULT",
            ecosystem_name="http://www.zlib.net/",
        )
        session.add_all([project1, project2])
        session.commit()

        output = self.app.get("/api/v2/projects/")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        for item in data["items"]:
            del item["created_on"]
            del item["updated_on"]

        exp = {
            "page": 1,
            "items_per_page": 25,
            "total_items": 2,
            "items": [
                {
                    "id": 2,
                    "backend": "custom",
                    "homepage": "http://www.zlib.net/",
                    "name": "zlib",
                    "regex": "DEFAULT",
                    "version": None,
                    "version_url": None,
                    "versions": [],
                    "ecosystem": "http://www.zlib.net/",
                },
                {
                    "id": 1,
                    "backend": "GitHub",
                    "homepage": "https://hackage.haskell.org/package/zlib",
                    "name": "zlib",
                    "regex": None,
                    "version": None,
                    "version_url": None,
                    "versions": [],
                    "ecosystem": "https://hackage.haskell.org/package/zlib",
                },
            ],
        }

        self.assertEqual(data, exp)
예제 #18
0
    def test_list_projects_with_same_name(self):
        """Assert two projects with the same name are sorted by the ecosystem."""
        self.maxDiff = None
        session = Session()
        project1 = models.Project(
            name="zlib",
            homepage="https://hackage.haskell.org/package/zlib",
            backend='GitHub',
            ecosystem_name="https://hackage.haskell.org/package/zlib",
        )
        project2 = models.Project(
            name="zlib",
            homepage="http://www.zlib.net/",
            backend="custom",
            regex="DEFAULT",
            ecosystem_name="http://www.zlib.net/",
        )
        session.add_all([project1, project2])
        session.commit()

        output = self.app.get('/api/v2/projects/')
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        for item in data['items']:
            del item['created_on']
            del item['updated_on']

        exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            2,
            'items': [{
                "id": 2,
                "backend": "custom",
                "homepage": "http://www.zlib.net/",
                "name": "zlib",
                "regex": "DEFAULT",
                "version": None,
                "version_url": None,
                "versions": [],
                "ecosystem": "http://www.zlib.net/",
            }, {
                "id": 1,
                "backend": "GitHub",
                "homepage": "https://hackage.haskell.org/package/zlib",
                "name": "zlib",
                "regex": None,
                "version": None,
                "version_url": None,
                "versions": [],
                "ecosystem": "https://hackage.haskell.org/package/zlib",
            }]
        }

        self.assertEqual(data, exp)
예제 #19
0
 def setUp(self):
     super(LoadUserFromRequestTests, self).setUp()
     self.app = self.flask_app.test_client()
     session = Session()
     self.user = User(email='*****@*****.**', username='******')
     self.api_token = ApiToken(user=self.user)
     session.add_all([self.user, self.api_token])
     session.commit()
예제 #20
0
    def test_user_id(self):
        """Assert Users have a UUID id assigned to them."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        session.add(user)
        session.commit()

        self.assertTrue(isinstance(user.id, UUID))
예제 #21
0
 def setUp(self):
     super(ProjectsResourceGetTests, self).setUp()
     self.app = self.flask_app.test_client()
     session = Session()
     self.user = models.User(email='*****@*****.**', username='******')
     self.api_token = models.ApiToken(user=self.user)
     session.add_all([self.user, self.api_token])
     session.commit()
예제 #22
0
    def test_user_get_id(self):
        """Assert Users implements the Flask-Login API for getting user IDs."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        session.add(user)
        session.commit()

        self.assertEqual(six.text_type(user.id), user.get_id())
예제 #23
0
 def setUp(self):
     """Set up the Flask testing environnment"""
     super(SettingsTests, self).setUp()
     self.app = self.flask_app.test_client()
     session = Session()
     self.user = models.User(email='*****@*****.**', username='******')
     session.add(self.user)
     session.commit()
예제 #24
0
def delete_project_version(project_id, version):

    project = models.Project.get(Session, project_id)
    if not project:
        flask.abort(404)

    version_obj = None
    for vers in project.versions_obj:
        if version == vers.version:
            version_obj = vers
            break

    if version_obj is None:
        flask.abort(
            404,
            "Version %s not found for project %s" % (version, project.name))

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.ConfirmationForm()
    confirm = flask.request.form.get("confirm", False)

    if form.validate_on_submit():
        if confirm:
            utilities.log(
                Session,
                project=project.__json__(),
                topic="project.version.remove",
                message=dict(agent=flask.g.user.username,
                             project=project.name,
                             version=version),
            )

            # Delete the record of the version for this project
            Session.delete(version_obj)
            # Adjust the latest_version if needed
            sorted_versions = project.get_sorted_version_objects()
            if len(sorted_versions
                   ) > 1 and sorted_versions[0].version == version:
                project.latest_version = sorted_versions[1].parse()
                Session.add(project)
            elif len(sorted_versions) == 1:
                project.latest_version = None
                Session.add(project)
            Session.commit()

            flask.flash("Version for %s has been removed" % version)
        return flask.redirect(
            flask.url_for("anitya_ui.project", project_id=project.id))

    return flask.render_template(
        "version_delete.html",
        current="projects",
        project=project,
        version=version,
        form=form,
    )
예제 #25
0
    def test_user_relationship(self):
        """Assert users have a reference to their tokens."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        token = models.ApiToken(user=user)
        session.add(token)
        session.commit()

        self.assertEqual(user.api_tokens, [token])
예제 #26
0
    def test_token_default(self):
        """Assert creating an ApiToken generates a random token."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        token = models.ApiToken(user=user)
        session.add(token)
        session.commit()

        self.assertEqual(40, len(token.token))
예제 #27
0
    def test_not_anonymous(self):
        """Assert User implements the Flask-Login API for authenticated users."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        session.add(user)
        session.commit()

        self.assertFalse(user.is_anonymous)
        self.assertTrue(user.is_authenticated)
예제 #28
0
    def test_default_active(self):
        """Assert User usernames have a uniqueness constraint on them."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        session.add(user)
        session.commit()

        self.assertTrue(user.active)
        self.assertTrue(user.is_active)
예제 #29
0
 def setUp(self):
     super(MapProjectTests, self).setUp()
     create_distro(self.session)
     create_project(self.session)
     self.client = self.flask_app.test_client()
     session = Session()
     self.user = models.User(email='*****@*****.**', username='******')
     session.add(self.user)
     session.commit()
예제 #30
0
    def test_filter_distribution(self):
        """Assert retrieving other pages works."""
        project = models.Project(
            name='requests',
            homepage='https://pypi.io/project/requests',
            backend='PyPI',
        )
        fedora_package = models.Packages(distro_name='Fedora',
                                         project=project,
                                         package_name='python-requests')
        debian_package = models.Packages(distro_name='Debian',
                                         project=project,
                                         package_name='python-requests')
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        fedora = self.app.get('/api/v2/packages/?distribution=Fedora')
        debian = self.app.get('/api/v2/packages/?distribution=Debian')
        self.assertEqual(fedora.status_code, 200)
        self.assertEqual(debian.status_code, 200)
        fedora_data = _read_json(fedora)
        debian_data = _read_json(debian)

        fedora_exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            1,
            'items': [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }
        debian_exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            1,
            'items': [
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }

        self.assertEqual(fedora_data, fedora_exp)
        self.assertEqual(debian_data, debian_exp)
예제 #31
0
 def setUp(self):
     super(IntegrityErrorHandlerTests, self).setUp()
     session = Session()
     user = models.User(email='*****@*****.**', username='******')
     social_auth_user = social_models.UserSocialAuth(
         provider='Demo Provider', user=user)
     session.add(social_auth_user)
     session.add(user)
     session.commit()
예제 #32
0
파일: ui.py 프로젝트: mscherer/anitya
def new_token():
    """Create a new API token for the current user."""
    form = anitya.forms.TokenForm()
    if form.validate_on_submit():
        token = models.ApiToken(user=flask.g.user, description=form.description.data)
        Session.add(token)
        Session.commit()
        return flask.redirect(flask.url_for("anitya_ui.settings"))
    else:
        flask.abort(400)
예제 #33
0
    def test_username_unique(self):
        """Assert User usernames have a uniqueness constraint on them."""
        session = Session()
        user = models.User(email='*****@*****.**', username='******')
        session.add(user)
        session.commit()

        user2 = models.User(email='*****@*****.**', username='******')
        session.add(user2)
        self.assertRaises(IntegrityError, session.commit)
예제 #34
0
    def test_set_automatically(self):
        """Assert the ecosystem gets set automatically based on the backend."""
        project = models.Project(
            name="requests", homepage="https://pypi.org/requests", backend="PyPI"
        )

        Session.add(project)
        Session.commit()

        project = models.Project.query.all()[0]
        self.assertEqual("pypi", project.ecosystem_name)
예제 #35
0
    def setUp(self):
        super(LoadUserFromSessionTests, self).setUp()

        session = Session()
        self.user = models.User(email="*****@*****.**", username="******")
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id, user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        session.commit()
예제 #36
0
def delete_project_version(project_id, version):

    project = models.Project.get(Session, project_id)
    if not project:
        flask.abort(404)

    version_obj = None
    for vers in project.versions_obj:
        if version == vers.version:
            version_obj = vers
            break

    if version_obj is None:
        flask.abort(
            404, "Version %s not found for project %s" % (version, project.name)
        )

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.ConfirmationForm()
    confirm = flask.request.form.get("confirm", False)

    if form.validate_on_submit():
        if confirm:
            utilities.log(
                Session,
                project=project.__json__(),
                topic="project.version.remove",
                message=dict(
                    agent=flask.g.user.username, project=project.name, version=version
                ),
            )

            # Delete the record of the version for this project
            Session.delete(version_obj)
            # Adjust the latest_version if needed
            if project.latest_version == version:
                project.latest_version = None
                Session.add(project)
            Session.commit()

            flask.flash("Version for %s has been removed" % version)
        return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id))

    return flask.render_template(
        "version_delete.html",
        current="projects",
        project=project,
        version=version,
        form=form,
    )
예제 #37
0
    def setUp(self):
        super(RequireTokenTests, self).setUp()
        self.app = self.flask_app.test_client()
        session = Session()
        self.user = models.User(email="*****@*****.**", username="******")
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id, user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.api_token = ApiToken(user=self.user)
        session.add(self.api_token)
        session.commit()
예제 #38
0
    def test_set_manually(self):
        """Assert the ecosystem can be set manually."""
        project = models.Project(
            name="requests",
            homepage="https://pypi.org/requests",
            ecosystem_name="crates.io",
            backend="PyPI",
        )

        Session.add(project)
        Session.commit()

        project = models.Project.query.all()[0]
        self.assertEqual("crates.io", project.ecosystem_name)
예제 #39
0
    def test_filter_distribution(self):
        """Assert retrieving other pages works."""
        project = models.Project(
            name="requests", homepage="https://pypi.io/project/requests", backend="PyPI"
        )
        fedora_package = models.Packages(
            distro_name="Fedora", project=project, package_name="python-requests"
        )
        debian_package = models.Packages(
            distro_name="Debian", project=project, package_name="python-requests"
        )
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        fedora = self.app.get("/api/v2/packages/?distribution=Fedora")
        debian = self.app.get("/api/v2/packages/?distribution=Debian")
        self.assertEqual(fedora.status_code, 200)
        self.assertEqual(debian.status_code, 200)
        fedora_data = _read_json(fedora)
        debian_data = _read_json(debian)

        fedora_exp = {
            "page": 1,
            "items_per_page": 25,
            "total_items": 1,
            "items": [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                }
            ],
        }
        debian_exp = {
            "page": 1,
            "items_per_page": 25,
            "total_items": 1,
            "items": [
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                }
            ],
        }

        self.assertEqual(fedora_data, fedora_exp)
        self.assertEqual(debian_data, debian_exp)
예제 #40
0
    def test_packages(self):
        """Assert packages are returned when they exist."""
        project = models.Project(
            name="requests", homepage="https://pypi.io/project/requests", backend="PyPI"
        )
        fedora_package = models.Packages(
            distro_name="Fedora", project=project, package_name="python-requests"
        )
        debian_package = models.Packages(
            distro_name="Debian", project=project, package_name="python-requests"
        )
        jcline_package = models.Packages(
            distro_name="jcline linux", project=project, package_name="requests"
        )
        Session.add_all([project, fedora_package, debian_package, jcline_package])
        Session.commit()

        output = self.app.get("/api/v2/packages/")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            "page": 1,
            "items_per_page": 25,
            "total_items": 3,
            "items": [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
                {
                    "distribution": "jcline linux",
                    "name": "requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
            ],
        }

        self.assertEqual(data, exp)
예제 #41
0
    def setUp(self):
        super(ProjectsResourcePostTests, self).setUp()
        self.app = self.flask_app.test_client()
        session = Session()
        self.user = models.User(email="*****@*****.**", username="******")
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id, user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.api_token = models.ApiToken(user=self.user)
        session.add(self.api_token)
        session.commit()

        self.auth = {"Authorization": "Token " + self.api_token.token}
예제 #42
0
def delete_project_mapping(project_id, distro_name, pkg_name):

    project = models.Project.get(Session, project_id)
    if not project:
        flask.abort(404)

    distro = models.Distro.get(Session, distro_name)
    if not distro:
        flask.abort(404)

    package = models.Packages.get(Session, project.id, distro.name, pkg_name)
    if not package:
        flask.abort(404)

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.ConfirmationForm()
    confirm = flask.request.form.get("confirm", False)

    if form.validate_on_submit():
        if confirm:
            utilities.log(
                Session,
                project=project.__json__(),
                topic="project.map.remove",
                message=dict(
                    agent=flask.g.user.username,
                    project=project.name,
                    distro=distro.name,
                ),
            )

            Session.delete(package)
            Session.commit()

            flask.flash("Mapping for %s has been removed" % project.name)
        return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id))

    return flask.render_template(
        "regex_delete.html",
        current="projects",
        project=project,
        package=package,
        form=form,
    )
예제 #43
0
    def setUp(self):
        super(PackagesResourceGetTests, self).setUp()
        self.app = self.flask_app.test_client()
        session = Session()
        self.user = models.User(email="*****@*****.**", username="******")
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id, user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.api_token = models.ApiToken(user=self.user)
        fedora = models.Distro("Fedora")
        debian = models.Distro("Debian")
        jcline_linux = models.Distro("jcline linux")
        session.add_all([self.api_token, fedora, debian, jcline_linux])
        session.commit()
예제 #44
0
    def setUp(self):
        super(PackagesResourcePostTests, self).setUp()
        self.app = self.flask_app.test_client()
        session = Session()
        self.user = models.User(email="*****@*****.**", username="******")
        user_social_auth = social_models.UserSocialAuth(
            user_id=self.user.id, user=self.user
        )

        session.add(self.user)
        session.add(user_social_auth)
        self.api_token = models.ApiToken(user=self.user)
        self.project = models.Project(
            name="requests", homepage="https://pypi.io/project/requests", backend="PyPI"
        )
        self.fedora = models.Distro("Fedora")
        session.add_all([self.api_token, self.project, self.fedora])
        session.commit()

        self.auth = {"Authorization": "Token " + self.api_token.token}
예제 #45
0
    def test_same_package_two_distros(self):
        """Assert packages can be created."""
        Session.add(models.Distro("Debian"))
        Session.commit()
        request_data = {
            "project_ecosystem": "pypi",
            "project_name": "requests",
            "package_name": "python-requests",
            "distribution": "Fedora",
        }

        output = self.app.post(
            "/api/v2/packages/", headers=self.auth, data=request_data
        )
        self.assertEqual(output.status_code, 201)

        request_data["distribution"] = "Debian"
        output = self.app.post(
            "/api/v2/packages/", headers=self.auth, data=request_data
        )
        self.assertEqual(output.status_code, 201)
예제 #46
0
def delete_project(project_id):

    project = models.Project.get(Session, project_id)
    if not project:
        flask.abort(404)

    if not is_admin():
        flask.abort(401)

    project_name = project.name

    form = anitya.forms.ConfirmationForm()
    confirm = flask.request.form.get("confirm", False)

    if form.validate_on_submit():
        if confirm:
            utilities.log(
                Session,
                project=project.__json__(),
                topic="project.remove",
                message=dict(agent=flask.g.user.username, project=project.name),
            )

            for version in project.versions_obj:
                Session.delete(version)

            Session.delete(project)
            Session.commit()
            flask.flash("Project %s has been removed" % project_name)
            return flask.redirect(flask.url_for("anitya_ui.projects"))
        else:
            return flask.redirect(
                flask.url_for("anitya_ui.project", project_id=project.id)
            )

    return flask.render_template(
        "project_delete.html", current="projects", project=project, form=form
    )
예제 #47
0
def set_user_active_state(user_id, state):

    if not is_admin():
        flask.abort(401)

    if state.upper() == "TRUE":
        state = True
    elif state.upper() == "FALSE":
        state = False
    else:
        flask.abort(422)

    try:
        user = Session.query(models.User).filter(models.User.id == user_id).one()
    except Exception as err:
        _log.exception(err)
        user = None

    if not user:
        flask.abort(404)

    form = anitya.forms.ConfirmationForm()

    if form.validate_on_submit():
        try:
            user.active = state
            Session.add(user)
            Session.commit()
            if state:
                flask.flash("User {0} is no longer banned".format(user.username))
            else:
                flask.flash("User {0} is banned".format(user.username))
        except Exception as err:
            _log.exception(err)
            flask.flash(str(err), "errors")
            Session.rollback()

    return flask.redirect(flask.url_for("anitya_ui.browse_users"))
예제 #48
0
파일: app.py 프로젝트: fedora-infra/anitya
def integrity_error_handler(error):
    """
    Flask error handler for unhandled IntegrityErrors.

    Args:
        error (IntegrityError): The exception to be handled.

    Returns:
        tuple: A tuple of (message, HTTP error code).
    """
    # Because social auth provides the route and raises the exception, this is
    # the simplest way to turn the error into a nicely formatted error message
    # for the user.
    if "email" in error.params:
        Session.rollback()
        other_user = models.User.query.filter_by(email=error.params["email"]).one()
        try:
            social_auth_user = other_user.social_auth.filter_by(
                user_id=other_user.id
            ).one()
            msg = (
                "Error: There's already an account associated with your email, "
                "authenticate with {}.".format(social_auth_user.provider)
            )
            return msg, 400
        # This error happens only if there is account without provider info
        except NoResultFound:
            Session.delete(other_user)
            Session.commit()
            msg = (
                "Error: There was already an existing account with missing provider. "
                "So we removed it. "
                "Please try to log in again."
            )
            return msg, 500

    return "The server encountered an unexpected error", 500
예제 #49
0
def edit_distro(distro_name):

    distro = models.Distro.by_name(Session, distro_name)
    if not distro:
        flask.abort(404)

    if not is_admin():
        flask.abort(401)

    form = anitya.forms.DistroForm(obj=distro)

    if form.validate_on_submit():
        name = form.name.data

        if name != distro.name:
            utilities.log(
                Session,
                distro=distro.__json__(),
                topic="distro.edit",
                message=dict(agent=flask.g.user.username, old=distro.name, new=name),
            )

            distro.name = name

            Session.add(distro)
            Session.commit()
            message = "Distribution edited"
            flask.flash(message)
        return flask.redirect(flask.url_for("anitya_ui.distros"))

    return flask.render_template(
        "distro_add_edit.html",
        context="Edit",
        current="distros",
        distro=distro,
        form=form,
    )
예제 #50
0
 def setUp(self):
     super(IntegrityErrorHandlerTests, self).setUp()
     session = Session()
     self.user = models.User(email="*****@*****.**", username="******")
     session.add(self.user)
     session.commit()
예제 #51
0
    def post(self):
        """
        Create a new project.

        **Example Request**:

        .. sourcecode:: http

            POST /api/v2/projects/ HTTP/1.1
            Authorization: token hxPpKow7nnT6UTAEKMtQwl310P6GtyqV8DDbexnk
            Accept: application/json
            Accept-Encoding: gzip, deflate
            Connection: keep-alive
            Content-Length: 114
            Content-Type: application/json
            Host: localhost:5000
            User-Agent: HTTPie/0.9.4

            {
                "backend": "custom",
                "homepage": "https://example.com/test",
                "name": "test_project",
                "version_prefix": "release-"
            }


        **Example Response**:

        .. sourcecode:: http

            HTTP/1.0 201 CREATED
            Content-Length: 276
            Content-Type: application/json
            Date: Sun, 26 Mar 2017 15:56:30 GMT
            Server: Werkzeug/0.12.1 Python/2.7.13

            {
                "backend": "PyPI",
                "created_on": 1490543790.0,
                "homepage": "http://python-requests.org",
                "id": 13857,
                "name": "requests",
                "regex": null,
                "updated_on": 1490543790.0,
                "version": null,
                "version_url": null,
                "versions": []
            }

        :query string access_token: Your API access token.
        :reqjson string name: The project name
        :reqjson string homepage: The project homepage URL
        :reqjson string backend: The project backend (github, folder, etc.).
        :reqjson string version_url: The URL to fetch when determining the
                                     project version (defaults to null).
        :reqjson string version_prefix: The project version prefix, if any. For
                                        example, some projects prefix with "v".
        :reqjson string regex: The regex to use when searching the
                               ``version_url`` page.
        :reqjson bool insecure: When retrieving the versions via HTTPS, do not
                                validate the certificate (defaults to false).
        :reqjson bool check_release: Check the release immediately after
                                     creating the project.

        :statuscode 201: When the project was successfully created.
        :statuscode 400: When required arguments are missing or malformed.
        :statuscode 401: When your access token is missing or invalid, or when
                         the server is not configured for OpenID Connect. The
                         response will include a JSON body describing the exact
                         problem.
        :statuscode 409: When the project already exists.
        """
        name_help = _("The project name")
        homepage_help = _("The project homepage URL")
        backend_help = _("The project backend (github, folder, etc.)")
        version_url_help = _(
            "The URL to fetch when determining the project "
            "version (defaults to null)"
        )
        version_prefix_help = _(
            "The project version prefix, if any. For "
            'example, some projects prefix with "v"'
        )
        regex_help = _("The regex to use when searching the version_url page")
        insecure_help = _(
            "When retrieving the versions via HTTPS, do not "
            "validate the certificate (defaults to false)"
        )
        check_release_help = _(
            "Check the release immediately after creating " "the project."
        )

        parser = _BASE_ARG_PARSER.copy()
        parser.add_argument("name", type=str, help=name_help, required=True)
        parser.add_argument("homepage", type=str, help=homepage_help, required=True)
        parser.add_argument("backend", type=str, help=backend_help, required=True)
        parser.add_argument(
            "version_url", type=str, help=version_url_help, default=None
        )
        parser.add_argument(
            "version_prefix", type=str, help=version_prefix_help, default=None
        )
        parser.add_argument("regex", type=str, help=regex_help, default=None)
        parser.add_argument("insecure", type=bool, help=insecure_help, default=False)
        parser.add_argument("check_release", type=bool, help=check_release_help)
        args = parser.parse_args(strict=True)

        try:
            project = utilities.create_project(
                Session, user_id=flask_login.current_user.email, **args
            )
            Session.commit()
            return project.__json__(), 201
        except ProjectExists as e:
            response = jsonify(e.to_dict())
            response.status_code = 409
            return response
예제 #52
0
    def post(self):
        """
        Create a new package associated with an existing project and distribution.

        **Example request**:

        .. sourcecode:: http

            POST /api/v2/packages/ HTTP/1.1
            Accept: application/json
            Accept-Encoding: gzip, deflate
            Authorization: Token gAOFi2wQPzUJFIfDkscAKjbJfXELCz0r44m57Ur2
            Connection: keep-alive
            Content-Length: 120
            Content-Type: application/json
            Host: localhost:5000
            User-Agent: HTTPie/0.9.4

            {
                "distribution": "Fedora",
                "package_name": "python-requests",
                "project_ecosystem": "pypi",
                "project_name": "requests"
            }

        .. sourcecode:: http

            HTTP/1.0 201 CREATED
            Content-Length: 69
            Content-Type: application/json
            Date: Mon, 15 Jan 2018 21:49:01 GMT
            Server: Werkzeug/0.14.1 Python/2.7.14

            {
                "distribution": "Fedora",
                "name": "python-requests"
            }


        :reqheader Authorization: API token to use for authentication
        :reqjson string distribution: The name of the distribution that contains this
            package.
        :reqjson string package_name: The name of the package in the distribution repository.
        :reqjson string project_name: The project name in Anitya.
        :reqjson string project_ecosystem: The ecosystem the project is a part of.
            If it's not part of an ecosystem, use the homepage used in the Anitya project.

        :statuscode 201: When the package was successfully created.
        :statuscode 400: When required arguments are missing or malformed.
        :statuscode 401: When your access token is missing or invalid
        :statuscode 409: When the package already exists.
        """
        distribution_help = _(
            "The name of the distribution that contains this package."
        )
        package_name_help = _("The name of the package in the distribution repository.")
        project_name_help = _("The project name in Anitya.")
        project_ecosystem_help = _(
            "The ecosystem the project is a part of. If it's not part of an ecosystem,"
            " use the homepage used in the Anitya project."
        )

        parser = _BASE_ARG_PARSER.copy()
        parser.add_argument(
            "distribution", type=str, help=distribution_help, required=True
        )
        parser.add_argument(
            "package_name", type=str, help=package_name_help, required=True
        )
        parser.add_argument(
            "project_name", type=str, help=project_name_help, required=True
        )
        parser.add_argument(
            "project_ecosystem", type=str, help=project_ecosystem_help, required=True
        )
        args = parser.parse_args(strict=True)
        try:
            project = models.Project.query.filter_by(
                name=args.project_name, ecosystem_name=args.project_ecosystem
            ).one()
        except NoResultFound:
            return (
                {
                    "error": 'Project "{}" in ecosystem "{}" not found'.format(
                        args.project_name, args.project_ecosystem
                    )
                },
                400,
            )

        try:
            distro = models.Distro.query.filter_by(name=args.distribution).one()
        except NoResultFound:
            return (
                {"error": 'Distribution "{}" not found'.format(args.distribution)},
                400,
            )

        try:
            package = models.Packages(
                distro_name=distro.name, project=project, package_name=args.package_name
            )

            Session.add(package)
            Session.commit()

            message = dict(
                agent=flask_login.current_user.email,
                project=project.name,
                distro=distro.name,
                new=package.package_name,
            )
            utilities.log(
                Session,
                project=project.__json__(),
                distro=distro.__json__(),
                topic="project.map.new",
                message=message,
            )
            return {u"distribution": distro.name, u"name": package.package_name}, 201
        except IntegrityError:
            Session.rollback()
            return {"error": "package already exists in distribution"}, 409