コード例 #1
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_imprint():
    HTML.write(mylib.path_out(),
               '''
<h2>Imprint / Impressum</h2>
<p>
  <strong>Lehrstuhl für Privatsphäre und Sicherheit in Informationssystemen (PSI)</strong><br>
  Otto-Friedrich Universität Bamberg<br>
  Kapuzinerstr. 16<br>
  96047 Bamberg<br>
  Germany
</p>
<p>Tel.: +49 951 863-2661</p>

<h3>Inhaltliche Verantwortlichkeit i.S.v. § 5 TMG und § 55 Abs. 2 RStV</h3>
<p>Für die Richtigkeit und Aktualität der Inhalte sind die jeweiligen Erstellerinnen und Ersteller der einzelnen Seiten verantwortlich.</p>
<p>
  Otto-Friedrich Universität Bamberg<br>
  Lehrstuhl für Privatsphäre und Sicherheit in Informationssystemen (PSI)<br>
  Prof. Dr. Dominik Herrmann<br>
  An der Weberei 5<br>
  96047 Bamberg<br>
  Deutschland<br>
  Tel.: +49 951 863-2661<br>
  E-Mail: <a href="mailto:[email protected]">[email protected]</a>
</p>

<h3>Technische Verantwortlichkeit</h3>
<p>
  <strong>Webmaster/in:</strong><br>
  Prof. Dr. Dominik Herrmann<br>
  Tel.: +49 951 863-2661<br>
  E-Mail: <a href="mailto:[email protected]">[email protected]</a>
</p>''',
               fname='imprint.html')
コード例 #2
0
def write_overview_page(base_dir, category_tuples, title):
    cluster = {}
    for x in category_tuples:
        i = int(int(x[0]) / 1000)
        try:
            cluster[i].append(x)
        except KeyError:
            cluster[i] = [x]
    src = HTML.h2_path_n_rank(title, [], 'compare/', 'Compare')
    src += '<div id="categories">'
    for i, arr in sorted(cluster.items()):
        mylib.sort_by_name(arr, 1)
        kind = 'Apps' if i == 6 else 'Games' if i == 7 else 'Other'
        src += '<h3 class="center">{}</h3>'.format(kind)
        src += '<div class="tags large center">'
        src += ''.join([HTML.a_category(*x) for x in arr]) + '</div>'
    HTML.write(base_dir, src + '</div>', title)

    # make groupby compare html
    base_dir = mylib.path_add(base_dir, 'compare')
    html_group_compare.write_groupby_multi(base_dir,
                                           [('/category', 'All Categories')],
                                           'Compare', 'Categories',
                                           [('category-6', 'Category: Apps'),
                                            ('category-7', 'Category: Games')])
コード例 #3
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_results(base_dir, c_apps, c_domains, title):
    [c_recs, c_logs] = index_rank.get_total_counts()
    print('    {} apps'.format(c_apps))
    print('    {} domains'.format(c_domains))
    print('    {} recordings'.format(c_recs))
    print('    {} logs'.format(c_logs))
    HTML.write(base_dir,
               '''
<h2>{}</h2>
<p>The appchk database currently contains <b>{:,}&nbsp;apps</b> with a total of <b>{:,} unique domains</b>.</p>
<p>Collected through <b>{:,}&nbsp;recordings</b> with <b>{:,} individual requests</b>.</p>
<ul>
  <li>List of <a href="/index/apps/">Apps</a></li>
  <li>List of <a href="/category/">Categories</a></li>
  <li>List of <a href="/index/domains/all/">All Domains</a>, 
  only <a href="/index/domains/tracker/">Trackers</a>,
  or <a href="/index/domains/highly-used/">Highly-used Domains</a> <br>which appear in at least 5 apps but are not considered tracker <i>yet</i>.</li>
</ul>
<ul>
  <li>Compare <a href="/lists/">App Lists</a></li>
  <li>Compare <a href="/compare/">Group Lists</a></li>
</ul>
'''.format(title, c_apps, c_domains, c_recs, c_logs),
               title=title)
    mylib.symlink(index_rank.fname_app_rank(),
                  mylib.path_add(base_dir, 'rank.json'))  # after HTML.write
コード例 #4
0
def write_groupby_multi(base_dir, h2_paths, h2_title, page_title, groups_arr):
    mylib.mkdir(base_dir)
    src = '<h2>{}</h2>'.format(HTML.a_path(h2_paths, h2_title))
    for gid, name in groups_arr:
        raw_name = gid if len(groups_arr) > 1 else 'data'
        src += f'\n<h3>{name}</h3>'
        src += gen_and_link_groupby(gid, base_dir, raw_name)
    HTML.write(base_dir, src, title='Compare: ' + page_title)
コード例 #5
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_redirect():
    HTML.write(mylib.path_out(),
               '''
<h2>Redirecting …</h2>
<script type="text/javascript">
  var GET={};
  window.location.search.substr(1).split("&").forEach(function(x){GET[x.split("=")[0]]=x.split("=")[1]});
  if (GET["id"]) { window.location = "/app/" + GET["id"] + "/"; }
</script>''',
               fname='redirect.html')
コード例 #6
0
ファイル: html_ranking.py プロジェクト: ubapsi/appchk-web
def write_ranking_custom_lists(base_dir, list_id, list_name, parent_title):
    base = mylib.path_add(base_dir, list_id)
    src = html_h2_path([('/results/', 'Results'), ('/lists/', parent_title)],
                       list_name)
    src += html_table()
    src += HTML.p_download_json('data.json',
                                'raw-list-{}.json'.format(list_id))
    src += html_script_chunk('data.json', 9, 1)  # tracker percent asc
    HTML.write(base, src, title='Compare: ' + list_name)
    mylib.symlink(index_rank.fname_rank_list('custom', list_id),
                  mylib.path_add(base, 'data.json'))
コード例 #7
0
ファイル: html_ranking.py プロジェクト: ubapsi/appchk-web
def write_ranking_all(title, base_dir):
    # full urls since app index can have page 2, 3, etc.
    src = html_h2_path([('/results/', 'Results'),
                        ('/index/apps/', 'Apps (A–Z)')])
    src += html_default_description()
    src += html_table()
    src += HTML.p_download_json('data.json', 'raw-apps.json')
    src += html_script_chunk('data.json', 12, -1)  # last update desc
    HTML.write(base_dir, src, title=title)
    mylib.symlink(index_rank.fname_ranking_all(),
                  mylib.path_add(base_dir, 'data.json'))
コード例 #8
0
ファイル: html_ranking.py プロジェクト: ubapsi/appchk-web
def write_ranking_category(cid, category_name):
    base = mylib.path_out('category', cid, 'ranking')
    # full urls since categories can have page 2, 3, etc.
    src = html_h2_path([('/category/', 'All Categories'),
                        ('/category/{}/'.format(cid), category_name)])
    src += html_default_description()
    src += html_table()
    src += HTML.p_download_json('data.json',
                                'raw-category-{}.json'.format(cid))
    src += html_script_chunk('data.json', 12, -1)  # last update desc
    HTML.write(base, src, title='Category Ranking: ' + category_name)
    mylib.symlink(index_rank.fname_rank_list('category', cid),
                  mylib.path_add(base, 'data.json'))
コード例 #9
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_appprivacy():
    HTML.write(mylib.path_out(),
               '''
<h2>Datenschutzerklärung (App)</h2>
<p>Die appchk app verarbeitet potentiell personenbeziehbare Daten.</p>
<p class="squeeze">
  Im Nachfolgenden werden diese Daten gelistet, die von der App erhoben und verarbeitet werden.
  Dies beinhaltet die Domainnamen der angesurften Webseiten bzw. von anderen Apps kontaktierte Domains, sowie das Datum und die Uhrzeit der Anfrage.
  Sofern ein App-Recording gestartet wird, wird außerdem die aktuelle Version des iOS Betriebssystems gespeichert.
  Andere als die genannten Daten werden nicht erhoben.
  Weiterhin werden diese Daten nur erhoben, solange der (lokale) VPN-Service aktiv ist.
  Wenn dieser Service inaktiv ist, werden keine Daten erhoben.
</p>
<p class="squeeze">
  Im Gegensatz zu einem konventionellen VPN Provider, verbindet sich dieser VPN-Service <strong>nicht</strong> zu einem anderen Server.
  Alle Daten werden ausschließlich auf dem eigenen Endgerät erfassten und gespeichert.
  Das heißt, diese Daten verlassen das eigene Gerät nicht und können demnach auch nicht von uns ausgewertet werden.
</p>
<p class="squeeze">
  Diese Daten werden nur an unsere Server (appchk.de) übermittelt, sofern der Nutzer / die Nutzerin der Übermittlung explizit zustimmt.
  Nutzer:innen haben weiterhin die Möglichkeit die erfassten Daten vor dem Upload zu filtern.
  Beim Übermitteln der Daten erhält der Server einen Zeitstempel der Anfrage.
  Andere Attribute wie Browsertyp, IP-Adresse, etc. werden, wie bei der Webseite, nicht ausgewertet oder gespeichert.
</p>
<p>Bei offenen Fragen wenden Sie sich bitte an <a href="mailto:[email protected]">[email protected]</a>.</p>

<h2>Privacy Policy (App)</h2>
<p>The appchk app collects potentially personally identifiable information.</p>
<p class="squeeze">
  The following section contains a list of the collected and processed data.
  This data includes the domain names of websites the user or another app contacted, as well as the date and time of the query.
  If the user starts an app-recording, the app will also store the current iOS version.
  Other than the listed data is not collected.
  Further, this data is only collected as long as the (local) VPN-service is active.
  As soon as this service is deactivated, no more data is collected.
</p>
<p class="squeeze">
  Contrary to conventional VPN providers, this VPN-service does <strong>not</strong> connect to another server.
  All collected data is processed and stored solely on the users end-device.
  This means that this data never leaves a user’s device and can therefore not be evaluated by us.
</p>
<p class="squeeze">
  This data is transmitted to our servers (appchk.de) only in the case if the user explicitly chooses to submit the data.
  Furthermore, users have the option to filter the data prior to upload.
  If the data is submitted, the server will also receive a timestamp of the upload.
  Other attributes like browser type, IP-address, etc. are, similarly to the website, not evaluated nor stored, similar.
</p>
<p>If you have further questions write an email to <a href="mailto:[email protected]">[email protected]</a>.</p>
''',
               fname='app-privacy.html')
コード例 #10
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_help():
    many = 7
    txt = '''<h2>Help needed!</h2>
<div class="squeeze"><p>
    With the release of iOS 14 some <a href="https://www.apple.com/ios/ios-14/features/#Privacy" target="_blank">Privacy</a> features are put into the spotlight.
    One of these features is making transparent how your data is being used for tracking purposes.
    Developers are now required to self-report their privacy practices.
  </p><p>
    We have selected a random sample of applications for evaluation and want to check whether the app behaviour changes over time.
    This study consists of two stages; this is the second.
    In the first stage we recorded the app communications before iOS 14 was released.
    In the second stage we repeat the process after the launch of iOS 14.
  </p><p>
    You can help us by providing app recordings of the following applications.
    Make sure to update to the lastest appchk version (v.34) which includes a check for the iOS version.
    Get the <a href="https://testflight.apple.com/join/9jjaFeHO" target="_blank">Testflight beta</a>.
  </p>
</div>
<div id="help-links">'''

    def app(bundle_id, name, appstore_id):
        iurl = 'https://apps.apple.com/de/app/id{}'.format(appstore_id)
        aref = '<a href="{}" target="_blank">AppStore</a>'.format(iurl)
        return '{} <span class="snd">Download from {}</span>'.format(
            HTML.a_app(bid, name), aref)

    def rec(count):
        return '<span class="{}"><b>{}</b>/{}</span> recordings'.format(
            'done' if count >= many else 'notyet', count, many)

    obj = mylib.json_read(mylib.path_root('src', 'help.json'))
    for land in sorted(obj.keys()):
        txt += '\n<h3>{}:</h3>\n<table class="alternate">'.format(land)
        txt += HTML.tr(['', 'App Name', 'pre iOS 14', 'post iOS 14'], 'th')
        for i, x in enumerate(obj[land]):
            bid = x[2]
            c = [0, 0]
            for fname, json in mylib.enum_jsons(bid):
                try:
                    ios14 = int(json['ios'].split('.')[0]) >= 14
                except KeyError:
                    # assume everything submitted after release date is iOS14
                    ios14 = os.path.getmtime(fname) > 1600258000
                c[1 if ios14 else 0] += 1
            txt += HTML.tr([i + 1, app(bid, x[0], x[1]), rec(c[0]), rec(c[1])])
        txt += '</table>'
    txt += '</div>'
    HTML.write(mylib.path_out('help'), txt)
コード例 #11
0
def gen_page(bundle_id, obj):

    name = index_app_names.get_name(bundle_id)
    gernes = index_categories.get_categories(bundle_id)
    obj['tracker'] = list(filter(lambda x: x[2], obj['subdom']))

    HTML.write(mylib.path_out_app(bundle_id), f'''
<h2 class="title">{name}</h2>
<p class="subtitle snd"><i class="mg_lr">Bundle-id:</i>{ bundle_id }</p>
<div id="meta">
  <div class="icons">
    { Graph.pie_chart_tracker(obj['tracker_percent']) }
    <img class="app-icon" src="icon.png" alt="app-icon" width="100" height="100">
  </div>
  <table>
    <tr><td>App Categories:</td><td>{
      ', '.join([HTML.a_category(i, name) for i, name in gernes])
    }</td></tr>
    <tr><td>Last Update:</td><td>{HTML.date_utc(obj['last_date'])}</td></tr>
  </table>
</div>
<div id="stats">
  { stat(1, 'Number of recordings:', 'sum_rec', obj['sum_rec']) }
  { stat(1, 'Average recording time:', 'avg_time', HTML.seconds_to_time(obj['avg_time'])) }
  { stat(2, 'Cumulative recording time:', 'sum_time', HTML.seconds_to_time(obj['sum_time'])) }
  { stat(1, 'Average number of requests:', 'avg_logs_pm', HTML.fmt_round_num(obj['avg_logs']), HTML.fmt_as_pm(obj['avg_logs_pm'])) }
  { stat(2, 'Total number of requests:', 'sum_logs_pm', str(obj['sum_logs']), HTML.fmt_as_pm(obj['sum_logs_pm'])) }
  { stat(1, 'Number of domains:', 'pardom', len(obj['pardom'])) }
  { stat(2, 'Number of subdomains:', 'subdom', len(obj['subdom'])) }
  { stat(3, 'Tracker percentage:', 'tracker_percent', HTML.fmt_as_percent(obj['tracker_percent'])) }
</div>
<h3>Connections</h3>
<div>
  <h4>Potential Trackers ({ len(obj['tracker']) }):</h4>
  { gen_dom_tags(obj['tracker'], HTML.a_subdomain, onlyTrackers=True) }
  <h4>Domains ({ len(obj['pardom']) }):</h4>
  { gen_dotgraph(obj['pardom']) }
  { gen_dom_tags(obj['pardom'], HTML.a_domain) }
  <h4>Subdomains ({ len(obj['subdom']) }):</h4>
  { gen_dotgraph(obj['subdom']) }
  { gen_dom_tags(obj['subdom'], HTML.a_subdomain) }
</div>
{ HTML.p_download_json('data.json', bundle_id + '.json') }
<script type="text/javascript" src="/static/lookup-rank.js"></script>
<script type="text/javascript">
  lookup_rank_js('/results/rank.json', '{bundle_id}');
</script>''', title=name)
コード例 #12
0
def gen_lookup(html_dir, doms_dict, flag, title):
    HTML.write(html_dir, f'''
<h2>{ HTML.a_path([('/index/domains/all/', 'All Domains')],
                  '<span id="name"></span>') }</h2>
<p>Known Tracker: <b id="known">?</b></p>
<p>Present in: <b id="num-apps">… applications</b></p>
{ '<h3>Subdomains:</h3><div id="subdoms" class="tags"></div>' if flag else '' }
<h3>Apps containing this domain:</h3>
<div id="app-toc" class="no-ul-all">
  { HTML.app_tile_template() }
</div>
<script type="text/javascript" src="/static/lookup-domain.js?2"></script>
<script type="text/javascript" src="/static/lozad.js"></script>
<script type="text/javascript">
  lookup_domain_js('doms.json', '/results/lookup-apps.json', '/results/subdoms.json');
</script>
''', title=title)
    mylib.json_write(mylib.path_add(html_dir, 'doms.json'), doms_dict)
コード例 #13
0
def gen_html_top_10(path, subset, total, title):
    src = ''
    for dom, count in subset:
        src += '\n<div>{} {}</div>'.format(
            div_dom(HTML.a_domain, dom, count), Graph.fill_bar(count / total))

    HTML.write(path, f'''
<h2 class="center">{ title }</h2>
<div class="div-center">
  <div id="dom-top10" class="found-in">
    { src }
  </div>
  <p class="mg_top">Get full list sorted by
    <a class="snd" href="by_count.html">Occurrence frequency</a> or in
    <a class="snd" href="by_name.html">Alphabetical order</a>.
  </p>
</div>
{ HTML.p_download_json('data.json', 'domains.json') }
''', title=title)
コード例 #14
0
ファイル: html_ranking.py プロジェクト: ubapsi/appchk-web
def process():
    print('generating html: ranking ...')
    print('  overall ranking')
    write_ranking_all('Ranking', mylib.path_out('index', 'apps', 'ranking'))

    print('  category ranking')
    for _, json in mylib.enum_categories():
        cid, name = json['meta']
        write_ranking_category(cid, name)

    print('  custom lists')
    base_custom = mylib.path_out('lists')
    title_custom = 'Lists'
    arr = []
    for list_id, json in mylib.enum_custom_lists('list_'):
        list_name = json['name']
        try:
            desc = json['desc']
        except KeyError:
            desc = None
        arr.append((list_id, list_name, len(json['apps']), desc))
        write_ranking_custom_lists(base_custom,
                                   list_id,
                                   list_name,
                                   parent_title=title_custom)

    print('    index page')
    mylib.sort_by_name(arr, 1)
    src = html_h2_path([('/results/', 'Results')], title_custom)
    src += '''
<p class="squeeze">
  App lists compare individual applications against each other.
  These curated lists group together, at least in some aspect, similar applications.
  This could be all instant messengers, health related apps, or apps from a common developer or country.
</p>
<div class="found-in">'''
    for x in arr:
        src += HTML.h4_a_title_sub_desc(x[0], x[1], f'contains {x[2]} apps',
                                        x[3])
    HTML.write(base_custom, src + '</div>', title=title_custom)
    print('')
コード例 #15
0
def process():
    print('generating html: group compare ...')
    print('  lists')
    base_custom = mylib.path_out('compare')
    title_custom = 'Compare'
    arr = []
    for list_id, json in mylib.enum_custom_lists('groupby_'):
        try:
            if json['hidden']:
                continue
        except KeyError:
            pass
        list_name = json['name']
        print('    ' + list_name)
        grp_count = len(json['groups'])
        app_count = sum([len(x['apps']) for x in json['groups']])
        try:
            desc = json['desc']
        except KeyError:
            desc = None
        arr.append((list_id, list_name, grp_count, app_count, desc))
        write_groupby_single(base_custom, list_id, list_name, title_custom)

    print('  index page')
    mylib.sort_by_name(arr, 1)
    src = f'''
<h2>{HTML.a_path([('/results/', 'Results')], title_custom)}</h2>
<p class="squeeze">
  Comparison groups do not compare a single application against another.
  Instead comparison groups cluster multiple applications into a single, logical group.
  For example, paid-vs-free apps could be a comparison group.
</p>
<div>'''
    for x in arr:
        src += HTML.h4_a_title_sub_desc(x[0], x[1],
                                        f'has {x[2]} groups with {x[3]} apps',
                                        x[4])
    HTML.write(base_custom, src + '</div>', title=title_custom)
    print('')
コード例 #16
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_privacy():
    HTML.write(mylib.path_out(),
               '''
<h2>Datenschutzerklärung (Webseite)</h2>
<p>Auf dieser Webseite werden keine personenbezogenen Daten erhoben.</p>
<p class="squeeze">
  Einige Daten werden jedoch technisch bedingt automatisch erfasst.
  Diese Daten werden von Ihrem Browser automatisch gesendet und beinhalten Browsertyp und -version, die Referrer-URL, Ihre IP-Adresse sowie Datum und Uhrzeit der Anfrage.
  Diese Daten werden explizit weder ausgewertet noch gespeichert.
</p>
<p>Bei offenen Fragen wenden Sie sich bitte an <a href="mailto:[email protected]">[email protected]</a>.</p>

<h2>Privacy Policy (Website)</h2>
<p>This website does not collect any personally identifiable information.</p>
<p class="squeeze">
  Some data is collected automatically by our IT systems when you visit the website.
  This technical data is sent automatically by your browser and includes the browser type and version, a referrer URL, your IP address, and date and time when you accessed the page.
  This data is explicitly neither evaluated nor stored.
</p>
<p>If you have further questions write an email to <a href="mailto:[email protected]">[email protected]</a>.</p>
''',
               fname='privacy.html')
コード例 #17
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_root():
    with open(mylib.path_root('templates', 'root.html'), 'r') as fp:
        HTML.write(mylib.path_out(), fp.read())
コード例 #18
0
 def write_index(fname, title, button):
     HTML.write(idx_dir, '<h2>{}</h2>{}{}'.format(
         HTML.a_path([('/results/', 'Results')], title),
         dropdown_choose(button), duo_list(list1, list2)
     ), title=title, fname=fname)
コード例 #19
0
ファイル: html_root.py プロジェクト: ubapsi/appchk-web
def gen_404():
    HTML.write(mylib.path_out(),
               '''
<h2>404 – Not Found</h2>
<p>Go back to <a href="/">start page</a></p>''',
               fname='404.html')