Commit 66ebb341 authored by Geoffroy ARNOUD's avatar Geoffroy ARNOUD

Updated idpApi (extracted objects / added UT), added IDP sorting into common.php #K7

parent 06596ec4
......@@ -70,3 +70,13 @@ foreach ($IDProviders as $key => $values) {
$IDProviders[$key]['Type'] = 'unknown';
}
}
/*------------------------------------------------*/
// Sort Identity Providers
/*------------------------------------------------*/
if ($useSAML2Metadata) {
// Only automatically sort if list of Identity Provider is parsed
// from metadata instead of being manualy managed
sortIdentityProviders($IDProviders);
}
......@@ -6,138 +6,7 @@
/*------------------------------------------------*/
/*------------------------------------------------*/
/*------------------------------------------------*/
// Classes ued to ease API management
/*------------------------------------------------*/
/*------------------------------------------------*/
/*
* This class models an IdP to be easily translated to Json
*/
final class IdpObject
{
// Attributes required by SELECT2 (cf https://select2.org/data-sources/formats)
public $id;
public $text;
// Attributes required by WAY
public $entityId;
public $SSO;
public $name;
public $names = array();
public $protocols;
public $logo;
public function __construct($entId, $idp)
{
// FIXME groups are missing
$this->entityId = $entId;
$this->id = $entId;
global $language;
if (!isset($language)) {
$language = 'fr';
}
$this->text = (isset($idp[$language]['Name'])) ? $idp[$language]['Name'] : $idp['Name'];
foreach ($idp as $key => $value) {
if ($key == "SSO") {
$this->SSO = $value;
}
if ($key == "Name") {
$this->name = $value;
}
if ($key == "Protocols") {
$this->protocols = $value;
}
if ($key == "Logo") {
if (sizeof($value) > 0) {
$this->logo = $value{"URL"};
}
}
// languages
if (isset($value{"Name"})) {
// Asume it's a language
$this->names{$key} = $value{"Name"};
}
}
}
}
/*
* The goal of this class is to provide accessors to IDP, in the form on JSON array
* with pagination
* Respects Select2 AJAX API => https://select2.org/data-sources/ajax
*/
final class IdpRepository
{
// The idps in the form of IdpObject
public $idpObjects = array();
public function __construct(array $IDProviders = array())
{
foreach ($IDProviders as $key => $value) {
$tmp = new IdpObject($key, $value);
$this->idpObjects[] = $tmp;
}
}
public function countIdps()
{
return sizeof($this->idpObjects);
}
/*
* JSON conversion of all IDPs
*/
public function toJson()
{
return json_encode($this->idpObjects);
}
/*
* Return a page of the IDPs
*/
public function toJsonByPage($pageNumber, $pageSize=10)
{
return $this->getPage($this->idpObjects, $pageNumber, $pageSize);
}
private function getPage($array, $pageNumber, $pageSize)
{
$from = ($pageNumber - 1) * $pageSize;
$idpPage = array_slice($array, $from, $pageSize);
$result{"results"} = $idpPage;
$result{"pagination"}{"more"} = (($pageNumber + 1)*$pageSize <= $this->countIdps());
return json_encode($result);
}
/*
* Return a pge of IDPs matching the $query
*/
public function toJsonByQuery($query, $pageNumber, $pageSize=10)
{
// Search in IdpObject::text, IdpObject::name
return $this->getPage(
array_filter(
$this->idpObjects,
function ($value) use ($query) {
// FIXME : ne pas comparer les accents
return (
fnmatch("*".$query."*", $value->name, FNM_CASEFOLD)
|| fnmatch("*".$query."*", $value->text, FNM_CASEFOLD)
);
}
),
$pageNumber,
$pageSize
);
}
}
// TODO : gérer la pré-sélection
// TODO : gérer le groupes
......@@ -145,6 +14,7 @@ final class IdpRepository
$topLevelDir = dirname(__DIR__);
require('common.php');
require('idpApiObjects.php');
header('Content-Type: application/json');
......
<?php
/*------------------------------------------------*/
/*------------------------------------------------*/
// Classes ued to ease API management
/*------------------------------------------------*/
/*------------------------------------------------*/
$topLevelDir = dirname(__DIR__);
require_once($topLevelDir . '/lib/functions.php');
/*
* This class models an IdP to be easily translated to Json
*/
final class IdpObject
{
// Attributes required by SELECT2 (cf https://select2.org/data-sources/formats)
public $id;
public $text;
// Attributes required by WAY
public $entityId;
public $SSO;
public $name;
public $names = array();
public $protocols;
public $logo;
public function __construct($entId, $idp)
{
// FIXME groups are missing
$this->entityId = $entId;
$this->id = $entId;
global $language;
if (!isset($language)) {
$language = 'fr';
}
$this->text = (isset($idp[$language]['Name'])) ? $idp[$language]['Name'] : $idp['Name'];
foreach ($idp as $key => $value) {
if ($key == "SSO") {
$this->SSO = $value;
}
if ($key == "Name") {
$this->name = $value;
}
if ($key == "Protocols") {
$this->protocols = $value;
}
if ($key == "Logo") {
if (sizeof($value) > 0) {
$this->logo = $value{"URL"};
}
}
// languages
if (isset($value{"Name"})) {
// Asume it's a language
$this->names{$key} = $value{"Name"};
}
}
}
}
/*
* The goal of this class is to provide accessors to IDP, in the form on JSON array
* with pagination
* Respects Select2 AJAX API => https://select2.org/data-sources/ajax
*/
final class IdpRepository
{
// The idps in the form of IdpObject
public $idpObjects = array();
public function __construct(array $IDProviders = array())
{
foreach ($IDProviders as $key => $value) {
$tmp = new IdpObject($key, $value);
$this->idpObjects[] = $tmp;
}
}
public function countIdps()
{
return sizeof($this->idpObjects);
}
/*
* JSON conversion of all IDPs
*/
public function toJson()
{
return json_encode($this->idpObjects);
}
/*
* Return a page of the IDPs
*/
public function toJsonByPage($pageNumber, $pageSize=10)
{
return $this->getPage($this->idpObjects, $pageNumber, $pageSize);
}
private function getPage($array, $pageNumber, $pageSize)
{
$from = ($pageNumber - 1) * $pageSize;
$idpPage = array_slice($array, $from, $pageSize);
$result{"results"} = $idpPage;
$result{"pagination"}{"more"} = (($pageNumber + 1)*$pageSize <= $this->countIdps());
return json_encode($result, JSON_UNESCAPED_SLASHES);
}
/*
* Return a pge of IDPs matching the $query
*/
public function toJsonByQuery($query, $pageNumber, $pageSize=10)
{
// Search in IdpObject::text, IdpObject::name
return $this->getPage(
array_filter(
$this->idpObjects,
function ($value) use ($query) {
// FIXME : ne pas comparer les accents
return (
fnmatch("*".removeAccents($query)."*", removeAccents($value->name), FNM_CASEFOLD)
|| fnmatch("*".removeAccents($query)."*", removeAccents($value->text), FNM_CASEFOLD)
);
}
),
$pageNumber,
$pageSize
);
}
}
<?php
use PHPUnit\Framework\TestCase;
require("../lib/idpApiObjects.php");
final class IdpApiTest extends TestCase
{
public function testCount()
{
require("test.idps.php");
printf("\nNb IDP = %d", count($metadataIDProviders));
$repo = new IdpRepository($metadataIDProviders);
$this->assertEquals(
3,
$repo->countIdps()
);
}
// École des Ponts ParisTech
public function testQuery()
{
$query="ecole des Ponts";
require("test.IDProvider.metadata.php");
$repo = new IdpRepository($metadataIDProviders);
$this->assertEquals(
'{"results":[{"id":"https://rigal.enpc.fr/idp/shibboleth","text":"\u00c9cole des Ponts ParisTech","entityId":"https://rigal.enpc.fr/idp/shibboleth","SSO":"https://rigal.enpc.fr/idp/profile/Shibboleth/SSO","name":"\u00c9cole des Ponts ParisTech","names":{"en":"\u00c9cole des Ponts ParisTech","fr":"\u00c9cole des Ponts ParisTech"},"protocols":"urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0 urn:oasis:names:tc:SAML:2.0:protocol","logo":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAB7ElEQVQoz42Rz2/SYBjHX/rSvmW0sK6WhLLLPIhwdX+C2YWYGdDIMJpF/Z+W6XHxJgtTTCZb0xX5ddOMpWNhbiCQFHugykvXtQIeZjAq030vT57n+X6e7+EB40tUq9WmzgkwTUo+n9l6Xa+f/L2aAti2fXhY43m+WHx/JeBdLufz+Z49fWJZ5/l84T+A1taOjuosy8qywnFctboPgP0vICdLPpYV5vhIJMzz3HA4yr7duRSoVqvn1tnq6mNsDnRdh5CMx++22x1dNyYe13g8njRra+sQQp6f6/f7hvFVEK55PDOtdksQhNRK8s+EQqHQM3qI9tA0EoRAOHzDP+tHCHloz+dmS1XVC5v7ohiGcXCgLt5a7HTasVhsckXX9Wy2G4ncLJUr0Wj0V8LurkTTaGnpNgFhJrM1Aba3cxzHLS/fGY9GiqL8BJrN5snpKULoVXqTdLuPjz9pmgYAUFW12/3iOE46vQkh/PBxH9g2AQDIF4pBURTF4L1EPBAQQvPi3p4CACiXK6IYDIXmE4n4wsJ1lmHe5HaIUqmCv/UfPUwBACRJpih6JZnEeLCx8ZKiUCqVNM2BJMkkCRMP7jcaDdf68xcYY5Zhvg+Hpml6Z7wQuswzC2M86/eTFOU4jmVZjJdxES7D6P32h6voB98GBPZakOIQAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE1LTA3LTIwVDEwOjUwOjIwKzAyOjAwq4YxQQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNS0wNy0yMFQxMDo1MDoyMCswMjowMNrbif0AAAAASUVORK5CYII="}],"pagination":{"more":true}}',
$repo->toJsonByQuery($query, 1)
);
}
// public function testIdpObject()
// {
// require("test.idps.php");
// foreach ($metadataIDProviders as $key => $value) {
// if ($key == "http://idp-condorcet.dev.entrouvert.org/idp/saml2/metadata") {
// // printf("\nkey = %s\n", $key);
// $idp = new IdpObject($key, $value);
// // printf("\nidp = %s\n", json_encode($idp));
// $this->assertEquals(
// "http://idp-condorcet.dev.entrouvert.org/idp/saml2/metadata",
// $idp->entityId
// );
// }
// }
// }
// public function testToJsonByQuery()
// {
// require("test.IDProvider.metadata.php");
//
// $repo = new IdpRepository($metadataIDProviders);
//
// printf("\n%s\n", $repo->toJsonByQuery("arnoud", 1));
// }
}
This diff is collapsed.
<?php
$metadataIDProviders = array(
'http://idp-condorcet.dev.entrouvert.org/idp/saml2/metadata' =>
array(
'SSO' => 'http://idp-condorcet.dev.entrouvert.org/idp/saml2/sso',
'Name' => 'Campus Condorcet - POC RICCO Project',
'en' =>
array(
'Name' => 'Campus Condorcet - POC RICCO Project',
),
'fr' =>
array(
'Name' => 'Campus Condorcet - POC Projet RICCO',
),
'Protocols' => 'urn:oasis:names:tc:SAML:2.0:protocol',
),
'http://idp-pre.math.cnrs.fr/idp/shibboleth' =>
array(
'SSO' => 'http://idp-pre.math.cnrs.fr/idp/profile/Shibboleth/SSO',
'Name' => 'idp de test mathrice-plm-team-bdx-novembre-2016',
'en' =>
array(
'Name' => 'idp de test mathrice-plm-team-bdx-novembre-2016',
),
'fr' =>
array(
'Name' => 'idp de test mathrice-plm-team-bdx-novembre-2016',
),
'Protocols' => 'urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0 urn:oasis:names:tc:SAML:2.0:protocol',
),'https://195.220.94.102/idp/shibboleth' =>
array(
'SSO' => 'https://195.220.94.102/idp/profile/SAML2/Redirect/SSO',
'Name' => 'Idp test G.Arnoud',
'en' =>
array(
'Name' => 'Idp test G.Arnoud EN',
),
'fr' =>
array(
'Name' => 'Idp test G.Arnoud FR',
),
'Protocols' => 'urn:oasis:names:tc:SAML:2.0:protocol',
'Logo' =>
array(
'URL' => 'data:image/gif;base64,R0lGODlhEAAQADUMACH5BAEAAAwAIfkEAQAADAAsAAAAABAAEACDREJExLqk/OZ07ObM7L5c1JIs/Pbs5Na8XFpc/PKM/Npk/P78////AAAAAAAAAAAABHCQMURrlXguszrvSIZ83DcMRighaOca8KAyQICaQ6DPtD1sOUIBcKEVbLCAQgj4LUKAAsGnZAIATyNBETAklkOaTKsQeMEAMVTKzaFph/VWEPhaD3GyIGEf4lU1bHxCAQCGGAB4BwSMimkZNIYWhxkRACH+DmF1dG9tYXR0aWNfaW5jADs=',
),
)
);
......@@ -364,15 +364,15 @@ if ($hintedCookieIdP != '-') {
$selectedIDP = '-';
}
/*------------------------------------------------*/
// Sort Identity Providers
/*------------------------------------------------*/
if ($useSAML2Metadata) {
// Only automatically sort if list of Identity Provider is parsed
// from metadata instead of being manualy managed
sortIdentityProviders($IDProviders);
}
// /*------------------------------------------------*/
// // Sort Identity Providers
// /*------------------------------------------------*/
//
// if ($useSAML2Metadata) {
// // Only automatically sort if list of Identity Provider is parsed
// // from metadata instead of being manualy managed
// sortIdentityProviders($IDProviders);
// }
/*------------------------------------------------*/
// Draw WAYF
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment