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  
20  package org.apache.myfaces.tobago.internal.config;
21  
22  import org.apache.myfaces.tobago.exception.TobagoConfigurationException;
23  
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  public class ContentSecurityPolicy {
29  
30    private Mode mode;
31    private Map<String, String> directiveMap;
32  
33    private boolean unmodifiable = false;
34  
35    private void checkLocked() throws IllegalStateException {
36      if (unmodifiable) {
37        throw new TobagoConfigurationException("The configuration must not be changed after initialization!");
38      }
39    }
40  
41    /**
42     * Lock the configuration, so it cannot be modified any more.
43     */
44    public void lock() {
45      unmodifiable = true;
46      directiveMap = Collections.unmodifiableMap(directiveMap);
47    }
48  
49    public ContentSecurityPolicy(final String mode) {
50      this.mode = Mode.parse(mode);
51      this.directiveMap = new HashMap<>();
52    }
53  
54    public void merge(final ContentSecurityPolicy other) {
55      checkLocked();
56      for (final Map.Entry<String, String> entry : other.directiveMap.entrySet()) {
57        addDirective(entry.getKey(), entry.getValue());
58      }
59      mode = other.mode;
60    }
61  
62    public void addDirective(final String name, final String text) {
63      final String old = directiveMap.get(name);
64      if (old != null) {
65        directiveMap.put(name, old + ' ' + text);
66      } else {
67        directiveMap.put(name, text);
68      }
69    }
70  
71    public Map<String, String> getDirectiveMap() {
72      return directiveMap;
73    }
74  
75    public Mode getMode() {
76      return mode;
77    }
78  
79    @Override
80    public String toString() {
81      return "ContentSecurityPolicy{"
82          + "mode=" + mode
83          + ", directiveMap=" + directiveMap
84          + '}';
85    }
86  
87    public enum Mode {
88      ON("on"),
89      OFF("off"),
90      REPORT_ONLY("report-only");
91  
92      private final String value;
93  
94      Mode(final String value) {
95        this.value = value;
96      }
97  
98      public String getValue() {
99        return value;
100     }
101 
102     public static Mode parse(final String string) {
103       if (ON.value.equals(string)) {
104         return ON;
105       } else if (OFF.value.equals(string)) {
106         return OFF;
107       } else if (REPORT_ONLY.value.equals(string)) {
108         return REPORT_ONLY;
109       } else {
110         throw new IllegalArgumentException("Found: " + string);
111       }
112     }
113   }
114 
115 }