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)
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
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)
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
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)
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
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
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'})
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)
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)
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)
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')
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")
def creator2(): return User(id=4, email='*****@*****.**')
def creator1(): return User(id=3, email='*****@*****.**')
def reviewer(): return User(id=2, email='*****@*****.**')
def admin(): return User(id=1, email='*****@*****.**')
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
def admin(): return User(id=1, login="******")
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)
def reviewer(): return User(id=2, login="******")
def creator1(): return User(id=3, login="******")
def creator2(): return User(id=4, login="******")
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()