~cedric/freshermeat

e6977eefa3d7c1624a58615dde9993164c9cdcda — C├ędric Bonhomme 10 days ago 2e261a7
fixed a rever-proxy issue with Swagger UI (fron flask-restx)
M README.md => README.md +2 -2
@@ 34,7 34,7 @@ $ poetry shell

(freshermeat) $ npm install

(freshermeat) $ export APPLICATION_SETTINGS=development.cfg
(freshermeat) $ export APPLICATION_SETTINGS=development.py

(freshermeat) $ python manager.py db_create
(freshermeat) $ python manager.py db_init


@@ 49,7 49,7 @@ $ poetry shell
 * Debugger PIN: 204-397-194
```

You can configure the application in ``instance/development.cfg`` or create
You can configure the application in ``instance/development.py`` or create
your own file and export it in the variable ``APPLICATION_SETTINGS``.



M freshermeat/bootstrap.py => freshermeat/bootstrap.py +4 -1
@@ 24,6 24,7 @@
import os
import errno
import logging
from werkzeug.middleware.proxy_fix import ProxyFix
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
import flask_restless


@@ 73,7 74,9 @@ def create_directory(directory):

# Create Flask application
application = Flask(__name__, instance_relative_config=True)

application.wsgi_app = ProxyFix(
    application.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1, x_prefix=1
)
application.config.from_pyfile(
    os.environ.get("APPLICATION_SETTINGS", "development.py"), silent=False
)

M freshermeat/scripts/import_github.py => freshermeat/scripts/import_github.py +49 -46
@@ 11,41 11,43 @@ from freshermeat.bootstrap import db, application
def import_project_from_github(owner, repo, submitter_id):
    """Imports a project hosted from GitHub.
    """
    url = 'https://api.github.com/repos/{owner}/{repo}'.format(owner=owner,
                                                                repo=repo)
    url = '{api_url}?client_id={client_id}&client_secret={client_secret}'. \
            format(api_url=url,
            client_id=application.config.get('GITHUB_CLIENT_ID', ''),
            client_secret=application.config.get('GITHUB_CLIENT_SECRET', ''))
    url = "https://api.github.com/repos/{owner}/{repo}".format(owner=owner, repo=repo)
    url = "{api_url}?client_id={client_id}&client_secret={client_secret}".format(
        api_url=url,
        client_id=application.config.get("GITHUB_CLIENT_ID", ""),
        client_secret=application.config.get("GITHUB_CLIENT_SECRET", ""),
    )

    try:
        r = requests.get(url)
        project = json.loads(r.text)
    except:
        return 'ERROR:OBSCURE'
        return "ERROR:OBSCURE"

    if Project.query.filter(Project.name == project['name']).first():
        return 'ERROR:DUPLICATE_NAME'
    if Project.query.filter(Project.name == project["name"]).first():
        return "ERROR:DUPLICATE_NAME"

    license = None
    try:
        spdx_id = project.get('license').get('spdx_id')
        spdx_id = project.get("license").get("spdx_id")
        if spdx_id:
            license = License.query.filter(License.license_id==spdx_id).first()
            license = License.query.filter(License.license_id == spdx_id).first()
    except:
        pass
    #if not license:
        #return 'ERROR:NO_LICENSE'
    # if not license:
    # return 'ERROR:NO_LICENSE'

    new_project = Project(
                    name=project['name'],
                    short_description=project['description'],
                    description=project['description'],
                    website=project['html_url'],
                    cve_vendor='',
                    cve_product='',
                    automatic_release_tracking='github:' + project.get('releases_url', '').replace('{/id}', ''),
                    submitter_id=submitter_id)
        name=project["name"],
        short_description=project["description"],
        description=project["description"],
        website=project["html_url"],
        cve_vendor="",
        cve_product="",
        automatic_release_tracking="github:"
        + project.get("releases_url", "").replace("{/id}", ""),
        submitter_id=submitter_id,
    )

    if license:
        new_project.licenses.append(license)


@@ 55,59 57,60 @@ def import_project_from_github(owner, repo, submitter_id):
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return 'ERROR:OBSCURE'
        return "ERROR:OBSCURE"

    new_code = Code(repository_url=project['clone_url'],
                    scm_type='Git',
                    project_id=new_project.id)
    new_code = Code(
        repository_url=project["clone_url"], scm_type="Git", project_id=new_project.id
    )
    db.session.add(new_code)
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return 'ERROR:OBSCURE'
        return "ERROR:OBSCURE"

    return new_project.name


def import_starred_projects_from_github(user, link=''):
def import_starred_projects_from_github(user, link=""):
    """Imports the starred projects of a GitHub user.
    """
    if link != '':
    if link != "":
        url = link
    else:
        url = 'https://api.github.com/users/{user}/starred'.format(user=user)
        url = '{api_url}?client_id={client_id}&client_secret={client_secret}'. \
                format(api_url=url,
                client_id=application.config.get('GITHUB_CLIENT_ID', ''),
                client_secret=application.config.get('GITHUB_CLIENT_SECRET', ''))
        url = "https://api.github.com/users/{user}/starred".format(user=user)
        url = "{api_url}?client_id={client_id}&client_secret={client_secret}".format(
            api_url=url,
            client_id=application.config.get("GITHUB_CLIENT_ID", ""),
            client_secret=application.config.get("GITHUB_CLIENT_SECRET", ""),
        )

    r = requests.get(url)
    starred = json.loads(r.text)

    for repo in starred:
        if repo['fork']:
        if repo["fork"]:
            continue
        new_project = Project(
                    name=repo['name'],
                    short_description=repo['description'],
                    description=repo['description'],
                    website=repo['html_url'],
                    cve_vendor='',
                    cve_product='',
                    automatic_release_tracking='github:' + repo.get('releases_url', '').replace('{/id}', ''))

            name=repo["name"],
            short_description=repo["description"],
            description=repo["description"],
            website=repo["html_url"],
            cve_vendor="",
            cve_product="",
            automatic_release_tracking="github:"
            + repo.get("releases_url", "").replace("{/id}", ""),
        )

        try:
            spdx_id = repo.get('license').get('spdx_id')
            spdx_id = repo.get("license").get("spdx_id")
            if spdx_id:
                license = License.query.filter(License.license_id==spdx_id).first()
                license = License.query.filter(License.license_id == spdx_id).first()
                if license:
                    new_project.licenses.append(license)
        except:
            pass


        db.session.add(new_project)
        try:
            # names of projects are unique on freshermeat


@@ 117,4 120,4 @@ def import_starred_projects_from_github(user, link=''):
            pass

    if r.links:
        import_starred_projects_from_github(user, r.links['next']['url'])
        import_starred_projects_from_github(user, r.links["next"]["url"])

M freshermeat/web/views/api/v2/common.py => freshermeat/web/views/api/v2/common.py +4 -1
@@ 33,7 33,9 @@ logger = logging.getLogger(__name__)
def auth_func(func):
    def wrapper(*args, **kwargs):
        if request.authorization:
            user = User.query.filter(User.login == request.authorization.username).first()
            user = User.query.filter(
                User.login == request.authorization.username
            ).first()
            if not user:
                raise ProcessingException("Couldn't authenticate your user", code=401)
            if not user.check_password(request.authorization.password):


@@ 44,6 46,7 @@ def auth_func(func):
        if not current_user.is_authenticated:
            raise ProcessingException(description="Not authenticated!", code=401)
        return func(*args, **kwargs)

    wrapper.__doc__ = func.__doc__
    wrapper.__name__ = func.__name__
    return wrapper

M freshermeat/web/views/api/v2/project.py => freshermeat/web/views/api/v2/project.py +19 -6
@@ 1,8 1,8 @@
from flask import Blueprint
from flask import Blueprint, render_template
from flask_login import login_required, current_user
from flask_restx import Api, Resource, fields, reqparse

from freshermeat.bootstrap import db
from freshermeat.bootstrap import db, application
from freshermeat.models import Project
from freshermeat.web.views.api.v2.common import auth_func



@@ 19,6 19,17 @@ api = Api(
)


@api.documentation
def custom_ui():
    return render_template(
        "swagger-ui.html",
        title=api.title,
        specs_url="{}/api/v2/projects/swagger.json".format(
            application.config["FRESHERMEAT_INSTANCE_URL"]
        ),
    )


# Argument Parsing
parser = reqparse.RequestParser()
parser.add_argument("name", type=str, help="Name of the project.")


@@ 35,12 46,14 @@ parser.add_argument("per_page", type=int, location="args")
project = api.model(
    "Project",
    {
        "id": fields.Integer(readonly=True, description="The project unique identifier"),
        "name": fields.String(
            description="Name of the project.",
        "id": fields.Integer(
            readonly=True, description="The project unique identifier"
        ),
        "name": fields.String(description="Name of the project.",),
        "description": fields.String(description="The description of the project."),
        "short_description": fields.String(description="The short descripton of the project."),
        "short_description": fields.String(
            description="The short descripton of the project."
        ),
        "website": fields.String(description="The website of the project."),
        "organization": fields.String(
            attribute=lambda x: x.organization.name if x.organization else None,

M freshermeat/web/views/organization.py => freshermeat/web/views/organization.py +2 -1
@@ 22,7 22,8 @@
import os
import uuid
from flask import Blueprint, render_template, request, abort, redirect, url_for, flash
#from werkzeug.contrib.atom import AtomFeed

# from werkzeug.contrib.atom import AtomFeed
from flask_login import login_required

from freshermeat.bootstrap import db, application

M freshermeat/web/views/project.py => freshermeat/web/views/project.py +2 -1
@@ 23,7 23,8 @@ import os
import uuid
from flask import Blueprint, render_template, redirect, url_for, flash, request, abort
from flask_login import login_required, current_user
#from werkzeug.contrib.atom import AtomFeed

# from werkzeug.contrib.atom import AtomFeed

from freshermeat.bootstrap import db, application
from freshermeat.models import (

M freshermeat/web/views/views.py => freshermeat/web/views/views.py +2 -1
@@ 30,7 30,8 @@ from flask import (
    send_from_directory,
    request,
)
#from werkzeug.contrib.atom import AtomFeed

# from werkzeug.contrib.atom import AtomFeed
from sqlalchemy import desc

from freshermeat.models import Release, Project, CVE, News

M freshermeat/workers/fetch_cve.py => freshermeat/workers/fetch_cve.py +1 -1
@@ 31,7 31,7 @@ logger = logging.getLogger(__name__)

sem = asyncio.Semaphore(20)

cve_search = CVESearch(base_url='')
cve_search = CVESearch(base_url="")


async def get_cve(*args, **kwargs):

M instance/development.py => instance/development.py +1 -0
@@ 8,6 8,7 @@ DEBUG = True
TESTING = True

FRESHERMEAT_INSTANCE_NAME = "Open Source Security Software"
FRESHERMEAT_INSTANCE_URL = "https://open-source-security-software.net"

DB_CONFIG_DICT = {
    "user": "pgsqluser",