family: use combo.utils.requests (#10565)

Warning: modification of FAMILY_SERVICE setting format:

  FAMILY_SERVICE = {'root': '/connector/instance/'}

where '/connector/instance/' is the URL of the connector created in
passerelle.

The family cell now use the first 'passerelle' service in
KNOWN_SERVICES setting.
This commit is contained in:
Thomas NOËL 2016-04-06 00:23:33 +02:00
parent 272c3fd5a5
commit 3800769470
4 changed files with 68 additions and 57 deletions

View File

@ -1,11 +1,8 @@
Combo family cell
=================
This cell is visible only if the setting:
To be visible, this cell needs a 'passerelle' entry in settings.KNOWN_SERVICES
(see ../wcs/README) and a FAMILY_SERVICE attribute in settings:
FAMILY_SERVICE = {
"url": "<webservice url",
"signature_key": "<key">
}
FAMILY_SERVICE = {'root': '/connector/instance/'}
is declared.

View File

@ -14,17 +14,14 @@
# 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 requests
from django.conf import settings
from django.db import models
from django import template
from django.utils.translation import ugettext_lazy as _
from django.utils.http import urlencode
from combo.data.models import CellBase
from combo.data.library import register_cell_class
from combo.utils import NothingInCacheException, sign_url
from combo.utils import NothingInCacheException
from .utils import is_family_enabled, get_family_json
@register_cell_class
@ -41,19 +38,15 @@ class FamilyInfosCell(CellBase):
@classmethod
def is_enabled(cls):
return getattr(settings, 'FAMILY_SERVICE', None)
return is_family_enabled,()
def get_cell_extra_context(self, context):
context = {}
if getattr(self.context.get('request'), 'session', {}).get('mellon_session'):
name_id = self.context['request'].session['mellon_session'].get('name_id_content')
if name_id:
params = {'NameID': name_id, 'orig': self.context['request'].get_host()}
ws_family_url = sign_url(settings.FAMILY_SERVICE.get('url') +
'/family/?' + urlencode(params),
settings.FAMILY_SERVICE.get('signature_key'))
context['family'] = requests.get(ws_family_url).json()
return context
response = get_family_json('family/',
user=self.get_concerned_user(context),
raise_if_not_cached=not(context.get('synchronous')))
if response.status_code == 200:
return {'family': response.json()}
return None
def render(self, context):
self.context = context

View File

@ -0,0 +1,34 @@
# combo - content management system
# Copyright (C) 2015-2016 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/>.
from django.conf import settings
from combo.utils import requests
def get_passerelle_service():
if hasattr(settings, 'KNOWN_SERVICES') and settings.KNOWN_SERVICES.get('passerelle'):
return settings.KNOWN_SERVICES['passerelle'].values()[0]
def is_family_enabled():
return get_passerelle_service() and hasattr(settings, 'FAMILY_SERVICE')
def get_family_json(endpoint, **kwargs):
path = settings.FAMILY_SERVICE.get('root') + endpoint
return requests.get(path,
cache_duration=0, # because link/unlink cannot invalidate cache
remote_service=get_passerelle_service(),
headers={'accept': 'application/json'},
**kwargs)

View File

@ -14,27 +14,21 @@
# 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 requests
from django.conf import settings
from django.views.generic import FormView, TemplateView
from django.utils.translation import ugettext_lazy as _
from django.utils.http import urlencode
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import messages
from combo.utils import sign_url
from .forms import FamilyLinkForm
from .utils import get_family_json
ERROR_MESSAGES = {
100: _('Wrong credentials: make sure you typed them correctly.'),
101: _('This family account is blocked.')
}
DEFAULT_ERROR = _('Failed to link to family. Please check your credentials and retry later.')
class FamilyLinkView(FormView):
form_class = FamilyLinkForm
@ -47,21 +41,19 @@ class FamilyLinkView(FormView):
return '.'
def form_valid(self, form):
url = settings.FAMILY_SERVICE.get('url') + '/family/link'
if hasattr(self.request, 'session') and \
self.request.session.get('mellon_session'):
mellon = self.request.session['mellon_session']
params = urlencode({'NameID': mellon['name_id_content'],
'orig': self.request.get_host(),
'login': form.cleaned_data['family_id'],
'password': form.cleaned_data['family_code']})
url = sign_url(url + '?' + params, settings.FAMILY_SERVICE.get('signature_key'))
r = requests.get(url)
if not r.ok or r.json().get('err'):
err_code = r.json()['err']
messages.error(self.request, ERROR_MESSAGES.get(err_code, DEFAULT_ERROR))
else:
messages.info(self.request, _('Your account was successfully linked.'))
endpoint = 'family/link/?' + urlencode({
'login': form.cleaned_data['family_id'],
'password': form.cleaned_data['family_code'],
})
response = get_family_json(endpoint, user=self.request.user)
if not response.ok or response.json().get('err'):
error_code = response.json().get('err')
error_message = ERROR_MESSAGES.get(error_code,
_('Failed to link to family. Please check your credentials and retry later.'))
messages.error(self.request, error_message)
else:
messages.info(self.request, _('Your account was successfully linked.'))
return super(FamilyLinkView, self).form_valid(form)
@ -69,18 +61,13 @@ class FamilyUnlinkView(TemplateView):
template_name = 'family/unlink_confirm.html'
def post(self, request, *args, **kwargs):
url = settings.FAMILY_SERVICE.get('url') + '/family/unlink'
if hasattr(request, 'session') and \
request.session.get('mellon_session'):
mellon = request.session['mellon_session']
params = urlencode({'NameID': mellon['name_id_content'],
'orig': request.get_host()})
url = sign_url(url + '?' + params, settings.FAMILY_SERVICE.get('signature_key'))
r = requests.get(url)
if not r.ok or r.json().get('err'):
messages.error(request, _('An error occured when unlinking.'))
else:
messages.info(request, _('Your account was successfully unlinked.'))
endpoint = 'family/unlink/'
response = get_family_json(endpoint, user=request.user)
if not response.ok or response.json().get('err'):
messages.error(request, _('An error occured when unlinking.'))
else:
messages.info(request, _('Your account was successfully unlinked.'))
if self.request.META.get('HTTP_REFERER'):
return HttpResponseRedirect(self.request.META['HTTP_REFERER'])