Minor refactoring of XML import code
[moonshot-ui.git] / src / moonshot-provisioning-common.vala
1 /*
2  * Copyright (c) 2011-2014, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31 */
32
33
34
35 namespace WebProvisioning
36
37     bool check_stack(SList<string> stack, string[] reference) {
38
39         if (stack.length() < reference.length)
40             return false;
41     
42         for (int i = 0; i < reference.length; i++)
43         {
44             if (stack.nth_data(i) != reference[i])
45                 return false;
46         }
47
48         return true;
49     }
50
51     bool always_confirm_handler(SList<string> stack)
52     {
53         string[] always_confirm_path = {"always-confirm", "rule", "selection-rules", "identity", "identities"};
54     
55         return check_stack(stack, always_confirm_path);
56     }
57   
58     bool
59     pattern_handler(SList<string> stack)
60     {
61         string[] pattern_path = {"pattern", "rule", "selection-rules", "identity", "identities"};
62     
63         return check_stack(stack, pattern_path);
64     }
65
66     bool server_cert_handler(SList<string> stack)
67     {
68         string[] server_cert_path = {"server-cert", "trust-anchor", "identity", "identities"};
69     
70         return check_stack(stack, server_cert_path);
71     }
72
73     bool subject_alt_handler(SList<string> stack)
74     {
75         string[] subject_alt_path = {"subject-alt", "trust-anchor", "identity", "identities"};
76     
77         return check_stack(stack, subject_alt_path);
78     }
79
80     bool subject_handler(SList<string> stack)
81     {
82         string[] subject_path = {"subject", "trust-anchor", "identity", "identities"};
83     
84         return check_stack(stack, subject_path);
85     }
86   
87     bool ca_cert_handler(SList<string> stack)
88     {
89         string[] ca_path = {"ca-cert", "trust-anchor", "identity", "identities"};
90     
91         return check_stack(stack, ca_path);
92     }
93
94     bool realm_handler(SList<string> stack)
95     {
96         string[] realm_path = {"realm", "identity", "identities"};
97     
98         return check_stack(stack, realm_path);
99     }
100
101     bool password_handler(SList<string> stack)
102     {
103         string[] password_path = {"password", "identity", "identities"};
104     
105         return check_stack(stack, password_path);
106     }
107
108     bool user_handler(SList<string> stack)
109     {
110         string[] user_path = {"user", "identity", "identities"};
111     
112         return check_stack(stack, user_path);
113     }
114
115     bool display_name_handler(SList<string> stack)
116     {
117         string[] display_name_path = {"display-name", "identity", "identities"};
118     
119         return check_stack(stack, display_name_path);
120     }
121   
122     public class Parser : Object
123     {
124         private static MoonshotLogger logger = new MoonshotLogger("WebProvisioning");
125
126         private void start_element_func(MarkupParseContext context,
127                                         string element_name,
128                                         string[] attribute_names,
129                                         string[] attribute_values) throws MarkupError 
130             {
131                 if (element_name == "identity")
132                 {
133                     logger.trace("start_element_func (%p): Adding an identity".printf(this));
134                     card = new IdCard();
135                     _cards += card;
136                 }
137                 else if (element_name == "rule")
138                 {
139                     card.add_rule(Rule());
140                 }
141             }
142
143             private void
144             text_element_func(MarkupParseContext context,
145                               string             text,
146                               size_t             text_len) throws MarkupError {
147                 unowned SList<string> stack = context.get_element_stack();
148     
149                 if (text_len < 1)
150                     return;
151     
152                 logger.trace("text_element_func (%p): text='%s'".printf(this, stack.nth_data(0)));
153
154                 if (stack.nth_data(0) == "display-name" && display_name_handler(stack))
155                 {
156                     card.display_name = text;
157                 }
158                 else if (stack.nth_data(0) == "user" && user_handler(stack))
159                 {
160                     card.username = text;
161                 }
162                 else if (stack.nth_data(0) == "password" && password_handler(stack))
163                 {
164                     card.password = text;
165                 }
166                 else if (stack.nth_data(0) == "realm" && realm_handler(stack))
167                 {
168                     card.issuer = text;
169                 }
170                 else if (stack.nth_data(0) == "service")
171                 {
172                     card.add_service(text);
173                 }
174
175                 /* Rules */
176                 else if (stack.nth_data(0) == "pattern" && pattern_handler(stack))
177                 {
178                     /* use temp array to workaround valac 0.10 bug accessing array property length */ 
179                     var temp = card.rules;
180                     card.rules[temp.length - 1].pattern = text;
181                 }
182                 else if (stack.nth_data(0) == "always-confirm" && always_confirm_handler(stack))
183                 {
184                     if (text == "true" || text == "false") {
185                         /* use temp array to workaround valac 0.10 bug accessing array property length*/
186                         var temp = card.rules;
187                         card.rules[temp.length - 1].always_confirm = text;
188                     }
189                 }
190                 /*Trust anchor*/
191                 else if (stack.nth_data(0) == "ca-cert" && ca_cert_handler(stack))
192                 {
193                     card.trust_anchor.ca_cert = text;
194                 }
195                 else if (stack.nth_data(0) == "subject" && subject_handler(stack))
196                 {
197                     card.trust_anchor.subject = text;
198                 }
199                 else if (stack.nth_data(0) == "subject-alt" && subject_alt_handler(stack))
200                 {
201                     card.trust_anchor.subject_alt = text;
202                 }
203                 else if (stack.nth_data(0) == "server-cert" && server_cert_handler(stack))
204                 {
205                     card.trust_anchor.server_cert = text;
206                 }
207             }
208
209
210
211         private const MarkupParser parser = {
212             start_element_func, null, text_element_func, null, null
213         };
214
215         private MarkupParseContext ctx;
216
217         private string       text;
218         private string       path;
219
220         private IdCard card;
221         private IdCard[] _cards = {};
222
223         public IdCard[] cards {
224             get {return _cards;}
225             private set {_cards = value ?? {};}
226         }
227
228         public Parser(string path) {
229
230             ctx = new MarkupParseContext(parser, 0, this, null);
231
232             text = "";
233             this.path = path;
234
235             var file = File.new_for_path(path);
236     
237             try
238             {
239                 var dis = new DataInputStream(file.read());
240                 string line;
241                 while ((line = dis.read_line(null)) != null)
242                     text += line;
243             }
244             catch(GLib.Error e)
245             {
246                 error("Could not retreive file size");
247             }
248       
249             logger.trace(@"Parser(): read text to parse; length=$(text.length)");
250         }
251
252         public void parse() {
253             try
254             {
255                 ctx.parse(text, text.length);
256             }
257             catch(GLib.Error e)
258             {
259                 error("Could not parse %s, invalid content", path);
260             } 
261         }
262     }
263 }