Commit 99641cc9 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Initial commit

parents
package irmago
import "strings"
// Base object for identifiers
type objectIdentifier struct {
string `json:"identifier"`
Parts []string
}
// IssuerIdentifier identifies an issuer.
type IssuerIdentifier struct {
objectIdentifier
}
// CredentialTypeIdentifier identifies a credential type
type CredentialTypeIdentifier struct {
objectIdentifier
issuer *IssuerIdentifier
}
// AttributeTypeIdentifier identifies an attribute within a credential type.
type AttributeTypeIdentifier struct {
objectIdentifier
cred *CredentialTypeIdentifier
}
// NewIssuerIdentifier returns a new IssuerIdentifier
func NewIssuerIdentifier(identifier string) *IssuerIdentifier {
return &IssuerIdentifier{
objectIdentifier: objectIdentifier{string: identifier},
}
}
// NewCredentialTypeIdentifier returns a new CredentialTypeIdentifier
func NewCredentialTypeIdentifier(identifier string) *CredentialTypeIdentifier {
return &CredentialTypeIdentifier{
objectIdentifier: objectIdentifier{string: identifier},
}
}
// NewAttributeTypeIdentifier returns a new AttributeTypeIdentifier
func NewAttributeTypeIdentifier(identifier string) *AttributeTypeIdentifier {
return &AttributeTypeIdentifier{
objectIdentifier: objectIdentifier{string: identifier},
}
}
func (o *objectIdentifier) split() []string {
if o.Parts == nil {
o.Parts = strings.Split(o.string, ".")
}
return o.Parts
}
// SchemeManagerName returns the name of the scheme maanger of the current credential type.
func (ci *CredentialTypeIdentifier) SchemeManagerName() string {
return ci.split()[0]
}
// IssuerName returns the issuer name of the current credential type.
func (ci *CredentialTypeIdentifier) IssuerName() string {
return ci.split()[1]
}
// IssuerIdentifier returns the issuer identifier of the current credential type.
func (ci *CredentialTypeIdentifier) IssuerIdentifier() *IssuerIdentifier {
if ci.issuer == nil {
ci.issuer = &IssuerIdentifier{
objectIdentifier: objectIdentifier{string: ci.SchemeManagerName() + "." + ci.IssuerName()},
}
}
return ci.issuer
}
// CredentialName returns the name of the current credential type.
func (ci *CredentialTypeIdentifier) CredentialName() string {
return ci.split()[2]
}
package irmago
import "encoding/xml"
// SchemeManagerDescription describes a scheme manager.
type SchemeManagerDescription struct {
Name string `xml:"Id"`
URL string `xml:"Contact"`
HRName string `xml:"Name"`
Description string
KeyshareServer string
KeyshareWebsite string
KeyshareAttribute string
XMLversion int `xml:"version,attr"`
XMLName xml.Name `xml:"SchemeManager"`
}
// IssuerDescription describes an issuer.
type IssuerDescription struct {
HRName string `xml:"Name"`
HRShortName string `xml:"ShortName"`
Name string `xml:"ID"`
SchemeManagerName string `xml:"SchemeManager"`
ContactAddress string
ContactEMail string
URL string `xml:"baseURL"`
XMLversion int `xml:"version,attr"`
identifier *IssuerIdentifier
}
// CredentialDescription is a description of a credential type, specifying (a.o.) its name, issuer, and attributes.
type CredentialDescription struct {
HRName string `xml:"Name"`
HRShortName string `xml:"ShortName"`
IssuerName string `xml:"IssuerID"`
SchemeManagerName string `xml:"SchemeManager"`
Name string `xml:"CredentialID"`
IsSingleton bool `xml:"ShouldBeSingleton"`
Description string
Attributes []AttributeDesscription `xml:"Attributes>Attribute"`
XMLversion int `xml:"version,attr"`
XMLName xml.Name `xml:"IssueSpecification"`
identifier *CredentialTypeIdentifier
}
// AttributeDesscription is a description of an attribute within a credential type.
type AttributeDesscription struct {
Name string
Description string
}
// Identifier returns the identifier of the specified credential type.
func (cd *CredentialDescription) Identifier() *CredentialTypeIdentifier {
if cd.identifier == nil {
cd.identifier = NewCredentialTypeIdentifier(cd.SchemeManagerName + "." + cd.IssuerName + "." + cd.Name)
}
return cd.identifier
}
// Identifier returns the identifier of the specified issuer description.
func (id *IssuerDescription) Identifier() *IssuerIdentifier {
if id.identifier == nil {
id.identifier = NewIssuerIdentifier(id.SchemeManagerName + "." + id.Name)
}
return id.identifier
}
package irmago
import (
"encoding/xml"
"io/ioutil"
"os"
"path/filepath"
"github.com/mhe/gabi"
)
// MetaStore is the global instance of ConfigurationStore
var MetaStore = ConfigurationStore{
make(map[string]*SchemeManagerDescription),
make(map[string]*IssuerDescription),
make(map[string]*CredentialDescription),
make(map[string]*gabi.PublicKey),
}
// ConfigurationStore ...
type ConfigurationStore struct {
managers map[string]*SchemeManagerDescription
issuers map[string]*IssuerDescription
credentials map[string]*CredentialDescription
publickeys map[string]*gabi.PublicKey
}
// ParseFolder ...
func (store *ConfigurationStore) ParseFolder(path string) error {
return iterateSubfolders(path, func(dir string) error {
manager := &SchemeManagerDescription{}
exists, err := pathToDescription(dir+"/description.xml", manager)
if err != nil {
return err
}
if exists {
MetaStore.managers[manager.Name] = manager
return store.parseIssuerFolders(dir)
}
return nil
})
}
func (store *ConfigurationStore) parseIssuerFolders(path string) error {
return iterateSubfolders(path, func(dir string) error {
issuer := &IssuerDescription{}
exists, err := pathToDescription(dir+"/description.xml", issuer)
if err != nil {
return err
}
if exists {
store.issuers[issuer.Identifier().string] = issuer
return store.parseCredentialsFolder(dir + "/Issues/")
}
return nil
})
}
func (store *ConfigurationStore) parseCredentialsFolder(path string) error {
return iterateSubfolders(path, func(dir string) error {
cred := &CredentialDescription{}
exists, err := pathToDescription(dir+"/description.xml", cred)
if err != nil {
return err
}
if exists {
store.credentials[cred.Identifier().string] = cred
}
return nil
})
}
func iterateSubfolders(path string, handler func(string) error) error {
dirs, err := filepath.Glob(path + "/*")
if err != nil {
return err
}
for _, dir := range dirs {
stat, err := os.Stat(dir)
if err != nil {
return err
}
if !stat.IsDir() {
continue
}
err = handler(dir)
if err != nil {
return err
}
}
return nil
}
func pathToDescription(path string, description interface{}) (bool, error) {
if _, err := os.Stat(path); err != nil {
return false, nil
}
file, err := os.Open(path)
if err != nil {
return true, err
}
defer file.Close()
bytes, err := ioutil.ReadAll(file)
if err != nil {
return true, err
}
err = xml.Unmarshal(bytes, description)
if err != nil {
return true, err
}
return true, nil
}
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