From 379e3713e98f38a5b03e1d6fc1538c628cd63d9b 2014-01-18 14:49:03 From: Branko Majic Date: 2014-01-18 14:49:03 Subject: [PATCH] DJPYD-2: Added API reference. Updated Sphinx configuration file in order to allow building of API reference. Wrote a section covering privacy. Wrote section covering application usage. --- diff --git a/docs/apireference.rst b/docs/apireference.rst new file mode 100644 index 0000000000000000000000000000000000000000..12f016c5e5fa17577c70af8d771dcdb02c80fd9f --- /dev/null +++ b/docs/apireference.rst @@ -0,0 +1,19 @@ +API Reference +============= + +Views +----- + +This section lists documentation for all views available in Django Pydenticon. + +.. automodule:: django_pydenticon.views + :members: + +URL +--- + +This section lists documentation for all URL-related functions available in +Django Pydenticon. + +.. automodule:: django_pydenticon.urls + :members: diff --git a/docs/conf.py b/docs/conf.py index 0dbeea539532e28664ab91740d3fe8e39d4e9000..9eaf3742b03a4ffa4d7b4cfdb346cd00bc73c824 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,6 +17,12 @@ import sys, os # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath('../testproject/')) + +# Set up the Django settings/environment +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings") +from django.conf import settings # -- General configuration ----------------------------------------------------- @@ -25,7 +31,7 @@ import sys, os # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/privacy.rst b/docs/privacy.rst new file mode 100644 index 0000000000000000000000000000000000000000..b08cfa68e4078a5336ea9ab0a90b32d1760ead72 --- /dev/null +++ b/docs/privacy.rst @@ -0,0 +1,55 @@ +.. _privacy: + +Privacy +======= + +Generating identicons thorugh Django Pydenticon using raw user data may have +undesirable consequences on privacy if the data used is meant to be ketp as +a secret. + +This privacy issue can in particular arise if using data like usernames, +e-mails, or real names of users for generating avatars in publicly-accessible +websites. + +As a rule-of-thumb, you should **never**, **ever** pass such data raw into the +identicon URL. This approach would leak the confidential information in plain +text to any interested parties. Instead, calculate a digest of the raw data, and +pass the hex digest as part of the URL instead. + +.. note:: + In some cases you may opt to pass raw data. For example, if usernames are + visible as part of posted comments, they're probably already scrapeable, and + having them as part of identicon URL won't hide them anyway. + +Additionally, the default digest algorithm (*MD5*) may not be safe enough for +such data. Even in case where a stronger digest algorithm is used, an attacker +might attempt to generate `rainbow tables +`_, and scrape the web pages +hashed data contained within identicon URLs. + +There's two feasible approaches to resolve this: + +* Always apply *salt* to user-identifiable data before calculating a hex + digest. This can hugely reduce the efficiency of brute force attacks based on + rainbow tables (although it will not mitigate it completely). +* Instead of hashing the user-identifiable data itself, every time you need to + do so, create some random data instead, hash that random data, and store it + for future use (cache it), linking it to the original data that it was + generated for. This way the hex digest being put as part of an image link into + HTML pages is not derived in any way from the original data, and can therefore + not be used to reveal what the original data was. + +Keep in mind that using identicons will inevitably still allow people to track +someone's posts across your website. Identicons will effectively automatically +create pseudonyms for people posting on your website. If that may pose a +problem, it might be better not to use identicons at all. + +Finally, small summary of the points explained above: + +* Always use hex digests in identicon URLs. +* Instead of using privately identifiable data for generating the hex digest, + use randmoly generated data, and associate it with privately identifiable + data. This way hex digest cannot be traced back to the original data through + brute force or rainbow tables. +* If unwilling to generate and store random data, at least make sure to use + salt when hashing privately identifiable data. diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000000000000000000000000000000000000..4e373d433ecbb38cc8d5ac2a9a7b060e87addd15 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,151 @@ +.. _usage: + +Usage +===== + +Django Pydenticon is targeted at developers who wish to integrate an identicon +service in their Django projects. This chapter covers details on how an +identicon image is served, and how to integrate Django Pydenticon with other +applications. + +Requesting identicons +--------------------- + +Identicon images are served through specially formatted URL. Whenever such URL +is submitted to Django Pydenticon application, an identicon image is created on +the fly. + +The format of URL is ``/image/USER_DATA`` (relative to prefix URL assigned for +the application), where **USER_DATA** can be either in hashed or raw format. For +example, if Django Pydenticon application is reachable under ``/identicon/``, +identicon images can be requested using the following URLs: + +* ``/identicon/image/somedataforhashing`` (raw data) +* ``/identicon/image/55d207ea47247b375dc1f495517f1332`` (pre-hashed data using + *md5*) + +.. warning:: + Keep in mind that if user data is submitted in pre-hashed form, the digest + used should match with the digest configured for Django Pydenticon + application. If digest does not match, the user data will be treated as any + other user data, and it will be hashed once again. + +URL instance namespaces +----------------------- + +When resolving Django Pydenticon URLs, you should always use the URL names in +conjunction with application instance namespace. + +Default application instance namespace is ``django_pydenticon``. Alternative +instance namespace can be specified by passing an (optional) argument to +``django_pydenticons.urls.get_patterns`` function. + +For example, if default namespace is in use, the ``image`` URL would be +referenced as ``django_pydenticon:image`` in template tag ``url`` or function +call ``reverse``. + +Generating identicon URLs in templates +-------------------------------------- + +If the data (whether raw or hashed) is available in template's context, an +identicon URL can be easily generated from within the template itself. This can +be achieved via ``url`` tag. + +The URL for serving the identicons is named ``image``. It should always be +referenced in conjunction with an application instance namespace. The +application namespace defaults to ``django_pydenticon``, unless custom instance +namespace is passed when including the application URLs via +``django_pydenticon.urls.get_patterns``. In case of default namespace, that +means the URL would be referenced to as ``django_pydenticon:image``. + +For example, let's say that it's necessary to show an identicon based on +username next to every comment. Related template snippet could look something +similar to the following:: + + + +Generating identicon URLs programatically +----------------------------------------- + +The URLs can be generated programtically, using Python code. Afterwards those +URLs can be either passed into template's rendering context, or used inside of +code for whatever other purposes. This is achieved by using the ``reverse`` URL +resolver (from ``django.core.urlresolvers``). + +The URL for serving the identicons is named ``image``. It should always be +referenced in conjunction with an application instance namespace. The +application namespace defaults to ``django_pydenticon``, unless custom instance +namespace is passed when including the application URLs via +``django_pydenticon.urls.get_patterns``. In case of default namespace, that +means the URL would be referenced to as ``django_pydenticon:image``. + +For example, let's say that it's necessary to show an identicon based on +username next to every comment. A special context variable could be passed into +template that would contain a list of comments, where each comment consists out +of identicon URL and comment itself. The Python code could look something +similar to:: + + comments_context = [] + + for comment in comments: + identicon_url = reverse("django_pydenticon:image", + kwargs={"data": comment.user.username}) + comments_context.append({"text": comment.text, + "identicon_url": identicon_url}) + + return render_to_response('myapp/comments.html', + {"comments": comments_context}) + +With the above context set-up, the ``myapp/comments.html`` template could +contain a snippet similar to:: + + + +Overriding identicon parameters +------------------------------- + +By default, the identicon generator will use parameters from project settings +for each request, falling back to application defaults if none were defined. In +addition to this static configuration, some parameters can be overridden per +request. + +Per-request identicon generator parameters are passed via *GET* parameters. The +following *GET* parameters are available: + +w + Specifies the width of generated identicon image in pixels. Overrides the + ``PYDENTICON_WIDTH`` configuration option. + +h + Specifies the height of generated identicon image in pixels. Overrides the + ``PYDENTICON_HEIGHT`` configuration option. + +f + Specifies the format of generated identicon. Overrides the + ``PYDENTICON_FORMAT`` configuration option. + +p + Specifies the padding that will be added to the generated identicon image. The + value should be provided as 4 comma-separated positive integers. + +i + Specifies whether the background and foreground colour in generated identicon + should be inverted (swapped) or not. The value passed for this parameter + should be ``true`` or ``false``. + +Passing an invalid parameter value via *GET* parameter will result in a +``SuspiciousOperation`` exception being raised. + +For example, the following request would generate an identicon with width of +``320``, height of ``240``, format ``PNG``, padding (top, bottom, left, right) +of ``10, 10, 20, 20``, and with inverted foreground and background colours:: + + /identicon/image/somedata?w=320&h=240&f=png&p=10,10,20,20&i=true