README.md 15.8 KB
Newer Older
Marco Malavolti's avatar
Marco Malavolti committed
1
# EduGAIN Connectivity Check Service - ECCS
Marco Malavolti's avatar
Marco Malavolti committed
2

Marco Malavolti's avatar
Marco Malavolti committed
3
4
5
6
7
8
9
10
1. [Introduction](#introduction)
2. [Check Performed on the IdPs](#check-performed-on-the-idps)
3. [Limitations](#limitations)
4. [Disable Checks](#disable-checks)
5. [On-line interface](#on-line-interface)
6. [Requirements Hardware](#requirements-hardware)
7. [Requirements Software](#requirements-software)
8. [HOWTO Install and Configure](#howto-install-and-configure)
Marco Malavolti's avatar
Marco Malavolti committed
11
   * [Python 3](#python-3)
Marco Malavolti's avatar
Marco Malavolti committed
12
13
     + [CentOS 7 requirements](#centos-7-requirements)
     + [Debian requirements](#debian-requirements)
Marco Malavolti's avatar
Marco Malavolti committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
     + [Install](#install)
   * [Install the Chromedriver](#install-the-chromedriver)
   * [Install Google Chrome needed by Selenium](#install-google-chrome-needed-by-selenium)
   * [ECCS Script](#eccs-script)
     + [Install](#install-1)
     + [Configure](#configure)
     + [Execute](#execute)    
9. [ECCS API Server (UWSGI)](#eccs-api-server-uwsgi)
   * [Install](#install-1)
   * [Configure](#configure-1)
   * [Utility](#utility)
10. [ECCS API JSON](#eccs-api-json)
11. [Utility for web interface](#utility-for-web-interface)
12. [Utility for developers](#utility-for-developers)
    * [ECCS API Development Server](#eccs-api-development-server)
13. [Authors](#authors)
Marco Malavolti's avatar
Marco Malavolti committed
30
31
32

# Introduction

Marco Malavolti's avatar
Marco Malavolti committed
33
The purpose of the eduGAIN Connectivity Check is to identify eduGAIN Identity Providers (IdP) that are not properly configured. In particular it checks if an IdP properly loads and consumes SAML2 metadata which contains the eduGAIN Service Providers (SP). The check results are published on the public eduGAIN Connectivity Check web page (### NOT-AVAILABLE-YET ###). The main purpose is to increase the service overall quality and user experience of the eduGAIN interfederation service by making federation and Identity Provider operators aware of configuration problems.
Marco Malavolti's avatar
Marco Malavolti committed
34
35
36
37
38
39
40
41
42
43
44
45

The check is performed by sending a SAML authentication request to each eduGAIN IdP and then follow the various HTTP redirects. The expected result is a login form that allows users to authenticate (typically with username/password) or an error message of some form. For those Identity Providers that output an error message, it can be assumed that they don't consume eduGAIN metadata properly or that they suffer from another configuration problem. There are some cases where the check will generate false positives, therefore IdPs can be excluded from checks as is described below.

The Identity Providers are checked once per day. Therefore, the login requests should not have any significant effect on the log entries/statistics of an Identity Provider. Also, no actual login is performed because the check cannot authenticate users due to missing username and password for the IdPs. Only Identity Providers are checked but not the Service Providers.

# Check Performed on the IdPs

The check executed by the service follows these steps:

1. It retrieves the eduGAIN IdPs from eduGAIN Operator Team database via a JSON interface

2. For each IdP that is was not manually disabled by the eduGAIN Operations Team, the check creates a Wayfless URL for each SP involved and retrieves the IdP login page. It expects to find the HTML form with a username and password field. Therefore, no complete login will happen at the Identity Provider because the check stops at the login page.
Marco Malavolti's avatar
Marco Malavolti committed
46
The SPs used for the check are "SP Demo provided by GARR" (https://sp-demo.idem.garr.it/shibboleth) from IDEM GARR AAI and the "AAI Viewer Interfederation Test" (https://attribute-viewer.aai.switch.ch/interfederation-test/shibboleth) from SWITCHaai. These SPs might change in the future if needed.
Marco Malavolti's avatar
Marco Malavolti committed
47
48
49
50
51
52
53
54
55
56
57
58
The SAML authenticatin request is not signed. Therefore, authentication request for any eduGAIN SP could be created because the SP's private key is not needed.

# Limitations

There are some situations where the check cannot work reliably. In those cases it is possible to disable the check for a particular IdP. The so far known cases where the check might generate a false negative are:

* IdP does not support HTTP or HTTPS with at least SSLv3 or TLS1 or newer (these IdPs are insecure anyway)
* IdP is part of a Hub & Spoke federation (some of them manually have to first approve eduGAIN SPs)
* IdP does not use web-based login form (e.g. HTTP Basic Authentication or X.509 login)

# Disable Checks

59
60
61
62
63
64
In cases where an IdP cannot be reliably checked, it is necessary to create or enrich the `robots.txt` file on the IdP's web root with:

```bash
User-agent: ECCS
Disallow: /
```
Marco Malavolti's avatar
Marco Malavolti committed
65

Marco Malavolti's avatar
Marco Malavolti committed
66
67
68
69
70
If an IdP is not able to create its own `robots.txt` file under the web root directory, it can be disabled by setting the dictionary `IDPS_DISABLED_DICT` into `eccs_properties.py` with a line in the form:

'<idp-entity-id>':'<eccs-check-disabling-reason>'


Marco Malavolti's avatar
Marco Malavolti committed
71
72
# On-line interface

Marco Malavolti's avatar
Marco Malavolti committed
73
The test eduGAIN Connectivity Check web pages is available at: https://technical-test.edugain.org/eccs
Marco Malavolti's avatar
Marco Malavolti committed
74
75
76
77

The tool uses following status for IdPs:

* ERROR (red):
Marco Malavolti's avatar
Marco Malavolti committed
78
  * The IdP's response contains an HTTP Error or the web page returned does not look like a login page.
Marco Malavolti's avatar
Marco Malavolti committed
79
    * **Invalid-Form**: considers those IdPs that do not load a standard username/password login page and do not return messages like "*No return endpoint available for relying party*" or "*No metadata found for relying party"*.
Marco Malavolti's avatar
Marco Malavolti committed
80
81
    * **Timeout**: considers those IdPs that do not load a standard username/password login page within 60 seconds.
    * **Connection-Error**: considers those IdPs that are not reachable due to a connection problem. View the "Page Source" value to discover which problem the IdP has. 
Marco Malavolti's avatar
Marco Malavolti committed
82
    * **IdP-Error**: considers those IdPs that the web page returned does not contain a Login Form and reports an unspecified error such as "*An error occured*". This has been seen on Micrsoft ADFS based IdPs
Marco Malavolti's avatar
Marco Malavolti committed
83
  * The IdP most likely does not consume the eduGAIN metadata correctly.
Marco Malavolti's avatar
Marco Malavolti committed
84
    A typical case that falls into this category is when an IdP returns a message "*No return endpoint available for relying party*" or "*No metadata found for relying party*":
Marco Malavolti's avatar
Marco Malavolti committed
85
86
87
    * **No-eduGAIN-Metadata**
  * The IdP has a problem with its SSL certificate:
    * **SSL-Error**
Marco Malavolti's avatar
Marco Malavolti committed
88
89
* OK (green):
  * The IdP most likely correctly consumes eduGAIN metadata and returns a valid login page. This is no guarantee that login on this IdP works for all eduGAIN services but if the check is passed for an IdP, this is probable.
Marco Malavolti's avatar
Marco Malavolti committed
90
* DISABLED (white)
Marco Malavolti's avatar
Marco Malavolti committed
91
  * The IdP is excluded because it cannot be checked reliably. The "*Page Source*" column, when an entity is disabled, shows the reason of the disabling.
Marco Malavolti's avatar
Marco Malavolti committed
92

93
94
# Requirements Hardware

Marco Malavolti's avatar
Marco Malavolti committed
95
* OS: Debian 9, CentOS 7.8 (tested)
96
97
* HDD: 10 GB
* RAM: 4 GB
98
* CPU: >= 2 vCPU (suggested)
Marco Malavolti's avatar
Marco Malavolti committed
99
* ARCH: 64 Bit
100
101
102
103

# Requirements Software

* Apache Server + WSGI
104
* Python 3 (tested with v3.9.1)
Marco Malavolti's avatar
Marco Malavolti committed
105
106
107
* Selenim + Google Chrome Web Brower (tested with v91.0.4472.164)
* Chromedriver (tested with v91.0.4472.101)
* Git
108
109
110

# HOWTO Install and Configure

Marco Malavolti's avatar
Marco Malavolti committed
111
## Download ECCS Repository
112

Marco Malavolti's avatar
Marco Malavolti committed
113
* `cd $HOME ; git clone https://gitlab.geant.org/edugain/eccs.git`
114

Marco Malavolti's avatar
Marco Malavolti committed
115
## Install Python 3
Marco Malavolti's avatar
Marco Malavolti committed
116
117
118
119
120
121

### CentOS 7 requirements

1. Update the system packages:
   * `sudo yum -y update`

122
123
2. Install the YUM utils:
   * `sudo yum install yum-utils`
Marco Malavolti's avatar
Marco Malavolti committed
124
125

3. Install needed packages to build python:
126
   * `sudo yum-builddep python3`
Marco Malavolti's avatar
Marco Malavolti committed
127

Marco Malavolti's avatar
Marco Malavolti committed
128
129
130
4. Install Git:
   * `sudo yum -y install git`

Marco Malavolti's avatar
Marco Malavolti committed
131
### Debian requirements
132
133
134
135

1. Update the system packages:
   * `sudo apt update ; sudo apt upgrade -y`

136
137
2. Install needed packages to build python3:
   * `sudo apt-get build-dep python3`
138

Marco Malavolti's avatar
Marco Malavolti committed
139
140
141
3. Install Git:
   * `sudo apt install git`

Marco Malavolti's avatar
Marco Malavolti committed
142
### Install
143

Marco Malavolti's avatar
Marco Malavolti committed
144
1. Download the last version of Python 3 from https://www.python.org/downloads/source/ into your home:
145
   * `wget https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz -O $HOME/eccs/Python-3.9.1.tgz`
146

Marco Malavolti's avatar
Marco Malavolti committed
147
2. Extract Python source package:
Marco Malavolti's avatar
Marco Malavolti committed
148
   * `cd $HOME/eccs/`
149
   * `tar xzf Python-3.9.1.tgz`
150

Marco Malavolti's avatar
Marco Malavolti committed
151
3. Build Python from the source package:
152
   * `cd $HOME/eccs/Python-3.9.1`
Marco Malavolti's avatar
Marco Malavolti committed
153
   * `./configure --prefix=$HOME/eccs/python`
154
155
   * `make`

Marco Malavolti's avatar
Marco Malavolti committed
156
4. Install Python 3 under `$HOME/eccs/python`:
157
   * `make install`
Marco Malavolti's avatar
Marco Malavolti committed
158
   * `$HOME/eccs/python/bin/python3 --version`
159
 
Marco Malavolti's avatar
Marco Malavolti committed
160
   This will install python3 under your $HOME/eccs directory.
161
162
   
5. Remove useless things:
163
   * `rm -Rf $HOME/eccs/Python-3.9.1 $HOME/eccs/Python-3.9.1.tgz`
164

Marco Malavolti's avatar
Marco Malavolti committed
165
## Install Google Chrome needed by Selenium
166

Marco Malavolti's avatar
Marco Malavolti committed
167
* Debian (64 bit):
Marco Malavolti's avatar
Marco Malavolti committed
168
  * `cd $HOME/eccs`
Marco Malavolti's avatar
Marco Malavolti committed
169
170
  * `sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb`
  * `sudo apt install ./google-chrome-stable_current_amd64.deb`
Marco Malavolti's avatar
Marco Malavolti committed
171

Marco Malavolti's avatar
Marco Malavolti committed
172
* CentOS (64 bit):
Marco Malavolti's avatar
Marco Malavolti committed
173
  * `cd $HOME/eccs`
Marco Malavolti's avatar
Marco Malavolti committed
174
175
  * `sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm`
  * `sudo yum install ./google-chrome-stable_current_x86_64.rpm`
176

Marco Malavolti's avatar
Marco Malavolti committed
177
## Install the Chromedriver
178

Marco Malavolti's avatar
Marco Malavolti committed
179
180
1. Find out which version of Chromium you are using:
   * Debian 9 (stretch):
Marco Malavolti's avatar
Marco Malavolti committed
181
     * `google-chrome -version` => Google Chrome 91.0.4472.164
Marco Malavolti's avatar
Marco Malavolti committed
182
   * CentOS 7.8:
Marco Malavolti's avatar
Marco Malavolti committed
183
     * `google-chrome -version` => Google Chrome 91.0.4472.164
Marco Malavolti's avatar
Marco Malavolti committed
184
185
186
187
188
189

2. Take the Chrome version number, remove the last part, and append the result to URL "`https://chromedriver.storage.googleapis.com/LATEST_RELEASE_`". For example, with Chrome version 73.0.3683.75, you'd get a URL "`https://chromedriver.storage.googleapis.com/LATEST_RELEASE_73.0.3683`".

3. Use the URL created in the last step to discover the version of ChromeDriver to use. For example, the above URL will get your a file containing "73.0.3683.68".

4. Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version `72.0.3626.69`, the URL would be "https://chromedriver.storage.googleapis.com/index.html?path=73.0.3683.68/"
190

Marco Malavolti's avatar
Marco Malavolti committed
191
5. Download the Chromedriver and extract it with:
Marco Malavolti's avatar
Marco Malavolti committed
192
   * `cd $HOME/eccs`
Marco Malavolti's avatar
Marco Malavolti committed
193
   * `wget https://chromedriver.storage.googleapis.com/73.0.3683.75/chromedriver_linux64.zip`
Marco Malavolti's avatar
Marco Malavolti committed
194
   * `unzip chromedriver_linux64.zip`
Marco Malavolti's avatar
Marco Malavolti committed
195
   * `rm chromedriver_linux64.zip google-chrome-stable_current_amd64.deb`
Marco Malavolti's avatar
Marco Malavolti committed
196
197
198

**Note:**
After the initial download, it is recommended that you occasionally go through the above process again to see if there are any bug fix releases.
199

Marco Malavolti's avatar
Marco Malavolti committed
200
## ECCS Script
Marco Malavolti's avatar
Marco Malavolti committed
201

Marco Malavolti's avatar
Marco Malavolti committed
202
### Install and Configure the Virtual Environment
Marco Malavolti's avatar
Marco Malavolti committed
203

Marco Malavolti's avatar
Marco Malavolti committed
204
205
206
207
208
209
* `cd $HOME/eccs`
* `./python/bin/python3 -m pip install virtualenv`
* `$HOME/eccs/python/bin/virtualenv --python=$HOME/eccs/python/bin/python3 eccs-venv`
* `$HOME/eccs/eccs-venv/bin/python3 -m pip install --upgrade pip`
* `source eccs-venv/bin/activate`   (`deactivate` to exit Virtualenv)
  * `python3 -m pip install -r requirements.txt`
210

Marco Malavolti's avatar
Marco Malavolti committed
211
### Configure ECCS
212

Marco Malavolti's avatar
Marco Malavolti committed
213
214
1. Configure ECCS properties:
   * `vim eccs_properties.py` (and change it upon your needs)
215

216
2. Change `PATH` by adding the virtualenv Python `bin` dir:
217
218
   * CentOS:
     * `vim $HOME/.bash_profile`
Marco Malavolti's avatar
Marco Malavolti committed
219
220
221
     * Add the following lines at the tail:
       
       ```bash
Marco Malavolti's avatar
Marco Malavolti committed
222
223
224
       # set PATH for ECCS
       if [ -d "$HOME/eccs" ] ; then
          PATH="$HOME/eccs/eccs-venv/bin:$PATH"
Marco Malavolti's avatar
Marco Malavolti committed
225
226
227
       fi
       ```

Marco Malavolti's avatar
Marco Malavolti committed
228
229
     * `source $HOME/.bash_profile`

230
   * Debian:
Marco Malavolti's avatar
Marco Malavolti committed
231
     * `vim $HOME/.bash_profile`
Marco Malavolti's avatar
Marco Malavolti committed
232
233
234
     * Add the following lines at the tail:
       
       ```bash
Marco Malavolti's avatar
Marco Malavolti committed
235
236
237
       # set PATH for ECCS
       if [ -d "$HOME/eccs" ] ; then
          PATH="$HOME/eccs/eccs-venv/bin:$PATH"
Marco Malavolti's avatar
Marco Malavolti committed
238
239
240
       fi
       ```

Marco Malavolti's avatar
Marco Malavolti committed
241
242
     * `source $HOME/.bash_profile`

Marco Malavolti's avatar
Marco Malavolti committed
243
3. Configure ECCS cron job for the local user:
244
   * `crontab -e`
245

246
     ```bash
Marco Malavolti's avatar
Marco Malavolti committed
247
248
     SHELL=/bin/bash

Marco Malavolti's avatar
Marco Malavolti committed
249
     0 4 * * * /bin/bash $HOME/eccs/cleanAndRunEccs.sh > $HOME/eccs/logs/eccs-cron.log 2>&1
250
     ```
Marco Malavolti's avatar
Marco Malavolti committed
251

Marco Malavolti's avatar
Marco Malavolti committed
252
## Execute
253

Marco Malavolti's avatar
Marco Malavolti committed
254
255
256
257
258
259
260
  * `cd $HOME/eccs`
  * `./cleanAndRunEccs.py` (to run a full and clean check)
  * `./runEccs.py` (to run a full check on the existing inputs)
  * `./runEccs.py --idp <IDP-ENTITYID>` (to run check on a single IdP)
  * `./runEccs.py --test` (to run a full check without effects)
  * `./runEccs.py --idp <IDP-ENTITYID> --test` (to run check on a single IdP without effects)
  * `./runEccs.py --idp <IDP-ENTITYID> --replace` (to run check on a single IdP and replace, or add, a result)
261

Marco Malavolti's avatar
Marco Malavolti committed
262
  If something prevent the good execution of the ECCS's check, the `logs/failed-cmd.sh` file will be not empty at the end of the execution.
Marco Malavolti's avatar
Marco Malavolti committed
263

Marco Malavolti's avatar
Marco Malavolti committed
264
  The "--test" parameter will not change the result of ECCS, but will write the output on the `logs/stdout_idp_YYYY-MM-DD.log`,`logs/stderr_idp_YYYY-MM-DD.log` and `logs/failed-cmd-idp.sh` files if the argument "--test" will be used.
Marco Malavolti's avatar
Marco Malavolti committed
265

Marco Malavolti's avatar
Marco Malavolti committed
266
# ECCS API Server (uWSGI)
Marco Malavolti's avatar
Marco Malavolti committed
267

268
## Install
Marco Malavolti's avatar
Marco Malavolti committed
269

270
271
272
273
274
1. Install requirements:
   * Debian:
     * `sudo apt-get install libpcre3 libpcre3-dev libapache2-mod-proxy-uwsgi build-essentials python3-dev unzip`
   * CentOS:
     * `sudo yum install mod_proxy_uwsgi unzip`
Marco Malavolti's avatar
Marco Malavolti committed
275
276
277
     * Configure SElinux to enable ECCS:
       * `sudo semanage fcontext -a -t httpd_sys_content_t "$HOME/eccs(/.*)?"`
       * `sudo restorecon -R -e $HOME/eccs/`
278
279
       * `sudo setsebool -P httpd_can_network_connect 1`
 
Marco Malavolti's avatar
Marco Malavolti committed
280
281
## Configure

Marco Malavolti's avatar
Marco Malavolti committed
282
283
284
285
286
287
288
1. Add the systemd service to enable ECCS API:
   * `cd $HOME/eccs`
   * `cp eccs.ini.template eccs.ini`
   * `cp eccs.service.template eccs.service`
   * `vim eccs.ini` (and change "`uid`", "`gid`" and "`base`" values opportunely)
   * `vim eccs.service` (and change "`User`","`Group`","`WorkingDirectory`","`RuntimeDirectory`","`ExecStart`" values opportunely)
   * `sudo cp $HOME/eccs/eccs.service /etc/systemd/system/eccs.service`
289
   * `sudo systemctl daemon-reload`
Marco Malavolti's avatar
Marco Malavolti committed
290
291
   * `sudo systemctl enable eccs.service`
   * `sudo systemctl start eccs.service`
292

Marco Malavolti's avatar
Marco Malavolti committed
293
2. Configure Apache for ECCS web side:
294
   * Debian:
Marco Malavolti's avatar
Marco Malavolti committed
295
296
     * `sudo cp $HOME/eccs/eccs-debian.conf /etc/apache2/conf-available/eccs.conf`
     * `sudo a2enconf eccs.conf`
297
298
299
     * `sudo chgrp www-data $HOME ; sudo chmod g+rx $HOME` (Apache needs permission to access the $HOME dir)
     * `sudo systemctl restart apache2.service`
   * CentOS:
Marco Malavolti's avatar
Marco Malavolti committed
300
     * `sudo cp $HOME/eccs/eccs-centos.conf /etc/httpd/conf.d/eccs.conf`
301
302
     * `sudo chgrp apache $HOME ; sudo apache g+rx $HOME` (Apache needs permission to access the $HOME dir)
     * `sudo systemctl restart httpd.service`
303

304
305
306
307
308
309
3. Restart API WSGI server each day to update the datetime:
   * `crontab -e`

   ```bash
   SHELL=/bin/bash

Marco Malavolti's avatar
Marco Malavolti committed
310
   0 3 * * * /usr/bin/touch $HOME/eccs/eccs.ini
311
312
   ```

313
314
315
316
## Utility

To perform a restart after an API change use the following command:

Marco Malavolti's avatar
Marco Malavolti committed
317
* `touch $HOME/eccs/eccs.ini`
318

Marco Malavolti's avatar
Marco Malavolti committed
319
# ECCS API JSON
320

321
* `/api/eccsresults` (Return the results of the last check ready for ECCS web interface)
Marco Malavolti's avatar
Marco Malavolti committed
322
* `/api/eccsresults?<parameter1>=<value1>&<parameter2>=<value2>`:
323
  * `date=2020-02-20` (select date)
Marco Malavolti's avatar
Marco Malavolti committed
324
  * `idp=https://idp.example.org/idp/shibboleth` (select a specific idp)
Marco Malavolti's avatar
Marco Malavolti committed
325
  * `status=` (select specific ECCS status)
326
327
328
    * 'OK'
    * 'ERROR'
    * 'DISABLED'
Marco Malavolti's avatar
Marco Malavolti committed
329
330
331
332
333
  * `check_result=`
    * `OK`
    * `Timeout`
    * `Invalid-Form`
    * `Connection-Error`
Marco Malavolti's avatar
Marco Malavolti committed
334
    * `IdP-Error`
Marco Malavolti's avatar
Marco Malavolti committed
335
336
337
    * `No-eduGAIN-Metadata`
    * `SSL-Error`
    * `DISABLED`
338
  * `reg_auth=https://reg.auth.example.org` (select a specific Registration Authority)
339
  * `format=simple` (retrieve results in a simple format)
340
341
* `/api/fedstats`
* `/api/fedstats?reg_auth=https://reg.auth.example.org`:
342

Marco Malavolti's avatar
Marco Malavolti committed
343
# Utility for web interface
344
345

The available dates are provided by the first and the last file created into the `output/` directory
346

Marco Malavolti's avatar
Marco Malavolti committed
347
348
## Clean old results

Marco Malavolti's avatar
Marco Malavolti committed
349
To clean the ECCS results from files older than last 7 days use (modify it on your needs):
350

Marco Malavolti's avatar
Marco Malavolti committed
351
352
353
354
355
* `crontab -e`

  ```bash
  SHELL=/bin/bash

Marco Malavolti's avatar
Marco Malavolti committed
356
  0 10 * * * /bin/bash $HOME/eccs/clean7daysOldFiles.sh > $HOME/eccs/logs/clean7daysOldFiles.log 2>&1  
Marco Malavolti's avatar
Marco Malavolti committed
357
  ```
Marco Malavolti's avatar
Marco Malavolti committed
358

Marco Malavolti's avatar
Marco Malavolti committed
359
## User interface
Marco Malavolti's avatar
Marco Malavolti committed
360
The eduGAIN Connectivity Check Service web page is available at https://technical-test.edugain.org/eccs
Marco Malavolti's avatar
Marco Malavolti committed
361
362
363
364
365
366
367
368
369
370
371
372
373

## User interface parameters

| Parameter name | Example                                      |
| -------------- | -------------------------------------------- |
| `date`         | `date=2020-02-20`                            |
| `reg_auth`     | `reg_auth=https://reg.auth.example.org`      |
| `idp`          | `idp=https://idp.example.org/idp/shibboleth` |
| `status`       | `status=ERROR`                               |
| `check_result` | `check_result=Timeout`                       |

**Example:**

Marco Malavolti's avatar
Marco Malavolti committed
374
`https://technical-test.edugain.org/eccs?reg_auth=http://www.idem.garr.it/&check_result=SSL-Error`
Marco Malavolti's avatar
Marco Malavolti committed
375

376
377
# Utility for developers

Marco Malavolti's avatar
Marco Malavolti committed
378
## ECCS API Development Server
379

Marco Malavolti's avatar
Marco Malavolti committed
380
* `cd $HOME/eccs ; ./api.py`
381

Marco Malavolti's avatar
Marco Malavolti committed
382
383
384
385
386
# Authors

## Original Author

 * Marco Malavolti (marco.malavolti@garr.it)