View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.console.panels;
20  
21  import com.fasterxml.jackson.core.JsonProcessingException;
22  import com.fasterxml.jackson.databind.json.JsonMapper;
23  import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
24  import java.io.IOException;
25  import java.io.StringReader;
26  import java.text.ParseException;
27  import java.util.Base64;
28  import javax.ws.rs.core.MediaType;
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.parsers.SAXParserFactory;
31  import org.apache.commons.lang3.time.DateFormatUtils;
32  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
33  import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
34  import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
35  import org.apache.syncope.common.lib.to.PlainSchemaTO;
36  import org.apache.syncope.common.lib.types.AttrSchemaType;
37  import org.apache.wicket.PageReference;
38  import org.bouncycastle.util.io.pem.PemReader;
39  import org.xml.sax.InputSource;
40  import org.xml.sax.SAXException;
41  
42  public class ParametersModalPanel extends AbstractModalPanel<ConfParam> {
43  
44      private static final long serialVersionUID = 4024126489500665435L;
45  
46      private static final JsonMapper JSON_MAPPER = JsonMapper.builder().findAndAddModules().build();
47  
48      private static final SAXParserFactory SAX_PARSER_FACTORY = SAXParserFactory.newInstance();
49  
50      private static boolean isDate(final String value) {
51          try {
52              DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.parse(value);
53              return true;
54          } catch (ParseException pe) {
55              return false;
56          }
57      }
58  
59      private static boolean isBase64(final String value) {
60          try {
61              Base64.getDecoder().decode(value);
62              return value.length() % 4 == 0;
63          } catch (IllegalArgumentException iae) {
64              return false;
65          }
66      }
67  
68      private static boolean isJSON(final String value) {
69          try {
70              JSON_MAPPER.readTree(value);
71              return true;
72          } catch (JsonProcessingException jpe) {
73              return false;
74          }
75      }
76  
77      private static boolean isXML(final String value) {
78          try {
79              SAX_PARSER_FACTORY.newSAXParser().getXMLReader().parse(new InputSource(new StringReader(value)));
80              return true;
81          } catch (IOException | ParserConfigurationException | SAXException xmle) {
82              return false;
83          }
84      }
85  
86      private static boolean isPEM(final String value) {
87          try (PemReader reader = new PemReader(new StringReader(value))) {
88              return reader.readPemObject() != null;
89          } catch (IOException e) {
90              return false;
91          }
92      }
93  
94      private final ParametersWizardPanel.ParametersForm form;
95  
96      public ParametersModalPanel(
97              final BaseModal<ConfParam> modal,
98              final ConfParam param,
99              final ConfParamOps confParamOps,
100             final AjaxWizard.Mode mode,
101             final PageReference pageRef) {
102 
103         super(modal, pageRef);
104 
105         PlainSchemaTO schema = new PlainSchemaTO();
106         schema.setMultivalue(param.isMultivalue());
107         schema.setMimeType(MediaType.APPLICATION_OCTET_STREAM);
108         if (param.getSchema() != null) {
109             if (param.isInstance(Boolean.class)) {
110                 schema.setType(AttrSchemaType.Boolean);
111             } else if (param.isInstance(Integer.class) || param.isInstance(Long.class)) {
112                 schema.setType(AttrSchemaType.Long);
113             } else if (param.isInstance(Float.class) || param.isInstance(Double.class)) {
114                 schema.setType(AttrSchemaType.Double);
115             } else // attempt to guess type from content: otherwise, it's bare String
116             if (!param.getValues().isEmpty()) {
117                 // 1. is it Date?
118                 if (isDate(param.getValues().get(0).toString())) {
119                     schema.setType(AttrSchemaType.Date);
120                 } else // 2. does it look like Base64?
121                 if (isBase64(param.getValues().get(0).toString())) {
122                     schema.setType(AttrSchemaType.Binary);
123                     String value = new String(Base64.getDecoder().decode(param.getValues().get(0).toString()));
124 
125                     // 3. is it JSON?
126                     if (isJSON(value)) {
127                         schema.setMimeType(MediaType.APPLICATION_JSON);
128                     } else // 4. is it XML?
129                     if (isXML(value)) {
130                         schema.setMimeType(MediaType.APPLICATION_XML);
131                     } else // 5. is it PEM?
132                     if (isPEM(value)) {
133                         schema.setMimeType("application/x-pem-file");
134                     }
135                 } else {
136                     schema.setType(AttrSchemaType.String);
137                 }
138             }
139         }
140 
141         if (schema.getType() == AttrSchemaType.Binary) {
142             modal.size(Modal.Size.Extra_large);
143         } else {
144             modal.size(Modal.Size.Default);
145         }
146 
147         form = new ParametersWizardPanel.ParametersForm(schema, param);
148         add(new ParametersWizardPanel(form, confParamOps, pageRef).build("parametersCreateWizardPanel", mode));
149     }
150 
151     @Override
152     public final ConfParam getItem() {
153         return form.getParam();
154     }
155 }