summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Marillonnet <pmarillonnet@entrouvert.com>2017-07-05 10:04:25 (GMT)
committerPaul Marillonnet <pmarillonnet@entrouvert.com>2017-07-05 10:04:25 (GMT)
commitf75740a333de1debaafdbdd77793410158ed0f54 (patch)
tree80ecbfdeac7f7abf81501c59a83b65a1f4af2407
parent4ef381c8088322f51f9d413b79f387a6eda8249a (diff)
downloadpaul-synchro-f75740a333de1debaafdbdd77793410158ed0f54.zip
paul-synchro-f75740a333de1debaafdbdd77793410158ed0f54.tar.gz
paul-synchro-f75740a333de1debaafdbdd77793410158ed0f54.tar.bz2
POC Campus Condorcet : docstrings partie 1
-rw-r--r--django/sp_sso/invite/forms.py16
-rw-r--r--django/sp_sso/invite/utils.py13
-rw-r--r--django/sp_sso/invite/views.py10
-rw-r--r--django/sp_sso/saml/decorators.py16
-rw-r--r--django/sp_sso/saml/forms.py6
-rw-r--r--django/sp_sso/saml/models.py8
-rw-r--r--django/sp_sso/saml/tests.py1
-rw-r--r--django/sp_sso/saml/utils.py17
8 files changed, 84 insertions, 3 deletions
diff --git a/django/sp_sso/invite/forms.py b/django/sp_sso/invite/forms.py
index 1b5f3bb..0736a3c 100644
--- a/django/sp_sso/invite/forms.py
+++ b/django/sp_sso/invite/forms.py
@@ -5,7 +5,23 @@ from .utils import get_invitaton_attributes_mapping, get_additional_prefilled_fi
class InvitationForm(forms.Form):
+ """ Used when sending invites to the Campus
+
+ Invites are sent to the `email` field. Multiple adresses are handled if
+ they are separated by a blank space ` ` character.
+
+ This form is restricted to users having previously registered to the
+ Campus ; therefore they must log in to their RENATER-federated account
+ before accessing the form.
+ """
def __init__(self, *args, **kwargs):
+ """
+ Attributes fetched from the identity provider are used to pre-fill
+ the fields.
+ An extra hidden field is used to store the user's
+ eduPersonPrincipalName, used as key identity attribute in the
+ corresponding LDAP entry.
+ """
super(InvitationForm, self).__init__(*args, **kwargs)
# Add a help text for sending multiple invitations
self.fields['email'].help_text = _(
diff --git a/django/sp_sso/invite/utils.py b/django/sp_sso/invite/utils.py
index 5cc40fd..4f49b39 100644
--- a/django/sp_sso/invite/utils.py
+++ b/django/sp_sso/invite/utils.py
@@ -21,12 +21,21 @@ PASSERELLE_PEOPLE_QUERY = 'http://dir-condorcet.dev.entrouvert.org/ldapquery/con
logger = logging.getLogger('django')
def get_invitaton_attributes_mapping():
+ """ Full copy of the invitation attributes mapping dictionary """
return INVITATION_ATTRIBUTES_MAPPING.copy()
def get_additional_prefilled_fields():
+ """
+ Returns a full copy of the additional fields to be prefilled with the
+ user's fetched attributes.
+ """
return ADDITIONAL_PREFILLED_FIELDS[:]
def do_invite(invitation):
+ """
+ Sends invitation data to the invitation w.c.s. form.
+ Invitations will then be sent as part of the w.c.s. workflow.
+ """
opener = build_opener(HTTPHandler)
# Generate a JSON to bind against the wcs ReST API
form = {}
@@ -48,6 +57,10 @@ def do_invite(invitation):
def get_affectations_from_eppn(eppn):
+ """
+ Returns a tuple (<Institution identifier>, <Researcher unit identifier>)
+ for a given eduPersonPrincipalName (a.k.a. `eppn`)
+ """
if eppn:
try:
ldapquery = urlopen(PASSERELLE_PEOPLE_QUERY)
diff --git a/django/sp_sso/invite/views.py b/django/sp_sso/invite/views.py
index e5b21fd..ce85b63 100644
--- a/django/sp_sso/invite/views.py
+++ b/django/sp_sso/invite/views.py
@@ -15,10 +15,20 @@ MSG_INVITATION_SENT = _("Your invitation has been sent.")
def invitation_sent(request):
+ """
+ Notifies the user about her invitation(s) by displaying a validation
+ message.
+ """
return render_message(request, MSG_INVITATION_SENT)
class InvitationFormView(FormView):
+ """
+ Main FormView for the invitation process.
+
+ Gathers SSO attributes from the identity provider, used to pre-fill and
+ set as readonly the `InvitationForm` fields.
+ """
form_class = InvitationForm
template_name = 'invite/invitation_form.html'
success_url = '/invite/sent'
diff --git a/django/sp_sso/saml/decorators.py b/django/sp_sso/saml/decorators.py
index 518ee87..91eda4f 100644
--- a/django/sp_sso/saml/decorators.py
+++ b/django/sp_sso/saml/decorators.py
@@ -18,6 +18,10 @@ MSG_USER_NOT_REGISTERED = _("Please register to the campus before sending "
"invites.")
def user_not_in_ldap(function):
+ """
+ Restricts access to users whose eduPersonPrincipalName attribute value
+ doesn't appear in a ou=people sub-entry in the Campus LDAP.
+ """
def wrapped(request, *args, **kwargs):
if 'type' in kwargs and kwargs['type'] == 'mellon':
user_data = saml_collect_data(request)
@@ -28,6 +32,10 @@ def user_not_in_ldap(function):
return wrapped
def user_in_ldap(function):
+ """
+ Restricts access to users whose eduPersonPrincipalName attribute value
+ appear in a `ou=people...` sub-entry in the Campus LDAP.
+ """
def wrapped(request, *args, **kwargs):
if not 'mellon_session' in request.session:
return redirect(reverse('auth_login') + "?next=/invite/")
@@ -39,6 +47,14 @@ def user_in_ldap(function):
return wrapped
def user_can_declare(function):
+ """
+ Ensure that all conditions are met for a user to self-subscribe to the
+ Campus. At the moment, these two conditions are:
+ - the user's EduPersonPrincipalName attribute value mustn't appear in the
+ Campus LDAP base
+ - the user's institution or research unit should appear as registered
+ structures in the Campus LDAP base
+ """
def wrapped(request, *args, **kwargs):
if not request.session.get('mellon_session'):
return redirect(reverse('auth_login') + '?next=/declare/')
diff --git a/django/sp_sso/saml/forms.py b/django/sp_sso/saml/forms.py
index 2fdbadd..5f51d31 100644
--- a/django/sp_sso/saml/forms.py
+++ b/django/sp_sso/saml/forms.py
@@ -32,7 +32,13 @@ ETABLISSEMENT_CHOICES = ()
UNITE_CHOICES = ()
class RegistrationForm(forms.Form):
+ """
+ Main registration form when requesting access to the Campus.
+ User data may be fetched for a single sign-on (SSO) procedure and used to
+ pre-fill the fields. Pre-filled fields are also set as readonly to ensure
+ that the data fetched from the SSO process and sent to w.c.s. is genuine.
+ """
user_help_msg = ''
user_nickname = ''
diff --git a/django/sp_sso/saml/models.py b/django/sp_sso/saml/models.py
index 0911263..ea5429b 100644
--- a/django/sp_sso/saml/models.py
+++ b/django/sp_sso/saml/models.py
@@ -3,6 +3,14 @@ from django.contrib.auth.models import AbstractUser
class SupAnnUser(AbstractUser):
+ """ Base user of the SSO scheme. OBSOLETE
+
+ eduPerson and supann2009 attributes have been added so that theses
+ attributes can be retrieved in mellon.
+
+ XXX mellon attributes are also stored in the session.
+ (see the request.session['mellon_session'] dict)
+ """
# eduPerson attributes:
ep_principal_name = models.CharField(max_length=100,default='user_eppn')
ep_primary_affiliation = models.CharField(max_length=100, default="")
diff --git a/django/sp_sso/saml/tests.py b/django/sp_sso/saml/tests.py
index e94c8ec..8134add 100644
--- a/django/sp_sso/saml/tests.py
+++ b/django/sp_sso/saml/tests.py
@@ -5,6 +5,7 @@ import requests
# Create your tests here.
class ServicesTestCase(TestCase):
+ """Ensure that all four services are up and running."""
def test_ldap_connection(self):
l = ldap_init()
self.assertTrue(l)
diff --git a/django/sp_sso/saml/utils.py b/django/sp_sso/saml/utils.py
index 5ff3502..5e5768b 100644
--- a/django/sp_sso/saml/utils.py
+++ b/django/sp_sso/saml/utils.py
@@ -29,9 +29,17 @@ supann_host_role_value = '{SUPANN}R10' # 'Responsable de mission'
def render_message(request, message):
+ """Renders a simple message to a base template"""
return render(request, 'simple_message.html', {'message': message})
def generate_eppn(lastname):
+ """
+ Used when no eduPersonPrincipalName attribute is fetched from the
+ identity provider during the single sign-on process.
+
+ Returns a randomly generated EPPN value in the form of a valid Campus
+ Condorcet email address.
+ """
return "%s-%06d@campus-condorcet.fr"%(lastname, randint(0,pow(10,6)))
@@ -59,19 +67,22 @@ def ldap_init():
def ldap_get_etablissements():
-# Used to fill the choices in hote_etablissemnt form ChoiceField:
+ """Used to fill the choices in hote_etablissemnt form ChoiceField."""
return ldap_get_attribute_from_subtree_nodes(
structures_base, '(objectClass=supannOrg)', 'ou')
def ldap_get_unites():
-# Used to fill the choices in hote_unite form ChoiceField:
+ """Used to fill the choices in hote_unite form ChoiceField."""
return ldap_get_attribute_from_subtree_nodes(
structures_base, '(supannTypeEntite=*)', 'ou')
def ldap_get_affectations():
-# Used to fill the choices in s_entite_affectation_principale form ChoiceField:
+ """
+ Used to fill the choices in s_entite_affectation_principale form
+ ChoiceField.
+ """
return ldap_get_attribute_from_subtree_nodes(
structures_base, '(objectClass=supannEntite)', 'supannCodeEntite')