def _get_unsupported_browser_message(self):
        user_agent = ParseUserAgent(
            self.request.META.get("HTTP_USER_AGENT", ""))

        unsupported_browser = user_agent["family"].lower() not in [
            "firefox",
            "chrome",
        ]

        unsupported_chrome_version = (user_agent["family"].lower() == "chrome"
                                      and int(user_agent["major"]) < 79)

        if unsupported_browser:
            unsupported_browser_message = (
                "Unfortunately your browser is not supported. "
                "Please try again with the latest version of Firefox or Chrome."
            )
        elif unsupported_chrome_version:
            unsupported_browser_message = (
                "Unfortunately your version of Chrome is not supported. "
                "Please update to the latest version and try again.")
        else:
            unsupported_browser_message = None

        return unsupported_browser_message
예제 #2
0
    def process_response(self, request, response):
        """
        Add Content Security Policy policy to the response header. Use either
        enforcement or report-only headers in all currently used variants.
        """
        # choose headers based enforcement mode
        is_ie = False
        if 'HTTP_USER_AGENT' in request.META:
            parsed_ua = ParseUserAgent(request.META['HTTP_USER_AGENT'])
            is_ie = parsed_ua['family'] == 'IE'

        csp_header = 'Content-Security-Policy'
        if is_ie:
            csp_header = 'X-Content-Security-Policy'
        report_only_header = 'Content-Security-Policy-Report-Only'

        # actually add appropriate headers
        if self._csp_mode == 'enforce':
            response[csp_header] = self._csp_string
        elif self._csp_mode == 'report-only':
            response[report_only_header] = self._csp_report_string
        elif self._csp_mode == 'enforce-and-report-only':
            response[csp_header] = self._csp_string
            response[report_only_header] = self._csp_report_string

        return response
예제 #3
0
async def store_click(ctx, *, link_id, ip, ts, user_agent):
    cache_key = f'click-{link_id}-{ip}'
    with await ctx['redis'] as redis:
        v = await redis.incr(cache_key)
        if v > 1:
            return 'recently_clicked'
        await redis.expire(cache_key, 60)

    async with ctx['pg'].acquire() as conn:
        message_id, target = await conn.fetchrow(
            'select message_id, url from links where id=$1', link_id)
        extra = {'target': target, 'ip': ip, 'user_agent': user_agent}
        if user_agent:
            ua_dict = ParseUserAgent(user_agent)
            platform = ua_dict['device']['family']
            if platform in {'Other', None}:
                platform = ua_dict['os']['family']
            extra['user_agent_display'] = ((
                '{user_agent[family]} {user_agent[major]} on '
                '{platform}').format(platform=platform, **ua_dict).strip(' '))

        ts = parse_datetime(ts)
        status = 'click'
        await conn.execute_b(
            'insert into events (:values__names) values :values',
            values=Values(message_id=message_id,
                          status=status,
                          ts=ts,
                          extra=json.dumps(extra)),
        )
예제 #4
0
def create_oc_url(request, context, payload):
    # Feature used wrong - an action is always required
    if 'action' not in payload:
        raise NotFound

    documents = parse_documents(request, context)

    if not documents:
        raise NotFound

    auth_plugin = get_auth_plugin(context)

    if not auth_plugin:
        raise Forbidden

    # Create a JWT for OfficeConnector - contents:
    # action - tells OfficeConnector which code path to take
    # url - tells OfficeConnector where from to fetch further instructions

    payload['url'] = '/'.join((
        api.portal.get().absolute_url(),
        'oc_' + payload['action'],
    ))

    # Create a multi-document payload
    payload['documents'] = []

    for document in documents:
        payload['documents'].append(api.content.get_uuid(document))

    user_id = api.user.get_current().getId()

    token = auth_plugin.create_token(user_id, data=payload)

    # https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/
    # IE11 only allows up to 507 characters for Application Protocols.
    #
    # This is eaten into by both the protocol identifier and the payload.
    #
    # In testing we've discovered for this to be a bit fuzzy and gotten
    # arbitrary and inconsistent results of 506..509.
    #
    # For operational safety we've set the total url + separator + payload
    # limit at 500 or 2000 characters.
    url = 'oc:' + token
    user_agent = ParseUserAgent(request.environ.get('HTTP_USER_AGENT', ''))

    if user_agent['family'] == u'IE' and user_agent['major'] == '11':
        limit = 500
    else:
        limit = 2000

    if len(url) <= limit:
        return url
    else:
        return None
예제 #5
0
파일: worker.py 프로젝트: Ojisama/morpheus
    async def store_click(self, *, target, ip, ts, user_agent, send_method, send_message_id):
        extra = {
            'target': target,
            'ip': ip,
            'user_agent': user_agent,
        }
        if user_agent:
            ua_dict = ParseUserAgent(user_agent)
            platform = ua_dict['device']['family']
            if platform in {'Other', None}:
                platform = ua_dict['os']['family']
            extra['user_agent_display'] = ('{user_agent[family]} {user_agent[major]} on '
                                           '{platform}').format(platform=platform, **ua_dict).strip(' ')

        # TODO process ip and add geo info
        m = ClickInfo(
            ts=ts,
            status='click',
            message_id=send_message_id,
            extra_=extra
        )
        return await self.update_message_status(send_method, m)
예제 #6
0
def browser(ua_string):
    parsed_string = ParseUserAgent(ua_string)
    browser = '{} {}'.format(parsed_string['family'], parsed_string['major'])

    return browser