diff --git a/authentication/.gitignore b/authentication/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/IAuthenticationService.java b/authentication/source/java/ch/systemsx/cisd/authentication/IAuthenticationService.java new file mode 100644 index 0000000000000000000000000000000000000000..2013b0d2dfb650f637c54635348a8d18b2245c47 --- /dev/null +++ b/authentication/source/java/ch/systemsx/cisd/authentication/IAuthenticationService.java @@ -0,0 +1,27 @@ +/* + * Copyright 2007 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.authentication; + +/** + * + * + * @author felmer + */ +public interface IAuthenticationService +{ + public boolean authenticate(String user, String password); +} diff --git a/authentication/source/java/ch/systemsx/cisd/authentication/crowd/CrowdAuthenticationService.java b/authentication/source/java/ch/systemsx/cisd/authentication/crowd/CrowdAuthenticationService.java new file mode 100644 index 0000000000000000000000000000000000000000..efd55ecb26aece7a48aa740a49ed5063a44863fc --- /dev/null +++ b/authentication/source/java/ch/systemsx/cisd/authentication/crowd/CrowdAuthenticationService.java @@ -0,0 +1,179 @@ +/* + * Copyright 2007 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.authentication.crowd; + +import java.text.MessageFormat; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; + +import ch.systemsx.cisd.authentication.IAuthenticationService; +import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel; + +/** + * + * + * @author felmer + */ +public class CrowdAuthenticationService implements IAuthenticationService +{ + private static final MessageFormat AUTHENTICATE_APPL = + new MessageFormat("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " + + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + " <soap:Body>\n" + + " <authenticateApplication xmlns=\"urn:SecurityServer\">\n" + " <in0>\n" + + " <credential xmlns=\"http://authentication.integration.crowd.atlassian.com\">\n" + + " <credential>{1}</credential>\n" + " </credential>\n" + + " <name xmlns=\"http://authentication.integration.crowd.atlassian.com\">{0}</name>\n" + + " <validationFactors xmlns=\"http://authentication.integration.crowd.atlassian.com\" " + + " xsi:nil=\"true\" />\n" + " </in0>\n" + + " </authenticateApplication>\n" + " </soap:Body>\n" + "</soap:Envelope>\n"); + + private static final MessageFormat AUTHENTICATE_USER = + new MessageFormat( + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " + + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + + " <soap:Body>\n" + + " <authenticatePrincipal xmlns=\"urn:SecurityServer\">\n" + + " <in0>\n" + + " <name xmlns=\"http://authentication.integration.crowd.atlassian.com\">{0}</name>\n" + + " <token xmlns=\"http://authentication.integration.crowd.atlassian.com\">{1}</token>\n" + + " </in0>\n" + + " <in1>\n" + + " <application xmlns=\"http://authentication.integration.crowd.atlassian.com\">{0}</application>\n" + + " <credential xmlns=\"http://authentication.integration.crowd.atlassian.com\">\n" + + " <credential>{3}</credential>\n" + + " </credential>\n" + + " <name xmlns=\"http://authentication.integration.crowd.atlassian.com\">{2}</name>\n" + + " <validationFactors xmlns=\"http://authentication.integration.crowd.atlassian.com\" />\n" + + " </in1>\n" + " </authenticatePrincipal>\n" + " </soap:Body>\n" + + "</soap:Envelope>\n"); + + private final String url; + private final String application; + private final String applicationToken; + + + public CrowdAuthenticationService(String host, int port, String application, String applicationPassword) + { + this("https://" + host + ":" + port + "/crowd/services/SecurityServer", application, applicationPassword); + } + + public CrowdAuthenticationService(String url, String application, String applicationPassword) + { + this.url = url; + this.application = application; + applicationToken = xmlEncode(execute("token", AUTHENTICATE_APPL, application, applicationPassword)); + } + + public boolean authenticate(String user, String password) + { + String userToken = xmlEncode(execute("out", AUTHENTICATE_USER, application, applicationToken, user, password)); + return userToken != null; + } + + private String execute(String responseElement, MessageFormat template, String... args) + { + Object[] decodedArguments = new Object[args.length]; + for (int i = 0; i < args.length; i++) + { + decodedArguments[i] = xmlDecode(args[i]); + } + String response = execute(template.format(decodedArguments)); + return pickElementContent(response, responseElement); + } + + private String pickElementContent(String xmlString, String element) + { + int index = xmlString.indexOf("<" + element); + if (index < 0) + { + return null; + } + index = xmlString.indexOf(">", index); + if (index < 0) + { + return null; + } + int endIndex = xmlString.indexOf("</" + element, index); + if (endIndex < 0) + { + return null; + } + return xmlString.substring(index + 1, endIndex); + } + + private String execute(String xmlMessage) + { + try + { + HttpClient client = new HttpClient(); + PostMethod post = new PostMethod(url); + StringRequestEntity entity = new StringRequestEntity(xmlMessage, "application/soap+xml", "utf-8"); + post.setRequestEntity(entity); + String response = null; + try + { + client.executeMethod(post); + response = post.getResponseBodyAsString(); + } finally + { + post.releaseConnection(); + } + return response; + } catch (Exception ex) + { + throw new CheckedExceptionTunnel(ex); + } + } + + private String xmlDecode(String text) + { + StringBuilder builder = new StringBuilder(); + for (int i = 0, n = text.length(); i < n; i++) + { + char c = text.charAt(i); + switch (c) + { + case '<': + builder.append("<"); + break; + case '>': + builder.append(">"); + break; + case '&': + builder.append("&"); + break; + case '"': + builder.append("""); + break; + default: + builder.append(c); + break; + } + } + return new String(builder); + } + + private String xmlEncode(String xml) + { + return xml; + } + +}