diff options
author | Nathan Kinder <nkinder@redhat.com> | 2015-03-16 21:58:10 -0700 |
---|---|---|
committer | Nathan Kinder <nkinder@redhat.com> | 2015-03-20 07:57:46 -0700 |
commit | 0562d486c6906bbba909bddf1326a9ed497b4443 (patch) | |
tree | ba8948711a8f9f2694f54158e12353c757b71c7c | |
parent | 83ec7148841303516fe31e76116b70c8a5f73aab (diff) | |
download | ipsilon-ticket_25.tar.gz ipsilon-ticket_25.tar.xz ipsilon-ticket_25.zip |
Mapped Attrs - WIPticket_25
-rw-r--r-- | ipsilon/providers/saml2/admin.py | 43 | ||||
-rw-r--r-- | ipsilon/providers/saml2/auth.py | 1 | ||||
-rw-r--r-- | ipsilon/providers/saml2/provider.py | 14 | ||||
-rw-r--r-- | ipsilon/util/config.py | 1 | ||||
-rw-r--r-- | templates/admin/providers/saml2_sp.html | 57 |
5 files changed, 115 insertions, 1 deletions
diff --git a/ipsilon/providers/saml2/admin.py b/ipsilon/providers/saml2/admin.py index 0ab2a41..e9d37ea 100644 --- a/ipsilon/providers/saml2/admin.py +++ b/ipsilon/providers/saml2/admin.py @@ -23,6 +23,7 @@ from ipsilon.admin.common import ADMIN_STATUS_WARN from ipsilon.providers.saml2.provider import ServiceProvider from ipsilon.providers.saml2.provider import ServiceProviderCreator from ipsilon.providers.saml2.provider import InvalidProviderId +import json import re import requests @@ -205,7 +206,32 @@ class SPAdminPage(AdminPage): raise InvalidValueFormat(err) return {'allowed_nameids': list(v)} else: - raise UnauthorizedUser("Unauthorized to set alowed nameids values") + raise UnauthorizedUser("Unauthorized to set allowed nameids values") + + def change_attribute_mappings(self, from_attrs, to_attrs, deleted_mappings): + mappings = [] + + if self.user.is_admin: + if len(from_attrs) != len(to_attrs): + raise InvalidValueFormat('Invalid attribute mapping value') + else: + raise UnauthorizedUser('Unauthorized to set attribute mapping values') + + mappings = [] + for i in range(len(from_attrs)): + # Don't add deleted mappings + if i not in deleted_mappings: + mappings.append([from_attrs[i], to_attrs[i]]) + + if mappings == self.sp.attribute_mappings: + return False + + if self.user.is_admin: + self._debug("Replacing attribute_mappings: %s -> %s" % + (self.sp.attribute_mappings, mappings)) + return {'attribute_mappings': json.dumps(mappings)} + else: + raise UnauthorizedUser('Unauthorized to set attribute mapping values') def POST(self, *args, **kwargs): @@ -219,6 +245,7 @@ class SPAdminPage(AdminPage): r = self.change_name(key, value) if r: results.update(r) + elif key == 'owner': r = self.change_owner(key, value) if r: @@ -234,6 +261,18 @@ class SPAdminPage(AdminPage): if r: results.update(r) + # Extract all of the attribute mapping values + from_attrs = dict((int(k.replace(' attribute_mappings-from', '')), v) for + k,v in kwargs.iteritems() if k.endswith('attribute_mappings-from')) + to_attrs = dict((int(k.replace(' attribute_mappings-to', '')), v) for + k,v in kwargs.iteritems() if k.endswith('attribute_mappings-to')) + deleted_mappings = dict((int(k.replace(' attribute_mappings-delete', '')), v) for + k, v in kwargs.iteritems() if k.endswith('attribute_mappings-delete')) + + r = self.change_attribute_mappings(from_attrs, to_attrs, deleted_mappings) + if r: + results.update(r) + except InvalidValueFormat, e: message = str(e) message_type = ADMIN_STATUS_WARN @@ -258,6 +297,8 @@ class SPAdminPage(AdminPage): self.sp.default_nameid = results['default_nameid'] if 'allowed_nameids' in results: self.sp.allowed_nameids = results['allowed_nameids'] + if 'attribute_mappings' in results: + self.sp.attribute_mappings = results['attribute_mappings'] self.sp.save_properties() if 'rename' in results: rename = results['rename'] diff --git a/ipsilon/providers/saml2/auth.py b/ipsilon/providers/saml2/auth.py index f5e8f0f..e3fcb48 100644 --- a/ipsilon/providers/saml2/auth.py +++ b/ipsilon/providers/saml2/auth.py @@ -202,6 +202,7 @@ class AuthenticateRequest(ProviderPageBase): raise AuthenticationError("Unavailable Name ID type", lasso.SAML2_STATUS_CODE_AUTHN_FAILED) + # NGK(TODO) - get and apply SP specific policies here # Check attribute policy and perform mapping and filtering policy = Policy(self.cfg.default_attribute_mapping, self.cfg.default_allowed_attributes) diff --git a/ipsilon/providers/saml2/provider.py b/ipsilon/providers/saml2/provider.py index c02d6fb..7e1c6c0 100644 --- a/ipsilon/providers/saml2/provider.py +++ b/ipsilon/providers/saml2/provider.py @@ -18,6 +18,7 @@ from ipsilon.providers.common import ProviderException from ipsilon.tools.saml2metadata import SAML2_NAMEID_MAP from ipsilon.util.log import Log +import json import lasso @@ -100,6 +101,19 @@ class ServiceProvider(Log): def default_nameid(self, value): self._staging['default nameid'] = value + # NGK(TODO) - the default needs to be the global policy, then override here. + # This hard-coded mapping will need to be removed at that time. + @property + def attribute_mappings(self): + if 'attribute mappings' in self._properties: + return json.loads(self._properties['attribute mappings']) + else: + return [['*', '*'],] + + @attribute_mappings.setter + def attribute_mappings(self, value): + self._staging['attribute mappings'] = json.dumps(value) + def save_properties(self): data = self.cfg.get_data(name='id', value=self.provider_id) if len(data) != 1: diff --git a/ipsilon/util/config.py b/ipsilon/util/config.py index 947c697..f6c09a6 100644 --- a/ipsilon/util/config.py +++ b/ipsilon/util/config.py @@ -199,6 +199,7 @@ class ComplexList(List): self.set_value(jsonval) +# NGK(TODO) - We might want to use this instead. class MappingList(ComplexList): def _check_value(self, value): diff --git a/templates/admin/providers/saml2_sp.html b/templates/admin/providers/saml2_sp.html index 84e46a9..5f1c305 100644 --- a/templates/admin/providers/saml2_sp.html +++ b/templates/admin/providers/saml2_sp.html @@ -1,4 +1,28 @@ {% extends "master-admin.html" %} +{% block scripts %} + <script> + $( document ).on("click", ".add-field", + function() { + var buttonRow = $(this).parents(".add-row") + var ourTable = $(this).parents(".extensible-table") + var lastRow = $(ourTable).find(".list-field:last") + var newRow = $(lastRow).clone() + var lastIndex = parseInt(newRow.find("td:first").text()) + newRow.find("td:first").text(lastIndex + 1) + var inputFields = newRow.find("input") + for (i = 0; i < inputFields.length; i++) { + var oldidx = (lastIndex-1).toString()+" " + var newidx = lastIndex.toString()+" " + var newname = $(inputFields[i]).attr("name").replace(oldidx, newidx) + $(inputFields[i]).attr("name", newname) + $(inputFields[i]).attr("value", "") + } + $(newRow).appendTo(ourTable) + $(buttonRow).appendTo(ourTable) + } + ); + </script> +{% endblock %} {% block main %} <h2>{{ title }}</h2> {% if message %} @@ -58,6 +82,39 @@ </div> {% endif %} + {% if user.is_admin %} + <div class="form-group"> + <label for="attribute_mappings">Attribute Mappings:</label> + <table class="table table-striped extensible-table"> + <tr><th>#</th><th>From</th><th>To</th><th>Delete</th></tr> + {% for line in data.attribute_mappings -%} + {%- set basename = "%d attribute_mappings-"|format(loop.index0) -%} + <tr class="list-field"> + <td>{{loop.index}}</td> + <td> + <input type="text" name="{{basename}}from" + value="{{ line[0] }}" + > + </td> + <td> + <input type="text" name="{{basename}}to" + value="{{ line[1] }}" + > + </td> + <td> + <input type="checkbox" name="{{basename}}delete"> + <!-- Never cheked by default --> + </td> + </tr> + {% endfor -%} + <tr class="add-row"> + <td><button class="btn add-field" type="button"> + </button></td> + <td colspan=3 /> + </tr> + </table> + </div> + {% endif %} + {% if user.name == data.owner or user.is_admin %} <button id="submit" class="btn btn-primary" name="submit" type="submit" value="Submit"> Save |