Example #1
0
 def setUp(self):
     super(SimplePipeLineTest, self).setUp()
     self.templates = TemplateLookup(
         directories=[os.path.join(self.datadir, 'simple-pipeline')])
     self.output = tempfile.NamedTemporaryFile('w').name
     self.signer = tempfile.NamedTemporaryFile('w').name
     self.signer_template = self.templates.get_template('signer.fd')
     self.validator = tempfile.NamedTemporaryFile('w').name
     self.validator_template = self.templates.get_template('validator.fd')
     self.md_signer = MDRepository(store=MemoryStore())
     self.md_validator = MDRepository(store=MemoryStore())
     with open(self.signer, "w") as fd:
         fd.write(self.signer_template.render(ctx=self))
     with open(self.validator, "w") as fd:
         fd.write(self.validator_template.render(ctx=self))
     self.signer_result = plumbing(self.signer).process(self.md_signer,
                                                        state={
                                                            'batch': True,
                                                            'stats': {}
                                                        })
     self.validator_result = plumbing(self.validator).process(
         self.md_validator, state={
             'batch': True,
             'stats': {}
         })
Example #2
0
    def __init__(self,
                 pipes=None,
                 autoreload=False,
                 frequency=600,
                 aliases=None,
                 cache_enabled=True,
                 observers=None,
                 store=None):

        if aliases is None:
            aliases = ATTRS
        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.cache_enabled = cache_enabled
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=frequency)
        self.refresh.subscribe()
        self.aliases = aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=self.cache_enabled, store=store)

        if autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)
Example #3
0
 def setUp(self):
     self.md = MDRepository(store=MemoryStore)
     self.datadir = resource_filename('metadata', 'test/data')
     self.xml_source = os.path.join(self.datadir, 'test01.xml')
     self.swamid_source = os.path.join(self.datadir, 'swamid-2.0-test.xml')
     self.swamid = root(parse_xml(self.swamid_source))
     self.t = parse_xml(self.xml_source)
     self.non_metadata = parse_xml(resource_filename("not-metadata.xml", self.datadir))
Example #4
0
File: mdx.py Project: peter-/pyFF
    def __init__(self,
                 pipes=None,
                 autoreload=False,
                 frequency=600,
                 aliases=None,
                 cache_enabled=True,
                 observers=None,
                 store=None):

        if aliases is None:
            aliases = ATTRS
        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.cache_enabled = cache_enabled
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=frequency)
        self.refresh.subscribe()
        self.aliases = aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=self.cache_enabled, store=store)

        if autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)
Example #5
0
    def _get_metadata_stream(self, load_streams):
        try:
            load = []
            select = []

            count = 1
            for stream in load_streams:
                curid = "%s%d" % (self.slug, count)
                load.append("%s as %s" % (stream[0], curid))
                if stream[1] == 'SP' or stream[1] == 'IDP':
                    select.append(
                        "%s!//md:EntityDescriptor[md:%sSSODescriptor]" %
                        (curid, stream[1]))
                else:
                    select.append("%s" % curid)
                count = count + 1

            if len(select) > 0:
                pipeline = [{'load': load}, {'select': select}]
            else:
                pipeline = [{'load': load}, 'select']

            md = MDRepository()
            entities = Plumbing(pipeline=pipeline,
                                id=self.slug).process(md,
                                                      state={
                                                          'batch': True,
                                                          'stats': {}
                                                      })
            return etree.tostring(entities)
        except Exception, e:
            raise Exception('Getting metadata from %s failed.\nError: %s' %
                            (load_streams, e))
Example #6
0
 def setUp(self):
     self.md = MDRepository(store=MemoryStore)
     self.datadir = resource_filename('metadata', 'test/data')
     self.xml_source = os.path.join(self.datadir, 'test01.xml')
     self.swamid_source = os.path.join(self.datadir, 'swamid-2.0-test.xml')
     self.swamid = root(parse_xml(self.swamid_source))
     self.t = parse_xml(self.xml_source)
     self.non_metadata = parse_xml(resource_filename("not-metadata.xml", self.datadir))
Example #7
0
    def __init__(self, pipes=None, observers=None):

        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=config.frequency)
        self.refresh.subscribe()
        self.aliases = config.aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=config.caching_enabled, store=config.store)

        if config.autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)
Example #8
0
 def exec_pipeline(self, pstr):
     md = MDRepository()
     p = yaml.load(StringIO(pstr))
     print(p)
     res = Plumbing(p, pid="test").process(md,
                                           state={
                                               'batch': True,
                                               'stats': {}
                                           })
     return res, md
Example #9
0
    def run_pipeline(self, pl_name, ctx=None, md=MDRepository()):
        if ctx is None:
            ctx = dict()

        templates = TemplateLookup(directories=[os.path.join(self.datadir, 'simple-pipeline')])
        pipeline = tempfile.NamedTemporaryFile('w').name
        template = templates.get_template(pl_name)
        with open(pipeline, "w") as fd:
            fd.write(template.render(ctx=ctx))
        res = plumbing(pipeline).process(md, state={'batch': True, 'stats': {}})
        os.unlink(pipeline)
        return res, md, ctx
Example #10
0
    def __init__(self, pipes=None, observers=None):

        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=config.frequency)
        self.refresh.subscribe()
        self.aliases = config.aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=config.caching_enabled, store=config.store)

        if config.autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)
Example #11
0
class MDServer(object):
    """The MDServer class is the business logic of pyFF. This class is isolated from the request-decoding logic
    of MDRoot and from the ancilliary classes like MDStats and WellKnown.
    """

    def __init__(self, pipes=None, observers=None):

        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=config.frequency)
        self.refresh.subscribe()
        self.aliases = config.aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=config.caching_enabled, store=config.store)

        if config.autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)

    @property
    def ready(self):
        return self.md.store.ready()

    def reload_pipeline(self):
        new_plumbings = [plumbing(v) for v in self._pipes]
        self.plumbings = new_plumbings

    class MediaAccept(object):

        def __init__(self):
            pass

        def has_key(self, key):
            return True

        def get(self, item):
            return self.__getitem__(item)

        def __getitem__(self, item):
            try:
                return cptools.accept(item, debug=True)
            except HTTPError:
                return False

    def request(self, **kwargs):
        """The main request processor. This code implements all rendering of metadata.
        """
        stats['MD Requests'] += 1

        if not self.ready:
            raise HTTPError(503, _("Service Unavailable (repository loading)"))

        pfx = kwargs.get('pfx', None)
        path = kwargs.get('path', None)
        content_type = kwargs.get('content_type', None)

        log.debug("MDServer pfx=%s, path=%s, content_type=%s" % (pfx, path, content_type))

        def _d(x, do_split=True):
            if x is not None:
                x = x.strip()
            log.debug("_d(%s,%s)" % (x, do_split))
            if x is None or len(x) == 0:
                return None, None

            if x.startswith("{base64}"):
                x = x[8:].decode('base64')

            if do_split and '.' in x:
                (pth, dot, extn) = x.rpartition('.')
                assert (dot == '.')
                if extn in _ctypes:
                    return pth, extn

            return x, None

        _ctypes = {'xml': 'application/xml',
                   'json': 'application/json',
                   'htm': 'text/html',
                   'html': 'text/html',
                   'ds': 'text/html',
                   's': 'application/json'}

        alias = None
        if pfx:
            alias = pfx
            pfx = self.aliases.get(alias, None)
            if pfx is None:
                raise NotFound()

        path, ext = _d(path, content_type is None)
        if pfx and path:
            q = "{%s}%s" % (pfx, path)
            path = "/%s/%s" % (alias, path)
        else:
            q = path

        if ext is not None:
            log.debug("request path: %s.%s, headers: %s" % (path, ext, cherrypy.request.headers))
        else:
            log.debug("request path: %s, headers: %s" % (path, cherrypy.request.headers))

        accept = {}
        if content_type is None:
            if ext is not None and ext in _ctypes:
                accept = {_ctypes[ext]: True}
            else:
                accept = MDServer.MediaAccept()
                if ext is not None:
                    path = "%s.%s" % (path, ext)
        else:
            accept = {content_type: True}

        with self.lock.readlock:
            if ext == 'ds':
                pdict = dict()
                entity_id = kwargs.get('entityID', None)
                if entity_id is None:
                    raise HTTPError(400, _("400 Bad Request - missing entityID"))
                pdict['sp'] = self.md.sha1_id(entity_id)
                e = self.md.store.lookup(entity_id)
                if e is None or len(e) == 0:
                    raise HTTPError(404)

                if len(e) > 1:
                    raise HTTPError(400, _("400 Bad Request - multiple matches for") + " %s" % entity_id)

                pdict['entity'] = self.md.simple_summary(e[0])
                if not path:
                    pdict['search'] = "/search/"
                    pdict['list'] = "/role/idp.json"
                else:
                    pdict['search'] = "%s.s" % path
                    pdict['list'] = "%s.json" % path
                cherrypy.response.headers['Content-Type'] = 'text/html'
                return render_template("ds.html", **pdict)
            elif ext == 's':
                paged = bool(kwargs.get('paged', False))
                query = kwargs.get('query', None)
                page = kwargs.get('page', 0)
                page_limit = kwargs.get('page_limit', 10)
                entity_filter = kwargs.get('entity_filter', None)
                related = kwargs.get('related', None)

                cherrypy.response.headers['Content-Type'] = 'application/json'

                if query is None:
                    log.debug("empty query - creating one")
                    query = [cherrypy.request.remote.ip]
                    referrer = cherrypy.request.headers.get('referrer', None)
                    if referrer is not None:
                        log.debug("including referrer: %s" % referrer)
                        url = urlparse.urlparse(referrer)
                        host = url.netloc
                        if ':' in url.netloc:
                            (host, port) = url.netloc.split(':')
                        for host_part in host.rstrip(self.psl.get_public_suffix(host)).split('.'):
                            if host_part is not None and len(host_part) > 0:
                                query.append(host_part)
                    log.debug("created query: %s" % ",".join(query))

                if paged:
                    res, more, total = self.md.search(query,
                                                      path=q,
                                                      page=int(page),
                                                      page_limit=int(page_limit),
                                                      entity_filter=entity_filter,
                                                      related=related)
                    # log.debug(dumps({'entities': res, 'more': more, 'total': total}))
                    return dumps({'entities': res, 'more': more, 'total': total})
                else:
                    return dumps(self.md.search(query,
                                                path=q,
                                                entity_filter=entity_filter,
                                                related=related))
            elif accept.get('text/html'):
                if not q:
                    if pfx:
                        title = pfx
                    else:
                        title = _("Metadata By Attributes")
                    return render_template("index.html",
                                           md=self.md,
                                           alias=alias,
                                           aliases=self.aliases,
                                           title=title)
                else:
                    entities = self.md.lookup(q)
                    if not entities:
                        raise NotFound()
                    if len(entities) > 1:
                        return render_template("metadata.html",
                                               md=self.md,
                                               subheading=q,
                                               entities=entities)
                    else:
                        entity = entities[0]
                        t = html.fragment_fromstring(unicode(xslt_transform(entity, "entity2html.xsl")))
                        for c_elt in t.findall(".//code[@role='entity']"):
                            c_txt = dumptree(entity)
                            parser = etree.XMLParser(remove_blank_text=True)
                            src = StringIO(c_txt)
                            tree = etree.parse(src, parser)
                            c_txt = dumptree(tree, pretty_print=True, xml_declaration=False).decode("utf-8")
                            p = c_elt.getparent()
                            p.remove(c_elt)
                            if p.text is not None:
                                p.text += c_txt
                            else:
                                p.text = c_txt
                        xml = dumptree(t, xml_declaration=False).decode('utf-8')
                        return render_template("entity.html",
                                               headline=self.md.display(entity).strip(),
                                               subheading=entity.get('entityID'),
                                               entity_id=entity.get('entityID'),
                                               content=xml)
            else:
                for p in self.plumbings:
                    state = {'request': True,
                             'headers': {'Content-Type': 'text/xml'},
                             'accept': accept,
                             'url': cherrypy.url(relative=False),
                             'select': q,
                             'path': path,
                             'stats': {}}
                    r = p.process(self.md, state=state)
                    if r is not None:
                        cache_ttl = state.get('cache', 0)
                        log.debug("caching for %d seconds" % cache_ttl)
                        for k, v in state.get('headers', {}).iteritems():
                            cherrypy.response.headers[k] = v
                        caching.expires(secs=cache_ttl)
                        return r
        raise NotFound()
Example #12
0
class TestRepo(TestCase):
    def setUp(self):
        self.md = MDRepository(store=MemoryStore)
        self.datadir = resource_filename('metadata', 'test/data')
        self.xml_source = os.path.join(self.datadir, 'test01.xml')
        self.swamid_source = os.path.join(self.datadir, 'swamid-2.0-test.xml')
        self.swamid = root(parse_xml(self.swamid_source))
        self.t = parse_xml(self.xml_source)
        self.non_metadata = parse_xml(resource_filename("not-metadata.xml", self.datadir))

    def test_md_exists(self):
        assert (self.md is not None)

    def test_clone(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        nmd = self.md.clone()
        assert (nmd.store.size() == self.md.store.size())
        assert (nmd.lookup(entity_id) is not None)

    def test_sha1_hash(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)
        assert (self.md.sha1_id(e[0]) == "{sha1}568515f6fae8c8b4d42d543853c96d08f051ef13")
        assert (hash_id(e[0], 'sha1', prefix=False) == "568515f6fae8c8b4d42d543853c96d08f051ef13")

    def test_entity_attribute(self):
        entity_id = root(self.t).get('entityID')
        self.md.set_entity_attributes(root(self.t), {"http://ns.example.org": "foo"})
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup("{%s}%s" % ("http://ns.example.org", 'foo'))[0]
        assert (e is not None)
        assert (e.get('entityID') == entity_id)

    def test_utils(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)[0]
        assert (self.md.is_idp(e))
        assert (not self.md.is_sp(e))
        assert (self.md.icon(e) in ['https://www.example.com/static/images/logo.jpg',
                                    'https://www.example.com/static/images/logo_eng.jpg'] )
        domains = self.md.domains(e)
        assert ('example.com' in domains)
        assert ('example.net' in domains)
        assert ('idp.example.com' not in domains)
        assert ('foo.com' not in domains)

        edup = deepcopy(e)
        name, desc = self.md.ext_display(e)
        assert(name == 'Example University')
        assert(desc == 'Identity Provider for Example University')

        disp = self.md.display(e)
        assert (disp == 'Example University')
        for elt in e.findall(".//{%s}DisplayName" % NS['mdui']):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert (disp == 'The Example University')
        for elt in e.findall(".//{%s}OrganizationDisplayName" % NS['md']):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert (disp == 'ExampleU')
        for elt in e.findall(".//{%s}OrganizationName" % NS['md']):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert (disp == entity_id)

        e = edup

        subs = self.md.sub_domains(e)
        assert ('example.com' in subs)
        assert ('example.net' in subs)
        assert ('idp.example.com' not in subs)

        summary = self.md.simple_summary(e)
        assert (summary['title'] == 'Example University')
        assert (summary['descr'] == 'Identity Provider for Example University')
        assert (summary['value'] == entity_id)
        assert ('icon' in summary)
        assert ('icon_url' in summary and summary['icon'] == summary['icon_url'])
        assert ('domains' in summary)
        assert ('id' in summary)

        empty = self.md.simple_summary(None)
        assert (not empty)

    def test_display(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get('Name'))
        funet_connect = self.md.lookup('https://connect.funet.fi/shibboleth')[0]
        name, desc = self.md.ext_display(funet_connect)
        assert(name == 'FUNET E-Meeting Service')
        dn = self.md.display(funet_connect)


    def test_missing(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get('Name'))
        missing = self.md.lookup('https://connect.funet.fi/shibboleth+missing')
        assert (len(missing) == 0)

    def test_non_metadata(self):
        e = root(self.non_metadata)
        assert self.md.expiration(e) is None
        try:
            self.md.annotate(e,"kaka","x","y")
            self.md.set_entity_attributes(e, dict(a=1))
            assert False
        except MetadataException:
            pass
Example #13
0
class MDServer(object):
    """The MDServer class is the business logic of pyFF. This class is isolated from the request-decoding logic
    of MDRoot and from the ancilliary classes like MDStats and WellKnown.
    """

    def __init__(self, pipes=None, observers=None):

        if not observers:
            observers = []
        if not pipes:
            pipes = []
        self._pipes = pipes
        self.lock = ReadWriteLock()
        self.plumbings = [plumbing(v) for v in pipes]
        self.refresh = MDUpdate(cherrypy.engine, server=self, frequency=config.frequency)
        self.refresh.subscribe()
        self.aliases = config.aliases
        self.psl = PublicSuffixList()
        self.md = MDRepository(metadata_cache_enabled=config.caching_enabled, store=config.store)

        if config.autoreload:
            for f in pipes:
                cherrypy.engine.autoreload.files.add(f)

    @property
    def ready(self):
        return self.md.store.ready()

    def reload_pipeline(self):
        new_plumbings = [plumbing(v) for v in self._pipes]
        self.plumbings = new_plumbings

    class MediaAccept(object):

        def __init__(self):
            pass

        def has_key(self, key):
            return True

        def get(self, item):
            return self.__getitem__(item)

        def __getitem__(self, item):
            try:
                return cptools.accept(item, debug=True)
            except HTTPError:
                return False

    def request(self, **kwargs):
        """The main request processor. This code implements all rendering of metadata.
        """
        stats['MD Requests'] += 1

        if not self.ready:
            raise HTTPError(503, _("Service Unavailable (repository loading)"))

        pfx = kwargs.get('pfx', None)
        path = kwargs.get('path', None)
        content_type = kwargs.get('content_type', None)

        log.debug("MDServer pfx=%s, path=%s, content_type=%s" % (pfx, path, content_type))

        def _d(x, do_split=True):
            if x is not None:
                x = x.strip()
            log.debug("_d(%s,%s)" % (x, do_split))
            if x is None or len(x) == 0:
                return None, None

            if x.startswith("{base64}"):
                x = x[8:].decode('base64')

            if do_split and '.' in x:
                (pth, dot, extn) = x.rpartition('.')
                assert (dot == '.')
                if extn in _ctypes:
                    return pth, extn

            return x, None

        _ctypes = {'xml': 'application/xml',
                   'json': 'application/json',
                   'htm': 'text/html',
                   'html': 'text/html',
                   'ds': 'text/html',
                   's': 'application/json'}

        alias = None
        if pfx:
            alias = pfx
            pfx = self.aliases.get(alias, None)
            if pfx is None:
                raise NotFound()

        path, ext = _d(path, content_type is None)
        if pfx and path:
            q = "{%s}%s" % (pfx, path)
            path = "/%s/%s" % (alias, path)
        else:
            q = path

        if ext is not None:
            log.debug("request path: %s.%s, headers: %s" % (path, ext, cherrypy.request.headers))
        else:
            log.debug("request path: %s, headers: %s" % (path, cherrypy.request.headers))

        accept = {}
        if content_type is None:
            if ext is not None and ext in _ctypes:
                accept = {_ctypes[ext]: True}
            else:
                accept = MDServer.MediaAccept()
                if ext is not None:
                    path = "%s.%s" % (path, ext)
        else:
            accept = {content_type: True}

        with self.lock.readlock:
            if ext == 'ds':
                pdict = dict()
                entity_id = kwargs.get('entityID', None)
                if entity_id is None:
                    raise HTTPError(400, _("400 Bad Request - missing entityID"))
                pdict['sp'] = self.md.sha1_id(entity_id)
                e = self.md.store.lookup(entity_id)
                if e is None or len(e) == 0:
                    raise HTTPError(404)

                if len(e) > 1:
                    raise HTTPError(400, _("400 Bad Request - multiple matches for") + " %s" % entity_id)

                pdict['entity'] = self.md.simple_summary(e[0])
                if not path:
                    pdict['search'] = "/search/"
                    pdict['list'] = "/role/idp.json"
                else:
                    pdict['search'] = "%s.s" % path
                    pdict['list'] = "%s.json" % path
                cherrypy.response.headers['Content-Type'] = 'text/html'
                return render_template("ds.html", **pdict)
            elif ext == 's':
                paged = bool(kwargs.get('paged', False))
                query = kwargs.get('query', None)
                page = kwargs.get('page', 0)
                page_limit = kwargs.get('page_limit', 10)
                entity_filter = kwargs.get('entity_filter', None)
                related = kwargs.get('related', None)

                cherrypy.response.headers['Content-Type'] = 'application/json'

                if query is None:
                    log.debug("empty query - creating one")
                    query = [cherrypy.request.remote.ip]
                    referrer = cherrypy.request.headers.get('referrer', None)
                    if referrer is not None:
                        log.debug("including referrer: %s" % referrer)
                        url = urlparse.urlparse(referrer)
                        host = url.netloc
                        if ':' in url.netloc:
                            (host, port) = url.netloc.split(':')
                        for host_part in host.rstrip(self.psl.get_public_suffix(host)).split('.'):
                            if host_part is not None and len(host_part) > 0:
                                query.append(host_part)
                    log.debug("created query: %s" % ",".join(query))

                if paged:
                    res, more, total = self.md.search(query,
                                                      path=q,
                                                      page=int(page),
                                                      page_limit=int(page_limit),
                                                      entity_filter=entity_filter,
                                                      related=related)
                    # log.debug(dumps({'entities': res, 'more': more, 'total': total}))
                    return dumps({'entities': res, 'more': more, 'total': total})
                else:
                    return dumps(self.md.search(query,
                                                path=q,
                                                entity_filter=entity_filter,
                                                related=related))
            elif accept.get('text/html'):
                if not q:
                    if pfx:
                        title = pfx
                    else:
                        title = _("Metadata By Attributes")
                    return render_template("index.html",
                                           md=self.md,
                                           alias=alias,
                                           aliases=self.aliases,
                                           title=title)
                else:
                    entities = self.md.lookup(q)
                    if not entities:
                        raise NotFound()
                    if len(entities) > 1:
                        return render_template("metadata.html",
                                               md=self.md,
                                               subheading=q,
                                               entities=entities)
                    else:
                        entity = entities[0]
                        t = html.fragment_fromstring(unicode(xslt_transform(entity, "entity2html.xsl")))
                        for c_elt in t.findall(".//code[@role='entity']"):
                            c_txt = dumptree(entity)
                            parser = etree.XMLParser(remove_blank_text=True)
                            src = StringIO(c_txt)
                            tree = etree.parse(src, parser)
                            c_txt = dumptree(tree, pretty_print=True, xml_declaration=False).decode("utf-8")
                            p = c_elt.getparent()
                            p.remove(c_elt)
                            if p.text is not None:
                                p.text += c_txt
                            else:
                                p.text = c_txt
                        xml = dumptree(t, xml_declaration=False).decode('utf-8')
                        return render_template("entity.html",
                                               headline=self.md.display(entity).strip(),
                                               subheading=entity.get('entityID'),
                                               entity_id=entity.get('entityID'),
                                               content=xml)
            else:
                for p in self.plumbings:
                    state = {'request': True,
                             'headers': {'Content-Type': 'text/xml'},
                             'accept': accept,
                             'url': cherrypy.url(relative=False),
                             'select': q,
                             'path': path,
                             'stats': {}}
                    r = p.process(self.md, state=state)
                    if r is not None:
                        cache_ttl = state.get('cache', 0)
                        log.debug("caching for %d seconds" % cache_ttl)
                        for k, v in state.get('headers', {}).iteritems():
                            cherrypy.response.headers[k] = v
                        caching.expires(secs=cache_ttl)
                        return r
        raise NotFound()
Example #14
0
class TestRepo(TestCase):
    def setUp(self):
        self.md = MDRepository()
        self.md.store = self.md.store_class()
        self.datadir = resource_filename('metadata', 'test/data')
        self.xml_source = os.path.join(self.datadir, 'test01.xml')
        self.swamid_source = os.path.join(self.datadir, 'swamid-2.0-test.xml')
        self.swamid = root(parse_xml(self.swamid_source))
        self.t = parse_xml(self.xml_source)
        self.non_metadata = parse_xml(
            resource_filename("not-metadata.xml", self.datadir))

    def test_md_exists(self):
        assert (self.md is not None)

    def test_clone(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        nstore = deepcopy(self.md.store)
        assert (nstore.size() == self.md.store.size())
        assert (nstore.lookup(entity_id) is not None)

    def test_sha1_hash(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)
        assert (sha1_id(
            e[0]) == "{sha1}568515f6fae8c8b4d42d543853c96d08f051ef13")
        assert (hash_id(
            e[0], 'sha1',
            prefix=False) == "568515f6fae8c8b4d42d543853c96d08f051ef13")

    def test_entity_attribute(self):
        entity_id = root(self.t).get('entityID')
        set_entity_attributes(root(self.t), {"http://ns.example.org": "foo"})
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup("{%s}%s" % ("http://ns.example.org", 'foo'))[0]
        assert (e is not None)
        assert (e.get('entityID') == entity_id)

    def test_utils(self):
        entity_id = root(self.t).get('entityID')
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)[0]
        assert (is_idp(e))
        assert (not is_sp(e))
        icon = entity_icon(e)
        assert ('url' in icon)
        assert ('https://www.example.com/static/images/umu_logo.jpg'
                in icon['url'])
        assert ('width' in icon)
        assert ('358' == icon['width'])
        assert ('height' in icon)
        assert ('63' == icon['height'])
        assert ('62' != icon['height'])

        domains = entity_domains(e)
        assert ('example.com' in domains)
        assert ('example.net' in domains)
        assert ('idp.example.com' not in domains)
        assert ('foo.com' not in domains)

        edup = deepcopy(e)
        name, desc = entity_extended_display(e)
        assert (name == 'Example University')
        assert (desc == 'Identity Provider for Example University')

        disp = entity_display_name(e)
        assert (disp == 'Example University')
        for elt in e.findall(".//{%s}DisplayName" % NS['mdui']):
            elt.getparent().remove(elt)

        disp = entity_display_name(e)
        assert (disp == 'The Example University')
        for elt in e.findall(".//{%s}OrganizationDisplayName" % NS['md']):
            elt.getparent().remove(elt)

        disp = entity_display_name(e)
        assert (disp == 'ExampleU')
        for elt in e.findall(".//{%s}OrganizationName" % NS['md']):
            elt.getparent().remove(elt)

        disp = entity_display_name(e)
        assert (disp == entity_id)

        e = edup

        subs = entity_domains(e)
        assert ('example.com' in subs)
        assert ('example.net' in subs)
        assert ('idp.example.com' not in subs)

        summary = entity_simple_summary(e)
        assert (summary['title'] == 'Example University')
        assert (summary['descr'] == 'Identity Provider for Example University')
        assert (summary['entityID'] == entity_id)
        assert ('entity_icon' in summary)
        assert ('icon_url' in summary
                and summary['entity_icon'] == summary['icon_url'])
        assert ('domains' in summary)
        assert ('id' in summary)

        empty = entity_simple_summary(None)
        assert (not empty)

    def test_display(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get('Name'))
        funet_connect = self.md.lookup(
            'https://connect.funet.fi/shibboleth')[0]
        name, desc = entity_extended_display(funet_connect)
        assert (name == 'FUNET E-Meeting Service')
        dn = entity_extended_display(funet_connect)

    def test_missing(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get('Name'))
        missing = self.md.lookup('https://connect.funet.fi/shibboleth+missing')
        assert (len(missing) == 0)

    def test_non_metadata(self):
        e = root(self.non_metadata)
        assert metadata_expiration(e) is None
        try:
            annotate_entity(e, "kaka", "x", "y")
            set_entity_attributes(e, dict(a=1))
            assert False
        except MetadataException:
            pass
Example #15
0
class TestRepo(TestCase):
    def setUp(self):
        self.md = MDRepository(store=MemoryStore)
        self.datadir = resource_filename("metadata", "test/data")
        self.xml_source = os.path.join(self.datadir, "test01.xml")
        self.swamid_source = os.path.join(self.datadir, "swamid-2.0-test.xml")
        self.swamid = root(parse_xml(self.swamid_source))
        self.t = parse_xml(self.xml_source)
        self.non_metadata = parse_xml(resource_filename("not-metadata.xml", self.datadir))

    def test_md_exists(self):
        assert self.md is not None

    def test_clone(self):
        entity_id = root(self.t).get("entityID")
        self.md.store.update(root(self.t), entity_id)
        nmd = self.md.clone()
        assert nmd.store.size() == self.md.store.size()
        assert nmd.lookup(entity_id) is not None

    def test_sha1_hash(self):
        entity_id = root(self.t).get("entityID")
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)
        assert self.md.sha1_id(e[0]) == "{sha1}568515f6fae8c8b4d42d543853c96d08f051ef13"
        assert hash_id(e[0], "sha1", prefix=False) == "568515f6fae8c8b4d42d543853c96d08f051ef13"

    def test_entity_attribute(self):
        entity_id = root(self.t).get("entityID")
        self.md.set_entity_attributes(root(self.t), {"http://ns.example.org": "foo"})
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup("{%s}%s" % ("http://ns.example.org", "foo"))[0]
        assert e is not None
        assert e.get("entityID") == entity_id

    def test_utils(self):
        entity_id = root(self.t).get("entityID")
        self.md.store.update(root(self.t), entity_id)
        e = self.md.lookup(entity_id)[0]
        assert self.md.is_idp(e)
        assert not self.md.is_sp(e)
        assert self.md.icon(e) in [
            "https://www.example.com/static/images/logo.jpg",
            "https://www.example.com/static/images/logo_eng.jpg",
        ]
        domains = self.md.domains(e)
        assert "example.com" in domains
        assert "example.net" in domains
        assert "idp.example.com" in domains
        assert "foo.com" not in domains

        edup = deepcopy(e)
        name, desc = self.md.ext_display(e)
        assert name == "Example University"
        assert desc == "Identity Provider for Example University"

        disp = self.md.display(e)
        assert disp == "Example University"
        for elt in e.findall(".//{%s}DisplayName" % NS["mdui"]):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert disp == "The Example University"
        for elt in e.findall(".//{%s}OrganizationDisplayName" % NS["md"]):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert disp == "ExampleU"
        for elt in e.findall(".//{%s}OrganizationName" % NS["md"]):
            elt.getparent().remove(elt)

        disp = self.md.display(e)
        assert disp == entity_id

        e = edup

        subs = self.md.sub_domains(e)
        assert "example.com" in subs
        assert "example.net" in subs
        assert "idp.example.com" not in subs

        summary = self.md.simple_summary(e)
        assert summary["title"] == "Example University"
        assert summary["descr"] == "Identity Provider for Example University"
        assert summary["value"] == entity_id
        assert "icon" in summary
        assert "icon_url" in summary and summary["icon"] == summary["icon_url"]
        assert "domains" in summary
        assert "id" in summary

        empty = self.md.simple_summary(None)
        assert not empty

    def test_display(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get("Name"))
        funet_connect = self.md.lookup("https://connect.funet.fi/shibboleth")[0]
        name, desc = self.md.ext_display(funet_connect)
        assert name == "FUNET E-Meeting Service"
        dn = self.md.display(funet_connect)

    def test_missing(self):
        swamid = root(self.swamid)
        self.md.store.update(swamid, swamid.get("Name"))
        missing = self.md.lookup("https://connect.funet.fi/shibboleth+missing")
        assert len(missing) == 0

    def test_non_metadata(self):
        e = root(self.non_metadata)
        assert self.md.expiration(e) is None
        try:
            self.md.annotate(e, "kaka", "x", "y")
            self.md.set_entity_attributes(e, dict(a=1))
            assert False
        except MetadataException:
            pass