def test_edit_project_insecure(self): """ Assert change of project insecure flag """ create_project(self.session) project_objs = models.Project.all(self.session) self.assertFalse(project_objs[0].insecure) utilities.edit_project( self.session, project=project_objs[0], name="geany", homepage="https://www.geany.org/", backend=project_objs[0].backend, version_scheme="RPM", version_pattern=None, version_url=project_objs[0].version_url, version_prefix=None, regex=project_objs[0].regex, insecure=True, user_id="*****@*****.**", releases_only=False, ) project_objs = models.Project.all(self.session) self.assertTrue(project_objs[0].insecure)
def test_edit_project(self): """ Test the edit_project function of Distro. """ create_distro(self.session) create_project(self.session) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") self.assertEqual(project_objs[1].name, "R2spec") self.assertEqual(project_objs[2].name, "subsurface") utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, homepage="https://www.geany.org", backend="PyPI", version_scheme="RPM", version_pattern=None, version_url=None, version_prefix=None, regex=None, insecure=False, user_id="*****@*****.**", releases_only=True, ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org") self.assertEqual(project_objs[0].backend, "PyPI")
def test_edit_project_check_release(self, mock_check): """ Assert that check_release is working as it should """ create_project(self.session) project_objs = models.Project.all(self.session) utilities.edit_project( self.session, project=project_objs[0], name="geany", homepage="https://www.geany.org/", backend=project_objs[0].backend, version_scheme="RPM", version_pattern=None, version_url=project_objs[0].version_url, version_prefix=None, pre_release_filter=None, version_filter=None, regex=project_objs[0].regex, insecure=False, user_id="*****@*****.**", releases_only=False, check_release=True, ) project_objs = models.Project.all(self.session) mock_check.assert_called_with(project_objs[0], mock.ANY)
def test_edit_project(self): """ Test the edit_project function of Distro. """ create_distro(self.session) create_project(self.session) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, 'geany') self.assertEqual(project_objs[0].homepage, 'https://www.geany.org/') self.assertEqual(project_objs[1].name, 'R2spec') self.assertEqual(project_objs[2].name, 'subsurface') utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, homepage='https://www.geany.org', backend='PyPI', version_url=None, version_prefix=None, regex=None, insecure=False, user_id='*****@*****.**') project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, 'geany') self.assertEqual(project_objs[0].homepage, 'https://www.geany.org') self.assertEqual(project_objs[0].backend, 'PyPI')
def test_edit_project_insecure(self): """ Assert change of project insecure flag """ create_project(self.session) project_objs = models.Project.all(self.session) self.assertFalse(project_objs[0].insecure) utilities.edit_project( self.session, project=project_objs[0], name="geany", homepage="https://www.geany.org/", backend=project_objs[0].backend, version_scheme="RPM", version_url=project_objs[0].version_url, version_prefix=None, regex=project_objs[0].regex, insecure=True, user_id="*****@*****.**", ) project_objs = models.Project.all(self.session) self.assertTrue(project_objs[0].insecure)
def test_edit_project(self): """ Test the edit_project function of Distro. """ create_distro(self.session) create_project(self.session) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") self.assertEqual(project_objs[1].name, "R2spec") self.assertEqual(project_objs[2].name, "subsurface") utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, homepage="https://www.geany.org", backend="PyPI", version_scheme="RPM", version_url=None, version_prefix=None, regex=None, insecure=False, user_id="*****@*****.**", ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org") self.assertEqual(project_objs[0].backend, "PyPI")
def test_edit_project_insecure(self): """ Assert change of project insecure flag """ create_project(self.session) project_objs = models.Project.all(self.session) self.assertFalse(project_objs[0].insecure) utilities.edit_project( self.session, project=project_objs[0], name='geany', homepage='https://www.geany.org/', backend=project_objs[0].backend, version_scheme='RPM', version_url=project_objs[0].version_url, version_prefix=None, regex=project_objs[0].regex, insecure=True, user_id='*****@*****.**', ) project_objs = models.Project.all(self.session) self.assertTrue(project_objs[0].insecure)
def test_edit_project_regex(self): """ Assert that change of project regex to same value doesn't trigger log """ create_project(self.session) logs = self.session.query(models.Log).all() project_objs = models.Project.all(self.session) self.assertEqual(len(logs), 3) self.assertEqual(project_objs[0].regex, 'DEFAULT') utilities.edit_project( self.session, project=project_objs[0], name='geany', homepage='https://www.geany.org/', backend=project_objs[0].backend, version_scheme='RPM', version_url=project_objs[0].version_url, version_prefix=None, regex='DEFAULT ', insecure=False, user_id='*****@*****.**', ) logs = self.session.query(models.Log).all() project_objs = models.Project.all(self.session) self.assertEqual(len(logs), 3) self.assertEqual(project_objs[0].regex, 'DEFAULT')
def test_edit_project_version_prefix(self): """ Assert that when version prefix is changed log message is generated """ create_project(self.session) logs = self.session.query(models.Log).all() project_objs = models.Project.all(self.session) self.assertEqual(len(logs), 3) self.assertEqual(project_objs[0].version_prefix, None) utilities.edit_project( self.session, project=project_objs[0], name='geany', homepage='https://www.geany.org/', backend=project_objs[0].backend, version_scheme='RPM', version_url=project_objs[0].version_url, version_prefix='v', regex=project_objs[0].regex, insecure=False, user_id='*****@*****.**', ) logs = self.session.query(models.Log).all() project_objs = models.Project.all(self.session) self.assertEqual(len(logs), 4) self.assertEqual(project_objs[0].version_prefix, 'v')
def set_project_archive_state(project_id, state): if not is_admin(): flask.abort(401) if state not in ("true", "false"): flask.abort(422) project = models.Project.get(Session, project_id) archive = False if state == "true": archive = True if not project: flask.abort(404) form = anitya.forms.ConfirmationForm() confirm = flask.request.form.get("confirm", False) if form.validate_on_submit(): if confirm: try: utilities.edit_project( Session, project=project, name=project.name, homepage=project.homepage, backend=project.backend, version_scheme=project.version_scheme, version_pattern=project.version_pattern, version_url=project.version_url, version_prefix=project.version_prefix, pre_release_filter=project.pre_release_filter, version_filter=project.pre_release_filter, regex=project.regex, insecure=project.insecure, releases_only=project.releases_only, archived=archive, user_id=flask.g.user.username, ) if bool(archive): flask.flash("Project '{0}' archived".format(project.name)) else: flask.flash("Project '{0}' is no longer archived".format( project.name)) except anitya.lib.exceptions.AnityaException as err: flask.flash(str(err), "errors") return flask.redirect( flask.url_for("anitya_ui.project", project_id=project.id)) return flask.render_template( "project_archive.html", current="projects", project=project, form=form, archive=archive, )
def test_edit_dry_run(self): """ Test the edit_project function dry_run parameter. """ create_distro(self.session) create_project(self.session) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") self.assertEqual(project_objs[1].name, "R2spec") self.assertEqual(project_objs[2].name, "subsurface") self.assertFalse(project_objs[0].releases_only) with fml_testing.mock_sends(): utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, homepage="https://www.geany.org", backend="PyPI", version_scheme="RPM", version_pattern=None, version_url=None, version_prefix=None, pre_release_filter="a;v", version_filter="foo", regex=None, insecure=False, user_id="*****@*****.**", releases_only=True, archived=True, dry_run=True, ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org") self.assertEqual(project_objs[0].backend, "PyPI") self.assertEqual(project_objs[0].pre_release_filter, "a;v") self.assertEqual(project_objs[0].version_filter, "foo") self.assertTrue(project_objs[0].releases_only) self.assertTrue(project_objs[0].archived) # This should be still a running transaction self.session.rollback() self.assertEqual(project_objs[0].backend, "custom") self.assertEqual(project_objs[0].pre_release_filter, None) self.assertEqual(project_objs[0].version_filter, None) self.assertFalse(project_objs[0].releases_only) self.assertFalse(project_objs[0].archived)
def edit_project(project_id): project = models.Project.get(Session, project_id) if not project: flask.abort(404) # Archived project is not editable if project.archived: flask.abort(404) backend_plugins = anitya_plugins.load_plugins(Session) plg_names = [plugin.name for plugin in backend_plugins] version_plugins = anitya_plugins.load_plugins(Session, family="versions") version_plg_names = [plugin.name for plugin in version_plugins] form = anitya.forms.ProjectForm(backends=plg_names, version_schemes=version_plg_names, obj=project) if form.validate_on_submit(): try: changes = utilities.edit_project( Session, project=project, name=form.name.data.strip(), homepage=form.homepage.data.strip(), backend=form.backend.data.strip(), version_scheme=form.version_scheme.data.strip(), version_pattern=form.version_pattern.data.strip(), version_url=form.version_url.data.strip(), version_prefix=form.version_prefix.data.strip(), pre_release_filter=form.pre_release_filter.data.strip(), version_filter=form.version_filter.data.strip(), regex=form.regex.data.strip(), insecure=form.insecure.data, user_id=flask.g.user.username, check_release=form.check_release.data, releases_only=form.releases_only.data, ) if changes: flask.flash("Project edited") else: flask.flash("Project edited - No changes were made") flask.session["justedit"] = True except exceptions.AnityaException as err: flask.flash(str(err), "errors") return flask.redirect( flask.url_for("anitya_ui.project", project_id=project_id)) return flask.render_template( "project_new.html", context="Edit", current="projects", form=form, project=project, plugins=backend_plugins, )
def test_edit_project(self): """ Test the edit_project function of Distro. """ create_distro(self.session) create_project(self.session) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") self.assertEqual(project_objs[1].name, "R2spec") self.assertEqual(project_objs[2].name, "subsurface") self.assertFalse(project_objs[0].releases_only) with fml_testing.mock_sends(anitya_schema.ProjectEdited): utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, homepage="https://www.geany.org", backend="PyPI", version_scheme="RPM", version_pattern=None, version_url=None, version_prefix=None, pre_release_filter="a;v", version_filter="alpha", regex=None, insecure=False, user_id="*****@*****.**", releases_only=True, archived=True, ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) self.assertEqual(project_objs[0].name, "geany") self.assertEqual(project_objs[0].homepage, "https://www.geany.org") self.assertEqual(project_objs[0].backend, "PyPI") self.assertEqual(project_objs[0].pre_release_filter, "a;v") self.assertTrue(project_objs[0].version_filter, "alpha") self.assertTrue(project_objs[0].releases_only) self.assertTrue(project_objs[0].archived)
def edit_project(project_id): project = anitya.lib.model.Project.get(SESSION, project_id) if not project: flask.abort(404) plugins = anitya.lib.plugins.load_plugins(SESSION) plg_names = [plugin.name for plugin in plugins] form = anitya.forms.ProjectForm(backends=plg_names, obj=project) if form.validate_on_submit(): try: utilities.edit_project( SESSION, project=project, name=form.name.data.strip(), homepage=form.homepage.data.strip(), backend=form.backend.data.strip(), version_url=form.version_url.data.strip(), version_prefix=form.version_prefix.data.strip(), regex=form.regex.data.strip(), insecure=form.insecure.data, user_id=flask.g.auth.openid, check_release=form.check_release.data, ) flask.flash('Project edited') flask.session['justedit'] = True except anitya.lib.exceptions.AnityaException as err: flask.flash(str(err), 'errors') return flask.redirect( flask.url_for('anitya_ui.project', project_id=project_id)) return flask.render_template( 'project_new.html', context='Edit', current='projects', form=form, project=project, plugins=plugins, )
def edit_project(project_id): project = models.Project.get(Session, project_id) if not project: flask.abort(404) backend_plugins = anitya_plugins.load_plugins(Session) plg_names = [plugin.name for plugin in backend_plugins] version_plugins = anitya_plugins.load_plugins(Session, family='versions') version_plg_names = [plugin.name for plugin in version_plugins] form = anitya.forms.ProjectForm( backends=plg_names, version_schemes=version_plg_names, obj=project) if form.validate_on_submit(): try: changes = utilities.edit_project( Session, project=project, name=form.name.data.strip(), homepage=form.homepage.data.strip(), backend=form.backend.data.strip(), version_scheme=form.version_scheme.data.strip(), version_url=form.version_url.data.strip(), version_prefix=form.version_prefix.data.strip(), regex=form.regex.data.strip(), insecure=form.insecure.data, user_id=flask.g.user.username, check_release=form.check_release.data, ) if changes: flask.flash('Project edited') else: flask.flash('Project edited - No changes were made') flask.session['justedit'] = True except exceptions.AnityaException as err: flask.flash(str(err), 'errors') return flask.redirect( flask.url_for('anitya_ui.project', project_id=project_id) ) return flask.render_template( 'project_new.html', context='Edit', current='projects', form=form, project=project, plugins=backend_plugins, )
def post(self): """ Check for new versions on the project. The API first checks if the project exists, if exists it will do check on it while applying any changes. If not it will create a temporary object in memory and do a check on the temporary object. **Example Request**: .. sourcecode:: http POST /api/v2/versions/ HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Authorization: token s12p01zUiVdEOZIhVf0jyZqtyYXfo2DECi6YdqqV Connection: keep-alive Content-Length: 15 Content-Type: application/json Host: localhost:5000 User-Agent: HTTPie/1.0.3 { "id": "55612" } **Example Response**: .. sourcecode:: http HTTP/1.0 200 OK Content-Length: 118 Content-Type: application/json Date: Tue, 20 Oct 2020 08:49:01 GMT Server: Werkzeug/0.16.0 Python/3.8.6 { "found_versions": [], "latest_version": "0.0.2", "versions": [ "0.0.2", "0.0.1" ], "stable_versions": [ "0.0.2", "0.0.1" ] } :query string access_token: Your API access token. :reqjson int id: Id of the project. If provided the check is done above existing project. :reqjson string name: The project name. Used as a filter to find existing project, if id not provided. :reqjson string homepage: The project homepage URL. Used as a filter to find existing project, if id not provided. :reqjson string backend: The project backend (github, folder, etc.). :reqjson string version_url: The URL to fetch when determining the project version. :reqjson string version_scheme: The project version scheme (defaults to "RPM" for temporary project). :reqjson string version_pattern: The version pattern for calendar version scheme. :reqjson string version_prefix: The project version prefix, if any. :reqjson string pre_release_filter: Filter for unstable versions. :reqjson string version_filter: Filter for blacklisted versions. :reqjson string regex: The regex to use when searching the ``version_url`` page (defaults to none for temporary project). :reqjson bool insecure: When retrieving the versions via HTTPS, do not validate the certificate (defaults to false for temporary project). :reqjson bool releases_only: When retrieving the versions, use releases instead of tags (defaults to false for temporary project). Only available for GitHub backend. :reqjson bool dry_run: If set, doesn't save anything (defaults to true). Can't be set to False for temporary project. :statuscode 200: When the versions were successfully retrieved. :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 404: When id is provided and the project doesn't exist or is archived. :statuscode 500: If there is error during the check """ id_help = _( "Id of the project. If provided the check is done above existing project." ) name_help = _( "The project name. Used as a filter to find existing project, " "if id not provided.") homepage_help = _("The project homepage URL. Used as a filter to find " "existing project, if id not provided.") backend_help = _("The project backend (github, folder, etc.).") version_url_help = _("The URL to fetch when determining the " "project version.") version_scheme_help = _("The project version scheme " "(defaults to 'RPM' for temporary project).") version_pattern_help = _( "The version pattern for calendar version scheme.") version_prefix_help = _("The project version prefix, if any.") pre_release_filter_help = _("Filter for unstable versions.") version_filter_help = _("Filter for blacklisted versions.") regex_help = _("The regex to use when searching the version_url page " "(defaults to none for temporary project).") insecure_help = _( "When retrieving the versions via HTTPS, do not " "validate the certificate (defaults to false for temporary project)." ) releases_only_help = _( "When retrieving the versions, use releases " "instead of tags (defaults to false for temporary project). " "Only available for GitHub backend.") dry_run_help = _("If set, doesn't save anything (defaults to true). " "Can't be set to False for temporary project.") parser = _BASE_ARG_PARSER.copy() parser.add_argument("id", type=int, help=id_help) parser.add_argument("name", type=str, help=name_help) parser.add_argument("homepage", type=str, help=homepage_help) parser.add_argument("backend", type=str, help=backend_help) parser.add_argument("version_url", type=str, help=version_url_help) parser.add_argument("version_scheme", type=str, help=version_scheme_help) parser.add_argument("version_pattern", type=str, help=version_pattern_help) parser.add_argument("version_prefix", type=str, help=version_prefix_help) parser.add_argument("pre_release_filter", type=str, help=pre_release_filter_help) parser.add_argument("version_filter", type=str, help=version_filter_help) parser.add_argument("regex", type=str, help=regex_help, default=None) parser.add_argument("insecure", type=inputs.boolean, help=insecure_help, default=False) parser.add_argument("releases_only", type=inputs.boolean, help=releases_only_help, default=False) parser.add_argument("dry_run", type=inputs.boolean, help=dry_run_help, default=True) args = parser.parse_args(strict=True) project = None dry_run = args.get("dry_run") # If we have id, try to get the project if args.id: project = models.Project.get(Session, project_id=args.pop("id")) if not project: response = "No such project", 404 return response # Don't look for the project if already retrieved if not project: homepage = args.get("homepage") name = args.get("name") q = models.Project.query if homepage: q = q.filter( func.lower(models.Project.homepage) == func.lower( homepage)) if name: q = q.filter( func.lower(models.Project.name) == func.lower(name)) query_result = q.all() if len(query_result) > 1: response = ( "More than one project found", 400, ) return response elif len(query_result) == 1: project = query_result[0] # If we still don't have project create temporary one if not project: # Check if we have all the required parameters missing_parameters = [] name = args.get("name") if not name: missing_parameters.append("name") homepage = args.get("homepage") if not homepage: missing_parameters.append("homepage") backend = args.get("backend") if not backend: missing_parameters.append("backend") version_url = args.get("version_url") if not version_url: version_url = homepage if missing_parameters: response = ( "Can't create temporary project. Missing arguments: " + str(missing_parameters), 400, ) return response # Before we create a temporary project, check the dry_run parameter if not dry_run: dry_run = True project = utilities.create_project( Session, user_id=flask_login.current_user.email, name=name, homepage=homepage, backend=backend, version_url=version_url, version_pattern=args.version_pattern, version_scheme=args.version_scheme, version_prefix=args.version_prefix, pre_release_filter=args.pre_release_filter, version_filter=args.version_filter, regex=args.regex, insecure=args.insecure, dry_run=dry_run, ) # If the project was retrieved, update it with provided arguments else: # If argument is missing, use the actual one name = args.get("name") if not name: name = project.name homepage = args.get("homepage") if not homepage: homepage = project.homepage backend = args.get("backend") if not backend: backend = project.backend version_scheme = args.get("version_scheme") if not version_scheme: version_scheme = project.version_scheme version_pattern = args.get("version_pattern") if not version_pattern: version_pattern = project.version_pattern version_url = args.get("version_url") if not version_url: version_url = project.version_url version_prefix = args.get("version_prefix") if not version_prefix: version_prefix = project.version_prefix pre_release_filter = args.get("pre_release_filter") if not pre_release_filter: pre_release_filter = project.pre_release_filter version_filter = args.get("version_filter") if not version_filter: version_filter = project.version_filter regex = args.get("regex") if not regex: regex = project.regex insecure = args.get("insecure") if not insecure: insecure = project.insecure releases_only = args.get("releases_only") if not releases_only: releases_only = project.releases_only try: utilities.edit_project( Session, user_id=flask_login.current_user.email, project=project, name=name, homepage=homepage, backend=backend, version_scheme=version_scheme, version_pattern=version_pattern, version_url=version_url, version_prefix=version_prefix, pre_release_filter=pre_release_filter, version_filter=version_filter, regex=regex, insecure=insecure, releases_only=releases_only, dry_run=dry_run, ) except AnityaException as err: response = str(err), 500 return response if project: try: versions = utilities.check_project_release(project, Session, test=dry_run) except AnityaException as err: response = "Error when checking for new version: " + str( err), 500 return response response = { "latest_version": project.latest_version, "found_versions": versions, "versions": project.versions, "stable_versions": [str(v) for v in project.stable_versions], } return response