Legal Toolsプラグイン

リポジトリ: GitHub - paviliondev/discourse-legal-tools: Tools to help with legal compliance when using Discourse · GitHub

このプラグインは、Discourse フォーラムの運営における法的コンプライアンスを支援するためのツールを提供します。ツールは継続的に追加されていきます。

以下の免責事項にご注意ください。本プラグインは法的コンプライアンスを保証するものではありません。

拡張ユーザーダウンロード

拡張ユーザーダウンロードは、以下のエントリを含む単一の CSV ファイルです。各エントリは 2 つの空行で区切られています。

  • ヘッダー(編集可能:カスタマイズ > テキストコンテンツ > “csv_export.extended.title”):

    %{site_name} が保存している %{username} のすべての情報

    • “username” は、ダウンロードに含まれる情報のユーザーのユーザー名です。
    • “site_name” は、title サイト設定です。
  • ヘッダー下部の注記(編集可能:カスタマイズ > テキストコンテンツ > “csv_export.extended.note”):

    %{username} のユーザー識別子に関連する一部の情報は、プライバシーおよび法的な利益との調整により、このダウンロードから除外されています。
    詳細については、%{site_contact} までお問い合わせください。

    • “username” は、ダウンロードに含まれる情報のユーザーのユーザー名です。
    • “site_contact” は、contact email サイト設定です。
  • 投稿:ユーザーダウンロードに含まれるデフォルトの情報。

  • アカウント:アカウントおよびプロフィール情報。

  • 外部アカウント:外部アカウントからの情報(存在する場合)。

  • 統計:ユーザーに関する保存された統計情報。

  • ログインとログイン履歴:ユーザーのログインに関する情報。

  • 検索:ユーザーが行った検索のすべての IP ログ記録。

  • トピック表示:ユーザーによるトピックのすべての IP ログ記録された表示。

  • トピックリンククリック:ユーザーがクリックしたトピックリンクのすべての IP ログ記録。

  • プロフィール表示:ユーザーによるプロフィールのすべての IP ログ記録された表示。

  • 行動:ユーザーが行ったすべての行動。

  • 履歴:ユーザーに関与する記録可能な行動のすべての IP ログ記録。

拡張ダウンロードを有効にする 2 つのサイト設定があります。

  • legal extended user download:有効にすると、ユーザーアクティビティページの「すべてダウンロード」機能が拡張ダウンロードになります。

    • 通常のユーザーダウンロードと同様に、拡張ユーザーダウンロードは 1 日に 1 回のみ実行できる点にご注意ください。
  • legal extended user download admin:有効にすると、許可されたスタッフはサイト内の任意のユーザーのすべての情報をダウンロードできます。各ユーザーの管理ユーザー情報の上部に新しい「すべてダウンロード」ボタンが表示されます。

      ![Screenshot%20at%20May%2026%2014-55-03|340x96,80%](upload://wvealMlRqo6xFgDCzkuXNmDAcOa.png)
    

    オプション:

    • 無効(デフォルト)
    • 管理者のみ(管理者のみが管理者拡張ダウンロード機能を使用可能)
    • 管理者とスタッフ(管理者とスタッフの両方が管理者拡張ダウンロード機能を使用可能)

この 2 つの設定は独立しており、つまり legal extended user download を有効にしても、管理者やスタッフに全ユーザーの情報をダウンロードする権限を与えないことができます。逆に、legal extended user download admin を有効にしても、ユーザーに自身の情報をすべてダウンロードする権限を与えないことも可能です。

この機能の背景には、EU の GDPR があります。特に以下を参照してください。

ユーザー、スタッフ、および/または管理者に上記のすべての情報をダウンロードする権限を与えることのセキュリティ上の影響を考慮する必要がある点にご注意ください。この機能は、すべての状況に適しているとは限りません。この問題に関する詳細は、上記のトピックでご確認ください。

ユーザー情報を直接ダウンロードする代わりに、関連するスタッフ(「データ保護責任者」)がデータベースクエリを通じて情報をまとめることも選択肢となります。

免責事項

Legal Tools プラグイン(以下「プラグイン」という)およびその著者である Angus McLeod(以下「著者」という)は、弁護士でも、弁護士の代わりでも、法的助言の代わりでもありません。お客様と著者との間の通信は、弁護士 - 顧客特権または職務成果として保護されません。プラグインおよびその著者は、可能な法的権利、救済措置、防御、選択肢、フォームの選択、または戦略について、いかなる助言、説明、意見、推奨、または確約も提供できません。

「いいね!」 62

@codinghorror how much of this do you think belongs in core? Should we just amend our default “download all my data” to include all this stuff?

「いいね!」 9

No, we need @riking to come through with the removal of IP where it’s unnecessarily recorded and should not be first. If that can’t be achieved in a reasonable timeframe we need to get someone else to do it.

「いいね!」 5

Update here.

Scope of the download

All user-related records in user activity (record of likes, bookmarks, topics, replies etc) have been added to the download (commit).

I initially didn’t add this as it seemed like overkill. However @RGJ raised it with me and we had a productive exchange on the question.

Essentially, we decided that the best approach for the purposes of this feature was to include all records of activity tied to the user’s identifier that don’t entail countervailing concerns about the privacy of others or similar rights.

I would emphasise “for the purposes of this feature”, as the purpose of this feature is to take a ‘maximalist’ approach to possible interpretations of the GDPR. It does not attempt to parse ‘likely’ approaches. I’ve laid out some of my own views on the ‘likely’ approaches in this topic (which remain unchanged).

The specifics of the reasoning behind this ‘maximalist’ approach are:

  • The broadest interpretation of A.4.1 (the definition of ‘Personal Data’ in the GDPR) as it applies to Discourse is any record in the db that contains the user’s user_id, i.e.:

    any information … identified or identifiable natural person … identified, directly or indirectly, in particular by reference to … an identification number

  • Read literally, this definition doesn’t care about how the data is produced (e.g. whether the user is acting or not). It merely requires the data to be related to the user’s identifier in some way.

  • However, applying that literally would produce a fair amount of duplication (e.g. the records in the directory_items table are duplicative of various other entries).

  • The point of the extended download is to guard against even the small risk that Article 4.1 could receive a very broad interpretation by some authority or court in Europe.

  • The factors against including it - size of download, potentially security (?) - do not outweigh the possible benefit of including it.

We also considered whether to include ‘administrative’ records with the user’s user_id such as flags, complaints and staff whispers. We decided against this, reasoning as follows:

  • They’re already in the territory of information associated with the user purely by their identifier. They are not information about the user per se (i.e. name, email, age, location etc). This is already assuming a wide interpretation of A.4.1.

  • Whether administrative records intrude on the privacy of other parties, or other relevant concerns (i.e. R. 63.5 & A.15.4) must be determined on a case-by-case basis.

  • Other parties, such as Facebook, do no include such data in their user download functionality.

「いいね!」 12

Hey Angus,

I’m having some trouble getting this to work. I’ve enabled the ‘legal extended user download’ setting, refreshed the page and clicked the ‘Download all’ button on the activity page. This results in an archive that contains one CSV file with topics in it. I checked both as an admin and as a regular user. What is the expected output - multiple CSV files, each for a different table?

The expected output is a single csv with headers for each item mentioned in the first post in this topic. If you try it out on my sandbox, this is what you’ll get.

Do you see any errors at /sidekiq?

@RGJ have you had this issue?

Nope. We had a few users with the same kind of complaint though but it turned out to be a false alarm.
I guess they never scrolled down past the posts. Maybe it’s an idea to move the posts section (i.e. the most unstructured / multiline content) to be the last section.

「いいね!」 1

Could you provide a few of the header rows as an example so I can do a search for them?

See the ‘separator’ lines here.

Thanks Richard. Definitely not seeing those. So just to be sure I’m doing the right thing: this plugin is supposed to replace the ‘Download’ button in the Profile > Activity sidebar, right?

First words of admiration go to @angus :clap: :heart: :+1: for doing such a great job helping everyone here to get those highly useful tools (not only this plugin but other plugins too).

I’ve got one question though: wouldn’t it be better to have this export available to admins only (at least as option for those concerned)?
Isn’t it potentially risky in case when given account password is compromised and then ‘all activity’ is easily downloaded by unauthorized person? (Sorry that is two questions :slight_smile: )

「いいね!」 3

I just did a few more tests and tried it on your sandbox too. My results are just the default download - they don’t match your new format. I don’t think I see any errors in sidekiq (at least not in ‘Failed’ - ‘Errors’ is not clickable). Any suggestions how I can best find more information here?

Please post (or PM) a screenshot of the csv you got from my sandbox with the ip addresses blacked out (if any).

I think I’ll make this a setting.

Potentially. This is partly what I meant by

Nevertheless, some people will need / want the functionality of allowing users to directly download their info. So I think a setting is the move here.

「いいね!」 1

There are now two site settings that enable the extended download:

  • legal extended user download: When enabled, the “Download All” feature in the User Activity page becomes an extended download.

    • Please note that, like the normal user download, the extended user download can only be performed by a user once a day.
  • legal extended user download admin. When enabled, permitted staff can download all the information of any user of the site. They will see an new “Download All” button at the top of the the admin user information of each user.

    Screenshot%20at%20May%2026%2014-55-03

    Options:

    • Disabled (default)
    • Admins Only (only admins can use the admin extended download feature)
    • Admins and Staff (both admins and staff can use the admin extended download feature)

The two settings are severable, i.e. you can enable legal extended user download without giving admins or staff the ability to download all the information of every user, or you can enable legal extended user download admin without giving users the ability to download all of their information.

Due to the security implications of allowing users (even if they’re admins) to download all the information of other users, I’ve been particularly careful with protecting the admin extended user download server methods, however I would appreciate a second set of eyes on that aspect of the changes, particularly considering this feature seems to be quite popular. Perhaps you could take a look @riking if you have the time? (i.e. particularly the changes to the Guardian).

I’ve also added text to the top of the extended csv:

  • A header (can be edited: Customize > Text Content > “csv_export.extended.title”):

    All information of %{username} stored by %{site_name}

    • “username” is the username of the user who’s information is in the download.
    • “site_name” is the title site setting.
  • A note below the header (can be edited: Customize > Text Content > “csv_export.extended.note”):

    Please note that some information associated with the user identifier of %{username}
    has been excluded from this download due to countervailing privacy and legal interests.
    For more information, please contact %{site_contact}.

    • “username” is the username of the user who’s information is in the download.
    • “site_contact” is the contact email site setting.

This has all been tested on my sandbox where it is currently live.

@bartv Let me know if these updates fix your issue.

「いいね!」 8

This new version solves the issue I had before. Thanks for all your hard work on this, Angus!

The extended note is interesting; could you shed some light on which information has been excluded and for which reasons?

「いいね!」 3

That is primarily referring to the exclusion mentioned below, and also helps if we’ve not included something some authority happens to consider relevant.

「いいね!」 4

6件の投稿が新しいトピックに分割されました: ユーザーデータの書き出しに失敗(トランザクションが中止されました)

管理者として、ユーザーからデータのエクスポート(GDPR リクエスト)を試みました。正しいボタン(すべてダウンロード)をクリックしましたが、システムからデータエクスポートが失敗したとのメッセージが表示され、ログを確認するよう指示されました。

これがプラグイン内部の問題なのか、それとも Discourse 自体の問題なのか判断できません。

更新(1 月 11 日 17:40 UTC):Discourse チームによると、バックトレースを確認した結果、これはサードパーティ製プラグインの問題であるとのことです。@angus さん、ご確認いただけますでしょうか。よろしくお願いいたします。

Discourse インスタンスは 2.7.0.beta1 (4f72830eb0) で動作しています。

更新(1 月 11 日 16:15 UTC):現在バージョン 2.7.0.beta1 (422f395042) にアップデートしましたが、エラーは同じままです。

プラグイン内で設定されている内容は以下の通りです:

ログには以下のエラーが表示されています:

Job 例外:nil:NilClass に対して collect メソッドが定義されていません

/usr/local/lib/ruby/2.7.0/csv/writer.rb:46:in `\u003c\u003c'
/usr/local/lib/ruby/2.7.0/csv.rb:1230:in `\u003c\u003c'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:66:in `block (3 levels) in execute'
/var/www/discourse/plugins/discourse-legal-tools/lib/export_csv_file_extension.rb:267:in `user_archive_export_extended'
/var/www/discourse/plugins/discourse-legal-tools/lib/export_csv_file_extension.rb:226:in `admin_user_archive_export'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:66:in `each'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:66:in `block (2 levels) in execute'
/usr/local/lib/ruby/2.7.0/csv.rb:658:in `open'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:64:in `block in execute'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:63:in `each'
/var/www/discourse/app/jobs/regular/export_csv_file.rb:63:in `execute'
/var/www/discourse/app/jobs/base.rb:232:in `block (2 levels) in perform'
rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'
/var/www/discourse/app/jobs/base.rb:221:in `block in perform'
/var/www/discourse/app/jobs/base.rb:217:in `each'
/var/www/discourse/app/jobs/base.rb:217:in `perform'
sidekiq-6.1.2/lib/sidekiq/processor.rb:196:in `execute_job'
sidekiq-6.1.2/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:138:in `call'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:143:in `invoke'
sidekiq-6.1.2/lib/sidekiq/processor.rb:163:in `block in process'
sidekiq-6.1.2/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_retry.rb:111:in `local'
sidekiq-6.1.2/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq.rb:38:in `block in \u003cmodule:Sidekiq\u003e'
sidekiq-6.1.2/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/processor.rb:257:in `stats'
sidekiq-6.1.2/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_logger.rb:13:in `call'
sidekiq-6.1.2/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
sidekiq-6.1.2/lib/sidekiq/job_retry.rb:78:in `global'
sidekiq-6.1.2/lib/sidekiq/processor.rb:124:in `block in dispatch'
sidekiq-6.1.2/lib/sidekiq/logger.rb:10:in `with'
sidekiq-6.1.2/lib/sidekiq/job_logger.rb:33:in `prepare'
sidekiq-6.1.2/lib/sidekiq/processor.rb:123:in `dispatch'
sidekiq-6.1.2/lib/sidekiq/processor.rb:162:in `process'
sidekiq-6.1.2/lib/sidekiq/processor.rb:78:in `process_one'
sidekiq-6.1.2/lib/sidekiq/processor.rb:68:in `run'
sidekiq-6.1.2/lib/sidekiq/util.rb:15:in `watchdog'
sidekiq-6.1.2/lib/sidekiq/util.rb:24:in `block in safe_thread'
「いいね!」 1

返信が遅くなり申し訳ありません。私は休暇に出ていました :beach_umbrella:

この問題を再現して修正しました。アップデートして、再度ダウンロードを試してください。可能であれば、その結果をお知らせください。

「いいね!」 6

問題ありません。週末でしたし、すぐに反応する必要はありません。
このプラグインに感謝しています。

アップデートして再度試しました。
正常に動作しました。修正ありがとうございます。素晴らしいお手伝いに心から感謝しています。

もし、ユーザーの user_id に加えて「管理」関連の記録(フラグ、苦情、スタッフ間の whisper など)も含めたい場合、Data Explorer でデータを取得するための最適な SQL 文はどのようなものになりますか?
必要であれば、データリクエストを行ったユーザーに別途これらのデータを提供することも可能です。

「いいね!」 3