<commit_before>"""
byceps.blueprints.common.authentication.views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 <NAME>
:License: Modified BSD, see LICENSE for details.
"""

from typing import Optional

from flask import abort, g, request, url_for

from ....config import get_app_mode
from ....services.authentication.exceptions import AuthenticationFailed
from ....services.authentication import service as authentication_service
from ....services.authentication.password import service as password_service
from ....services.authentication.password import (
    reset_service as password_reset_service,
)
from ....services.authentication.session import service as session_service
from ....services.consent import (
    consent_service,
    subject_service as consent_subject_service,
)
from ....services.email import service as email_service
from ....services.email.transfer.models import Sender
from ....services.site import service as site_service
from ....services.user import service as user_service
from ....services.verification_token import (
    service as verification_token_service,
)
from ....services.verification_token.models import Token as VerificationToken
from ....typing import UserID
from ....util.framework.blueprint import create_blueprint
from ....util.framework.flash import flash_error, flash_notice, flash_success
from ....util.framework.templating import templated
from ....util.views import redirect_to, respond_no_content

from ...admin.core.authorization import AdminPermission

from .forms import (
    LoginForm,
    RequestPasswordResetForm,
    ResetPasswordForm,
    UpdatePasswordForm,
)
from . import service, session as user_session


blueprint = create_blueprint('authentication', __name__)


# -------------------------------------------------------------------- #
# log in/out


@blueprint.route('/login')
@templated
def login_form():
    """Show login form."""
    logged_in = g.current_user.is_active
    if logged_in:
        flash_notice(
            f'Du bist bereits als Benutzer "{g.current_user.screen_name}" '
            'angemeldet.'
        )

    in_admin_mode = get_app_mode().is_admin()

    if not _is_login_enabled(in_admin_mode):
        return {
            'login_enabled': False,
        }

    form = LoginForm()
    user_account_creation_enabled = _is_user_account_creation_enabled(
        in_admin_mode
    )

    return {
        'login_enabled': True,
        'logged_in': logged_in,
        'form': form,
        'user_account_creation_enabled': user_account_creation_enabled,
    }


@blueprint.route('/login', methods=['POST'])
@respond_no_content
def login():
    """Allow the user to authenticate with e-mail address and password."""
    if g.current_user.is_active:
        return

    in_admin_mode = get_app_mode().is_admin()

    if not _is_login_enabled(in_admin_mode):
        abort(403, 'Log in to this site is generally disabled.')

    form = LoginForm(request.form)

    screen_name = form.screen_name.data.strip()
    password = form.password.data
    permanent = form.permanent.data
    if not all([screen_name, password]):
        abort(403)

    try:
        user = authentication_service.authenticate(screen_name, password)
    except AuthenticationFailed:
        abort(403)

    if in_admin_mode:
        _require_admin_access_permission(user.id)

    if not in_admin_mode:
        required_consent_subject_ids = _get_required_consent_subject_ids()
        if _is_consent_required(user.id, required_consent_subject_ids):
            verification_token = verification_token_service.create_for_terms_consent(
                user.id
            )

            consent_form_url = url_for(
                'consent.consent_form', token=verification_token.token
            )

            return [('Location', consent_form_url)]

    # Authorization succeeded.

    session_token = session_service.get_session_token(user.id)

    session_service.record_recent_login(user.id)
    service.create_login_event(user.id, request.remote_addr)

    user_session.start(user.id, session_token.token, permanent=permanent)
    flash_success(f'Erfolgreich eingeloggt als {user.screen_name}.')


def _require_admin_access_permission(user_id: UserID) -> None:
    permissions = service.get_permissions_for_user(user_id)
    if AdminPermission.access not in permissions:
        # The user lacks the admin access permission which is required
        # to enter the admin area.
        abort(403)


def _get_required_consent_subject_ids():
    return consent_subject_service.get_subject_ids_required_for_brand(
        g.brand_id
    )


def _is_consent_required(user_id, subject_ids):
    return not consent_service.has_user_consented_to_all_subjects(
        user_id, subject_ids
    )


@blueprint.route('/logout', methods=['POST'])
@respond_no_content
def logout():
    """Log out user by deleting the corresponding cookie."""
    user_session.end()
    flash_success('Erfolgreich ausgeloggt.')


# -------------------------------------------------------------------- #
# password update


@blueprint.route('/password/update')
@templated
def password_update_form(erroneous_form=None):
    """Show a form to update the current user's password."""
    _get_current_user_or_404()
<commit_msg>Move code into function<commit_after>"""
byceps.blueprints.common.authentication.views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 <NAME>
:License: Modified BSD, see LICENSE for details.
"""

from typing import Optional

from flask import abort, g, request, url_for

from ....config import get_app_mode
from ....services.authentication.exceptions import AuthenticationFailed
from ....services.authentication import service as authentication_service
from ....services.authentication.password import service as password_service
from ....services.authentication.password import (
    reset_service as password_reset_service,
)
from ....services.authentication.session import service as session_service
from ....services.consent import (
    consent_service,
    subject_service as consent_subject_service,
)
from ....services.email import service as email_service
from ....services.email.transfer.models import Sender
from ....services.site import service as site_service
from ....services.user import service as user_service
from ....services.verification_token import (
    service as verification_token_service,
)
from ....services.verification_token.models import Token as VerificationToken
from ....typing import UserID
from ....util.framework.blueprint import create_blueprint
from ....util.framework.flash import flash_error, flash_notice, flash_success
from ....util.framework.templating import templated
from ....util.views import redirect_to, respond_no_content

from ...admin.core.authorization import AdminPermission

from .forms import (
    LoginForm,
    RequestPasswordResetForm,
    ResetPasswordForm,
    UpdatePasswordForm,
)
from . import service, session as user_session


blueprint = create_blueprint('authentication', __name__)


# -------------------------------------------------------------------- #
# log in/out


@blueprint.route('/login')
@templated
def login_form():
    """Show login form."""
    logged_in = g.current_user.is_active
    if logged_in:
        flash_notice(
            f'Du bist bereits als Benutzer "{g.current_user.screen_name}" '
            'angemeldet.'
        )

    in_admin_mode = get_app_mode().is_admin()

    if not _is_login_enabled(in_admin_mode):
        return {
            'login_enabled': False,
        }

    form = LoginForm()
    user_account_creation_enabled = _is_user_account_creation_enabled(
        in_admin_mode
    )

    return {
        'login_enabled': True,
        'logged_in': logged_in,
        'form': form,
        'user_account_creation_enabled': user_account_creation_enabled,
    }


@blueprint.route('/login', methods=['POST'])
@respond_no_content
def login():
    """Allow the user to authenticate with e-mail address and password."""
    if g.current_user.is_active:
        return

    in_admin_mode = get_app_mode().is_admin()

    if not _is_login_enabled(in_admin_mode):
        abort(403, 'Log in to this site is generally disabled.')

    form = LoginForm(request.form)

    screen_name = form.screen_name.data.strip()
    password = form.password.data
    permanent = form.permanent.data
    if not all([screen_name, password]):
        abort(403)

    try:
        user = authentication_service.authenticate(screen_name, password)
    except AuthenticationFailed:
        abort(403)

    if in_admin_mode:
        _require_admin_access_permission(user.id)

    if not in_admin_mode:
        if _is_consent_required(user.id):
            verification_token = verification_token_service.create_for_terms_consent(
                user.id
            )

            consent_form_url = url_for(
                'consent.consent_form', token=verification_token.token
            )

            return [('Location', consent_form_url)]

    # Authorization succeeded.

    session_token = session_service.get_session_token(user.id)

    session_service.record_recent_login(user.id)
    service.create_login_event(user.id, request.remote_addr)

    user_session.start(user.id, session_token.token, permanent=permanent)
    flash_success(f'Erfolgreich eingeloggt als {user.screen_name}.')


def _require_admin_access_permission(user_id: UserID) -> None:
    permissions = service.get_permissions_for_user(user_id)
    if AdminPermission.access not in permissions:
        # The user lacks the admin access permission which is required
        # to enter the admin area.
        abort(403)


def _is_consent_required(user_id):
    required_subject_ids = consent_subject_service.get_subject_ids_required_for_brand(
        g.brand_id
    )

    return not consent_service.has_user_consented_to_all_subjects(
        user_id, required_subject_ids
    )


@blueprint.route('/logout', methods=['POST'])
@respond_no_content
def logout():
    """Log out user by deleting the corresponding cookie."""
    user_session.end()
    flash_success('Erfolgreich ausgeloggt.')


# -------------------------------------------------------------------- #
# password update


@blueprint.route('/password/update')
@templated
def password_update_form(erroneous_form=None):
    """Show a form to update the current user's password."""
    _get_current_user_or_404()

{'fraction_non_alphanumeric': 0.12347926046556183, 'fraction_numerical': 0.004406552351757831, 'mean_word_length': 3.231860559383867, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1880794', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2921, 'n_words': 679}