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
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
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)), )
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
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)
def browser(ua_string): parsed_string = ParseUserAgent(ua_string) browser = '{} {}'.format(parsed_string['family'], parsed_string['major']) return browser