View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package fr.cnes.doi.security;
20  
21  import fr.cnes.doi.logging.business.JsonMessage;
22  import fr.cnes.doi.settings.Consts;
23  import fr.cnes.doi.settings.DoiSettings;
24  import java.util.Set;
25  import java.util.StringTokenizer;
26  import java.util.concurrent.CopyOnWriteArraySet;
27  import org.apache.logging.log4j.LogManager;
28  import org.apache.logging.log4j.Logger;
29  import org.restlet.Context;
30  import org.restlet.Request;
31  import org.restlet.Response;
32  import org.restlet.data.Status;
33  
34  /**
35   * IP filtering.
36   *
37   * When the service is disabled, no filtering is applied. When the service is
38   * enabled, the service allows IPs such as 127.0.0.1 and IPs coming from {@link fr.cnes.doi.security.AllowerIP#addCustomIP(java.util.Set)
39   * }
40   * Allowed IPs are set based on a parameter from the configuration file
41   * {@link fr.cnes.doi.settings.Consts#ADMIN_IP_ALLOWER}
42   *
43   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
44   */
45  public class AllowerIP extends org.restlet.routing.Filter {
46  
47      /**
48       * Logger.
49       */
50      private static final Logger LOG = LogManager.getLogger(AllowerIP.class.getName());
51  
52      /**
53       * Localhost in IPv6.
54       */
55      public static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";
56      /**
57       * Localhost in IPv4.
58       */
59      public static final String LOCALHOST_IPV4 = "127.0.0.1";
60  
61      /**
62       * List of allowed IPs addresses.
63       */
64      private final Set<String> allowedAddresses;
65  
66      /**
67       * Service enabled/disabled.
68       */
69      private final boolean enabled;
70  
71      /**
72       * Constructor based on the context and a parameter to make enabled/disabled
73       * the service
74       *
75       * @param context context
76       * @param isEnabledIP True when the service is enabled otherwise False
77       */
78      public AllowerIP(final Context context, final boolean isEnabledIP) {
79          super(context);
80          LOG.traceEntry();
81          this.enabled = isEnabledIP;
82          this.allowedAddresses = new CopyOnWriteArraySet<>();
83          this.allowedAddresses.add(LOCALHOST_IPV6);
84          this.allowedAddresses.add(LOCALHOST_IPV4);
85          addCustomIP(allowedAddresses);
86          LOG.traceExit();
87      }
88  
89      /**
90       * Adds custom IPs based on the settings.
91       *
92       * @param allowedAddresses the new allowed addresses
93       */
94      private void addCustomIP(final Set<String> allowedAddresses) {
95          LOG.traceEntry("Parameter\n\tallowedAddresses: {}", allowedAddresses);
96          final String ips = DoiSettings.getInstance().getString(Consts.ADMIN_IP_ALLOWER);
97          if (ips != null) {
98              final StringTokenizer tokenizer = new StringTokenizer(ips, "|");
99              while (tokenizer.hasMoreTokens()) {
100                 final String newIP = tokenizer.nextToken();
101                 LOG.info("Adds this IP {} for allowing the access "
102                         + "to the amdinistration application", newIP);
103                 allowedAddresses.add(newIP);
104             }
105         }
106         LOG.traceExit();
107     }
108 
109     /**
110      * Before Handler.
111      *
112      * @param request request
113      * @param response response
114      * @return beforeHandler
115      */
116     @Override
117     protected int beforeHandle(final Request request,
118             final Response response) {
119         LOG.traceEntry(new JsonMessage(request));
120         int result = STOP;
121         final String ipClient = request.getClientInfo().getAddress();
122         if (this.enabled && getAllowedAddresses().contains(ipClient)) {
123             result = CONTINUE;
124         } else if (this.enabled && !getAllowedAddresses().contains(ipClient)) {
125             LOG.info("You IP address {} was blocked", ipClient);
126             response.setStatus(Status.CLIENT_ERROR_FORBIDDEN,
127                     "Your IP address " + ipClient + " was blocked");
128         } else {
129             // the service is disabled, then continue
130             result = CONTINUE;
131         }
132         return LOG.traceExit(result);
133     }
134 
135     /**
136      * Returns the allowed addresses.
137      *
138      * @return the allowed addresses
139      */
140     public Set<String> getAllowedAddresses() {
141         LOG.traceEntry();
142         return LOG.traceExit(allowedAddresses);
143     }
144 
145     /**
146      * Returns True when the service is enabled otherwise False.
147      *
148      * @return True when the service is enabled otherwise False
149      */
150     public boolean isEnabled() {
151         return this.enabled;
152     }
153 
154 }