Upgrade to new Gitlab Version 13.9 on Saturday 19th April 20:00. Expect an interruption of about 30 to 60 minutes

idpApiObjects.php 6.97 KB
Newer Older
1 2 3 4
<?php

/*------------------------------------------------*/
/*------------------------------------------------*/
5
// Classes used to ease API management
6 7 8 9 10 11 12
/*------------------------------------------------*/
/*------------------------------------------------*/

$topLevelDir = dirname(__DIR__);

require_once($topLevelDir . '/lib/functions.php');

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
function getImage($imageString)
{
    global $disableRemoteLogos;

    $image = '';

    $pos = strpos($imageString, "data:image");

    if ($pos === false) {
        // remote image
        if (!$disableRemoteLogos) {
            $image = $imageString;
        }
    } else {
        // embedded image
        $image = $imageString;
    }

    return $image;
}

34 35 36 37 38 39 40 41 42 43 44
/*
 * 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;

    public $name;
    public $logo;
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
45 46
    /* group */
    public $type;
47

48

49 50
    public function __construct($entId, $idp)
    {
51
        // $this->entityId = $entId;
52 53 54 55 56 57 58 59 60 61 62 63 64 65
        $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 == "Name") {
                $this->name = $value;
            }
            if ($key == "Logo") {
                if (sizeof($value) > 0) {
66
                    $this->logo = getImage($value{"URL"});
67 68
                }
            }
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
69 70 71 72 73 74
            // Group
            if ($key == "Type") {
                $this->type = $value;
            }
        }
    }
75 76 77 78 79 80 81 82 83 84

    /*
     * Legacy data select field construction
     * to enable serach as usual
     */
    public function getDataForSearch()
    {
        global $IDProviders;
        return buildIdpData($IDProviders[$this->id], $this->id);
    }
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
85 86 87 88 89 90 91 92 93 94 95 96 97
}

/*
{
      "text": "Group 1",
      "children" : [
        {
            "id": 1,
            "text": "Option 1.1"
        },
        {
            "id": 2,
            "text": "Option 1.2"
98
        }
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
99
      ]
100
    }
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
101 102 103 104 105
*/
final class IdpGroup
{
    public $text;
    public $children = array();
106
    public $hide;
107 108 109 110 111 112 113 114 115 116 117 118
}

/*
 * 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();

Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
119
    public function __construct(array $IDProviders = array(), array $previouslySelectedIdps = null)
120
    {
121 122
        global $showNumOfPreviouslyUsedIdPs;

123

124 125 126 127 128 129 130 131
        if (isset($previouslySelectedIdps) && count($previouslySelectedIdps) > 0) {
            $counter = (isset($showNumOfPreviouslyUsedIdPs)) ? $showNumOfPreviouslyUsedIdPs : 3;
            for ($n = count($previouslySelectedIdps) - 1; $n >= 0; $n--) {
                if ($counter <= 0) {
                    break;
                }

                $selIdp = $previouslySelectedIdps[$n];
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
132 133 134
                $idp = new IdpObject($selIdp, $IDProviders[$selIdp]);
                $idp->type = getLocalString('last_used');
                $this->idpObjects[] = $idp;
135 136

                $counter--;
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
137 138 139
            }
        }

140
        foreach ($IDProviders as $key => $value) {
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
141 142 143 144 145 146 147 148 149 150 151 152 153

            // Skip categories
            if ($value['Type'] == 'category') {
                continue;
            }

            // Skip incomplete descriptions
            if (!is_array($value) || !isset($value['Name'])) {
                continue;
            }

            $idp = new IdpObject($key, $value);
            $this->idpObjects[] = $idp;
154 155 156
        }
    }

Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
157 158 159
    /*
     * Groups a given array
     */
160
    private function toGroups($array, $hideFirstGroup = false)
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
161 162 163
    {
        $result = array();
        $tmp = array();
164 165

        $firstGroup = true;
166 167
        $firstGroupName = '';
        if (!empty($array)) {
168 169
            $firstGroupName = $array[0]->type;
            // logInfo(sprintf("firstGroupName = %s", $firstGroupName));
170
        }
171

Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
172 173 174 175 176 177 178
        foreach ($array as $key => $idpObject) {
            $type = $idpObject->type;

            if (!isset($tmp[$type])) {
                $group = new IdpGroup();
                $group->text = $type;
                $tmp[$type] = $group;
179
                $group->hide = $hideFirstGroup && ($type == $firstGroupName);
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
180 181 182 183 184 185 186 187 188 189
            }
            $tmp[$type]->children[] = $idpObject;
        }

        foreach ($tmp as $key => $idpGroup) {
            $result[] = $idpGroup;
        }
        return $result;
    }

190 191 192 193 194 195 196 197 198 199
    public function countIdps()
    {
        return sizeof($this->idpObjects);
    }

    /*
     * JSON conversion of all IDPs
     */
    public function toJson()
    {
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
200
        return json_encode($this->toGroups($this->idpObjects), JSON_UNESCAPED_SLASHES);
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
    }

    /*
     * 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);

217 218 219 220 221 222 223
        $hideFirstGroup = false;
        if (isset($pageNumber) && $pageNumber > 1) {

            // Get last from previous page
            $lastPageLastGroup = $this->idpObjects[$pageNumber * $pageSize - 1]->type;
            $thisPageFirstGroup = $this->idpObjects[$pageNumber * $pageSize]->type;
            $hideFirstGroup = ($lastPageLastGroup == $thisPageFirstGroup);
224
            // logInfo(sprintf("lastPageLastGroup = %s / thisPageFirstGroup = %s", $lastPageLastGroup, $thisPageFirstGroup));
225
        }
226
        // logInfo(sprintf("hideFirstGroup = %s", $hideFirstGroup?"true":"false"));
227
        $result{"results"} = $this->toGroups($idpPage, $hideFirstGroup);
Geoffroy ARNOUD's avatar
Geoffroy ARNOUD committed
228 229

        $result{"pagination"}{"more"} = (($pageNumber + 1)*$pageSize <= sizeof($array));
230 231 232 233 234

        return json_encode($result, JSON_UNESCAPED_SLASHES);
    }

    /*
235 236 237 238 239
     * Return a page of IDPs matching the $query.
     * Search is done in:
     * - name/text
     * - getDomainNameFromURI(entityId)
     * - composeOptionData(IDProviders[entityId])
240 241 242 243 244 245 246 247
     */
    public function toJsonByQuery($query, $pageNumber, $pageSize=10)
    {
        // Search in IdpObject::text, IdpObject::name
        return $this->getPage(
          array_filter(
            $this->idpObjects,
            function ($value) use ($query) {
248
                // logDebug(sprintf("Data(%s) = %s", $value->id, $value->getDataForSearch()));
249 250 251
                return (
                    fnmatch("*".removeAccents($query)."*", removeAccents($value->name), FNM_CASEFOLD)
                 || fnmatch("*".removeAccents($query)."*", removeAccents($value->text), FNM_CASEFOLD)
252
                 || fnmatch("*".removeAccents($query)."*", removeAccents($value->getDataForSearch()), FNM_CASEFOLD)
253 254 255 256 257 258 259 260
               );
            }
          ),
          $pageNumber,
          $pageSize
          );
    }
}