|
57 | 57 | root, |
58 | 58 | safe_write, |
59 | 59 | total_seconds, |
| 60 | + unicode_stream, |
60 | 61 | utc_now, |
61 | 62 | validate_document, |
62 | 63 | with_tree, |
@@ -1938,6 +1939,63 @@ def signcerts(req: Plumbing.Request, *opts): |
1938 | 1939 | return req.t |
1939 | 1940 |
|
1940 | 1941 |
|
| 1942 | +@pipe |
| 1943 | +def read_xml(req: Plumbing.Request, *opts): |
| 1944 | + """ |
| 1945 | + Make an XML file the working document. |
| 1946 | +
|
| 1947 | + :param req: The request |
| 1948 | + :param opts: Options (unused) |
| 1949 | + :return: the root element of the file |
| 1950 | +
|
| 1951 | + Unlike ``load`` this does not put anything in the store and does not split the file into entities, and it does |
| 1952 | + not depend on ``select``: the file is the working document, e.g. for signing a document that is not |
| 1953 | + SAML metadata. The file is parsed as it is and is not modified: xi:include elements are not expanded. |
| 1954 | + Takes a dict with a single key, ``file``, the path to the XML file. |
| 1955 | +
|
| 1956 | + **Examples** |
| 1957 | +
|
| 1958 | + .. code-block:: yaml |
| 1959 | +
|
| 1960 | + - read_xml: |
| 1961 | + file: /opt/metadata/mdsl.xml |
| 1962 | + - sign: |
| 1963 | + key: signer.key |
| 1964 | + cert: signer.crt |
| 1965 | + - emit application/xml |
| 1966 | +
|
| 1967 | + **Possible extensions** |
| 1968 | +
|
| 1969 | + - Expand xi:include elements, relative to the file, with an ``xinclude`` option. |
| 1970 | + - Ensure the root element, e.g. with a ``root`` option in ``{namespace}name`` form, to fail early when the file is |
| 1971 | + not the kind of document the rest of the pipeline expects. |
| 1972 | + - Make the working document work with ``finalize`` (and other pipes that assume entity metadata), to support |
| 1973 | + more file types than SAML metadata. |
| 1974 | + - Support ``mdsl`` (eIDAS MetadataServiceList) as a file type. The file type would ensure the root element and |
| 1975 | + tell ``finalize`` which attributes the document has. For an MDSL that is ``IssueDate`` and ``NextUpdate`` |
| 1976 | + instead of ``validUntil`` and ``cacheDuration``, which the schema does not allow on this root element. |
| 1977 | + The pipeline could then look like this: |
| 1978 | +
|
| 1979 | + .. code-block:: yaml |
| 1980 | +
|
| 1981 | + - read_xml: |
| 1982 | + file: /opt/metadata/mdsl.xml |
| 1983 | + type: mdsl |
| 1984 | + - finalize: |
| 1985 | + validUntil: PT5M # sets NextUpdate, and IssueDate to the current time |
| 1986 | + - sign: |
| 1987 | + key: signer.key |
| 1988 | + cert: signer.crt |
| 1989 | + - emit application/xml |
| 1990 | +
|
| 1991 | + """ |
| 1992 | + if not isinstance(req.args, dict) or 'file' not in req.args: |
| 1993 | + raise PipeException("usage: read_xml {file: <path>}") |
| 1994 | + |
| 1995 | + with open(req.args['file'], encoding='utf-8') as fd: |
| 1996 | + return root(parse_xml(unicode_stream(fd.read()))) |
| 1997 | + |
| 1998 | + |
1941 | 1999 | @pipe |
1942 | 2000 | def finalize(req: Plumbing.Request, *opts): |
1943 | 2001 | r""" |
|
0 commit comments