<commit_before>"""
Decorators that can be used to interact with third_party_auth.
"""
from functools import wraps
from urlparse import urlparse, urlunparse

from django.conf import settings
from django.utils.decorators import available_attrs

from third_party_auth.models import SAMLProviderData
from third_party_auth.models import LTIProviderConfig
from six.moves.urllib.parse import urlencode, urlparse


def allow_frame_from_whitelisted_url(view_func):  # pylint: disable=invalid-name
    """
    Modifies a view function so that it can be rendered in a frame or iframe
    if parent url is whitelisted and request HTTP referrer is matches one of SAML providers's sso url.
    """

    def wrapped_view(request, *args, **kwargs):
        """ Modify the response with the correct X-Frame-Options and . """
        resp = view_func(request, *args, **kwargs)
        x_frame_option = 'DENY'
        content_security_policy = "frame-ancestors 'none'"

        if settings.FEATURES['ENABLE_THIRD_PARTY_AUTH']:
            referer = request.META.get('HTTP_REFERER')
            if referer is not None:
                parsed_url = urlparse(referer)
                # reconstruct a referer url without querystring and trailing slash
                referer_url = urlunparse(
                    (parsed_url.scheme, parsed_url.netloc, parsed_url.path.rstrip('/'), '', '', '')
                )
                sso_urls = SAMLProviderData.objects.values_list('sso_url', flat=True)
                sso_urls = [url.rstrip('/') for url in sso_urls]
                if referer_url in sso_urls:
                    allowed_urls = ' '.join(settings.THIRD_PARTY_AUTH_FRAME_ALLOWED_FROM_URL)
                    x_frame_option = 'ALLOW-FROM {}'.format(allowed_urls)
                    content_security_policy = "frame-ancestors {}".format(allowed_urls)
        resp['X-Frame-Options'] = x_frame_option
        resp['Content-Security-Policy'] = content_security_policy
        return resp
    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)


def xframe_allow_whitelisted(view_func):
    """<commit_msg>MCKIN-28814 Include internally whitelisted urls for sso registration inside a frame (#2046)<commit_after>"""
Decorators that can be used to interact with third_party_auth.
"""
from functools import wraps
from urlparse import urlparse, urlunparse

from django.conf import settings
from django.utils.decorators import available_attrs

from third_party_auth.models import SAMLProviderData
from third_party_auth.models import LTIProviderConfig
from edx_solutions_organizations.models import WhitelistedUrls
from six.moves.urllib.parse import urlencode, urlparse


def allow_frame_from_whitelisted_url(view_func):  # pylint: disable=invalid-name
    """
    Modifies a view function so that it can be rendered in a frame or iframe
    if parent url is whitelisted and request HTTP referrer is matches one of SAML providers's sso url.
    """

    def wrapped_view(request, *args, **kwargs):
        """ Modify the response with the correct X-Frame-Options and . """
        resp = view_func(request, *args, **kwargs)
        x_frame_option = 'DENY'
        content_security_policy = "frame-ancestors 'none'"

        if settings.FEATURES['ENABLE_THIRD_PARTY_AUTH']:
            referer = request.META.get('HTTP_REFERER')
            if referer is not None:
                parsed_url = urlparse(referer)
                # reconstruct a referer url without querystring and trailing slash
                referer_url = urlunparse(
                    (parsed_url.scheme, parsed_url.netloc, parsed_url.path.rstrip('/'), '', '', '')
                )
                sso_urls = SAMLProviderData.objects.values_list('sso_url', flat=True)
                sso_urls = [url.rstrip('/') for url in sso_urls]
                if referer_url in sso_urls:
                    internal_allowed_urls = [url.url for url in WhitelistedUrls.objects.all()]
                    allowed_urls = ' '.join(settings.THIRD_PARTY_AUTH_FRAME_ALLOWED_FROM_URL + internal_allowed_urls)
                    x_frame_option = 'ALLOW-FROM {}'.format(allowed_urls)
                    content_security_policy = "frame-ancestors {}".format(allowed_urls)
        resp['X-Frame-Options'] = x_frame_option
        resp['Content-Security-Policy'] = content_security_policy
        return resp
    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)


def xframe_allow_whitelisted(view_func):
    """
{'fraction_non_alphanumeric': 0.085040071237756, 'fraction_numerical': 0.002003561887800534, 'mean_word_length': 3.018783542039356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '247027', 'n_tokens_mistral': 1342, 'n_tokens_neox': 1302, 'n_words': 330}