Skip to content
This repository was archived by the owner on Sep 19, 2022. It is now read-only.

Commit 4e5e00f

Browse files
author
Dominik František Bučík
authored
Merge pull request #169 from BaranekD/wayf_enhanced_search
feat: WAYF search by localized name and domain
2 parents 528ec6e + fb205cb commit 4e5e00f

File tree

5 files changed

+271
-80
lines changed

5 files changed

+271
-80
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
All notable changes to this project will be documented in this file.
33

44
## [Unreleased]
5+
#### Changed
6+
- Improve WAYF searching by localized name and domain
7+
58
#### Fixed
69
- Detailed endpoint format when spaced in EndpointMapToArray
710
- Revert change to INDEX_MIN in EndpointMapToArray

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"ext-curl": "*",
3333
"ext-json": "*",
3434
"ext-openssl": "*",
35+
"ext-iconv": "*",
3536
"web-token/jwt-key-mgmt": "^2.2",
3637
"web-token/jwt-signature": "^2.2",
3738
"web-token/jwt-signature-algorithm-rsa": "^2.2",

lib/Disco.php

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SimpleSAML\Module\perun;
44

5+
use Normalizer;
56
use SimpleSAML\Module\discopower\PowerIdPDisco;
67
use SimpleSAML\Utils\HTTP;
78
use SimpleSAML\Error\Exception;
@@ -486,9 +487,11 @@ public static function showEntry(
486487
array $metadata,
487488
$favourite = false
488489
): string {
490+
$searchData = htmlspecialchars(self::constructSearchData($metadata));
489491
$extra = ($favourite ? ' favourite' : '');
490492
$href = $t->getContinueUrl($metadata[self::IDP_ENTITY_ID]);
491-
$html = '<a class="metaentry' . $extra . ' list-group-item" href="' . $href. '">';
493+
$html = '<a class="metaentry' . $extra .
494+
' list-group-item" data-search="' . $searchData . '" href="' . $href. '">';
492495
$html .= '<strong>' . $t->getTranslatedEntityName($metadata) . '</strong>';
493496
$html .= '</a>';
494497

@@ -773,11 +776,53 @@ public static function getScripts(bool $boxed): string
773776
{
774777
$html = '<script type="text/javascript" src="' .
775778
Module::getModuleUrl('discopower/assets/js/suggest.js') . '"></script>' . PHP_EOL;
779+
780+
$html .= '<script type="text/javascript" src="' .
781+
Module::getModuleUrl('perun/res/js/jquery.livesearch.js') . '"></script>' . PHP_EOL;
782+
776783
$html .= '<script type="text/javascript" src="' .
777784
Module::getModuleUrl('perun/res/js/disco.js') . '"></script>' . PHP_EOL;
778785
if ($boxed) {
779786
$html .= Disco::boxedDesignScript() . PHP_EOL;
780787
}
781788
return $html;
782789
}
790+
791+
private static function arrayFlatten($array): array
792+
{
793+
$return = [];
794+
if (is_array($array)) {
795+
foreach ($array as $key => $value) {
796+
if (is_array($value)) {
797+
$return = [ ...$return, ...self::arrayFlatten($value)];
798+
} else {
799+
$return = [ ...$return, $value];
800+
}
801+
}
802+
} else {
803+
$return = [$array];
804+
}
805+
return $return;
806+
}
807+
808+
private static function constructSearchData($idpMetadata): string
809+
{
810+
$res = '';
811+
$dataSearchKeys = [];
812+
if (!empty($idpMetadata['UIInfo'])) {
813+
$idpMetadata = array_merge($idpMetadata, $idpMetadata['UIInfo']);
814+
}
815+
816+
$keys = ['entityid', 'OrganizationName', 'OrganizationDisplayName',
817+
'name', 'url', 'OrganizationURL', 'scope', 'DisplayName'];
818+
819+
foreach ($keys as $key) {
820+
if (!empty($idpMetadata[$key])) {
821+
$dataSearchKeys = [...$dataSearchKeys, ...self::arrayFlatten($idpMetadata[$key])];
822+
}
823+
}
824+
$res .= (' ' . implode(' ', $dataSearchKeys));
825+
826+
return strtolower(str_replace('"', '', iconv('UTF-8', 'US-ASCII//TRANSLIT', $res)));
827+
}
783828
}

www/res/js/disco.js

Lines changed: 49 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,63 @@
1-
let forceShow = false;
2-
3-
function setForceShow(val) {
4-
forceShow = val;
5-
}
6-
7-
$.fn.liveUpdate = function(list) {
8-
list = $(list);
9-
if (list.length) {
10-
var rows = list.children('a'), cache = rows.map(function () {
11-
return jQuery(this).text().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, "");
12-
});
13-
14-
this.keyup(filter).keyup().parents('form').submit(function () {
15-
return false;
16-
});
17-
}
18-
return this;
19-
20-
function filter() {
21-
const searchTerm = $.trim($(this).val().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, ""));
22-
const scores = [];
23-
rows.hide();
24-
showNoEntriesFound(false);
25-
if (!searchTerm) {
26-
setForceShow(false);
27-
return;
28-
}
29-
cache.each(function (i) {
30-
const score = this.score(searchTerm);
31-
if (score > 0) {
32-
scores.push([score, i]);
33-
}
34-
});
35-
if (scores.length === 0) {
36-
showNoEntriesFound(true);
37-
} else if (!forceShow && scores.length > 7) {
38-
showWarningTooMuchEntries(true, scores.length + 1);
39-
} else {
40-
$.each(
41-
scores.sort(
42-
function(a, b) { return b[0] - a[0];}),
43-
function() {$(rows[this[1]]).show();
44-
});
45-
}
46-
}
47-
};
48-
49-
function showWarningTooMuchEntries(show, cnt = 0) {
1+
function hideAll () {
2+
$("#list").hide();
503
$('#no-entries').hide();
51-
if (show) {
52-
$('#warning-entries').show();
53-
} else {
54-
$('#warning-entries').hide();
55-
}
56-
$('#results-cnt').text(cnt);
4+
$('#warning-entries').hide();
575
}
586

59-
function showNoEntriesFound(show) {
60-
$('#warning-entries').hide();
61-
if (show) {
62-
$('#no-entries').show();
7+
$(document).ready(function() {
8+
if ($("#last-used-idp-wrap").length > 0) {
9+
$("#last-used-idp .metaentry").focus();
6310
} else {
64-
$('#no-entries').hide();
11+
$("#entries").show();
6512
}
66-
}
6713

68-
$(document).ready(function() {
69-
$("#query").liveUpdate("#list");
7014
$("#showEntries").click(function() {
7115
$("#last-used-idp-wrap").hide();
7216
$("#entries").show();
7317
$("#showEntries").hide();
7418
});
75-
$("#showEntriesFromDropdown").click(function() {
76-
$("#dropdown-entries").toggle();
19+
20+
let forceShow = false
21+
$('#query').keyup(function() {
22+
const filter = $(this).val().trim().toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, "")
23+
if (!filter) {
24+
hideAll();
25+
forceShow = false;
26+
} else {
27+
let matches = [];
28+
$('#list a').each(function () {
29+
if ($(this).attr('data-search').indexOf(filter) >= 0) {
30+
matches.push(this);
31+
} else {
32+
$(this).hide();
33+
}
34+
});
35+
if (matches.length <= 0) {
36+
$('#no-entries').show();
37+
$('#warning-entries').hide();
38+
} else {
39+
$("#list").show();
40+
$('#results-cnt').text(matches.length);
41+
$('#no-entries').hide();
42+
if (matches.length > 10 && !forceShow) {
43+
matches.forEach(m => {
44+
$(m).hide();
45+
});
46+
$('#warning-entries').show();
47+
} else {
48+
$('#warning-entries').hide();
49+
matches.forEach(m => {
50+
$(m).show();
51+
});
52+
}
53+
}
54+
}
7755
});
78-
if ($("#last-used-idp-wrap").length > 0) {
79-
$("#last-used-idp .metaentry").focus();
80-
} else {
81-
$("#entries").show();
82-
}
83-
$('#warning-entries-btn-force-show').click(function() {
84-
$('#query').trigger('keyup');
85-
showWarningTooMuchEntries(false);
86-
showEntries();
56+
57+
$('#warning-entries-btn-force-show').click(function(event) {
58+
event.preventDefault();
59+
forceShow = true;
60+
$('#warning-entries').hide();
61+
$('#query').trigger('keyup').focus();
8762
});
8863
});
89-
90-
function showEntries() {
91-
setForceShow(true);
92-
$('#query').trigger('keyup');
93-
}

0 commit comments

Comments
 (0)