bdp connector (#5777)
This commit is contained in:
parent
1b603959fa
commit
7c4557a623
|
@ -0,0 +1,9 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from models import Bdp
|
||||
|
||||
|
||||
class BdpAdmin(admin.ModelAdmin):
|
||||
prepopulated_fields = {'slug': ('title',)}
|
||||
|
||||
admin.site.register(Bdp, BdpAdmin)
|
|
@ -0,0 +1,20 @@
|
|||
from django.utils.text import slugify
|
||||
from django import forms
|
||||
|
||||
from .models import Bdp
|
||||
|
||||
class BdpForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Bdp
|
||||
exclude = ('slug', 'users')
|
||||
|
||||
def save(self, commit=True):
|
||||
if not self.instance.slug:
|
||||
self.instance.slug = slugify(self.instance.title)
|
||||
return super(BdpForm, self).save(commit=commit)
|
||||
|
||||
|
||||
class BdpUpdateForm(BdpForm):
|
||||
class Meta:
|
||||
model = Bdp
|
||||
exclude = ('users',)
|
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'Bdp'
|
||||
db.create_table(u'bdp_bdp', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
|
||||
('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
|
||||
('description', self.gf('django.db.models.fields.TextField')()),
|
||||
('service_url', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('username', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)),
|
||||
('password', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)),
|
||||
('verify_cert', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('keystore', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal(u'bdp', ['Bdp'])
|
||||
|
||||
# Adding M2M table for field users on 'Bdp'
|
||||
m2m_table_name = db.shorten_name(u'bdp_bdp_users')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('bdp', models.ForeignKey(orm[u'bdp.bdp'], null=False)),
|
||||
('apiuser', models.ForeignKey(orm[u'base.apiuser'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['bdp_id', 'apiuser_id'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Bdp'
|
||||
db.delete_table(u'bdp_bdp')
|
||||
|
||||
# Removing M2M table for field users on 'Bdp'
|
||||
db.delete_table(db.shorten_name(u'bdp_bdp_users'))
|
||||
|
||||
|
||||
models = {
|
||||
u'base.apiuser': {
|
||||
'Meta': {'object_name': 'ApiUser'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'fullname': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ipsource': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
|
||||
'key': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
|
||||
'keytype': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'bdp.bdp': {
|
||||
'Meta': {'object_name': 'Bdp'},
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'keystore': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'service_url': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['base.ApiUser']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'verify_cert': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['bdp']
|
|
@ -0,0 +1,66 @@
|
|||
import json
|
||||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from passerelle.base.models import BaseResource
|
||||
|
||||
class Bdp(BaseResource):
|
||||
service_url = models.CharField(max_length=128, blank=False,
|
||||
verbose_name=_('Service URL'),
|
||||
help_text=_('BDP Web Service URL'))
|
||||
username = models.CharField(max_length=128, blank=True,
|
||||
verbose_name=_('Username'))
|
||||
password = models.CharField(max_length=128, blank=True,
|
||||
verbose_name=_('Password'))
|
||||
verify_cert = models.BooleanField(default=True,
|
||||
verbose_name=_('Check HTTPS Certificate validity'))
|
||||
keystore = models.FileField(upload_to='pastell',
|
||||
blank=True, null=True,
|
||||
verbose_name=_('Keystore'),
|
||||
help_text=_('Certificate and private key in PEM format'))
|
||||
|
||||
category = _('Business Process Connectors')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('BDP Web Service')
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('bdp-view', kwargs={'slug': self.slug})
|
||||
|
||||
@classmethod
|
||||
def get_add_url(cls):
|
||||
return reverse('bdp-add')
|
||||
|
||||
@classmethod
|
||||
def get_verbose_name(cls):
|
||||
return cls._meta.verbose_name
|
||||
|
||||
@classmethod
|
||||
def get_icon_class(cls):
|
||||
return 'bdp'
|
||||
|
||||
def requests_options(self):
|
||||
options = {}
|
||||
if self.keystore:
|
||||
options['cert'] = (self.keystore.path, self.keystore.path)
|
||||
if not self.verify_cert:
|
||||
options['verify'] = False
|
||||
if self.username:
|
||||
options['auth'] = HTTPBasicAuth(self.username, self.password)
|
||||
return options
|
||||
|
||||
def get_api(self, endpoint, **params):
|
||||
options = self.requests_options()
|
||||
return requests.get(self.service_url + '/api/' + endpoint,
|
||||
params=params, **options).json()
|
||||
|
||||
def post_api(self, endpoint, obj):
|
||||
data = json.dumps(obj)
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
options = self.requests_options()
|
||||
return requests.post(self.service_url + '/api/' + endpoint,
|
||||
data=data, headers=headers, **options).json()
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "passerelle/manage.html" %}
|
||||
|
||||
{% block more-user-links %}
|
||||
{{ block.super }}
|
||||
{% if object.id %}
|
||||
<a href="{% url 'bdp-view' slug=object.slug %}">{{ object.title }}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,65 @@
|
|||
{% extends "bdp/base.html" %}
|
||||
{% load i18n passerelle %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>BDP - {{ object.title }}</h2>
|
||||
{% if perms.bdp.change_bdp %}
|
||||
<a rel="popup" class="button" href="{% url 'bdp-edit' slug=object.slug %}">{% trans 'edit' %}</a>
|
||||
{% endif %}
|
||||
{% if perms.bdp.delete_bdp %}
|
||||
<a rel="popup" class="button" href="{% url 'bdp-delete' slug=object.slug %}">{% trans 'delete' %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>
|
||||
Service URL : {{ object.service_url }}
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<h3>{% trans 'Endpoints' %}</h3>
|
||||
<ul>
|
||||
<li>{% trans 'Listing ressources:' %} <a
|
||||
>{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='ressources' %}</a> (GET)</li>
|
||||
<li>{% trans 'Create a new user:' %} <a
|
||||
>{{ site_base_uri }}{% url 'bdp-post-adherent' slug=object.slug %}</a> (POST)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>{% trans 'Examples' %}</h3>
|
||||
<ul>
|
||||
<li>{% trans 'Libraries:' %} <a
|
||||
href="{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='bibliotheques' %}"
|
||||
>{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='bibliotheques' %}</a>
|
||||
</li>
|
||||
<li>{% trans 'Libraries with a text label:' %} <a
|
||||
href="{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='bibliotheques' %}?text_key=nom"
|
||||
>{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='bibliotheques' %}?text_key=nom</a>
|
||||
</li>
|
||||
<li>{% trans 'Members:' %} <a
|
||||
href="{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='adherents' %}"
|
||||
>{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='adherents' %}</a>
|
||||
</li>
|
||||
<li>{% trans 'Filtered Members:' %} <a
|
||||
href="{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='adherents' %}?filter[0][field]=email&filter[0][operator]=eq&filter[0][value]=login@example.net"
|
||||
>{{ site_base_uri }}{% url 'bdp-ressources' slug=object.slug ressources='adherents' %}?filter[0][field]=email&filter[0][operator]=eq&filter[0][value]=login@example.net</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if perms.base.view_accessright %}
|
||||
<div>
|
||||
<h3>{% trans "Security" %}</h3>
|
||||
|
||||
<p>
|
||||
{% trans 'Accessing is limited to the following API users:' %}
|
||||
</p>
|
||||
|
||||
{% access_rights_table resource=object permission='can_access' %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
|||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.conf.urls import patterns, url
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from views import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^(?P<slug>[\w,-]+)/$', BdpDetailView.as_view(), name='bdp-view'),
|
||||
url(r'^(?P<slug>[\w,-]+)/(?P<ressources>[\w,-]+)/$', RessourcesView.as_view(), name='bdp-ressources'),
|
||||
url(r'^(?P<slug>[\w,-]+)/post/adherent/$', csrf_exempt(PostAdherentView.as_view()), name='bdp-post-adherent'),
|
||||
)
|
||||
|
||||
management_urlpatterns = patterns('',
|
||||
url(r'^add$', BdpCreateView.as_view(), name='bdp-add'),
|
||||
url(r'^(?P<slug>[\w,-]+)/edit$', BdpUpdateView.as_view(), name='bdp-edit'),
|
||||
url(r'^(?P<slug>[\w,-]+)/delete$', BdpDeleteView.as_view(), name='bdp-delete'),
|
||||
)
|
|
@ -0,0 +1,88 @@
|
|||
import json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import Http404
|
||||
from django.views.generic.base import View
|
||||
from django.views.generic.detail import SingleObjectMixin, DetailView
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||
|
||||
from jsonresponse import to_json
|
||||
|
||||
from passerelle import utils
|
||||
|
||||
from .models import Bdp
|
||||
from .forms import BdpForm, BdpUpdateForm
|
||||
|
||||
# See documentation:
|
||||
# https://dev.entrouvert.org/projects/bdp/wiki/WebServices
|
||||
|
||||
|
||||
class RessourcesView(View, SingleObjectMixin):
|
||||
model = Bdp
|
||||
|
||||
@utils.protected_api('can_access')
|
||||
@to_json('api')
|
||||
def get(self, request, *args, **kwargs):
|
||||
text_key = request.GET.get('text_key')
|
||||
id_key = request.GET.get('id_key')
|
||||
ressources = self.get_object().get_api(kwargs['ressources'], **(request.GET))
|
||||
for r in ressources:
|
||||
if id_key:
|
||||
r['id'] = r[id_key]
|
||||
r['id'] = '%s' % r['id']
|
||||
if text_key:
|
||||
r['text'] = r[text_key]
|
||||
elif 'text' not in r:
|
||||
r['text'] = r['id']
|
||||
return ressources
|
||||
|
||||
|
||||
class PostAdherentView(View, SingleObjectMixin):
|
||||
model = Bdp
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
raise Http404
|
||||
|
||||
@utils.protected_api('can_access')
|
||||
@to_json('api')
|
||||
def post(self, request, *args, **kwargs):
|
||||
data = json.loads(request.body) # JSON w.c.s. formdata
|
||||
date_de_naissance = data['fields'].get('date_de_naissance')
|
||||
if len(date_de_naissance) == 19: # 1973-04-18T00:00:00 without timezone
|
||||
date_de_naissance += 'Z'
|
||||
adherent = {
|
||||
'nom': data['fields'].get('nom'),
|
||||
'prenom': data['fields'].get('prenom'),
|
||||
'email': data['fields'].get('courriel'),
|
||||
'hashpass': data['fields'].get('mot_de_passe'),
|
||||
'dateNaissance': date_de_naissance,
|
||||
'actif': 'on',
|
||||
'bibliotheque': {'id': data['fields'].get('bibliotheque_raw')},
|
||||
'abonnements': '15',
|
||||
}
|
||||
return self.get_object().post_api('adherents', adherent)
|
||||
|
||||
|
||||
class BdpDetailView(DetailView):
|
||||
model = Bdp
|
||||
template_name = 'bdp/bdp_detail.html'
|
||||
|
||||
|
||||
class BdpCreateView(CreateView):
|
||||
model = Bdp
|
||||
form_class = BdpForm
|
||||
template_name = 'passerelle/manage/service_form.html'
|
||||
|
||||
|
||||
class BdpUpdateView(UpdateView):
|
||||
model = Bdp
|
||||
form_class = BdpUpdateForm
|
||||
template_name = 'passerelle/manage/service_form.html'
|
||||
|
||||
|
||||
class BdpDeleteView(DeleteView):
|
||||
model = Bdp
|
||||
template_name = 'passerelle/manage/service_confirm_delete.html'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('manage-home')
|
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -26,3 +26,6 @@ li.pastell a:hover { background-image: url(icons/icon-pastell-hover.png); }
|
|||
|
||||
li.concerto a { background-image: url(icons/icon-concerto.png); }
|
||||
li.concerto a:hover { background-image: url(icons/icon-concerto-hover.png); }
|
||||
|
||||
li.bdp a { background-image: url(icons/icon-bdp.png); }
|
||||
li.bdp a:hover { background-image: url(icons/icon-bdp-hover.png); }
|
||||
|
|
|
@ -18,6 +18,7 @@ import ovh.urls
|
|||
import oxyd.urls
|
||||
import pastell.urls
|
||||
import concerto.urls
|
||||
import bdp.urls
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
|
@ -69,6 +70,10 @@ urlpatterns = patterns('',
|
|||
url(r'^manage/concerto/',
|
||||
decorated_includes(login_required, include(concerto.urls.management_urlpatterns))),
|
||||
|
||||
url(r'^bdp/', include(bdp.urls.urlpatterns)),
|
||||
url(r'^manage/bdp/',
|
||||
decorated_includes(login_required, include(bdp.urls.management_urlpatterns))),
|
||||
|
||||
)
|
||||
|
||||
# activate URL for installed apps only
|
||||
|
|
Loading…
Reference in New Issue