summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2015-03-16 21:58:10 -0700
committerNathan Kinder <nkinder@redhat.com>2015-03-20 07:57:46 -0700
commit0562d486c6906bbba909bddf1326a9ed497b4443 (patch)
treeba8948711a8f9f2694f54158e12353c757b71c7c
parent83ec7148841303516fe31e76116b70c8a5f73aab (diff)
downloadipsilon-ticket_25.tar.gz
ipsilon-ticket_25.tar.xz
ipsilon-ticket_25.zip
Mapped Attrs - WIPticket_25
-rw-r--r--ipsilon/providers/saml2/admin.py43
-rw-r--r--ipsilon/providers/saml2/auth.py1
-rw-r--r--ipsilon/providers/saml2/provider.py14
-rw-r--r--ipsilon/util/config.py1
-rw-r--r--templates/admin/providers/saml2_sp.html57
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