From c10ccf739394f35ecbe1915d9c20379fc47ac901 Mon Sep 17 00:00:00 2001
From: Guillaume Rousse <guillaume.rousse@renater.fr>
Date: Wed, 5 Dec 2018 18:27:56 +0100
Subject: [PATCH] use user authentication to filter SPs attached to the same
 organization as its IdP

---
 lib/AccountManager/App.pm                | 36 ++++++++++++++++--------
 templates/web/edugain/select_sp.tt2.html | 24 +++++++---------
 templates/web/renater/select_sp.tt2.html | 25 ++++++++--------
 3 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/lib/AccountManager/App.pm b/lib/AccountManager/App.pm
index 99dc1c1..9b9769b 100644
--- a/lib/AccountManager/App.pm
+++ b/lib/AccountManager/App.pm
@@ -202,6 +202,8 @@ sub respond {
         $theme_templates_dir  :
         $default_templates_dir;
 
+    $Template::Stash::PRIVATE = undef;
+
     my $tt2 = Template->new({
         ENCODING     => 'utf8',
         PRE_CHOMP    => CHOMP_ONE,
@@ -255,7 +257,7 @@ sub req_select_sp {
 
     my @federations = split(/, */, $self->{configuration}->{federations}->{list});
 
-    my %federations;
+    my %groups;
     my @self_entities;
     foreach my $federation (@federations) {
         my $file = $self->get_metadata_file(federation => $federation);
@@ -272,9 +274,15 @@ sub req_select_sp {
         ) if $EVAL_ERROR;
 
         my $entities = $metadata->parse(type => 'sp');
-        $federations{$federation} = {
+        $groups{$federation} = {
             label    => $self->{configuration}->{$federation}->{label},
-            entities => $entities
+            entities => [
+                map { {
+                    id         => $_->{entityid},
+                    name       => $_->{display_name},
+                    federation => $federation
+                 } } @$entities
+            ]
         };
 
         # if user is authenticated, and its IdP is found in metadata,
@@ -283,13 +291,19 @@ sub req_select_sp {
             my $idps = $metadata->parse(id => $ENV{HTTP_SHIB_IDENTITY_PROVIDER});
             my $idp  = $idps->[0];
             if ($idp) {
-                $self->{logger}->debugf(
-		    "idp %s found in federation %s metadata",
-		    $ENV{HTTP_SHIB_IDENTITY_PROVIDER},
-		    $federation
-		);
                 my $organization = $idp->{organization};
+                $self->{logger}->debugf(
+                    "idp %s found in federation %s metadata with organization %s",
+                    $ENV{HTTP_SHIB_IDENTITY_PROVIDER},
+                    $federation,
+                    $organization
+                );
                 push @self_entities,
+                    map { {
+                        id         => $_->{entityid},
+                        name       => $_->{display_name},
+                        federation => $federation
+                    } }
                     grep { $_->{organization} eq $organization }
                     @$entities;
             }
@@ -297,7 +311,7 @@ sub req_select_sp {
     }
 
     if (@self_entities) {
-        $federations{self} = {
+        $groups{_self} = {
             label    => $self->{lh}->maketext("My organization"),
             entities => \@self_entities,
         };
@@ -306,8 +320,8 @@ sub req_select_sp {
     $self->respond(
         template => 'select_sp.tt2.html',
         data     => {
-            action      => 'select_sp',
-            federations => \%federations,
+            action => 'select_sp',
+            groups => \%groups,
         }
     );
 }
diff --git a/templates/web/edugain/select_sp.tt2.html b/templates/web/edugain/select_sp.tt2.html
index 35d5d90..10f7b4e 100644
--- a/templates/web/edugain/select_sp.tt2.html
+++ b/templates/web/edugain/select_sp.tt2.html
@@ -15,13 +15,13 @@
             [% lh.maketext("You must be an administrator of that service to continue afterwards.") %]
         </p>
 
-        [% FOREACH federation IN federations.keys.sort() %]
+        [% FOREACH group IN groups.keys.sort() %]
         <fieldset>
-            <label for="[% federation %]_entityid">[% federations.$federation.label %]</label>
-            <select id="[% federation %]_entityid" name="[% federation %]_entityid">
+            <label for="[% group %]">[% groups.$group.label %]</label>
+            <select id="[% group %]" name="[% group %]">
                 <option value=""></option>
-            [% FOREACH entity IN federations.$federation.entities.sort('display_name') %]
-                <option value="[% entity.entityid %]">[% entity.display_name %]</option>
+            [% FOREACH entity IN groups.$group.entities.sort('name') %]
+                <option value="[% entity.id %]" data-federation="[% entity.federation %]">[% entity.name %]</option>
             [% END %]
             </select>
         </fieldset>
@@ -80,17 +80,13 @@ $( document ).ready(function() {
                         item: ui.item.option
                     });
 
-                    // retrieve federation and entityid
-                    var id = this.element.attr('id');
-                    var id_parts = id.split('_');
-                    var federation = id_parts[0];
-                    var entity = this.element.val();
-
                     // reset other comboboxes
                     $("input[id!='" + id + "_combobox']").val("");
                     $("select[id!='" + id + "']  option:selected").prop('selected', false);
 
-                    // set federation
+                    // retrieve federation and entityid
+                    var entity     = this.element.val();
+                    var federation = this.element.find('option:selected').attr('data-federation');
                     $("#federation").val(federation);
                     $("#entityid").val(entity);
                 },
@@ -186,8 +182,8 @@ $( document ).ready(function() {
         }
     });
 
-[% FOREACH federation IN federations.keys() %]
-    $( "#[% federation %]_entityid" ).combobox();
+[% FOREACH group IN groups.keys() %]
+    $( "#[% group %]" ).combobox();
 [% END %]
 
     $.validator.messages.required = "[% lh.maketext("This information is required") %]";
diff --git a/templates/web/renater/select_sp.tt2.html b/templates/web/renater/select_sp.tt2.html
index b193c1f..7185249 100644
--- a/templates/web/renater/select_sp.tt2.html
+++ b/templates/web/renater/select_sp.tt2.html
@@ -15,13 +15,13 @@
             [% lh.maketext("You must be an administrator of that service to continue afterwards.") %]
         </p>
 
-        [% FOREACH federation IN federations.keys.sort() %]
+        [% FOREACH group IN groups.keys.sort() %]
         <fieldset>
-            <label for="[% federation %]_entityid">[% federations.$federation.label %]</label>
-            <select id="[% federation %]_entityid" name="[% federation %]_entityid">
+            <label for="[% group %]">[% groups.$group.label %]</label>
+            <select id="[% group %]" name="[% group %]">
                 <option value=""></option>
-            [% FOREACH entity IN federations.$federation.entities.sort('display_name') %]
-                <option value="[% entity.entityid %]">[% entity.display_name %]</option>
+            [% FOREACH entity IN groups.$group.entities.sort('name') %]
+                <option value="[% entity.id %]" data-federation="[% entity.federation %]">[% entity.name %]</option>
             [% END %]
             </select>
         </fieldset>
@@ -80,17 +80,14 @@ $( document ).ready(function() {
                         item: ui.item.option
                     });
 
-                    // retrieve federation and entityid
-                    var id = this.element.attr('id');
-                    var id_parts = id.split('_');
-                    var federation = id_parts[0];
-                    var entity = this.element.val();
-
                     // reset other comboboxes
+                    var id = this.element.attr('id');
                     $("input[id!='" + id + "_combobox']").val("");
                     $("select[id!='" + id + "']  option:selected").prop('selected', false);
 
-                    // set federation
+                    // retrieve federation and entityid
+                    var entity     = this.element.val();
+                    var federation = this.element.find('option:selected').attr('data-federation');
                     $("#federation").val(federation);
                     $("#entityid").val(entity);
                 },
@@ -186,8 +183,8 @@ $( document ).ready(function() {
         }
     });
 
-[% FOREACH federation IN federations.keys() %]
-    $( "#[% federation %]_entityid" ).combobox();
+[% FOREACH group IN groups.keys() %]
+    $( "#[% group %]" ).combobox();
 [% END %]
 
     $.validator.messages.required = "[% lh.maketext("This information is required") %]";
-- 
GitLab