tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

fledge-bidding-logic.py (3860B)


      1 # These functions are used by FLEDGE to determine the logic for the ad buyer.
      2 # For our testing purposes, we only need the minimal amount of boilerplate
      3 # code in place to allow them to be invoked properly and move the FLEDGE
      4 # process along. The tests generally do usually not deal with reporting results,
      5 # so we leave `reportWin` empty unless we need to call registerAdBeacon(). See
      6 # `generateURNFromFledge` in "utils.js" to see how this file is used.
      7 
      8 from wptserve.utils import isomorphic_decode
      9 
     10 def main(request, response):
     11  # Set up response headers.
     12  headers = [
     13    ('Content-Type', 'Application/Javascript'),
     14    ('Ad-Auction-Allowed', 'true')
     15  ]
     16 
     17  # Parse URL params.
     18  requested_size = request.GET.first(b"requested-size", None)
     19  ad_with_size = request.GET.first(b"ad-with-size", None)
     20  beacon = request.GET.first(b"beacon", None)
     21 
     22  # Use URL params to modify Javascript.
     23  requested_size_check = ''
     24  if requested_size is not None:
     25    # request.GET stores URL keys and values in iso-8859-1 binary encoding. We
     26    # have to decode the values back to a string to parse width/height. Don't
     27    # bother sanitizing the size, because it is sanitized before auction logic
     28    # runs already.
     29    width, height = isomorphic_decode(requested_size).split('-')
     30 
     31    requested_size_check = (
     32      f'''
     33        if (!(browserSignals.requestedSize.width === '{width}') &&
     34             (browserSignals.requestedSize.height === '{height}')) {{
     35          throw new Error('requestedSize missing/incorrect in browserSignals');
     36        }}
     37      '''
     38    )
     39 
     40  render_obj = 'ad.renderURL'
     41  if ad_with_size is not None:
     42    render_obj = '{ url: ad.renderURL, width: "100px", height: "50px" }'
     43 
     44  component_render_obj = 'component.renderURL'
     45  if ad_with_size is not None:
     46    component_render_obj = (
     47      '''{
     48          url: component.renderURL,
     49          width: "100px",
     50          height: "50px"
     51         }
     52      '''
     53    )
     54 
     55  register_ad_beacon = ''
     56  if beacon is not None:
     57    register_ad_beacon = (
     58    '''registerAdBeacon({
     59        'reserved.top_navigation_start':
     60        browserSignals.interestGroupOwner +
     61        '/fenced-frame/resources/beacon-store.py?type=reserved.top_navigation_start',
     62        'reserved.top_navigation_commit':
     63        browserSignals.interestGroupOwner +
     64        '/fenced-frame/resources/beacon-store.py?type=reserved.top_navigation_commit',
     65        'click':
     66        browserSignals.interestGroupOwner +
     67        '/fenced-frame/resources/beacon-store.py?type=click',
     68      });
     69    '''
     70  )
     71 
     72  # Generate Javascript.
     73  # Note: Python fstrings use double-brackets ( {{, }} ) to insert bracket
     74  # literals instead of substitution sequences.
     75  generate_bid = (
     76    f'''function generateBid(
     77      interestGroup,
     78      auctionSignals,
     79      perBuyerSignals,
     80      trustedBiddingSignals,
     81      browserSignals) {{
     82        {requested_size_check}
     83        const ad = interestGroup.ads[0];
     84 
     85        // `auctionSignals` controls whether or not component auctions are
     86        // allowed.
     87        let allowComponentAuction = (typeof auctionSignals === 'string' &&
     88          auctionSignals.includes('bidderAllowsComponentAuction'));
     89 
     90        let result = {{
     91          'ad': ad,
     92          'bid': 1,
     93          'render': {render_obj},
     94          'allowComponentAuction': allowComponentAuction
     95        }};
     96        if (interestGroup.adComponents && interestGroup.adComponents.length > 0)
     97          result.adComponents = interestGroup.adComponents.map((component) => {{
     98            return {component_render_obj};
     99          }});
    100        return result;
    101      }}
    102    '''
    103  )
    104 
    105  report_win = (
    106    f'''function reportWin(
    107      auctionSignals,
    108      perBuyerSignals,
    109      sellerSignals,
    110      browserSignals) {{
    111        {register_ad_beacon}
    112        return;
    113      }}
    114    '''
    115  )
    116 
    117  content = f'{generate_bid}\n{report_win}'
    118 
    119  return (headers, content)