Skip to content

Commit 1b09631

Browse files
committed
templating attributes with mako
1 parent 456e202 commit 1b09631

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"requests",
2626
"PyYAML",
2727
"gunicorn",
28+
"mako",
2829
"Werkzeug"
2930
],
3031
zip_safe=False,

src/satosa/internal_data.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from enum import Enum
77
import hashlib
88
import json
9+
from mako.template import Template
910
from satosa.exception import SATOSAError
1011

1112
__author__ = 'haho0032'
@@ -42,6 +43,7 @@ def __init__(self, internal_attributes):
4243
(dict[internal_name, dict[external_type, external_name]])
4344
"""
4445
self.separator = "." # separator for nested attribute values, e.g. address.street_address
46+
self.multivalue_separator = ";" # separates multiple values, e.g. when using templates
4547
self.from_internal_attributes = internal_attributes["attributes"]
4648

4749
self.external2internal_attribute_name_mapping = {}
@@ -119,14 +121,23 @@ def to_internal(self, external_type, external_dict):
119121
def _collate_attribute_values_by_priority_order(self, attribute_names, data):
120122
result = []
121123
for attr_name in attribute_names:
122-
attr_val = self._get_nested_attribute_value(attr_name, data)
124+
attr_val = None
125+
if '$' in attr_name: # this looks like a template...
126+
attr_val = self._render_attribute_template(attr_name, data)
127+
else:
128+
attr_val = self._get_nested_attribute_value(attr_name, data)
129+
123130
if isinstance(attr_val, list):
124131
result.extend(attr_val)
125132
elif attr_val:
126133
result.append(attr_val)
127134

128135
return result
129136

137+
def _render_attribute_template(self, template, data):
138+
t = Template(template,cache_enabled=True)
139+
return t.render(**data).split(self.multivalue_separator)
140+
130141
def _get_nested_attribute_value(self, nested_key, data):
131142
keys = nested_key.split(self.separator)
132143

tests/satosa/test_internal_data.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,29 @@ def test_to_internal_filter_profile_missing_attribute_mapping(self):
249249
filter = converter.to_internal_filter("bar", ["email", "uid"])
250250
assert Counter(filter) == Counter(["id"])
251251

252+
def test_simple_template_mapping(self):
253+
mapping = {
254+
"attributes": {
255+
"last_name": {
256+
"p1": ["sn"],
257+
"p2": ["sn"]
258+
},
259+
"first_name": {
260+
"p1": ["givenName"],
261+
"p2": ["givenName"]
262+
},
263+
"name": {
264+
"p2": ["cn","${givenName[0]} ${sn[0]}"]
265+
}
266+
}
267+
}
268+
269+
converter = DataConverter(mapping)
270+
internal_repr = converter.to_internal("p2", {"givenName": ["Valfrid"], "sn": ["Lindeman"]})
271+
assert "name" in internal_repr
272+
assert len(internal_repr["name"]) == 1
273+
assert internal_repr["name"][0] == "Valfrid Lindeman"
274+
252275

253276
@pytest.mark.parametrize("attribute_value", [
254277
{"email": "[email protected]"},

0 commit comments

Comments
 (0)