# SmeeFeds

`SmeeFeds` is a SAML federation data management extension to [Smee]( for use in
research, testing and development.

[Smee]( has tools for handling the sources of SAML metadata but 
nothing to represent the publishers of metadata. SmeeFeds adds a few tools for handling federations and includes a large
collection of information about research and education federations.

[![Hex pm](](
[![API Docs](](
![Github Elixir CI](

[![Run in Livebook](](

## Features

* Easily find information on National Research and Education organisation (NREN) federations.
* Filter and group federations by location, type, structure and tags.
* Use federation records directly with Smee to download metadata from aggregates or MDQ servers
* Export lists of federation information as CSV, JSON or Markdown documents
* Manage and load federation data into your applications

The top level `SmeeFeds` module has tools for selecting individual federation details or lists of many at once.
SmeeFeds contain more tools for handling federations, such as:

* `SmeeFeds.Federation` - tools for accessing data such as metadata download URLs, contacts, homepages, and so on.
* `SmeeFeds.Export` - convert lists of federations into JSON or CSV data for export, or simple text reports
* `SmeeFeds.Import` - convert JSON documents into Federation lists
* `SmeeFeds.Filter` - filter lists of federations by various criteria


SmeeFeds comes with a built-in list of federations, using information gathered from various sources on the Internet.

This collection of information is example data for use by **researchers, developers and testers**. 


Metadata is the bedrock of trust and information security in SAML federations. DO NOT use metadata URLs, certificates 
and certificate fingerprints to download and use metadata in live services without confirming each detail yourself.

If you must use SmeeFeds as part of a production service, then after information has been verified you can export only
the verified information you need as a JSON file and set it as the new default using 
`:smee_feds, :data_file` config setting in your application (if compiled) or set a list of Federations with 
`:smee_feds, :federations` at runtime.

There is absolutely no guarantee or warranty that the data in SmeeFeds is correct, and it is not supported by any of 
the federations listed. It's totally unofficial. 

## Examples

### Using with Smee to download UK Access Management Federation metadata, pick a random entity and get its XML
Useful for testing as there's no need to remember or look up metadata details.

random_xml = SmeeFeds.federation(:ukamf)
|> SmeeFeds.Federation.aggregate()
|> Smee.fetch!()
|> Smee.Metadata.random_entity()
|> Smee.Entity.xml()

### Finding an MDQ service 
Very few MDQ services are present in the data, but they can be used as follows:

cern_idp = SmeeFeds.federation(:incommon)
|> SmeeFeds.Federation.mdq()
|> Smee.MDQ.lookup!("")

You can list the IDs of all federations that have an MDQ service using a filter:

|> SmeeFeds.Filter.mdq()
|> SmeeFeds.ids()

### Getting a list of specific federations and writing their details to disk as a JSON file or CSV
The JSON file can be used a new default set of federations. 

SmeeFeds.federations([:wayf, :haka, :dfnaai, :swamid])
|> SmeeFeds.Export.json_file!("my_feds.json")

The CSV export is a simpler, lossy summary.
csv = SmeeFeds.federations([:wayf, :haka, :dfnaai, :swamid])
       |> SmeeFeds.Export.csv()

File.write!("my_feds.csv", csv)

### Defining your own lists of federations

my_feds = [, name: "Example 1", sources: ["")]),, name: "Example 2", sources: ["")])

### Filtering lists of federations

Listing all known federations, then selecting those in the EU, and listing their unique IDs

|> SmeeFeds.ids()

Finding all hub-and-spoke networks with an MDQ service and returning their names

|> SmeeFeds.Filter.structure(:has)
|> SmeeFeds.Filter.mdq()
|> f -> end)


### Opening all homepages 

Perhaps you want to check the homepages of all federations in a collection (this example works on a Mac)

|> Enum.each(fn f -> if f.url, do: System.cmd("open", [f.url]) end)

Or see all logos

|> Enum.each(fn f -> if f.logo, do: System.cmd("open", [f.logo]) end)

### Information about lists of federations

The top level SmeeFeds module can return unique values present in collections. For example, all tags:

tags = SmeeFeds.federations()
|> SmeeFeds.tags()

or structure types

structures = SmeeFeds.federations()
|> SmeeFeds.structures()

## Installation

If [available in Hex](, the package can be installed
by adding `smee_feds` to your list of dependencies in `mix.exs`:

def deps do
    {:smee_feds, "~> 0.3.0"}

SmeeFeds requires [Smee](, which has its own unusual requirements, so
please make sure you read the documentation for installing Smee before using SmeeFeds.

## Uses

The main reason SmeeFeds was hurriedly put together on a Sunday afternoon is that I needed to test `Smee` with a variety
of federations, and my various scattered notes and comments and tests with URLs and certificate fingerprints were becoming a nuisance.
The original focus was on the default data, as a convenient resource for testing.

It's possibly an over-engineered solution to that problem but it was fun.

Over time the federation collection features of SmeeFeds have become useful in other projects as a way to load sources
of metadata in a consistent way, so these have been expanded and strengthened. 

## Alternatives and Sources

The best source of this information is the websites of the federations themselves, and the best way to find those
websites is to read the websites of Edugain and REFEDS.

* [Edugain]( "eduGAIN comprises over 80 participant federations connecting more than 8,000 Identity and Service Providers" 
* [REFEDS]( "REFEDS is a community of practitioners actively engaged in access and identity work within their home countries and supportive of standards-compliant developments to enhance international collaboration"
* [MET]( "Metadata explorer tool is a fast way to find federations, entities, and their relations through entity/federation metadata file information."

## Documentation

Documentation can be generated with [ExDoc](
and published on [HexDocs]( Once published, the docs can
be found at <>.

## Contributing

You can request new features by creating an [issue](,
or submit a [pull request]( with your contribution.

If you are comfortable working with Python but Smee's Elixir code is unfamiliar then this blog post may help: 
[Elixir For Humans Who Know Python](

## Copyright and License

Copyright (c) 2023, 2024 Digital Identity Ltd, UK

SmeeFeds is Apache 2.0 licensed.

## Disclaimer
Smee is not endorsed by The Shibboleth Foundation or any of the NREN's described within.
The API will definitely change considerably in the first few releases after 0.1.0 - it is not stable!