summaryrefslogblamecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/authentication/ShibbolethEcp.java
blob: 071b92adbc4c9373df97fda50ee9f7896e1184cf (plain) (tree)
1
2
3
4
5
6
7
8
                                          
 
                           
                                      

                                   
                    
 


                                                      
                                        
                               

                                                             
                                   
                                                 
 



                                           

                                                          
 
                            
 


                                         
                                                                                   
 
           


                                                                    
 
           
                                                                                    
           
                                                                   
           
                                       
           
                                                  
 
           


                                       
                                      

                                                                                                                                     
                                                                                                   
                                                                                                       


                                                                                       
 

                                         
 



                                                
 


                                       
 


                                        
         
 
           

                                
                                        

                        
                     
                                                                                                              



                                                                                               
                 
                              

         
                                                             
                                    
         
 

                               
           
                        

                                                                              



                                         
                  

                                                         
           
                                                                                                   
                                                                                                                 
                                                                                    
 
                                                   

                                                                                                                   
                                                        


                                                                                                               
                                                        
                 

                                                                       
                                                        
                 

                                                                       
                                                        
                 

                                                                            
                                                                                                                                        
 
                                        
                     
                                                         
                                                        
                                                                                     

                                                                                                            
 






                                                                                                       
 

                                                                                         






                                                                                                  
                


                                                                           
                                                                    
                                                             






                                                                                 
                                                                                                               
                                                                                                                                                                    






                                                             
         
 


                                                    
                                                
                                       

         
package org.openslx.dozmod.authentication;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.AuthorizationError;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.dozmod.Branding;
import org.openslx.dozmod.util.ProxyConfigurator;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;

import edu.kit.scc.dei.ecplean.ECPAuthenticationException;
import edu.kit.scc.dei.ecplean.ECPAuthenticator;

public class ShibbolethEcp {

	/**
	 * Logger instance for this class
	 */
	private final static Logger LOGGER = Logger.getLogger(ShibbolethEcp.class);

	/**
	 * Static gson object for (de)serialization
	 */
	private static final Gson GSON = new GsonBuilder().create();

	/**
	 * ServiceProviderResponse Object representing the last response we received
	 */
	private static ServiceProviderResponse lastResponse = null;
	/**
	 * URL for service registration
	 */
	private static URL registrationUrl = null;

	/**
	 * Return codes
	 */
	public static enum ReturnCode {
		// TODO rework this...
		NO_ERROR(0,
				"Authentication against the identity provider and request of the service provider resource worked."),
		IDENTITY_PROVIDER_ERROR(1, "Authentication against the identity provider failed."),
		UNREGISTERED_ERROR(2, "User not registered to use " + Branding.getServiceName() + "."),
		SERVICE_PROVIDER_ERROR(3, "Invalid resource of the service provider."),
		INVALID_URL_ERROR(4, "Invalid URL received from master server."),
		GENERIC_ERROR(5, "Internal error.");

		private final int id;
		private final String msg;

		ReturnCode(int id, String msg) {
			this.id = id;
			this.msg = msg;
		}

		public int getId() {
			return this.id;
		}

		public String getMsg() {
			return this.msg;
		}
	}

	/**
	 * Static URI to the SP.
	 */
	public final static URI BWLP_SP;
	static {
		URI tmp;
		try {
			tmp = new URI("https://" + Branding.getMasterServerAddress() + "/webif/shib/api.php");
		} catch (URISyntaxException e) {
			// should never happen!
			LOGGER.error("Bad URI syntax of the service provider, see trace: ", e);
			tmp = null;
		}
		BWLP_SP = tmp;
	}

	public static ServiceProviderResponse getResponse() {
		return lastResponse;
	}

	/**
	 * Fetches the resource
	 * 
	 * @param idpUrl
	 *            URL of the identity provider to authenticate against, as
	 *            String.
	 * @param user
	 *            Username as String.
	 * @param pass
	 *            Password as String.
	 * @return
	 *         true if login worked, false otherwise.
	 * @throws TAuthorizationException
	 */
	public static ReturnCode doLogin(final String idpUrl, final String user, final String pass)
			throws TAuthorizationException, URISyntaxException, ClientProtocolException, IOException,
			ParseException, JsonSyntaxException, MalformedURLException {

		// first lets do some sanity checks
		if (BWLP_SP == null) {
			LOGGER.error("URI to service provider is not set. Check the initialization of 'BWLP_SP'.");
			return ReturnCode.GENERIC_ERROR;
		}
		if (idpUrl == null) {
			LOGGER.error("Identity provider is not set, did you initialize this class correctly?");
			return ReturnCode.GENERIC_ERROR;
		}
		if (user == null) {
			LOGGER.error("No username given, aborting...");
			return ReturnCode.GENERIC_ERROR;
		}
		if (pass == null) {
			LOGGER.error("No password given, aborting...");
			return ReturnCode.GENERIC_ERROR;
		}

		// now init the authenticator for that idp and our static sp
		final ECPAuthenticator auth = new ECPAuthenticator(ProxyConfigurator.getClient(), user, pass, new URI(idpUrl), BWLP_SP);

		HttpResponse spResponse;
		try {
			spResponse = auth.authenticate();
		} catch (ECPAuthenticationException e) {
			LOGGER.error("ECP Authentication Exception, see trace: ", e);
			throw new TAuthorizationException(AuthorizationError.GENERIC_ERROR, e.getMessage());
		}

		if (spResponse.getStatusLine().getStatusCode() != 200) {
			LOGGER.error("SP does not return HTTP status code 200");
			throw new TAuthorizationException(AuthorizationError.GENERIC_ERROR, "SP says: "
					+ spResponse.getStatusLine().toString());
		}
		
		LOGGER.debug("Login complete, getting body");

		final String responseBody = EntityUtils.toString(spResponse.getEntity());
		
		try {
			lastResponse = GSON.fromJson(responseBody, ServiceProviderResponse.class);
		} catch (JsonSyntaxException e) {
			LOGGER.warn("Json data from Service Provider malformed", e);
			LOGGER.warn("Response was:\n" + responseBody);
			throw e;
		}
		
		// TODO: here we will need to parse the answer accordingly.
		// no errors, meaning everything worked fine.
		if (lastResponse.status.equals("unregistered")) {
			registrationUrl = new URL(lastResponse.url);
			return ReturnCode.UNREGISTERED_ERROR;
		}
		// TODO the rest of the cases...
		if (lastResponse.status.equals("error")) {
			LOGGER.error("Server side error: " + lastResponse.error);
			return ReturnCode.GENERIC_ERROR;
		}
		if (lastResponse.status.equals("anonymous")) {
			LOGGER.error("IdP did not forward user account information to SP. Contact developer.");
			lastResponse.error = "Ihr Identity-Provider hat dem " + Branding.getServiceName() + "-System Ihre E-Mail oder Ihren Namen nicht mitgeteilt";
			return ReturnCode.GENERIC_ERROR;
		}
		if (lastResponse.status.equals("ok")) {
			return ReturnCode.NO_ERROR;
		}
		// still here? then something else went wrong
		return ReturnCode.GENERIC_ERROR;
	}

	/**
	 * @return Registration URL given by the SP.
	 */
	public static URL getRegistrationUrl() {
		return registrationUrl;
	}
}