Some progress on this

This commit is contained in:
E Rasche
2018-04-10 11:57:46 +02:00
parent 4a6eb37b47
commit abfb69252a
8 changed files with 68 additions and 19 deletions
+1
View File
@@ -286,6 +286,7 @@ class Configuration(object):
for ip in kwargs.get("fetch_url_whitelist", "").split(',')
if len(ip.strip()) > 0
]
self.gdpr_compliance_mode = string_as_bool(kwargs.get("gdpr_compliance_mode", "False"))
self.allow_user_creation = string_as_bool(kwargs.get("allow_user_creation", "True"))
self.allow_user_deletion = string_as_bool(kwargs.get("allow_user_deletion", "False"))
self.allow_user_dataset_purge = string_as_bool(kwargs.get("allow_user_dataset_purge", "True"))
@@ -18,12 +18,19 @@ class BiostarsPlugin(ErrorPlugin):
def __init__(self, **kwargs):
self.app = kwargs['app']
self.gdpr_compliant = self.app.config.gdpr_compliance_mode
self.verbose = string_as_bool(kwargs.get('verbose', True))
self.user_submission = string_as_bool(kwargs.get('user_submission', True))
def submit_report(self, dataset, job, tool, **kwargs):
"""Doesn't do anything, just shows a link to submit on biostars.
"""
# This class specifically does nothing special for GDPR compliance
# because the user is willingly posting their data on a public
# first/third-party site. Maybe should do something about the dialog
# linking to the biostars privacy policy during the "submit to
# biostars" dialog?
try:
assert biostar.biostar_enabled(self.app), ValueError("Biostar is not configured for this galaxy instance")
assert self.app.config.biostar_enable_bug_reports, ValueError("Biostar is not configured to allow bug reporting for this galaxy instance")
@@ -17,6 +17,7 @@ class EmailPlugin(ErrorPlugin):
def __init__(self, **kwargs):
self.app = kwargs['app']
self.gdpr_compliant = self.app.config.gdpr_compliance_mode
self.verbose = string_as_bool(kwargs.get('verbose', True))
self.user_submission = string_as_bool(kwargs.get('user_submission', True))
@@ -25,7 +26,7 @@ class EmailPlugin(ErrorPlugin):
"""
try:
error_reporter = EmailErrorReporter(dataset.id, self.app)
error_reporter.send_report(user=job.get_user(), email=kwargs.get('email', None), message=kwargs.get('message', None))
error_reporter.send_report(user=job.get_user(), email=kwargs.get('email', None), message=kwargs.get('message', None), gdpr_compliant=self.gdpr_compliant)
return ("Your error report has been sent", "success")
except Exception as e:
return ("An error occurred sending the report by email: %s" % str(e), "danger")
@@ -17,6 +17,7 @@ class GithubPlugin(ErrorPlugin):
def __init__(self, **kwargs):
self.app = kwargs['app']
self.gdpr_compliant = self.app.config.gdpr_compliance_mode
self.verbose = string_as_bool(kwargs.get('verbose', False))
self.user_submission = string_as_bool(kwargs.get('user_submission', False))
try:
@@ -69,7 +70,7 @@ class GithubPlugin(ErrorPlugin):
# We'll re-use the email error reporter's template since github supports HTML
error_reporter = EmailErrorReporter(dataset.id, self.app)
error_reporter.create_report(job.get_user(), email=kwargs.get('email', None), message=kwargs.get('message', None))
error_reporter.create_report(job.get_user(), email=kwargs.get('email', None), message=kwargs.get('message', None), gdpr_compliant=self.gdpr_compliant)
# The HTML report
error_message = error_reporter.html_report
@@ -20,6 +20,7 @@ class JsonPlugin(ErrorPlugin):
def __init__(self, **kwargs):
self.app = kwargs['app']
self.verbose = string_as_bool(kwargs.get('verbose', False))
self.gdpr_compliant = self.app.config.gdpr_compliance_mode
self.user_submission = string_as_bool(kwargs.get('user_submission', False))
self.report_directory = kwargs.get("directory", tempfile.gettempdir())
if not os.path.exists(self.report_directory):
@@ -40,12 +41,17 @@ class JsonPlugin(ErrorPlugin):
'exit_code': job.exit_code,
'stdout': job.stdout,
'handler': job.handler,
'user': job.get_user().to_dict(),
'tool_version': job.tool_version,
'tool_xml': str(tool.config_file) if tool else None
}
if 'email' in kwargs:
data['email'] = kwargs['email']
if self.gdpr_compliant:
data['user'] = {
'id': job.get_user().id
}
else:
data['user'] = job.get_user().to_dict()
if 'email' in kwargs:
data['email'] = kwargs['email']
if 'message' in kwargs:
data['message'] = kwargs['message']
@@ -29,6 +29,7 @@ class SentryPlugin(ErrorPlugin):
def __init__(self, **kwargs):
self.app = kwargs['app']
self.gdpr_compliant = self.app.config.gdpr_compliance_mode
self.verbose = string_as_bool(kwargs.get('verbose', False))
self.user_submission = string_as_bool(kwargs.get('user_submission', False))
self.custom_dsn = kwargs.get('custom_dsn', None)
@@ -61,8 +62,11 @@ class SentryPlugin(ErrorPlugin):
'tool_version': unicodify(job.tool_version),
'tool_xml': unicodify(tool.config_file) if tool else None
}
if 'email' in kwargs:
extra['email'] = unicodify(kwargs['email'])
if self.gdpr_compliant:
extra['email'] = 'gdpr-redacted'
else:
if 'email' in kwargs:
extra['email'] = unicodify(kwargs['email'])
# User submitted message
extra['message'] = unicodify(kwargs.get('message', ''))
@@ -86,13 +90,20 @@ class SentryPlugin(ErrorPlugin):
# The above does not work when handlers are separate from the web handlers
url = None
if user:
# User information here also places email links + allows seeing
# a list of affected users in the tags/filtering.
context['user'] = {
'name': user.username,
'email': user.email,
}
if self.gdpr_compliant:
if user:
# Opauqe identifier
context['user'] = {
'id': user.id
}
else:
if user:
# User information here also places email links + allows seeing
# a list of affected users in the tags/filtering.
context['user'] = {
'name': user.username,
'email': user.email,
}
context['request'] = {'url': url}
+23 -4
View File
@@ -154,7 +154,7 @@ class ErrorReporter(object):
roles = []
return self.app.security_agent.can_access_dataset(roles, self.hda.dataset)
def create_report(self, user, email='', message='', **kwd):
def create_report(self, user, email='', message='', gdpr_compliant=False, **kwd):
hda = self.hda
job = self.job
host = web.url_for('/', qualified=True)
@@ -163,10 +163,29 @@ class ErrorReporter(object):
hda_id_encoded = self.app.security.encode_id(hda.id)
hda_show_params_link = web.url_for(controller="dataset", action="show_params", dataset_id=hda_id_encoded, qualified=True)
# Build the email message
if user and user.email != email:
email_str = "'%s' (providing preferred contact email '%s')" % (user.email, email)
if self.gdpr_compliant:
# This is sub-optimal but it is hard to solve fully. This affects
# the github posting method more than the traditional email plugin.
# There is no way around CCing the person with the traditional
# email bug report plugin, however with the GitHub plugin we can
# submit to GH without putting the email in the bug report.
#
# A secondary system with access to the github issue and access to
# the galaxy database can shuttle email back and forth between
# github comments and user-emails. Something like
# https://github.com/erasche/github-issue-to-mailgun-gateway
# Thus preventing issue helpers from every knowing the identity of
# the bug reporter (and preventing information about the bug
# reporter from leaving the EU until it hits email directly to the
# user.)
email_str = 'gdpr-redacted'
if user:
email_str += ' (user: %s)' % user.id
else:
email_str = "'%s'" % (email or 'anonymously')
if user and user.email != email:
email_str = "'%s' (providing preferred contact email '%s')" % (user.email, email)
else:
email_str = "'%s'" % (email or 'anonymously')
report_variables = dict(
host=host,
+4 -1
View File
@@ -2039,7 +2039,10 @@ mapping:
desc: |
Enables GDPR Compliance mode. This makes several changes to the way
Galaxy logs and exposes data externally such as removing
emails/usernames from logs and bug reports.
emails/usernames from logs and bug reports. It also causes the delete
user admin action to permanently delete all information stored on a
user, removing all related rows from the database. (You are
responsible for removing the data from backups.)
enable_beta_ts_api_install:
type: bool