aboutsummaryrefslogtreecommitdiff
path: root/xacml-translation/json_xacml_translator/lib/translator.ml
blob: 13125abf761eb24f997c5b48a08b66c1c1448fb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
open Base

type xml_element = (string * (string * string) list * Xml.xml list)

let rec get_attr (needle : string) : (string * string) list -> string option = function
  | (k, v) :: xs -> if String.(k = needle) then Some v else get_attr needle xs
  | _ -> None

let get_exn opt message =
  match opt with
  | Some x -> x
  | _ -> failwith message

let get_attr_exn needle attrs : string =
  get_exn (get_attr needle attrs) "missing attribute"

let xml_element_of_children (children : Xml.xml list) : xml_element list =
  List.map children ~f:(function
      | Element x -> x
      | _ -> failwith "called on element with non-element children")

let xml_element_of_Xml : Xml.xml -> xml_element = function
  | Element (elt) -> elt
  | _ -> failwith "not an element"

(* --- *)

let compile_attribute_value category identifier issuer ((tag_name, attributes, children) : xml_element) =
  assert String.(tag_name = "AttributeValue");
  let typ = get_attr_exn "DataType" attributes in
  match children with
  | [PCData s] ->
    (match issuer with
     | Some issuer ->
       `Assoc
         [
           ("category", `String category);
           ("identifier", `String identifier);
           ("issuer", `String issuer);
           ("value", `Assoc [("kind", `String "primitive");
                             ("type", `String typ);
                             ("value", `String s)])
         ]
     | _ ->
       `Assoc
         [
           ("category", `String category);
           ("identifier", `String identifier);
           ("value", `Assoc [("kind", `String "primitive");
                             ("type", `String typ);
                             ("value", `String s)])
         ])
    | _ -> failwith "ill-formed attribute value"

let compile_attribute category ((tag_name, attributes, children) : xml_element) =
  assert String.(tag_name = "Attribute");
  let identifier = get_attr_exn "AttributeId" attributes in
  let issuer = get_attr "Issuer" attributes in
  compile_attribute_value category identifier issuer (List.nth_exn children 0 |> xml_element_of_Xml)

let compile_attributes ((tag_name, attributes, children) : xml_element) : _ =
  assert String.(tag_name = "Attributes");
  let category = get_attr_exn "Category" attributes in
  children
  |> xml_element_of_children
  |> List.map ~f:(compile_attribute category)
  (* |> List.concat *)

let compile_request' : Xml.xml -> _ = function
  | Element (("Request", _attributes, children)) ->
    List.map ~f:xml_element_of_Xml children
    |> List.map ~f:compile_attributes
    |> List.concat
  | Element ((tag_name, _, _)) ->
    failwith (Printf.sprintf "(%s)" tag_name)
  | PCData s -> failwith s

let compile_request (request : string) : string =
  let request = Xml.parse_string request in
  let attributes = compile_request' request in
  Yojson.Basic.to_string (`List attributes)

© 2015 - 2026 Jakob L. Kreuze