AAVSOPostUserPassXMLAuthenticationSource.java
/**
* VStar: a statistical analysis tool for variable star data.
* Copyright (C) 2014 AAVSO (http://www.aavso.org/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.aavso.tools.vstar.auth;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.aavso.tools.vstar.exception.AuthenticationError;
import org.aavso.tools.vstar.exception.ConnectionException;
import org.aavso.tools.vstar.input.database.IAuthenticationSource;
import org.aavso.tools.vstar.ui.resources.LoginType;
import org.aavso.tools.vstar.ui.resources.ResourceAccessor;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* This class authenticates an AAVSO user via an http POST method that makes use
* of a VSX web service to obtain user information.
*
* see Auth0JSONAutheticationSource
*/
@Deprecated
public class AAVSOPostUserPassXMLAuthenticationSource implements IAuthenticationSource {
private static final String AUTH_URL = "https://www.aavso.org/apps/api-auth/";
private String endPoint;
private boolean authenticated;
private String userID;
public AAVSOPostUserPassXMLAuthenticationSource(String endPoint) {
this.endPoint = endPoint;
authenticated = false;
}
public AAVSOPostUserPassXMLAuthenticationSource() {
this(AUTH_URL);
}
/**
* Return the authentiated user ID.
*
* @return the user ID
*/
public String getUserID() {
return userID;
}
@Override
public boolean authenticate(String username, String password) throws AuthenticationError, ConnectionException {
try {
// Create a POST request for the authentication end point.
URL url = new URL(endPoint);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setDoInput(true); // TODO: why twice!?
// conn.setRequestProperty("Authorization", "Basic " + encode);
conn.setRequestMethod("POST");
// Note: despite this XML content type, JSON is returned without the
// Accept property below. See:
// http://en.wikipedia.org/wiki/POST_(HTTP)#Use_for_submitting_web_forms
String type = "application/x-www-form-urlencoded";
conn.setRequestProperty("Content-Type", type);
// This is required to get an XML response! Indeed, "Content-Type"
// can be omitted with no ill-effect.
conn.setRequestProperty("Accept", "application/xml");
// Create the POST message data.
String usernameEncoded = URLEncoder.encode(username, "UTF-8");
String passwordEncoded = URLEncoder.encode(password, "UTF-8");
String data = String.format("%s=%s&%s=%s", "username", usernameEncoded, "password", passwordEncoded);
conn.setRequestProperty("Content-Length", String.valueOf(data.length()));
// Send the POST request.
OutputStream os = conn.getOutputStream();
os.write(data.getBytes());
os.flush();
os.close();
if (conn.getResponseCode() == 200) {
authenticated = true;
ResourceAccessor.getLoginInfo().setUserName(username);
ResourceAccessor.getLoginInfo().setType(getLoginType());
} else {
String message = "Authentication failed";
throw new AuthenticationError(message);
}
processResponse(conn);
VSXWebServiceMemberInfo memberInfo = new VSXWebServiceMemberInfo();
memberInfo.retrieveUserInfo(userID, ResourceAccessor.getLoginInfo());
} catch (MalformedURLException e) {
throw new ConnectionException(e.getLocalizedMessage());
} catch (IOException e) {
throw new ConnectionException(e.getLocalizedMessage());
} catch (ParserConfigurationException e) {
throw new ConnectionException(e.getLocalizedMessage());
} catch (SAXException e) {
throw new ConnectionException(e.getLocalizedMessage());
}
return authenticated;
}
@Override
public LoginType getLoginType() {
return LoginType.AAVSO;
}
// Process the POST response, extracting ID, authentication token.
private void processResponse(HttpsURLConnection conn)
throws IOException, ParserConfigurationException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(conn.getInputStream());
document.getDocumentElement().normalize();
NodeList idNodes = document.getElementsByTagName("id");
if (idNodes.getLength() == 1) {
userID = idNodes.item(0).getTextContent();
}
NodeList tokenNodes = document.getElementsByTagName("token");
if (tokenNodes.getLength() == 1) {
String token = tokenNodes.item(0).getTextContent();
ResourceAccessor.getLoginInfo().setToken(token);
}
}
}