welco/welco/contacts/views.py

169 lines
6.4 KiB
Python

# welco - multichannel request processing
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import logging
import random
import requests
import time
from django import template
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.template import RequestContext
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView, FormView
from welco.utils import get_wcs_data, sign_url
from .forms import ContactAddForm
class HomeZone(object):
def __init__(self, request):
self.request = request
def render(self):
tmpl = template.loader.get_template('contacts/zone.html')
return tmpl.render(request=self.request)
class ContactsZone(TemplateView):
template_name = 'contacts/zone.html'
def get_context_data(self, **kwargs):
context = super(ContactsZone, self).get_context_data(**kwargs)
context['source_pk'] = self.request.GET.get('source_pk')
if 'source_pk' in self.request.GET:
source_class = ContentType.objects.get(
id=self.request.GET['source_type']).model_class()
source_object = source_class.objects.get(id=self.request.GET['source_pk'])
context['contact_user_id'] = source_object.contact_id
return context
def post(self, request, *args, **kwargs):
if 'user_id' in request.POST:
source_class = ContentType.objects.get(
id=self.request.POST['source_type']).model_class()
source_object = source_class.objects.get(id=self.request.POST['source_pk'])
source_object.contact_id = request.POST['user_id']
source_object.save()
return HttpResponse('ok')
zone = csrf_exempt(ContactsZone.as_view())
def search_json(request):
user_groups = set([x.name for x in request.user.groups.all()])
for channel in settings.CHANNEL_ROLES:
channel_groups = set(settings.CHANNEL_ROLES[channel])
if user_groups.intersection(channel_groups):
break
else:
raise PermissionDenied()
query = request.GET.get('q')
if query:
result = get_wcs_data('api/users/', {'q': query, 'limit': 10})
if result.get('err') != 0:
raise Exception('error %r' % result)
for user in result.get('data'):
user['title'] = user['user_display_name']
more = [user.get('user_var_address'), user.get('user_var_phone'),
user.get('user_var_mobile'), user.get('user_var_email')]
user['more'] = ' / '.join([x for x in more if x])
if user.get('user_roles'):
user['roles'] = ' / '.join([r['text'] for r in user['user_roles']])
user['slug'] = 'user-%s' % user['user_id']
else:
result = {'data': []}
response = HttpResponse(content_type='application/json')
json.dump(result, response, indent=2)
return response
class ContactDetailFragmentView(TemplateView):
template_name = 'contacts/contact_detail_fragment.html'
def get_context_data(self, **kwargs):
context = super(ContactDetailFragmentView, self).get_context_data(**kwargs)
user_id = self.kwargs.get('slug').split('-')[-1]
user_details = get_wcs_data('api/users/%s/' % user_id)
context.update(user_details)
context['forms'] = get_wcs_data('api/users/%s/forms' % user_id).get('data') or []
context['user_id'] = user_id
if 'source_pk' in self.request.GET:
source_class = ContentType.objects.get(
id=self.request.GET['source_type']).model_class()
source_object = source_class.objects.get(id=self.request.GET['source_pk'])
context['is_pinned_user'] = bool(source_object.contact_id == user_id)
return context
contact_detail_fragment = ContactDetailFragmentView.as_view()
class ContactAdd(FormView):
template_name = 'contacts/contact_add.html'
form_class = ContactAddForm
def post(self, request):
form = self.get_form(self.get_form_class())
msg = {}
for field_key in form.fields:
if form[field_key].value():
msg[field_key] = form[field_key].value()
msg['password'] = str(random.SystemRandom().random())
msg['send_registration_email'] = getattr(settings, 'CONTACT_SEND_REGISTRATION_EMAIL', True)
authentic_site = settings.KNOWN_SERVICES.get('authentic').values()[0]
authentic_url = authentic_site.get('url')
authentic_orig = authentic_site.get('orig')
authentic_secret = authentic_site.get('secret')
url = authentic_url + 'api/users/?orig=%s' % authentic_orig
signed_url = sign_url(url, authentic_secret)
logger = logging.getLogger(__name__)
logger.info('POST to authentic (%r)', json.dumps(msg))
authentic_response = requests.post(
signed_url,
data=json.dumps(msg),
headers={'Content-type': 'application/json'})
logger.info('Got authentic response (%r)', authentic_response.text)
user_uuid = authentic_response.json().get('uuid')
for i in range(100):
try:
user_details = get_wcs_data('api/users/%s/' % user_uuid)
result = {'data': {'user_id': user_details.get('id')}}
break
except requests.HTTPError as e:
if e.response.status_code != 404:
raise
time.sleep(0.1)
else:
result = {'err': 1, 'data': 'timeout when calling wcs'}
response = HttpResponse(content_type='application/json')
json.dump(result, response, indent=2)
return response
contact_add = csrf_exempt(ContactAdd.as_view())