Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

SmeeView Workbook

notebooks/smee_view.livemd

SmeeView Workbook

Mix.install(
  [{:smee_view, ">= 0.2.1"}, {:rambo, "~> 0.3.4"}, {:kino, "~>0.12"}]
)
alias Smee.{Metadata, Entity, Source, MDQ}

What is SmeeView?

SmeeView is a metadata parsing extension to Smee. SmeeView provides easy to use functions for extracting lists of information from SAML metadata as Elixir structs.

Smee provides access to entity metadata XML as both strings and parsed xmerl records but leaves the user to find and extract the information they need. SmeeView aims to fill this gap by providing tools for working with the most commonly used information in SAML metadata.

SmeeView is loosely based on the concept of functional data access “lenses”.

Requirements - Please Read!

Backend tools Please note: SmeeView extends Smee, which does not do all processing itself using Elixir - it sometimes cheats (OK, it often cheats) by sending data to external programs for processing. At the moment it requires the following commandline utilities:

  • xmlsec1
  • xmllint
  • xsltproc

On Debian: sudo apt-get install xmlsec1 libxml2-utils xsltproc On RedHat: sudo yum install xmlsec1 libxml2 libxslt On Macs: brew install xmlsec1 libxml2 libxslt

First let’s get one entity via MDQ

We’ll reuse this entity data a few times later


entity = Smee.MDQ.source("http://mdq.ukfederation.org.uk/")
         |> Smee.MDQ.lookup!("https://cern.ch/login")

Extracting all data for an entity

The top-level view_one/2 function will return one entity “aspect” struct. You can see how the data in a SmeeView.Aspects.Entity struct is very different to the Smee.Entity struct - it has much more detail in an easier format.


SmeeView.view_one(entity)

Viewing all logos in an entire federation

You can view all logos as a list…

Smee.source("http://metadata.ukfederation.org.uk/ukfederation-metadata.xml")
|> Smee.fetch!()
|> SmeeView.Logos.view()

… but it might be more useful to have a list of all logos for each entity:

Smee.source("http://metadata.ukfederation.org.uk/ukfederation-metadata.xml")
|> Smee.fetch!()
|> SmeeView.Logos.prism()

Selecting the most appropriate service displayname

Entity metadata often contains information in various languages so that UIs can be localised.

entity
|> SmeeView.Displaynames.view()
|> SmeeView.Displaynames.pick("en")
|> SmeeView.Aspects.Displayname.text()

Find all the tiny square logos for IdPs in PNG format in German

(It’s a very contrived example)

Smee.source("http://metadata.ukfederation.org.uk/ukfederation-metadata.xml")
|> Smee.fetch!()
|> SmeeView.Logos.view(:idp)
|> Enum.filter(
     fn logo ->
       SmeeView.Aspects.Logo.size(logo) == :tiny &&
         SmeeView.Aspects.Logo.shape(logo) == :square &&
         SmeeView.Aspects.Logo.format(logo) == :png &&
         SmeeView.Aspects.Logo.lang(logo) == "de"
     end
   )

There might not actually be any of course.

Extract the assurance certifications of each entity in a federation

This demonstrates the usefulness of prism views. A map of entityID => assurance certifications is returned.

certifications = Smee.source("http://metadata.ukfederation.org.uk/ukfederation-metadata.xml")
                 |> Smee.fetch!()
                 |> SmeeView.EntityAttributes.prism()
                 |> SmeeView.EntityAttributes.assurance_certifications()

The same data again, restructured into a list of maps so Kino can show it easily:

certifications
|> Enum.map(fn {k, v} -> %{entity: k, certifications: v} end)
|> Kino.DataTable.new(name: "Certifications", keys: [:entity, :certifications])