001/*
002 * Copyright (c) 2013 - 2016 TDP Ltd All Rights Reserved.
003 * TDP Ltd grants permission, free of charge, to any person obtaining copies
004 * of this software and its associated documentation files (the "Software"),
005 * to deal in the Software without restriction, including to use, copy, adapt,
006 * publish, distribute, display, perform, sublicense, and sell copies of the
007 * Software, subject to the following condition: You must include the above
008 * copyright notice and this permission notice in all full or partial copies
009 * of the Software.
010 * 
011 * TDP LTD PROVIDES THE SOFTWARE "AS IS," WITHOUT ANY EXPRESS OR IMPLIED WARRANTY,
012 * INCLUDING WITHOUT THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
013 * PARTICULAR PURPOSE, AND NON-INFRINGMENT. TDP LTD, THE AUTHORS OF THE SOFTWARE,
014 * AND THE OWNERS OF COPYRIGHT IN THE SOFTWARE ARE NOT LIABLE FOR ANY CLAIM, DAMAGES,
015 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING
016 * FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
017 * THE SOFTWARE.
018 */
019package cz.tdp.kshield.integration.web;
020
021import java.util.List;
022
023import javax.servlet.http.HttpServletRequest;
024
025import cz.tdp.kshield.client.ClientMessage;
026import cz.tdp.kshield.client.KShieldClientException;
027import cz.tdp.kshield.client.UserInfo;
028import cz.tdp.kshield.integration.AuthenticationService;
029import cz.tdp.kshield.integration.ServletAuthenticationService;
030
031/**
032 * Implementation of KeyShield SSO Server AuthenticationService that delegates all functionality to list of AuthenticationService instances.
033 */
034public class DelegatingAuthenticationServiceImpl implements ServletAuthenticationService
035{
036  /**
037   * list of AuthenticationService instances
038   */
039  private final List<ServletAuthenticationService> services;
040  
041  /**
042   * @param services list of AuthenticationService instances
043   */
044  public DelegatingAuthenticationServiceImpl(List<ServletAuthenticationService> services) {
045    if (services == null || services.isEmpty()) throw new IllegalArgumentException("Please provide valid list of KeyShield SSO AuthenticationService instances");
046    
047    this.services = services;
048  }
049  
050  @Override
051  public void init() {
052    for (AuthenticationService service : services) {
053      service.init();
054    }
055  }
056  
057  @Override
058  public void destroy() {
059    for (AuthenticationService service : services) {
060      service.destroy();
061    }
062  }
063  
064  @Override
065  public void checkService() throws KShieldClientException {
066    for (AuthenticationService service : services) {
067      service.checkService();
068    }
069  }
070  
071  /**
072   * Return true if any service returns true
073   */
074  @Override
075  public boolean authenticate(HttpServletRequest request) {
076    for (ServletAuthenticationService service : services) {
077      if (service.authenticate(request)) {
078        return true;
079      }
080    }
081    
082    return false;
083  }
084
085  /**
086   * Return first non null userInfo
087   * 
088   * @param ipAddr remote request IP address
089   */
090  @Override
091  public UserInfo createUserInfo(String ipAddr) {
092    for (AuthenticationService service : services) {
093      final UserInfo userInfo = service.createUserInfo(ipAddr);
094      
095      if (userInfo != null) {
096        return userInfo;
097      }
098    }
099    
100    return null;
101  }
102  
103  @Override
104  public void sendClientMessage(String from, String to, String message) throws KShieldClientException {
105    sendClientMessage(new ClientMessage(from, to, message));
106  }
107  
108  @Override
109  public void sendClientMessage(ClientMessage msg) throws KShieldClientException {
110    KShieldClientException lastEx = null;
111    
112    for (AuthenticationService service : services) {
113      try {
114        service.sendClientMessage(msg);
115      }
116      catch (KShieldClientException e) {
117        // exception logged
118        lastEx = e;
119      }
120    }
121    
122    if (lastEx != null) {
123      //XXX maybe aggregate all errors and throw some other exception something like KShieldMutipleErrorsException
124      throw lastEx;
125    }
126  }
127}