diff options
22 files changed, 206 insertions, 18 deletions
diff --git a/_config.yml b/_config.yml index ad5c74aeb..6ee6be0e1 100644 --- a/_config.yml +++ b/_config.yml @@ -4,6 +4,8 @@ baseurl: / permalink: pretty markdown: kramdown url: http://code.alaveteli.org -exclude: [ node_modules ] +exclude: + - node_modules + - script gems: - jekyll-redirect-from diff --git a/_layouts/page.html b/_layouts/page.html index 0fc63db64..0eb0d0dbf 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -66,6 +66,7 @@ layout: default <li><a href="{{ site.baseurl }}docs/running/">Running</a> <ul> <li><a href="{{ site.baseurl }}docs/running/admin_manual/">Admin manual</a></li> + <li><a href="{{ site.baseurl }}docs/running/redaction">Redaction</a></li> <li><a href="{{ site.baseurl }}docs/running/security/">Security & Maintenance</a></li> <li><a href="{{ site.baseurl }}docs/running/server/">Server checklist</a></li> <li><a href="{{ site.baseurl }}docs/running/upgrading/">Upgrading</a></li> diff --git a/assets/img/redaction-address-outside-fence.png b/assets/img/redaction-address-outside-fence.png Binary files differnew file mode 100644 index 000000000..bbed100cf --- /dev/null +++ b/assets/img/redaction-address-outside-fence.png diff --git a/assets/img/redaction-address-quoted-redacted.png b/assets/img/redaction-address-quoted-redacted.png Binary files differnew file mode 100644 index 000000000..f5e2591d8 --- /dev/null +++ b/assets/img/redaction-address-quoted-redacted.png diff --git a/assets/img/redaction-automatically-added-id-number-censor-rule.png b/assets/img/redaction-automatically-added-id-number-censor-rule.png Binary files differnew file mode 100644 index 000000000..a05b6bc9d --- /dev/null +++ b/assets/img/redaction-automatically-added-id-number-censor-rule.png diff --git a/assets/img/redaction-domicile-censor-rule-applied.png b/assets/img/redaction-domicile-censor-rule-applied.png Binary files differnew file mode 100644 index 000000000..8933c409a --- /dev/null +++ b/assets/img/redaction-domicile-censor-rule-applied.png diff --git a/assets/img/redaction-domicile-censor-rule.png b/assets/img/redaction-domicile-censor-rule.png Binary files differnew file mode 100644 index 000000000..dcbae99ab --- /dev/null +++ b/assets/img/redaction-domicile-censor-rule.png diff --git a/assets/img/redaction-id-number-in-main-body-not-redacted.png b/assets/img/redaction-id-number-in-main-body-not-redacted.png Binary files differnew file mode 100644 index 000000000..215bc8051 --- /dev/null +++ b/assets/img/redaction-id-number-in-main-body-not-redacted.png diff --git a/assets/img/redaction-id-number-in-main-body-redacted.png b/assets/img/redaction-id-number-in-main-body-redacted.png Binary files differnew file mode 100644 index 000000000..437568733 --- /dev/null +++ b/assets/img/redaction-id-number-in-main-body-redacted.png diff --git a/assets/img/redaction-id-number-in-quoted-section.png b/assets/img/redaction-id-number-in-quoted-section.png Binary files differnew file mode 100644 index 000000000..f46fc0ebb --- /dev/null +++ b/assets/img/redaction-id-number-in-quoted-section.png diff --git a/assets/img/redaction-id-number-redacted.png b/assets/img/redaction-id-number-redacted.png Binary files differnew file mode 100644 index 000000000..2e8d2c8d8 --- /dev/null +++ b/assets/img/redaction-id-number-redacted.png diff --git a/assets/img/redaction-outgoing-message-with-general-law.png b/assets/img/redaction-outgoing-message-with-general-law.png Binary files differnew file mode 100644 index 000000000..80f9b3e53 --- /dev/null +++ b/assets/img/redaction-outgoing-message-with-general-law.png diff --git a/assets/img/redaction-outgoing-message-with-id-number.png b/assets/img/redaction-outgoing-message-with-id-number.png Binary files differnew file mode 100644 index 000000000..834ad3d08 --- /dev/null +++ b/assets/img/redaction-outgoing-message-with-id-number.png diff --git a/assets/img/redaction-pdf-redaction-as-html.png b/assets/img/redaction-pdf-redaction-as-html.png Binary files differnew file mode 100644 index 000000000..e98aba73e --- /dev/null +++ b/assets/img/redaction-pdf-redaction-as-html.png diff --git a/assets/img/redaction-pdf-redaction-download.png b/assets/img/redaction-pdf-redaction-download.png Binary files differnew file mode 100644 index 000000000..b24a50568 --- /dev/null +++ b/assets/img/redaction-pdf-redaction-download.png diff --git a/assets/img/redaction-sign-up-form.png b/assets/img/redaction-sign-up-form.png Binary files differnew file mode 100644 index 000000000..5a36a7304 --- /dev/null +++ b/assets/img/redaction-sign-up-form.png diff --git a/docs/customising/themes.md b/docs/customising/themes.md index cc0ca3b29..c8d4a8037 100644 --- a/docs/customising/themes.md +++ b/docs/customising/themes.md @@ -189,3 +189,7 @@ necessary. ## Adding or overriding models and controllers If you need to extend the behaviour of Alaveteli at the controller or model level, see `alavetelitheme/lib/controller_patches.rb` and `alavetelitheme/lib/model_patches.rb` for examples. + +## Working with themes + +You can use [`script/switch-theme.rb`](https://github.com/mysociety/alaveteli/blob/master/script/switch-theme.rb) to set the current theme if you are working with multiple themes. This might be useful for switching between the default `alavetelitheme` and your own fork. diff --git a/docs/installing/next_steps.md b/docs/installing/next_steps.md index 1426a2fce..4199daabf 100644 --- a/docs/installing/next_steps.md +++ b/docs/installing/next_steps.md @@ -112,6 +112,12 @@ follow the steps described in the previous section. If that doesn't sort it out, [get in touch]({{ site.baseurl}}community/) on the [developer mailing list](https://groups.google.com/forum/#!forum/alaveteli-dev) or [IRC](http://www.irc.mysociety.org/) for help. +## Import Public Authorities + +Alaveteli can import a list of public authorities and their contact email addresses from a CSV file. + +You can find the uploader in under the "Authorities" tab of the admin section, or go straight to `/admin/body/import_csv`. + ## Start thinking about customising Alaveteli Check out [our guide]({{ site.baseurl}}docs/customising/). diff --git a/docs/running/index.md b/docs/running/index.md index 7257417ce..bbf30d3b9 100644 --- a/docs/running/index.md +++ b/docs/running/index.md @@ -16,10 +16,13 @@ site, you need to make sure day-to-day tasks get done too. Most Alaveteli sites are run by a team who allocate some time every day to user support and generally keeping the project up to date. -* the [administrator's guide]({{ site.baseurl }}docs/running/admin_manual/) describes +* The [administrator's guide]({{ site.baseurl }}docs/running/admin_manual/) describes what you need to do and know to run your site -* we've prepared a checklist of +* The [redaction guide]({{ site.baseurl }}docs/running/redaction/) includes some + examples of Alaveteli's ability to redact sensitive information + +* We've prepared a checklist of [things to consider]({{ site.baseurl }}docs/running/server/) when setting up your production server diff --git a/docs/running/redaction.md b/docs/running/redaction.md new file mode 100644 index 000000000..6ab8fed86 --- /dev/null +++ b/docs/running/redaction.md @@ -0,0 +1,135 @@ +--- +layout: page +title: Redacting Sensitive Information +--- + +# Redacting Sensitive Information + +In some countries, local requirements mean that requests need to contain personal information such as the address or ID number of the person asking for information. Usually requesters do not want this information to be displayed to the general public. + +Alaveteli has some ability to deal with this through the use of <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rules</a>. + +The [theme](https://github.com/mysociety/derechoapreguntar-theme) we'll use as an example requires a National Identity Card Number and what's known as General Law in Nicaragua (Date of Birth, Domicile, Occupation and Marital Status). + + + +## Identity Card Number + +We'll start off by looking at the National Identity Card Number (ID Number from here). Its a good example of something that is relatively easy to redact. It's unique for each user, and it has a specified format to match against. + +To send the ID Number to the authority we'll override the [initial request template](https://github.com/mysociety/alaveteli/blob/master/app/views/outgoing_mailer/initial_request.text.erb) (code snippet shortened): + + <%= raw @outgoing_message.body.strip %> + + ------------------------------------------------------------------- + + <%= _('Requestor details') %> + <%= _('Identity Card Number') %>: <%= @user_identity_card_number %> + +When a request is made the user's ID Number is now added to the footer of the outgoing email. + + + +At this point we haven't added any <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rules</a>. When the authority replies it is unlikely that the responder will remove the quoted section of the email: + + + +We could add a <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> for the individual request, but as every request will contain a user's ID Number its better to add some code to do do it automatically. + +To illustrate this we'll patch the `User` model with a callback that creates a <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> when the user is created and updated. + + # THEME_ROOT/lib/model_patches.rb + User.class_eval do + after_save :update_censor_rules + + private + + def update_censor_rules + censor_rules.where(:text => identity_card_number).first_or_create( + :text => identity_card_number, + :replacement => _('REDACTED'), + :last_edit_editor => THEME_NAME, + :last_edit_comment => _('Updated automatically after_save') + ) + end + end + +You can see the new <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> in the admin interface: + + + +Now the ID Number gets redacted: + + + +It also gets redacted if the public body use the ID Number in the main email body: + + + +A <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">censor rule</a> added to a user only gets applied to correspondence on requests created by that user. It does not get applied to annotations made by the user. + +**Warning:** Redaction in this way requires the sensitive text to be in exactly the same format as the <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a>. If it differs even slightly, the redaction can fail. If the public body was to remove the hyphens from the number it would not be redacted: + + + +**Warning:** Alaveteli also attempts to redact the text from any attachments. It can only do this if it can find the exact string, which is often not possible in binary formats such as PDF or Word. + +Alaveteli can usually redact the sensitive information when converting a PDF or text based attachment to HTML: + + + +This PDF does not contain the string in the raw binary so the redaction is _not_ applied when downloading the original PDF document: + + + +## General Law + +The General Law information is much harder to automatically redact. It is not as structured, and the information is unlikely to be unique (e.g. Domicile: London). + +We'll add the General Law information to the [initial request template](https://github.com/mysociety/alaveteli/blob/master/app/views/outgoing_mailer/initial_request.text.erb) in the same way as the ID Number: + + <%= _('Requestor details') %>: + <%-# !!!IF YOU CHANGE THE FORMAT OF THE BLOCK BELOW, ADD A NEW CENSOR RULE!!! -%> + =================================================================== + # <%= _('Name') %>: <%= @user_name %> + # <%= _('Identity Card Number') %>: <%= @user_identity_card_number %> + <% @user_general_law_attributes.each do |key, value| %> + # <%= _(key.humanize) %>: <%= value %> + <% end %> + =================================================================== + +Note that the information is now contained in a specially formatted block of text. + + + +This allows a <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> to match the special formatting and remove anything contained within. This <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> is global, so it will act on matches in all requests. + + # THEME_ROOT/lib/censor_rules.rb + # If not already created, make a CensorRule that hides personal information + regexp = '={67}\s*\n(?:[^\n]*?#[^\n]*?: ?[^\n]*\n){3,10}[^\n]*={67}' + + unless CensorRule.find_by_text(regexp) + Rails.logger.info("Creating new censor rule: /#{regexp}/") + CensorRule.create!(:text => regexp, + :allow_global => true, + :replacement => _('REDACTED'), + :regexp => true, + :last_edit_editor => THEME_NAME, + :last_edit_comment => 'Added automatically') + end + + + +**Warning:** Redacting unstructured information is a very fragile approach, as it relies on authorities always quoting the entire formatted block. + +In this case the authority has revealed the user's Date of Birth and Domicile: + + + +Its really difficult to add a <a href="{{site.baseurl}}docs/glossary/#censor-rule" class="glossary__link">Censor Rule</a> to remove this type of information. One suggestion might be to remove all mentions of the user's Date of Birth, but you would have to account for [every type of date format](http://en.wikipedia.org/wiki/Calendar_date#Date_format). Likewise, you could redact all occurrences of the user's Domicile, but if they a question about their local area (very likely) the request would become unintelligible. + + + +The redaction has been applied but there is no way of knowing the context that the use of the sensitive word is used. + + diff --git a/docs/running/upgrading.md b/docs/running/upgrading.md index 67a9eeba0..533035892 100644 --- a/docs/running/upgrading.md +++ b/docs/running/upgrading.md @@ -12,6 +12,23 @@ Upgrading Alaveteli This page describes how to keep your site up-to-date </p> +## How to upgrade the code + +* If you're using Capistrano for deployment, + simply [deploy the code]({{site.baseurl}}docs/installing/deploy/#usage): + set the repo and branch in `deploy.yml` to be the version you want. + We recommend you set this to the explicit tag name (for example, + `0.18`, and not `master`) so there's no risk of you accidentally deploying + a new version before you're aware it's been released. +* otherwise, you can simply upgrade by running `git pull` + +## Run the post-deploy script + +Unless you're [using Capistrano for deployment]({{site.baseurl}}docs/installing/deploy/), +you should always run the script `scripts/rails-post-deploy` after each +deployment. This runs any database migrations for you, plus various other +things that can be automated for deployment. + ## Alaveteli Version Numbers Alaveteli uses a shifted version of [semver](http://semver.org). @@ -47,16 +64,6 @@ other changes ("further action"). For this reason, for anything other than a document **before** doing an upgrade. This way you'll be able to prepare for any other changes that might be needed to make the new code work. -## How to upgrade the code - -* If you're using Capistrano for deployment, - simply [deploy the code]({{site.baseurl}}docs/installing/deploy/#usage): - set the repo and branch in `deploy.yml` to be the version you want. - We recommend you set this to the explicit tag name (for example, - `0.18`, and not `master`) so there's no risk of you accidentally deploying - a new version before you're aware it's been released. -* otherwise, you can simply upgrade by running `git pull` - ## Patches Patch version increases (e.g. 0.1.2.3 → 0.1.2.**4**) should not require any further action on your part. They will be backwards compatible with the current minor release version. @@ -85,9 +92,20 @@ Only major releases may remove existing functionality. You will be warned about Special instructions will accompany series releases. -## Run the post-deploy script +## Deprecation Notices -Unless you're [using Capistrano for deployment]({{site.baseurl}}docs/installing/deploy/), -you should always run the script `scripts/rails-post-deploy` after each -deployment. This runs any database migrations for you, plus various other -things that can be automated for deployment. +You may start to see deprecation notices in your application log. They will look like: + + DEPRECATION WARNING: Object#id will be deprecated; use Object#object_id + +Deprecation notices allow us to communicate with you that some functionality will change or be removed in a later release of Alaveteli. + +### What to do if you see a deprecation notice + +You will usually see a deprecation notice if you have been using functionality in your theme that is now due to change or be removed. The notice should give you a fair explanation of what to do about it. Usually it will be changing or removing methods. The [changelog](https://github.com/mysociety/alaveteli/blob/rails-3-develop/doc/CHANGES.md) will include more detailed information about the deprecation and how to make the necessary changes. + +If you're ever unsure, don't hesitate to ask in the [developer mailing list](https://groups.google.com/group/alaveteli-dev) or [Alaveteli IRC channel](http://www.irc.mysociety.org/). + +### When will the change take place? + +We introduce deprecation notices in a **minor** release. The following **major** release will make the change unless otherwise stated in the deprecation notice. diff --git a/script/translation-export b/script/translation-export new file mode 100755 index 000000000..5dba7455e --- /dev/null +++ b/script/translation-export @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +TOP_DIR="$(dirname "$0")/.." +cd "$TOP_DIR" + +REPO="$(basename "$PWD")" +SHA="$(git rev-parse --short HEAD)" +TIMESTAMP=$(date '+%FT%T') +FILENAME="${REPO}_${SHA}_${TIMESTAMP}.tar" + +tar -cvf "$FILENAME" _includes/*.html +tar -uvf "$FILENAME" _layouts/*.html +tar -uvf "$FILENAME" $(ls -1 community/*.md) +tar -uvf "$FILENAME" $(find docs -type f -name "*.md") +tar -uvf "$FILENAME" --exclude README.md $(ls -1 *.md) + +gzip "$FILENAME" |