summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/util/ShibbolethECP.java
blob: a3e13a38f3e910fc2eb02e8f41c202833bb19421 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package util;

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.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

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();
	
	/**
	 * 
	 */
	private static ServiceProviderResponse _lastResponse = null;
	/**
	 * URL for bwLehrpool registration  
	 */
	private static URL _registrationUrl = null;
	/**
	 * Return codes
	 */
	public static enum ReturnCode {
		NO_ERROR(0, "Authentication against the identity provider and request of the service provider resource worked."),
	  ERROR_IDP(1, "Authentication against the identity provider failed."),
	  ERROR_UNREG(2, "User not registered to use bwLehrpool"),
	  ERROR_SP(3, "Invalid resource of the service provider."),
	  ERROR_URL(4, "Invalid URL received from master server."),
		ERROR_OTHER(5, "Internal class 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.
	 */
	private final static URI BWLP_SP;
	static {
		URI tmp;
		try {
			tmp = new URI("https://bwlp-masterserver.ruf.uni-freiburg.de/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.
	 */
	public static ReturnCode doLogin(final String idpUrl, final String user, final String pass) {

		// 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.ERROR_OTHER;
		}
		if (idpUrl == null) {
			LOGGER.error("Identity provider is not set, did you initialize this class correctly?");
			return ReturnCode.ERROR_OTHER;
		}
		if (user == null) {
			LOGGER.error("No username given, aborting...");
			return ReturnCode.ERROR_OTHER;
		}
		if (pass == null) {
			LOGGER.error("No password given, aborting...");
			return ReturnCode.ERROR_OTHER;
		}

		// now init the authenticator for that idp and our static sp
    ECPAuthenticator auth = null;
		try {
			auth = new ECPAuthenticator(user, pass, new URI(idpUrl), BWLP_SP);
		} catch (URISyntaxException e) {
			LOGGER.error("Bad URI syntax, see trace: ", e);
			return ReturnCode.ERROR_OTHER;
		}
    try {
			auth.authenticate();
    } catch (ECPAuthenticationException e) {
			LOGGER.error("ECP Authentication Exception, see trace: ", e);
			return ReturnCode.ERROR_IDP;
    }
    // here test again for the SPURL
    HttpGet testSp = new HttpGet(BWLP_SP);
    HttpResponse response = null;
    try {
			response = auth.getHttpClient().execute(testSp);
		} catch (ClientProtocolException e) {
			LOGGER.error("Bad protocol, see trace: ", e);
			return ReturnCode.ERROR_OTHER;
		} catch (IOException e) {
			LOGGER.error("I/O error, see trace: ", e);
			return ReturnCode.ERROR_OTHER;
		}
    LOGGER.debug("SP request returned: " + response.getStatusLine());
    String responseBody = null;
    try {
			responseBody = EntityUtils.toString(response.getEntity());
		} catch (ParseException e) {
			LOGGER.error("Parsing error, see trace: ", e);
			return ReturnCode.ERROR_OTHER;
		} catch (IOException e) {
			LOGGER.error("I/O error, see trace: ", e);
			return ReturnCode.ERROR_OTHER;
		}
    _lastResponse = null;
    try {
    	_lastResponse = GSON.fromJson(responseBody, ServiceProviderResponse.class);
    } catch (JsonSyntaxException e) {
    	LOGGER.error("Bad JSON syntax, see trace: ", e);
    	return ReturnCode.ERROR_SP;
    }
    // TODO: here we will need to parse the answer accordingly.
    // no errors, meaning everything worked fine.
    if (_lastResponse.status.equals("unregistered")) {
    	try {
				_registrationUrl = new URL(_lastResponse.url);
			} catch (MalformedURLException e) {
				LOGGER.error("URL returned by masterserver is malformed, see trace: " + e);
				return ReturnCode.ERROR_URL;
			}
    	return ReturnCode.ERROR_UNREG;
    }
    // TODO the rest of the cases...
    if (_lastResponse.status.equals("error")) {
    	LOGGER.error("Server side error: " + _lastResponse.error);
    	return ReturnCode.ERROR_OTHER;
    }
    if (_lastResponse.status.equals("anonymous")) {
    	LOGGER.error("IdP did not forward user account information to SP. Contact developper.");
    	return ReturnCode.ERROR_OTHER;
    }
    if (_lastResponse.status.equals("ok")) {
    	return ReturnCode.NO_ERROR;
    }
    // still here? then something else went wrong
    return ReturnCode.ERROR_OTHER;
	}
	public static URL getRegistrationUrl() {
		return _registrationUrl;
	}
}