Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HDX-9960 & HDX-9987 contact the contributor & HDX Connect new pages #6412

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import ckan.logic.action as core
import ckan.model as model
import ckan.plugins as plugins
from collections import OrderedDict
from ckan.common import _, c, config
import ckan.plugins.toolkit as toolkit
import ckan.lib.base as base
Expand Down Expand Up @@ -756,13 +757,14 @@ def hdx_user_in_org_or_group(group_id, include_pending=False):
return length != 0


def hdx_organization_type_list(include_default_value=None):
result = []
def hdx_organization_type_dict(include_default_value=None):
result = OrderedDict()

if include_default_value:
result.append({'value': '-1', 'text': _('-- Please select --')})
result.extend([{'value': t[1], 'text': _(t[0])} for t in static_lists.ORGANIZATION_TYPE_LIST])
# return [{'value': '-1', 'text': _('-- Please select --')}] + \
# [{'value': t[1], 'text': _(t[0])} for t in static_lists.ORGANIZATION_TYPE_LIST]
result['-1'] = _('-- Please select --')

result.update(OrderedDict({t[1]: _(t[0]) for t in static_lists.ORGANIZATION_TYPE_LIST}))

return result


Expand Down
2 changes: 1 addition & 1 deletion ckanext-hdx_org_group/ckanext/hdx_org_group/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_helpers(self):
from ckanext.hdx_org_group.helpers import organization_helper as hdx_org_h
from ckanext.hdx_org_group.helpers import country_helper as hdx_country_h
return {
'hdx_organization_type_list': hdx_org_h.hdx_organization_type_list,
'hdx_organization_type_dict': hdx_org_h.hdx_organization_type_dict,
'hdx_organization_type_get_value': hdx_org_h.hdx_organization_type_get_value,
'hdx_datagrid_org_get_display_text': hdx_country_h.hdx_datagrid_org_get_display_text
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def find_organisation() -> str:



def _set_custom_rect_logo_url(org_dict):
def set_custom_rect_logo_url(org_dict):
if 'customization' in org_dict and org_dict.get('customization'):
customization = json.loads(org_dict.get('customization'))
if customization and customization.get('image_rect', None):
Expand All @@ -82,7 +82,7 @@ def confirm_organisation() -> str:
org_id = request.form.get('org_id')
if org_id is not None:
org_dict = get_action(u'organization_show')(context, {'id':org_id})
_set_custom_rect_logo_url(org_dict)
set_custom_rect_logo_url(org_dict)
else:
return redirect(url_for('hdx_org_join.find_organisation'))
except Exception as ex:
Expand Down
13 changes: 13 additions & 0 deletions ckanext-hdx_package/ckanext/hdx_package/actions/authorize.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import ckan.authz as new_authz
import ckan.logic.auth.create as create
import ckan.logic.auth.update as update
import ckan.plugins.toolkit as tk
Expand Down Expand Up @@ -168,3 +169,15 @@ def hdx_send_mail_request_tags(context, data_dict):

def hdx_mark_resource_in_hapi(context: Context, data_dict: DataDict):
return _check_hdx_user_permission(context, Permissions.PERMISSION_MANAGE_IN_HAPI_FLAG)


def hdx_request_access(context: Context):
"""
Only a logged-in user can request data access.
"""

user_obj = context.get('auth_user_obj') or context.get('user_obj')
if user_obj:
return {'success': True}

return {'success': False, 'msg': _('Not authorized to perform this request.')}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import logging
ccataalin marked this conversation as resolved.
Show resolved Hide resolved

import ckan.lib.navl.dictization_functions as dictization_functions
import ckan.logic as logic
import ckan.plugins.toolkit as tk
from ckan.types import Context, DataDict, Request, Validator
from ckan.logic.schema import validator_args
from ckan.lib.navl.dictization_functions import validate

get_action = tk.get_action
check_access = tk.check_access
config = tk.config
h = tk.h
NotAuthorized = tk.NotAuthorized
unicode_safe = tk.get_validator('unicode_safe')
log = logging.getLogger(__name__)


@validator_args
def dataset_contact_contributor_schema(not_empty: Validator, email_validator: Validator):
schema = {
'topic': [not_empty, unicode_safe],
'fullname': [not_empty, unicode_safe],
'email': [not_empty, email_validator, unicode_safe],
'msg': [not_empty, unicode_safe],
}
return schema


class DatasetContactContributorLogic(object):
def __init__(self, context: Context, request: Request):
self.request = request
self.context = context
self.form = request.form
self.schema = dataset_contact_contributor_schema()

def read(self) -> DataDict:
data_dict = logic.clean_dict(dictization_functions.unflatten(logic.tuplize_dict(logic.parse_params(self.form))))
return data_dict

def validate(self, data_dict: DataDict):
try:
validated_response = validate(data_dict, self.schema, self.context)
except Exception as ex:
log.error(ex)

return validated_response

def send_mail(self):
data_dict = {
'topic': self.request.form.get('topic'),
'fullname': self.request.form.get('fullname'),
'email': self.request.form.get('email'),
'msg': self.request.form.get('msg'),
'pkg_owner_org': self.request.form.get('pkg_owner_org'),
'pkg_title': self.request.form.get('pkg_title'),
'pkg_id': self.request.form.get('pkg_id'),
'pkg_url': h.url_for('dataset_read', id=self.request.form.get('pkg_id'), qualified=True),
'hdx_email': config.get('hdx.faqrequest.email', '[email protected]'),
}

get_action('hdx_send_mail_contributor')(self.context, data_dict)
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import json
import logging

import ckan.lib.navl.dictization_functions as dictization_functions
import ckan.logic as logic
import ckan.model as model
import ckan.plugins.toolkit as tk
import ckanext.hdx_users.helpers.mailer as hdx_mailer
from ckan.types import Context, DataDict, Request
from ckan.lib.navl.dictization_functions import validate
from ckanext.requestdata.logic.schema import request_create_schema
from ckanext.requestdata.view_helper import process_extras_fields

get_action = tk.get_action
check_access = tk.check_access
config = tk.config
h = tk.h
g = tk.g
NotAuthorized = tk.NotAuthorized
NotFound = tk.ObjectNotFound
unicode_safe = tk.get_validator('unicode_safe')
log = logging.getLogger(__name__)


class DatasetRequestAccessLogic(object):
def __init__(self, context: Context, request: Request):
self.request = request
self.context = context
self.form = request.form
self.schema = request_create_schema()

def read(self) -> DataDict:
data_dict = logic.clean_dict(dictization_functions.unflatten(logic.tuplize_dict(logic.parse_params(self.form))))
return data_dict

def validate(self, data_dict: DataDict):
try:
validated_response = validate(data_dict, self.schema, self.context)
except Exception as ex:
log.error(ex)

return validated_response

def send_request(self) -> tuple[bool, str]:
data = self.request.form.to_dict()
get_action('requestdata_request_create')(self.context, data)

pkg_dict = get_action('package_show')(self.context, {'id': data['package_id']})

maintainer_id = pkg_dict['maintainer']
if maintainer_id is None:
return False, 'Dataset maintainer email not found.'

user_obj = self.context['auth_user_obj']

# Get users objects from maintainers list
context_user_show = {
'model': model,
'session': model.Session,
'user': g.user,
'auth_user_obj': g.userobj,
'keep_email': True,
}

data_dict = {
'users': []
}
recipients = []
maintainer_dict = {}
try:
maintainer_dict = get_action('user_show')(context_user_show, {'id': maintainer_id})
data_dict['users'].append(maintainer_dict)
recipients.append({'display_name': maintainer_dict.get('fullname'), 'email': maintainer_dict.get('email')})
except NotFound:
pass

if len(recipients) == 0:
admins = _org_admins_for_dataset(self.context, pkg_dict['name'])

for admin in admins:
recipients.append({'display_name': admin.get('fullname'), 'email': admin.get('email')})

sender_name = data.get('sender_name', '')
sender_email = data.get('email_address', '')
user_email = user_obj.email
message = data['message_content']

try:
sender_org = get_action('organization_show')(self.context, {'id': data.get('sender_organization_id')})
except NotFound:
sender_org = None

organizations = get_action('organization_list_for_user')(self.context, {
'id': user_obj.id,
'permission': 'read'
})
extras = json.loads(process_extras_fields(data, organizations, sender_org))

_send_email_to_maintainer(sender_name, message, user_email, extras, recipients, maintainer_dict, pkg_dict)
_send_email_to_requester(sender_name, sender_email, message, user_email, pkg_dict)

# notify package creator that new data request was made
get_action('requestdata_notification_create')(self.context, data_dict)

data_dict = {
'package_id': data['package_id'],
'flag': 'request'
}
get_action('requestdata_increment_request_data_counters')(self.context, data_dict)

return True, 'Email message was successfully sent.'


def _org_admins_for_dataset(context: Context, dataset_name: str):
pkg_dict = get_action('package_show')(context, {'id': dataset_name})
owner_org = pkg_dict['owner_org']

org = get_action('organization_show')(context, {'id': owner_org})

admins = []
for user in org['users']:
if user['capacity'] == 'admin':
db_user = model.User.get(user['id'])
data = {
'email': db_user.email,
'fullname': db_user.fullname or db_user.name
}
admins.append(data)

return admins


def _send_email_to_requester(sender_name: str, sender_email: str, message: str, user_email: str,
pkg_dict: DataDict) -> None:
subject = u'Request for access to metadata-only dataset'
email_data = {
'user_fullname': sender_name,
'msg': message,
'org_name': pkg_dict.get('organization').get('title'),
'dataset_link': h.url_for('dataset_read', id=pkg_dict['name'], qualified=True),
'dataset_title': pkg_dict['title'],
}
senders_email = [{'display_name': sender_name, 'email': sender_email}]
hdx_mailer.mail_recipient(senders_email, subject, email_data, footer=user_email,
snippet='email/content/request_data_to_user.html')


def _send_email_to_maintainer(sender_name: str, message: str, user_email: str, extras, recipients,
maintainer_dict: DataDict, pkg_dict: DataDict):
subject = sender_name + u' has requested access to one of your datasets: ' + pkg_dict['title']
email_data = {
'user_fullname': sender_name,
'user_email': user_email,
'msg': message,
'extras': extras,
'org_name': pkg_dict.get('organization').get('title'),
'dataset_link': h.url_for('dataset_read', id=pkg_dict['name'], qualified=True),
'dataset_title': pkg_dict['title'],
'maintainer_fullname': maintainer_dict.get('display_name') or maintainer_dict.get(
'fullname') if maintainer_dict else 'HDX user',
'requestdata_org_url': h.url_for('requestdata_organization_requests.requested_data',
id=pkg_dict.get('owner_org'), qualified=True)
}
hdx_mailer.mail_recipient(recipients, subject, email_data, footer='[email protected]',
snippet='email/content/request_data_to_admins.html')
1 change: 1 addition & 0 deletions ckanext-hdx_package/ckanext/hdx_package/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ def get_auth_functions(self):
'hdx_dataseries_update': authorize.hdx_dataseries_update,
'hdx_p_coded_resource_update': authorize.hdx_p_coded_resource_update,
'hdx_mark_resource_in_hapi': authorize.hdx_mark_resource_in_hapi,
'hdx_request_access': authorize.hdx_request_access,
'hdx_qa_hapi_report_view': authorize.hdx_qa_hapi_report_view,
}

Expand Down
57 changes: 0 additions & 57 deletions ckanext-hdx_package/ckanext/hdx_package/views/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
import logging

from flask import Blueprint, make_response
from six import text_type

import ckan.lib.captcha as captcha
import ckan.model as model
import ckan.plugins.toolkit as tk

from ckan.views.api import CONTENT_TYPES
from ckan.lib.mailer import MailerException

import ckanext.hdx_package.helpers.membership_data as membership_data
import ckanext.hdx_users.helpers.helpers as usr_h
Expand Down Expand Up @@ -43,60 +41,6 @@ def _build_json_response(data_dict, status=200):
return response


def contact_contributor():
'''
Send a contact request form
:return:
'''
context = {
'model': model,
'session': model.Session,
'user': g.user,
'auth_user_obj': g.userobj
}
data_dict = {}
try:
usr_h.is_valid_captcha(request.form.get('g-recaptcha-response'))

check_access('hdx_send_mail_contributor', context, data_dict)
# for k, v in membership_data.get('contributor_topics').iteritems():
# if v == request.form.get('topic'):
# data_dict['topic'] = v
data_dict['topic'] = request.form.get('topic')
data_dict['fullname'] = request.form.get('fullname')
data_dict['email'] = request.form.get('email')
data_dict['msg'] = request.form.get('msg')
data_dict['pkg_owner_org'] = request.form.get('pkg_owner_org')
data_dict['pkg_title'] = request.form.get('pkg_title')
data_dict['pkg_id'] = request.form.get('pkg_id')
data_dict['pkg_url'] = h.url_for('dataset_read', id=request.form.get('pkg_id'), qualified=True)
data_dict['hdx_email'] = config.get('hdx.faqrequest.email', '[email protected]')

hdx_validate_email(data_dict['email'])

except NotAuthorized:
return _build_json_response(
{'success': False, 'error': {'message': u'You have to log in before sending a contact request'}})
except captcha.CaptchaError:
return _build_json_response(
{'success': False, 'error': {'message': _(u'Bad Captcha. Please try again.')}})
except Exception as e:
log.error(e)
return _build_json_response({'success': False, 'error': {'message': u'There was an error. Please contact support'}})

try:
get_action('hdx_send_mail_contributor')(context, data_dict)
except MailerException as e:
error_summary = _('Could not send request for: %s') % text_type(e)
log.error(error_summary)
return _build_json_response({'success': False, 'error': {'message': error_summary}})
except Exception as e:
# error_summary = e.error or str(e)
log.error(e)
return _build_json_response({'success': False, 'error': {'message': u'There was an error. Please contact support'}})
return _build_json_response({'success': True})


def contact_members():
'''
Send a contact request form
Expand Down Expand Up @@ -150,5 +94,4 @@ def contact_members():
return _build_json_response({'success': True})


hdx_contact.add_url_rule(u'/contact_contributor', view_func=contact_contributor, methods=[u'POST'])
hdx_contact.add_url_rule(u'/contact_members', view_func=contact_members, methods=[u'POST'])
Loading
Loading