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.ui.commons;
20  
21  import java.security.AccessControlException;
22  import java.util.Optional;
23  import java.util.stream.Collectors;
24  import javax.ws.rs.BadRequestException;
25  import javax.ws.rs.ForbiddenException;
26  import javax.xml.ws.WebServiceException;
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.syncope.common.lib.SyncopeClientException;
29  import org.apache.syncope.common.lib.types.ClientExceptionType;
30  import org.apache.wicket.authorization.UnauthorizedInstantiationException;
31  import org.apache.wicket.core.request.handler.PageProvider;
32  import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
33  import org.apache.wicket.markup.html.pages.ExceptionErrorPage;
34  import org.apache.wicket.protocol.http.PageExpiredException;
35  import org.apache.wicket.request.IRequestHandler;
36  import org.apache.wicket.request.component.IRequestablePage;
37  import org.apache.wicket.request.cycle.IRequestCycleListener;
38  import org.apache.wicket.request.cycle.RequestCycle;
39  import org.apache.wicket.request.mapper.parameter.PageParameters;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  public abstract class SyncopeUIRequestCycleListener implements IRequestCycleListener {
44  
45      private static final Logger LOG = LoggerFactory.getLogger(SyncopeUIRequestCycleListener.class);
46  
47      @SuppressWarnings("unchecked")
48      private static <T extends Exception> Optional<T> instanceOf(final Exception e, final Class<T> clazz) {
49          if (clazz.isAssignableFrom(e.getClass())) {
50              return Optional.of((T) e);
51          }
52  
53          if (e.getCause() != null && clazz.isAssignableFrom(e.getCause().getClass())) {
54              return Optional.of((T) e.getCause());
55          }
56  
57          if (e.getCause() != null && e.getCause().getCause() != null
58                  && clazz.isAssignableFrom(e.getCause().getCause().getClass())) {
59  
60              return Optional.of((T) e.getCause().getCause());
61          }
62  
63          return Optional.empty();
64      }
65  
66      @Override
67      public IRequestHandler onException(final RequestCycle cycle, final Exception e) {
68          LOG.error("Exception found", e);
69  
70          PageParameters errorParameters = new PageParameters();
71  
72          IRequestablePage errorPage;
73          if (instanceOf(e, UnauthorizedInstantiationException.class).isPresent()) {
74              errorParameters.add("errorMessage", BaseSession.Error.AUTHORIZATION.message());
75              errorPage = getErrorPage(errorParameters);
76          } else if (instanceOf(e, AccessControlException.class).isPresent()) {
77              AccessControlException ace = instanceOf(e, AccessControlException.class).get();
78              if (StringUtils.containsIgnoreCase(ace.getMessage(), "expired")) {
79                  errorParameters.add("errorMessage", BaseSession.Error.SESSION_EXPIRED.message());
80              } else {
81                  errorParameters.add("errorMessage", BaseSession.Error.AUTHORIZATION.message());
82              }
83              errorPage = getErrorPage(errorParameters);
84          } else if (instanceOf(e, SyncopeClientException.class).isPresent()) {
85              SyncopeClientException sce = instanceOf(e, SyncopeClientException.class).get();
86              String errorMessage = sce.getType() == ClientExceptionType.Unknown
87                      ? sce.getElements().stream().collect(Collectors.joining())
88                      : sce.getMessage();
89              errorParameters.add("errorMessage", errorMessage);
90              errorPage = getErrorPage(errorParameters);
91          } else if (instanceOf(e, BadRequestException.class).isPresent()
92                  || instanceOf(e, WebServiceException.class).isPresent()) {
93  
94              errorParameters.add("errorMessage", BaseSession.Error.REST.message());
95              errorPage = getErrorPage(errorParameters);
96          } else if (instanceOf(e, PageExpiredException.class).isPresent() || !isSignedIn()) {
97              errorParameters.add("errorMessage", BaseSession.Error.SESSION_EXPIRED.message());
98              errorPage = getErrorPage(errorParameters);
99          } else {
100             Optional<ForbiddenException> cause = instanceOf(e, ForbiddenException.class);
101             if (cause.isPresent()) {
102                 errorParameters.add("errorMessage", cause.get().getMessage());
103                 errorPage = getErrorPage(errorParameters);
104             } else {
105                 // redirect to default Wicket error page
106                 errorPage = new ExceptionErrorPage(e, null);
107             }
108         }
109 
110         if (errorPage instanceof BaseLogin) {
111             try {
112                 invalidateSession();
113             } catch (Throwable t) {
114                 // ignore
115                 LOG.debug("Unexpected error while forcing logout after error", t);
116             }
117         }
118 
119         return new RenderPageRequestHandler(new PageProvider(errorPage));
120     }
121 
122     protected abstract boolean isSignedIn();
123 
124     protected abstract void invalidateSession();
125 
126     protected abstract IRequestablePage getErrorPage(PageParameters errorParameters);
127 }