Esempio n. 1
0
def register():
    """Страница регистрации"""
    form = RegisterForm()
    if form.validate_on_submit():
        if form.password.data != form.password_again.data:
            return render_template('register.html',
                                   title='MyTube: Регистрация',
                                   form=form,
                                   message="Пароли не совпадают")
        db_sess = db_session.create_session()
        if db_sess.query(User).filter(User.email == form.email.data).first():
            return render_template('register.html',
                                   title='MyTube: Регистрация',
                                   form=form,
                                   message="Такой пользователь уже есть")
        user = User(
            name=form.name.data,
            email=form.email.data,
        )
        user.set_password(form.password.data)
        db_sess.add(user)
        db_sess.commit()
        return redirect('/login')
    return render_template('register.html',
                           title='MyTube: Регистрация',
                           form=form)
Esempio n. 2
0
def as_user(client: testing.FlaskClient):
    ui = regular_user_info()
    with client.session_transaction() as session:
        session["user_info"] = ui

    user = User(full_name=ui["name"], login=ui["email"], profile_picture=ui["picture"])
    user.roles = [
        Role(name=PredefinedRoles.USER),
    ]
    return user
Esempio n. 3
0
def authorize(user: User, they: RuleList):
    def per_role(cls):
        """Reads _permissions from the given class and creates rules from it."""
        perms = getattr(cls, "_permissions")
        if perms is None or user is None:
            return

        # normalize role data type
        perms = {str(role): p for role, p in perms.items()}
        for role in user.roles:
            role_perms = perms.get(role.name)
            if role_perms is None:
                continue

            for action, check in role_perms.items():
                # accept all
                if check == ALL or check is True:
                    they.can(action, cls)
                # based on attribute values
                elif isinstance(check, dict):
                    they.can(action, cls, **check)
                # based on check function
                elif hasattr(check, "__call__"):

                    def gen_wrapper(check):
                        def wrapper(subject):
                            return check(subject, user)

                        return wrapper

                    they.can(action, cls, gen_wrapper(check))
                else:
                    they.can(action, cls, check)

    if user is not None:
        they.can(MANAGE, User, id=user.id)
        they.can(READ, User)
        they.can("READ_OWN", "Proposal")
        if user.is_reviewer():
            # reviewers can see the list of proposals
            they.can(READ, "Proposal")
        if user.is_admin():
            # admins can do everything
            they.can(MANAGE, ALL)

    # pylint: disable=import-outside-toplevel
    # import locally to avoid import cycle
    from data.models.vulnerability import Vulnerability

    # pylint: enable=import-outside-toplevel

    per_role(Vulnerability)

    log.debug("%s can %s", user, they)
Esempio n. 4
0
def as_user(client: testing.FlaskClient):
    ui = regular_user_info()
    with client.session_transaction() as session:
        session['user_info'] = ui

    user = User(full_name=ui['name'],
                email=ui['email'],
                profile_picture=ui['picture'])
    user.roles = [
        Role(name=PredefinedRoles.USER),
    ]
    return user
Esempio n. 5
0
def load_user():
    if not is_authenticated():
        g.user = None
        return

    log.debug('Loading user')

    # Ignore all non-admin users during maintenance or restricted mode.
    if (current_app.config["MAINTENANCE_MODE"]
            or current_app.config['RESTRICT_LOGIN']
            and not current_app.config['IS_LOCAL']) and not is_admin():
        logout()
        flash('Login restricted.', 'danger')
        return

    # don't override existing user
    if getattr(g, 'user', None) is not None:
        log.debug('Reusing existing user %s', g.user)
        return

    data = session["user_info"]
    email = data["email"]

    user = User.query.filter_by(email=email).one_or_none()
    if not user:
        name, host = email.rsplit('@', 1)
        log.info('Creating new user %s...%s@%s', name[0], name[-1], host)
        user = User(email=email,
                    full_name=data.get("name", name),
                    profile_picture=data.get("picture"))
    else:
        log.info('Updating user %s', user)
        if 'name' in data:
            user.full_name = data["name"]
        if 'picture' in data:
            user.profile_picture = data["picture"]

    # update automatic roles
    user.roles.append(get_or_create_role(PredefinedRoles.USER))
    email = session["user_info"]["email"]
    if email in current_app.config["APPLICATION_ADMINS"]:
        user.roles.append(get_or_create_role(PredefinedRoles.ADMIN))
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
    elif email == '*****@*****.**':
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
    db.session.add(user)
    db.session.commit()

    g.user = user
    log.debug('Loaded user %s', g.user)
Esempio n. 6
0
def get_user_status_info(questioner_user: User, target_user) -> dict:
    """ Функция возвращает информацию для карточки пользователя в виде json """

    response = {
        'buttons': None,
        'status_text': None,
        'status_style_color': None,
        'type': None
    }

    if target_user in questioner_user.friends():  # Карточка друга
        response['buttons'] = [
            f'''<a class="btn btn-primary" href="{url_for('users_dialog', id_from=questioner_user.id, id_to=target_user.id)}">Написать</a>''',
            f'''<a class="btn btn-danger" href="javascript:card_type('remove_friend', {questioner_user.id}, {target_user.id})">Удалить из друзей</a>'''
        ]
        response['status_text'] = ' - Друг'
        response['status_style_color'] = 'green'
        response['type'] = 'friend'
    elif target_user in questioner_user.subscribers():  # Карточка подписчика
        response['buttons'] = [
            f'''<a class="btn btn-success" href="javascript:card_type('add_friend', {questioner_user.id}, {target_user.id})">Принять заявку</a>'''
            f'''<a class="btn btn-primary" href="{url_for('users_dialog', id_from=questioner_user.id, id_to=target_user.id)}">Написать</a>'''
        ]
        if questioner_user.need_answer(
                target_user):  # Добавление кнопки "Оставить в подписчиках"
            response['buttons'].append(
                f'''<a id="user_{target_user.id}_sub_btn" class="btn btn-secondary" href="javascript:answer_offer({questioner_user.id}, {target_user.id})">Оставить в подписчиках</a>'''
            )
        response['status_text'] = ' - Подписчик'
        response['status_style_color'] = 'red'
        response['type'] = 'subscriber'
    elif target_user in questioner_user.offers():  # Карточка запроса в друзья
        response['buttons'] = [
            f'''<a class="btn btn-primary" href="{url_for('users_dialog', id_from=questioner_user.id, id_to=target_user.id)}">Написать</a>'''
            f'''<a class="btn btn-danger" href="javascript:card_type('remove_req', {questioner_user.id}, {target_user.id})">Отменить заявку</a>'''
        ]
        response['status_text'] = ' - Заявка в друзья'
        response['status_style_color'] = 'darkgray'
        response['type'] = 'offer'
    else:  # Карточка обычного пользователя
        response['buttons'] = [
            f'''<a class="btn btn-primary" href="{url_for('users_dialog', id_from=questioner_user.id, id_to=target_user.id)}">Написать</a>'''
            f'''<a class="btn btn-success" href="javascript:card_type('add_req', {questioner_user.id}, {target_user.id})">Добавить в друзья</a>'''
        ]
        response['status_text'] = ''
        response['status_style_color'] = 'black'
        response['type'] = 'usual'

    return response
Esempio n. 7
0
def as_admin(client: testing.FlaskClient):
    ui = admin_user_info()
    with client.session_transaction() as session:
        session['user_info'] = ui
        session['google_token'] = 'testing-admin'

    user = User(full_name=ui['name'],
                email=ui['email'],
                profile_picture=ui['picture'])
    user.roles = [
        Role(name=PredefinedRoles.ADMIN),
        Role(name=PredefinedRoles.REVIEWER),
        Role(name=PredefinedRoles.USER),
    ]
    return user
Esempio n. 8
0
 def post(self):
     db_sess = db_session.create_session()
     username = request.args.get('username')
     password = request.args.get('password')
     email = request.args.get('email')
     if username is None or password is None or email is None:
         abort(
             400,
             message=
             'Missing arguments. You have to pass username, password and email'
         )
     if not valid_email(email):
         abort(400, message='Invalid email')
     if db_sess.query(User).filter(User.email == email).first():
         abort(400, message='User already registered')
     user = User(name=username, email=email)
     user.set_password(password)
     db_sess.add(user)
     db_sess.commit()
     return jsonify({'success': 'OK'})
Esempio n. 9
0
def finish_registration(nickname, email, password, token):
    """ Обработчик для завершения регистрации """

    session = db_session.create_session()
    user = User(nickname=nickname, email=email, password=password)

    if user.verify_token(
            token
    ):  # Если токен действительный, то добавление пользователя в бд
        session.add(user)
        session.commit()

        login_user(user)
        return redirect(url_for('home_page', user_id=user.id))

    # Вывод сообщения при недействительном токене
    h3 = 'Недействительный токен! Попробуйте зарегистрироваться заново.'
    return render_template('message_page.html',
                           title='Ошибка',
                           h1='Ошибка!',
                           h3=h3)
Esempio n. 10
0
def registration():
    """ Обработчик для регистрации пользователя """

    form = RegistrationForm()
    if form.validate_on_submit():
        session = db_session.create_session()

        # Проверка на существование пользователя с указанной почтой
        if session.query(User).filter(User.email == form.email.data).first():
            return render_template(
                'registration.html',
                title='Регистрация',
                form=form,
                message='Пользователь с такой почтой уже существует')
        #

        # Создание нового пользователя
        user = User(
            nickname=form.nickname.data,
            email=form.email.data,
        )
        user.set_password(form.password.data)
        #

        # Отправка сообщения на указанную почту для подтверждения почты
        link = f'http://{host}:{port}/verifying_email/{user.nickname}/{user.email}' \
               f'/{user.password}/{user.get_token()}'
        send_email(app=app,
                   mail=mail,
                   subject='Change email',
                   sender=app.config['ADMINS'][0],
                   recipients=[form.email.data],
                   html_body=render_template('email_template.html',
                                             username=user.nickname,
                                             link=link))
        #

        return redirect(url_for('check_email'))

    return render_template('registration.html', title='Регистрация', form=form)
Esempio n. 11
0
def authorize(user: User, they: RuleList):
    def per_role(cls):
        """Reads _permissions from the given class and creates rules from it."""
        perms = getattr(cls, '_permissions')
        if perms is None or user is None:
            return

        # normalize role data type
        perms = {str(role): p for role, p in perms.items()}
        for role in user.roles:
            role_perms = perms.get(role.name)
            if role_perms is None:
                continue

            for action, check in role_perms.items():
                # accept all
                if check == ALL or check is True:
                    they.can(action, cls)
                # based on attribute values
                elif isinstance(check, dict):
                    they.can(action, cls, **check)
                # based on check function
                else:
                    they.can(action, cls, check)

    if user is not None:
        they.can(MANAGE, User, id=user.id)
        they.can('READ_OWN', 'Proposal')
        if user.is_reviewer():
            # reviewers can see the list of proposals
            they.can(READ, 'Proposal')
        if user.is_admin():
            # admins can do everything
            they.can(MANAGE, ALL)

    # import locally to avoid import
    from data.models.vulnerability import Vulnerability
    per_role(Vulnerability)

    log.debug('%s can %s', user, they)
Esempio n. 12
0
def load_user():
    # continue for assets
    if request.path.startswith('/static'):
        return

    # continue for logout page
    if request.path == url_for('auth.logout'):
        return

    # continue for terms page
    if request.path == url_for('auth.terms'):
        return

    if not is_authenticated():
        g.user = None
        return

    log.debug('Loading user')

    # Ignore all non-admin users during maintenance or restricted mode.
    if (current_app.config["MAINTENANCE_MODE"]
            or current_app.config['RESTRICT_LOGIN']
            and not current_app.config['IS_LOCAL']) and not is_admin():
        logout()
        flash('Login restricted.', 'danger')
        return

    # don't override existing user
    if getattr(g, 'user', None) is not None:
        log.debug('Reusing existing user %s', g.user)
        return

    data = session["user_info"]
    email = data["email"]

    user = User.query.filter_by(email=email).one_or_none()
    is_new = False
    is_changed = False
    if not user:
        if not session.get('terms_accepted'):
            log.warn('Terms not accepted yet')
            request._authorized = True
            return redirect(url_for('auth.terms'))

        name, host = email.rsplit('@', 1)
        log.info('Creating new user %s...%s@%s', name[0], name[-1], host)
        user = User(email=email,
                    full_name=data.get("name", name),
                    profile_picture=data.get("picture"))
        is_new = True
    else:
        log.info('Updating user %s', user)
        if 'name' in data and user.full_name != data['name']:
            user.full_name = data["name"]
            is_changed = True
        if 'picture' in data and user.profile_picture != data['picture']:
            user.profile_picture = data["picture"]
            is_changed = True

    # update automatic roles
    if is_new:
        user.roles.append(get_or_create_role(PredefinedRoles.USER))

    if email in current_app.config["APPLICATION_ADMINS"]:
        user.roles.append(get_or_create_role(PredefinedRoles.ADMIN))
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
        if is_new:
            user.state = UserState.ACTIVE
        is_changed = True
    elif email == '*****@*****.**':
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
        is_changed = True

    if is_changed or is_new:
        log.info('Saving user %s', user)
        db.session.add(user)
        db.session.commit()

    if user.is_blocked():
        logout()
        flash('Account blocked', 'danger')
    elif user.is_enabled():
        g.user = user
        log.debug('Loaded user %s', g.user)
    else:
        logout()
        flash('Account not yet activated', 'danger')
Esempio n. 13
0
def load_user():
    # pylint: disable=too-many-return-statements,too-many-branches
    # TODO: split into smaller functions

    # continue for assets
    if request.path.startswith("/static"):
        return

    # continue for logout page
    if request.path == url_for("auth.logout"):
        return

    # continue for terms page
    if request.path == url_for("auth.terms"):
        return

    if not is_authenticated():
        g.user = None
        return

    log.debug("Loading user")

    # Ignore all non-admin users during maintenance or restricted mode.
    if (current_app.config["MAINTENANCE_MODE"]
            or current_app.config["RESTRICT_LOGIN"]
            and not current_app.config["IS_LOCAL"]) and not is_admin():
        logout()
        flash("Login restricted.", "danger")
        return

    # don't override existing user
    if getattr(g, "user", None) is not None:
        log.debug("Reusing existing user %s", g.user)
        return

    data = session["user_info"]

    # Make sure old and incompatible sessions get dropped.
    if "type" not in data.keys():
        logout()
        return

    login_type = LoginType(data["type"])

    if login_type in (LoginType.GOOGLE, LoginType.LOCAL):
        login_id = data["email"]
        picture = data.get("picture")
    elif login_type == LoginType.GITHUB:
        login_id = data["login"]
        picture = data.get("avatar_url")
    else:
        log.error("Unsupported login type %r", login_type)
        flash("Login unsupported.", "danger")
        logout()
        return
    user = User.query.filter_by(login=login_id).one_or_none()
    is_new = False
    is_changed = False
    if not user:
        resp, invite_code = registration_required(login_id=login_id)
        if resp is not None:
            return resp

        if "@" in login_id:
            name, host = login_id.rsplit("@", 1)
            log.info("Creating new user %s...%s@%s (%s)", name[0], name[-1],
                     host, login_type)
        else:
            name = login_id
            log.info(
                "Creating new user %s...%s (%s)",
                login_id[:2],
                login_id[-2:],
                login_type,
            )
        user = User(
            login=login_id,
            full_name=data.get("name", name),
            profile_picture=picture,
            login_type=login_type,
        )
        is_new = True
        if invite_code is not None:
            session.pop("invite_code")
            user.roles = invite_code.roles
            user.invite_code = invite_code
            invite_code.remaining_uses -= 1
            if current_app.config["AUTO_ENABLE_INVITED_USERS"]:
                user.enable()
            db.session.add(invite_code)
    else:
        log.info("Updating user %s", user)
        if "name" in data and not user.full_name:
            user.full_name = data["name"]
            is_changed = True
        if picture and not user.profile_picture:
            user.profile_picture = picture
            is_changed = True
        if user.login_type is None:
            user.login_type = login_type

    # update automatic roles
    if is_new:
        user.roles.append(get_or_create_role(PredefinedRoles.USER))

    email = data.get("email")
    if email in current_app.config["APPLICATION_ADMINS"]:
        user.roles.append(get_or_create_role(PredefinedRoles.ADMIN))
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
        if is_new:
            user.state = UserState.ACTIVE
        is_changed = True
    elif email == "*****@*****.**":
        user.roles.append(get_or_create_role(PredefinedRoles.REVIEWER))
        is_changed = True

    if is_changed or is_new:
        log.info("Saving user %s", user)
        db.session.add(user)
        db.session.commit()

    if user.is_blocked():
        logout()
        flash("Account blocked", "danger")
    elif user.is_enabled():
        g.user = user
        log.debug("Loaded user %s", g.user)
        if user.is_first_login():
            user.enable()
            db.session.add(user)
            db.session.commit()
            flash(
                jinja2.Markup(
                    "Welcome to Vulncode-DB!<br>"
                    "Please take a look at your "
                    f'<a href="{url_for("profile.index")}">profile page</a> '
                    "to review your settings."),
                "info",
            )
    else:
        logout()
        flash("Account not yet activated", "danger")
Esempio n. 14
0
def creator2():
    return User(id=4, email='*****@*****.**')
Esempio n. 15
0
def creator1():
    return User(id=3, email='*****@*****.**')
Esempio n. 16
0
def reviewer():
    return User(id=2, email='*****@*****.**')
Esempio n. 17
0
def admin():
    return User(id=1, email='*****@*****.**')
Esempio n. 18
0
def _db(app):
    """Returns session-wide initialised database."""
    db = DEFAULT_DATABASE.db

    # setup databases and tables
    with open(os.path.join(cfg.BASE_DIR, 'docker/db_schema.sql'), 'rb') as f:
        create_schemas_sql = f.read().decode('utf8')

    with app.app_context():
        # clear database
        db.drop_all()
        db.engine.execute('DROP TABLE IF EXISTS alembic_version')

        # build database
        db.engine.execute(create_schemas_sql)
        alembic_upgrade()

        # create data
        vuln_cves = list('CVE-1970-{}'.format(1000 + i) for i in range(10))
        new_cves = list('CVE-1970-{}'.format(2000 + i) for i in range(10))
        cves = vuln_cves + new_cves
        session = db.session

        nvds = []
        for i, cve in enumerate(cves, 1):
            nvds.append(
                Nvd(cve_id=cve,
                    descriptions=[
                        Description(value='Description {}'.format(i), ),
                    ],
                    references=[
                        Reference(
                            link=
                            'https://cve.mitre.org/cgi-bin/cvename.cgi?name={}'
                            .format(cve),
                            source='cve.mitre.org',
                        ),
                    ],
                    published_date=datetime.date.today(),
                    cpes=[
                        Cpe(
                            vendor='Vendor {}'.format(i),
                            product='Product {}'.format(j),
                        ) for j in range(1, 4)
                    ]))
        session.add_all(nvds)

        vulns = []
        for i, cve in enumerate(vuln_cves, 1):
            repo_owner = 'OWNER'
            repo_name = 'REPO{i}'.format(i=i)
            repo_url = 'https://github.com/{owner}/{repo}/'.format(
                owner=repo_owner,
                repo=repo_name,
            )
            commit = '{:07x}'.format(0x1234567 + i)
            vulns.append(
                Vulnerability(
                    cve_id=cve,
                    date_created=datetime.date.today(),
                    comment='Vulnerability {} comment'.format(i),
                    commits=[
                        VulnerabilityGitCommits(
                            commit_link='{repo_url}commit/{commit}'.format(
                                repo_url=repo_url,
                                commit=commit,
                            ),
                            repo_owner=repo_owner,
                            repo_name=repo_name,
                            # repo_url=repo_url,
                            commit_hash=commit)
                    ]))
        vulns.append(
            Vulnerability(
                cve_id='CVE-1970-1500',
                date_created=datetime.date.today(),
                comment='Vulnerability {} comment'.format(len(vuln_cves) + 1),
                commits=[]))
        session.add_all(vulns)

        users = [
            User(
                email='*****@*****.**',
                full_name='Admin McAdmin',
            ),
            User(
                email='*****@*****.**',
                full_name='User McUser',
            )
        ]
        session.add_all(users)

        session.commit()
    return db
Esempio n. 19
0
def admin():
    return User(id=1, login="******")
Esempio n. 20
0
 def user_can_delete(self, user: User):
     return (self.is_creator(user) and self.state in (
         VulnerabilityState.READY,
         VulnerabilityState.NEW,
         VulnerabilityState.NEEDS_IMPROVEMENT,
     ) or user.is_admin() and self.state == VulnerabilityState.ARCHIVED)
Esempio n. 21
0
def reviewer():
    return User(id=2, login="******")
Esempio n. 22
0
def creator1():
    return User(id=3, login="******")
Esempio n. 23
0
def creator2():
    return User(id=4, login="******")
Esempio n. 24
0
def setup_test_database():
    """Returns session-wide initialised database."""

    # Create a temporary flask app for the database setup.
    # We don't use the app or db fixtures here as they should be
    # executed in the function scope, not in the session scope like
    # this function is.
    app = create_app(TEST_CONFIG)
    with app.app_context():
        db: SQLAlchemy = app.extensions["sqlalchemy"].db

        # setup databases and tables
        with open(os.path.join(cfg.BASE_DIR, "docker/db_schema.sql"), "rb") as f:
            create_schemas_sql = f.read().decode("utf8")

        # with app.app_context():
        # clear database
        db.drop_all()
        db.engine.execute("DROP TABLE IF EXISTS alembic_version")

        # build database
        db.engine.execute(create_schemas_sql)
        alembic_upgrade()

        # create data
        session = db.session
        roles = [
            Role(name=role) for role in (PredefinedRoles.ADMIN, PredefinedRoles.USER)
        ]
        session.add_all(roles)
        users = [
            User(
                login="******",
                full_name="Admin McAdmin",
                roles=roles,
                state=UserState.ACTIVE,
                login_type=LoginType.LOCAL,
            ),
            User(
                login="******",
                full_name="User McUser",
                roles=[roles[1]],
                state=UserState.ACTIVE,
                login_type=LoginType.LOCAL,
            ),
            User(
                login="******",
                full_name="Blocked User",
                roles=[roles[1]],
                state=UserState.BLOCKED,
                login_type=LoginType.LOCAL,
            ),
        ]
        session.add_all(users)

        vuln_cves = list("CVE-1970-{}".format(1000 + i) for i in range(10))
        new_cves = list("CVE-1970-{}".format(2000 + i) for i in range(10))
        cves = vuln_cves + new_cves

        nvds = []
        for i, cve in enumerate(cves, 1):
            nvds.append(
                Nvd(
                    cve_id=cve,
                    descriptions=[
                        Description(
                            value="Description {}".format(i),
                        ),
                    ],
                    references=[
                        Reference(
                            link="https://cve.mitre.org/cgi-bin/cvename.cgi?name={}".format(
                                cve
                            ),
                            source="cve.mitre.org",
                        ),
                    ],
                    published_date=datetime.date.today(),
                    cpes=[
                        Cpe(
                            vendor="Vendor {}".format(i),
                            product="Product {}".format(j),
                        )
                        for j in range(1, 4)
                    ],
                )
            )
        session.add_all(nvds)

        vulns = []
        for i, cve in enumerate(vuln_cves, 1):
            repo_owner = "OWNER"
            repo_name = "REPO{i}".format(i=i)
            repo_url = "https://github.com/{owner}/{repo}/".format(
                owner=repo_owner,
                repo=repo_name,
            )
            commit = "{:07x}".format(0x1234567 + i)
            vulns.append(
                Vulnerability(
                    vcdb_id=i,
                    cve_id=cve,
                    date_created=datetime.date.today(),
                    creator=users[1],
                    state=VulnerabilityState.PUBLISHED,
                    version=0,
                    comment="Vulnerability {} comment".format(i),
                    commits=[
                        VulnerabilityGitCommits(
                            commit_link="{repo_url}commit/{commit}".format(
                                repo_url=repo_url,
                                commit=commit,
                            ),
                            repo_owner=repo_owner,
                            repo_name=repo_name,
                            # TODO: test conflicting data?
                            repo_url=repo_url,
                            commit_hash=commit,
                        )
                    ],
                )
            )
        vulns.append(
            Vulnerability(
                state=VulnerabilityState.PUBLISHED,
                version=0,
                vcdb_id=len(vulns) + 1,
                cve_id="CVE-1970-1500",
                date_created=datetime.date.today(),
                comment="Vulnerability {} comment".format(len(vuln_cves) + 1),
                commits=[],
            )
        )
        session.add_all(vulns)

        session.commit()