Configuration and Auto-Certificates
[aaf/authz.git] / auth / auth-gui / src / main / java / org / onap / aaf / auth / gui / Page.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.gui;
23
24 import static org.onap.aaf.misc.xgen.html.HTMLGen.A;
25 import static org.onap.aaf.misc.xgen.html.HTMLGen.H1;
26 import static org.onap.aaf.misc.xgen.html.HTMLGen.LI;
27 import static org.onap.aaf.misc.xgen.html.HTMLGen.TITLE;
28 import static org.onap.aaf.misc.xgen.html.HTMLGen.UL;
29
30 import java.io.IOException;
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import javax.servlet.http.HttpServletRequest;
35
36 import org.onap.aaf.auth.common.Define;
37 import org.onap.aaf.auth.env.AuthzEnv;
38 import org.onap.aaf.auth.env.AuthzTrans;
39 import org.onap.aaf.auth.rserv.CachingFileAccess;
40 import org.onap.aaf.cadi.Permission;
41 import org.onap.aaf.cadi.aaf.AAFPermission;
42 import org.onap.aaf.cadi.config.Config;
43 import org.onap.aaf.cadi.principal.TaggedPrincipal;
44 import org.onap.aaf.misc.env.APIException;
45 import org.onap.aaf.misc.env.Slot;
46 import org.onap.aaf.misc.env.StaticSlot;
47 import org.onap.aaf.misc.env.util.Split;
48 import org.onap.aaf.misc.xgen.Cache;
49 import org.onap.aaf.misc.xgen.CacheGen;
50 import org.onap.aaf.misc.xgen.Code;
51 import org.onap.aaf.misc.xgen.DynamicCode;
52 import org.onap.aaf.misc.xgen.Mark;
53 import org.onap.aaf.misc.xgen.html.HTMLCacheGen;
54 import org.onap.aaf.misc.xgen.html.HTMLGen;
55 import org.onap.aaf.misc.xgen.html.Imports;
56
57 /**
58  * A Base "Mobile First" Page 
59  * 
60  * @author Jonathan
61  *
62  */
63 public class Page extends HTMLCacheGen {
64         public static final String AAFURL_TOOLS = "aaf_url.tools";
65         public static final String AAF_URL_TOOL_DOT = "aaf_url.tool.";
66         public static final String AAF_URL_CUIGUI = "aaf_url.cuigui"; // link to help
67         public static final String AAF_URL_GUI_ONBOARD = "aaf_url.gui_onboard";
68         public static final String AAF_URL_AAF_HELP = "aaf_url.aaf_help";
69         public static final String AAF_URL_CADI_HELP = "aaf_url.cadi_help";
70         public static final String PERM_CA_TYPE = "certman";
71         public static final String PERM_NS = Define.ROOT_NS();
72
73         public static enum BROWSER {iPhone,html5,ie,ieOld};
74         
75         public static final int MAX_LINE=20;
76
77         protected static final String[] NO_FIELDS = new String[0];
78
79         private static final String BROWSER_TYPE = "BROWSER_TYPE";
80
81         private final String bcName, bcUrl;
82         private final String[] fields;
83
84         public final boolean no_cache;
85
86         // Note: Only access is synchronized in "getPerm"
87         private final static Map<String,Map<String,Permission>> perms = new HashMap<>();
88
89         public String name() {
90                 return bcName;
91         }
92         
93         public String url() {
94                 return bcUrl;
95         }
96         
97         public String[] fields() {
98                 return fields;
99         }
100         
101         public Page(AuthzEnv env, String name, String url, Enum<?>[] en, final NamedCode ...content) throws APIException, IOException {
102                 super(CacheGen.PRETTY, new PageCode(env, 1, content));
103                 fields = new String[en.length];
104                 int i=-1;
105                 for(Enum<?> p : en) {
106                         fields[++i]=p.name();
107                 }
108
109                 bcName = name;
110                 bcUrl = url;
111                 // Mark which fields must be "no_cache"
112                 boolean no_cacheTemp=false;
113                 for(NamedCode nc : content) {
114                         if(nc.no_cache()) { 
115                                 no_cacheTemp=true;
116                                 break;
117                         }
118                 }
119                 no_cache=no_cacheTemp;
120         }
121         public Page(AuthzEnv env, String name, String url, String [] fields, final NamedCode ... content) throws APIException,IOException {
122                 this(env,name,url,1,fields,content);
123         }
124         
125         public Page(AuthzEnv env, String name, String url, int backdots, String [] fields, final NamedCode ... content) throws APIException,IOException {
126                 super(CacheGen.PRETTY, new PageCode(env, backdots, content));
127                 if(fields==null) {
128                         this.fields = new String[0];
129                 } else {
130                         this.fields = fields;
131                 }
132                 bcName = name;
133                 bcUrl = url;
134                 // Mark which fields must be "no_cache"
135                 boolean no_cacheTemp=false;
136                 for(NamedCode nc : content) {
137                         if(nc.no_cache()) { 
138                                 no_cacheTemp=true;
139                                 break;
140                         }
141                 }
142                 no_cache=no_cacheTemp;
143         }
144         
145         
146         private static class PageCode implements Code<HTMLGen> {
147                         private static final String AAF_GUI_TITLE = "aaf_gui_title";
148                         
149                         private final ContentCode[] content;
150                         private final Slot browserSlot;
151                         private final int backdots;
152                         protected AuthzEnv env;
153                         private StaticSlot sTheme;
154
155                         public PageCode(AuthzEnv env, int backdots, final ContentCode[] content) {
156                                 this.content = content;
157                                 this.backdots = backdots;
158                                 browserSlot = env.slot(BROWSER_TYPE);
159                                 sTheme = env.staticSlot(CachingFileAccess.CFA_WEB_PATH);
160                                 this.env = env;
161                         }
162                         
163                         @Override
164                         public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
165                                 // Note: I found that App Storage saves everything about the page, or not.  Thus, if you declare the page uncacheable, none of the 
166                                 // Artifacts, like JPGs are stored, which makes this feature useless for Server driven elements
167                                 cache.dynamic(hgen,  new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
168                                         @Override
169                                         public void code(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
170                                                 switch(browser(trans,browserSlot)) {
171                                                         case ieOld:
172                                                         case ie:
173                                                                 hgen.directive("!DOCTYPE html");
174                                                                 hgen.directive("meta", "http-equiv=X-UA-Compatible","content=IE=11");
175                                                         default:
176                                                 }
177                                         }
178                                 });
179                                 hgen.html();
180                                 final String title = env.getProperty(AAF_GUI_TITLE,"Authentication/Authorization Framework");
181                                 final String theme = env.get(sTheme); 
182                                 Mark head = hgen.head();
183                                         hgen.leaf(TITLE).text(title).end();
184                                         hgen.imports(new Imports(backdots).css(theme + "/aaf5.css")
185                                                                                                 .js(theme + "/comm.js")
186                                                                                                 .js(theme + "/console.js")
187                                                                                                 .js(theme + "/common.js"));
188                                         cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
189                                                 @Override
190                                                 public void code(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
191                                                         switch(browser(trans,browserSlot)) {
192                                                                 case iPhone:
193                                                                         hgen.imports(new Imports(backdots).css(theme + "/aaf5iPhone.css"));
194                                                                         break;
195                                                                 case ie:
196                                                                 case ieOld:
197                                                                         hgen.js().text("document.createElement('header');")
198                                                                                         .text("document.createElement('nav');")
199                                                                                         .done();
200                                                                 case html5:
201                                                                         hgen.imports(new Imports(backdots).css(theme + "/aaf5Desktop.css"));
202                                                                         break;
203                                                         }
204                                                 }
205                                         });
206                                         hgen.end(head);
207                                         
208                                 Mark body = hgen.body();
209                                         Mark header = hgen.header();
210                                         cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
211                                                 @Override
212                                                 public void code(AAF_GUI state, AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen xgen)
213                                                                 throws APIException, IOException {
214                                                         // Obtain Server Info, and print
215                                                         // AT&T Only
216                                                         String env = trans.getProperty(Config.AAF_ENV,"N/A");
217                                                         xgen.leaf(H1).text(title + " on " + env).end();
218                                                         xgen.leaf("p","id=version").text("AAF Version: " + state.deployedVersion).end();
219                                                         
220                                                         // Obtain User Info, and print
221                                                         TaggedPrincipal p = trans.getUserPrincipal();
222                                                         String user,secured;
223                                                         if(p==null) {
224                                                                 user = "please choose a Login Authority";
225                                                                 secured = "NOT Secure!";
226                                                         } else {
227                                                                 user = p.personalName();
228                                                                 secured = p.tag();
229                                                         }
230                                                         xgen.leaf("p","id=welcome").text("Welcome, ")
231                                                                 .text(user)
232                                                                 .text("<sup>")
233                                                                 .text(secured)
234                                                                 .text("</sup>").end();
235                                                         
236                                                         switch(browser(trans,browserSlot)) {
237                                                                 case ieOld:
238                                                                 case ie:
239                                                                         xgen.incr("h5").text("This app is Mobile First HTML5.  Internet Explorer " 
240                                                                                         + " does not support all HTML5 standards. Old, non TSS-Standard versions may not function correctly.").br()
241                                                                                         .text("  For best results, use a highly compliant HTML5 browser like Firefox.")
242                                                                                 .end();
243                                                                         break;
244                                                                 default:
245                                                         }
246                                                 }
247                                         });
248                                         
249                                         hgen.hr();
250                                         
251                                         int cIdx;
252                                         ContentCode nc;
253                                         // If BreadCrumbs, put here
254                                         if(content.length>0 && content[0] instanceof BreadCrumbs) {
255                                                 nc = content[0];
256                                                 Mark ctnt = hgen.divID(nc.idattrs());
257                                                 nc.code(cache, hgen);
258                                                 hgen.end(ctnt);
259                                                 cIdx = 1;
260                                         } else {
261                                                 cIdx = 0;
262                                         }
263                                         
264                                         hgen.end(header);
265                                         
266                                         Mark inner = hgen.divID("inner");
267                                                 // Content
268                                                 for(int i=cIdx;i<content.length;++i) {
269                                                         nc = content[i];
270                                                         Mark ctnt = hgen.divID(nc.idattrs());
271                                                         nc.code(cache, hgen);
272                                                         hgen.end(ctnt);
273                                                 }
274
275                                         hgen.end(inner);        
276                                         
277                                         // Navigation - Using older Nav to work with decrepit  IE versions
278                                         
279                                         Mark nav = hgen.divID("nav");
280                                         hgen.incr("h2").text("Related Links").end();
281                                         hgen.incr(UL);
282                                         String aaf_help = env.getProperty(AAF_URL_AAF_HELP,null);
283                                         if(aaf_help!=null) {
284                                                 hgen.leaf(LI).leaf(A,"href="+env.getProperty(AAF_URL_AAF_HELP),"target=_blank").text("AAF WIKI").end(2);
285                                                 String sub = env.getProperty(AAF_URL_AAF_HELP+".sub");
286                                                 if(sub!=null) {
287                                                         hgen.incr(UL,"style=margin-left:5%");
288                                                         for(String s : Split.splitTrim(',', sub)) {
289                                                                 hgen.leaf(LI).leaf(A,"href="+env.getProperty(AAF_URL_AAF_HELP+".sub."+s),"target=_blank").text(s.replace('+', ' ')).end(2);
290                                                         }
291                                                         hgen.end();
292                                                 }
293                                         }
294                                         aaf_help = env.getProperty(AAF_URL_CADI_HELP,null);
295                                         if(aaf_help!=null) {
296                                                 hgen.leaf(LI).leaf(A,"href="+aaf_help,"target=_blank").text("CADI WIKI").end(2);
297                                         }
298                                         String tools = env.getProperty(AAFURL_TOOLS);
299                                         if(tools!=null) {
300                                                 hgen.hr()
301                                                         .incr(HTMLGen.UL,"style=margin-left:5%")
302                                                         .leaf(HTMLGen.H3).text("Related Tools").end();
303
304                                                 for(String tool : Split.splitTrim(',',tools)) {
305                                                         hgen.leaf(LI).leaf(A,"href="+env.getProperty(AAF_URL_TOOL_DOT+tool),"target=_blank").text(tool.replace('+', ' ')).end(2);
306                                                 }
307                                                 hgen.end();
308                                         }
309                                         hgen.end();
310                                         
311                                         hgen.hr();
312                                         
313                                         hgen.end(nav);
314                                         // Footer - Using older Footer to work with decrepit IE versions
315                                         Mark footer = hgen.divID("footer");
316                                                 hgen.textCR(1, env.getProperty(AAF_GUI.AAF_GUI_COPYRIGHT))
317                                                 .end(footer);
318                                                 
319                                         hgen.end(body);
320                                 hgen.endAll();
321                 }
322         }
323
324         public static String getBrowserType() {
325                 return BROWSER_TYPE;
326         }
327         
328         /**
329          * It's IE if int >=0
330          * 
331          * Use int found in "ieVersion"
332          * 
333          * Official IE 7
334          *              Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; 
335          *              .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
336          * Official IE 8
337          *              Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; 
338          *              .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; ATT)
339          * 
340          * IE 11 Compatibility
341          *              Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; 
342          *              .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
343          * 
344          * IE 11 (not Compatiblity)
345          *              Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; 
346          *              .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
347          * 
348          * @param trans
349          * @return
350          */
351         public static BROWSER browser(AuthzTrans trans, Slot slot) {
352                 BROWSER br = trans.get(slot, null);
353                 if(br==null) {
354                         String agent = trans.agent();
355                         int msie; 
356                         if(agent.contains("iPhone") /* other phones? */) {
357                                 br=BROWSER.iPhone;
358                         } else if ((msie = agent.indexOf("MSIE"))>=0) {
359                                 msie+=5;
360                                 int end = agent.indexOf(";",msie);
361                                 float ver;
362                                 try {
363                                         ver = Float.valueOf(agent.substring(msie,end));
364                                         br = ver<8f?BROWSER.ieOld:BROWSER.ie;
365                                 } catch (Exception e) {
366                                         br = BROWSER.ie;
367                                 }
368                         } else {
369                                 br = BROWSER.html5;
370                         }
371                         trans.put(slot,br);
372                 }
373                 return br;
374         }
375         
376         /*
377          * Get, rather than create each time, permissions for validations
378          */
379         protected static synchronized Permission getPerm(String instance, String action) {
380                 Map<String,Permission> msp = perms.get(instance);
381                 Permission p;
382                 if(msp==null) {
383                         msp = new HashMap<>();
384                         perms.put(instance, msp);
385                         p=null;
386                 } else {
387                         p = msp.get(instance);
388                 }
389                 if(p==null) {
390                         p=new AAFPermission(PERM_NS, PERM_CA_TYPE,instance,action);
391                         msp.put(action, p);
392                 }
393                 return p;
394         }
395
396         protected static String getSingleParam(HttpServletRequest req, String tag) {
397                 String values[] = req.getParameterValues(tag);
398                 return values.length<1?null:values[0];
399         }
400
401
402 }
403