blob: 7bbfbeaa8c41c12fae05d69c8f2bb865f029ba79 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.manifoldcf.authorities.authorities.confluence.v6;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.manifoldcf.agents.interfaces.ServiceInterruption;
import org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector;
import org.apache.manifoldcf.authorities.interfaces.AuthorizationResponse;
import org.apache.manifoldcf.core.interfaces.CacheManagerFactory;
import org.apache.manifoldcf.core.interfaces.ConfigParams;
import org.apache.manifoldcf.core.interfaces.ICacheCreateHandle;
import org.apache.manifoldcf.core.interfaces.ICacheDescription;
import org.apache.manifoldcf.core.interfaces.ICacheHandle;
import org.apache.manifoldcf.core.interfaces.ICacheManager;
import org.apache.manifoldcf.core.interfaces.IHTTPOutput;
import org.apache.manifoldcf.core.interfaces.IPasswordMapperActivity;
import org.apache.manifoldcf.core.interfaces.IPostParameters;
import org.apache.manifoldcf.core.interfaces.IThreadContext;
import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
import org.apache.manifoldcf.core.interfaces.StringSet;
import org.apache.manifoldcf.crawler.connectors.confluence.v6.ConfluenceConfiguration;
import org.apache.manifoldcf.crawler.connectors.confluence.v6.client.ConfluenceClient;
import org.apache.manifoldcf.crawler.connectors.confluence.v6.model.ConfluenceUser;
import org.apache.manifoldcf.authorities.system.Logging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
* Confluence Authority Connector class
* </p>
* <p>
* ManifoldCF Authority connector to deal with Confluence documents
* </p>
*
* @author Antonio David Perez Morales &lt;adperezmorales@gmail.com&gt;
*
*/
public class ConfluenceAuthorityConnector extends BaseAuthorityConnector {
/*
* Prefix for Confluence configuration and specification parameters
*/
private static final String PARAMETER_PREFIX = "confluence_";
/* Configuration tabs */
private static final String CONF_SERVER_TAB_PROPERTY = "ConfluenceAuthorityConnector.Server";
private static final String CONF_CACHE_TAB_PROPERTY = "ConfluenceAuthorityConnector.Cache";
// pages & js
// Template names for Confluence configuration
/**
* Forward to the javascript to check the configuration parameters
*/
private static final String EDIT_CONFIG_HEADER_FORWARD = "editConfiguration_conf.js";
/**
* Cache tab template
*/
private static final String EDIT_CONFIG_FORWARD_CACHE = "editConfiguration_conf_cache.html";
/**
* Server tab template
*/
private static final String EDIT_CONFIG_FORWARD_SERVER = "editConfiguration_conf_server.html";
/**
* Forward to the HTML template to view the configuration parameters
*/
private static final String VIEW_CONFIG_FORWARD = "viewConfiguration_conf.html";
private Logger logger = LoggerFactory
.getLogger(ConfluenceAuthorityConnector.class);
/* Confluence instance parameters */
protected String protocol = null;
protected String host = null;
protected String port = null;
protected String path = null;
protected String username = null;
protected String password = null;
protected String socketTimeout = null;
protected String connectionTimeout = null;
private String cacheLifetime = null;
private String cacheLRUsize = null;
private final long responseLifetime = 60000L;
private final int LRUsize = 1000;
/** Cache manager. */
private ICacheManager cacheManager = null;
protected ConfluenceClient confluenceClient = null;
/**
* <p>
* Default constructor
* </p>
*/
public ConfluenceAuthorityConnector() {
super();
}
/**
* Used Mainly for testing
*
* @param cm
*/
public void setCacheManager(ICacheManager cm){
this.cacheManager = cm;
}
/**
* Used Mainly for testing
*
* @param client Injected Confluence Client
*/
public void setConfluenceClient(ConfluenceClient client){
this.confluenceClient = client;
}
/**
* Set thread context.
*/
@Override
public void setThreadContext(final IThreadContext tc) throws ManifoldCFException {
super.setThreadContext(tc);
cacheManager = CacheManagerFactory.make(tc);
}
/**
* Clear thread context.
*/
@Override
public void clearThreadContext() {
super.clearThreadContext();
cacheManager = null;
}
/**
* Close the connection. Call this before discarding the connection.
*/
@Override
public void disconnect() throws ManifoldCFException {
if (confluenceClient != null) {
confluenceClient = null;
}
protocol = null;
host = null;
port = null;
path = null;
username = null;
password = null;
socketTimeout = null;
connectionTimeout = null;
cacheLifetime = null;
cacheLRUsize = null;
}
/**
* Makes connection to server
*
*
*/
@Override
public void connect(ConfigParams configParams) {
super.connect(configParams);
protocol = params.getParameter(ConfluenceConfiguration.Server.PROTOCOL);
host = params.getParameter(ConfluenceConfiguration.Server.HOST);
port = params.getParameter(ConfluenceConfiguration.Server.PORT);
path = params.getParameter(ConfluenceConfiguration.Server.PATH);
username = params.getParameter(ConfluenceConfiguration.Server.USERNAME);
password = params
.getObfuscatedParameter(ConfluenceConfiguration.Server.PASSWORD);
socketTimeout = params.getParameter(ConfluenceConfiguration.Server.SOCKET_TIMEOUT);
connectionTimeout = params.getParameter(ConfluenceConfiguration.Server.CONNECTION_TIMEOUT);
cacheLifetime = params.getParameter(ConfluenceConfiguration.Authority.CACHE_LIFETIME);
if (cacheLifetime == null) {
cacheLifetime = "1";
}
cacheLRUsize = params.getParameter(ConfluenceConfiguration.Authority.CACHE_LRU_SIZE);
if (cacheLRUsize == null) {
cacheLRUsize = "1000";
}
try {
initConfluenceClient();
} catch (ManifoldCFException e) {
logger.debug(
"Not possible to initialize Confluence client. Reason: {}",
e.getMessage());
}
}
/**
* Checks if connection is available
*/
@Override
public String check() throws ManifoldCFException {
try {
if (!isConnected()) {
initConfluenceClient();
}
Boolean result = confluenceClient.checkAuth();
if (result)
return super.check();
else
throw new ManifoldCFException(
"Confluence instance could not be reached");
} catch (ServiceInterruption e) {
return "Connection temporarily failed: " + e.getMessage();
} catch (ManifoldCFException e) {
return "Connection failed: " + e.getMessage();
} catch (Exception e) {
return "Connection failed: " + e.getMessage();
}
}
/**
* <p>
* Initialize Confluence client using the configured parameters
*
* @throws ManifoldCFException
*/
protected void initConfluenceClient() throws ManifoldCFException {
if (confluenceClient == null) {
if (StringUtils.isEmpty(protocol)) {
throw new ManifoldCFException("Parameter "
+ ConfluenceConfiguration.Server.PROTOCOL
+ " required but not set");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence protocol = '" + protocol
+ "'");
}
if (StringUtils.isEmpty(host)) {
throw new ManifoldCFException("Parameter "
+ ConfluenceConfiguration.Server.HOST
+ " required but not set");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence host = '" + host + "'");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence port = '" + port + "'");
}
if (StringUtils.isEmpty(path)) {
throw new ManifoldCFException("Parameter "
+ ConfluenceConfiguration.Server.PATH
+ " required but not set");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence path = '" + path + "'");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence username = '" + username
+ "'");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors
.debug("Confluence password '" + password != null ? "set"
: "not set" + "'");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence socket timeout = '" + socketTimeout
+ "'");
}
if (Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Confluence connection timeout = '" + connectionTimeout
+ "'");
}
int portInt;
if (port != null && port.length() > 0) {
try {
portInt = Integer.parseInt(port);
} catch (NumberFormatException e) {
throw new ManifoldCFException("Bad number: "
+ e.getMessage(), e);
}
} else {
if (protocol.toLowerCase(Locale.ROOT).equals("http"))
portInt = 80;
else
portInt = 443;
}
int socketTimeoutInt;
if (socketTimeout != null && socketTimeout.length() > 0) {
try {
socketTimeoutInt = Integer.parseInt(socketTimeout);
} catch (NumberFormatException e) {
throw new ManifoldCFException("Bad number: "
+ e.getMessage(), e);
}
} else {
socketTimeoutInt = 900000;
}
int connectionTimeoutInt;
if (connectionTimeout != null && connectionTimeout.length() > 0) {
try {
connectionTimeoutInt = Integer.parseInt(connectionTimeout);
} catch (NumberFormatException e) {
throw new ManifoldCFException("Bad number: "
+ e.getMessage(), e);
}
} else {
connectionTimeoutInt = 60000;
}
/* Generating a client to perform Confluence requests */
confluenceClient = new ConfluenceClient(protocol, host, portInt,
path, username, password, socketTimeoutInt, connectionTimeoutInt);
}
}
/**
* This method is called to assess whether to count this connector instance
* should actually be counted as being connected.
*
* @return true if the connector instance is actually connected.
*/
@Override
public boolean isConnected() {
return confluenceClient != null;
}
private void fillInCacheTab(final Map<String, String> velocityContext, final IPasswordMapperActivity mapper, final ConfigParams parameters) {
String cacheLifetime = parameters.getParameter(ConfluenceConfiguration.Authority.CACHE_LIFETIME);
if (cacheLifetime == null) {
cacheLifetime = "1";
}
velocityContext.put("CACHE_LIFETIME", cacheLifetime);
String cacheLRUsize = parameters.getParameter(ConfluenceConfiguration.Authority.CACHE_LRU_SIZE);
if (cacheLRUsize == null) {
cacheLRUsize = "1000";
}
velocityContext.put("CACHE_LRU_SIZE", cacheLRUsize);
}
private void fillInServerConfigurationMap(Map<String, String> serverMap,
IPasswordMapperActivity mapper, ConfigParams parameters) {
String confluenceProtocol = parameters
.getParameter(ConfluenceConfiguration.Server.PROTOCOL);
String confluenceHost = parameters
.getParameter(ConfluenceConfiguration.Server.HOST);
String confluencePort = parameters
.getParameter(ConfluenceConfiguration.Server.PORT);
String confluencePath = parameters
.getParameter(ConfluenceConfiguration.Server.PATH);
String confluenceUsername = parameters
.getParameter(ConfluenceConfiguration.Server.USERNAME);
String confluencePassword = parameters
.getObfuscatedParameter(ConfluenceConfiguration.Server.PASSWORD);
String confluenceSocketTimeout = parameters
.getParameter(ConfluenceConfiguration.Server.SOCKET_TIMEOUT);
String confluenceConnectionTimeout = parameters
.getParameter(ConfluenceConfiguration.Server.CONNECTION_TIMEOUT);
if (confluenceProtocol == null)
confluenceProtocol = ConfluenceConfiguration.Server.PROTOCOL_DEFAULT_VALUE;
if (confluenceHost == null)
confluenceHost = ConfluenceConfiguration.Server.HOST_DEFAULT_VALUE;
if (confluencePort == null)
confluencePort = ConfluenceConfiguration.Server.PORT_DEFAULT_VALUE;
if (confluencePath == null)
confluencePath = ConfluenceConfiguration.Server.PATH_DEFAULT_VALUE;
if (confluenceUsername == null)
confluenceUsername = ConfluenceConfiguration.Server.USERNAME_DEFAULT_VALUE;
if (confluencePassword == null)
confluencePassword = ConfluenceConfiguration.Server.PASSWORD_DEFAULT_VALUE;
else
confluencePassword = mapper.mapPasswordToKey(confluencePassword);
if(confluenceSocketTimeout == null) {
confluenceSocketTimeout = ConfluenceConfiguration.Server.SOCKET_TIMEOUT_DEFAULT_VALUE;
}
if(confluenceConnectionTimeout == null) {
confluenceConnectionTimeout = ConfluenceConfiguration.Server.CONNECTION_TIMEOUT_DEFAULT_VALUE;
}
serverMap.put(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PROTOCOL, confluenceProtocol);
serverMap.put(PARAMETER_PREFIX + ConfluenceConfiguration.Server.HOST,
confluenceHost);
serverMap.put(PARAMETER_PREFIX + ConfluenceConfiguration.Server.PORT,
confluencePort);
serverMap.put(PARAMETER_PREFIX + ConfluenceConfiguration.Server.PATH,
confluencePath);
serverMap.put(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.USERNAME, confluenceUsername);
serverMap.put(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PASSWORD, confluencePassword);
serverMap.put(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.SOCKET_TIMEOUT, confluenceSocketTimeout);
serverMap.put(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.CONNECTION_TIMEOUT, confluenceConnectionTimeout);
}
@Override
public void viewConfiguration(IThreadContext threadContext,
IHTTPOutput out, Locale locale, ConfigParams parameters)
throws ManifoldCFException, IOException {
Map<String, String> paramMap = new HashMap<String, String>();
/* Fill server configuration parameters */
fillInServerConfigurationMap(paramMap, out, parameters);
fillInCacheTab(paramMap, out, parameters);
Messages.outputResourceWithVelocity(out, locale, VIEW_CONFIG_FORWARD,
paramMap, true);
}
@Override
public void outputConfigurationHeader(IThreadContext threadContext,
IHTTPOutput out, Locale locale, ConfigParams parameters,
List<String> tabsArray) throws ManifoldCFException, IOException {
// Add the Server tab
tabsArray.add(Messages.getString(locale, CONF_SERVER_TAB_PROPERTY));
tabsArray.add(Messages.getString(locale, CONF_CACHE_TAB_PROPERTY));
// Map the parameters
Map<String, String> paramMap = new HashMap<String, String>();
/* Fill server configuration parameters */
fillInServerConfigurationMap(paramMap, out, parameters);
/* Fill cache configuration parameters */
fillInCacheTab(paramMap, out, parameters);
// Output the Javascript - only one Velocity template for all tabs
Messages.outputResourceWithVelocity(out, locale,
EDIT_CONFIG_HEADER_FORWARD, paramMap, true);
}
@Override
public void outputConfigurationBody(IThreadContext threadContext,
IHTTPOutput out, Locale locale, ConfigParams parameters,
String tabName) throws ManifoldCFException, IOException {
// Call the Velocity templates for each tab
Map<String, String> paramMap = new HashMap<String, String>();
// Set the tab name
paramMap.put("TabName", tabName);
// Fill in the parameters
fillInServerConfigurationMap(paramMap, out, parameters);
fillInCacheTab(paramMap, out, parameters);
// Server tab
Messages.outputResourceWithVelocity(out, locale,
EDIT_CONFIG_FORWARD_SERVER, paramMap, true);
// Cache tab
Messages.outputResourceWithVelocity(out, locale,
EDIT_CONFIG_FORWARD_CACHE, paramMap, true);
}
/*
* Repository specification post handle, (server and proxy & client secret
* etc)
*
* @see
* org.apache.manifoldcf.core.connector.BaseConnector#processConfigurationPost
* (org.apache.manifoldcf.core.interfaces.IThreadContext,
* org.apache.manifoldcf.core.interfaces.IPostParameters,
* org.apache.manifoldcf.core.interfaces.ConfigParams)
*/
@Override
public String processConfigurationPost(IThreadContext threadContext,
IPostParameters variableContext, ConfigParams parameters)
throws ManifoldCFException {
// Cache parameters
final String cacheLifetime = variableContext.getParameter(ConfluenceConfiguration.Authority.CACHE_LIFETIME);
if (cacheLifetime != null) {
parameters.setParameter(ConfluenceConfiguration.Authority.CACHE_LIFETIME, cacheLifetime);
}
final String cacheLRUsize = variableContext.getParameter(ConfluenceConfiguration.Authority.CACHE_LRU_SIZE);
if (cacheLRUsize != null) {
parameters.setParameter(ConfluenceConfiguration.Authority.CACHE_LRU_SIZE, cacheLRUsize);
}
String confluenceProtocol = variableContext
.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PROTOCOL);
if (confluenceProtocol != null)
parameters.setParameter(ConfluenceConfiguration.Server.PROTOCOL,
confluenceProtocol);
String confluenceHost = variableContext.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.HOST);
if (confluenceHost != null)
parameters.setParameter(ConfluenceConfiguration.Server.HOST,
confluenceHost);
String confluencePort = variableContext.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PORT);
if (confluencePort != null)
parameters.setParameter(ConfluenceConfiguration.Server.PORT,
confluencePort);
String confluencePath = variableContext.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PATH);
if (confluencePath != null)
parameters.setParameter(ConfluenceConfiguration.Server.PATH,
confluencePath);
String confluenceUsername = variableContext
.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.USERNAME);
if (confluenceUsername != null)
parameters.setParameter(ConfluenceConfiguration.Server.USERNAME,
confluenceUsername);
String confluencePassword = variableContext
.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.PASSWORD);
if (confluencePassword != null)
parameters.setObfuscatedParameter(
ConfluenceConfiguration.Server.PASSWORD,
variableContext.mapKeyToPassword(confluencePassword));
String confluenceSocketTimeout = variableContext
.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.SOCKET_TIMEOUT);
if (confluenceSocketTimeout != null)
parameters.setParameter(ConfluenceConfiguration.Server.SOCKET_TIMEOUT,
confluenceSocketTimeout);
String confluenceConnectionTimeout = variableContext
.getParameter(PARAMETER_PREFIX
+ ConfluenceConfiguration.Server.CONNECTION_TIMEOUT);
if (confluenceConnectionTimeout != null)
parameters.setParameter(ConfluenceConfiguration.Server.CONNECTION_TIMEOUT,
confluenceConnectionTimeout);
/* null means process configuration has been successful */
return null;
}
/*
* (non-Javadoc)
* @see org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector#getDefaultAuthorizationResponse(java.lang.String)
*/
@Override
public AuthorizationResponse getDefaultAuthorizationResponse(String userName) {
return RESPONSE_UNREACHABLE;
}
/*
* (non-Javadoc)
* @see org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector#getAuthorizationResponse(java.lang.String)
*/
@Override
public AuthorizationResponse getAuthorizationResponse(String userName)
throws ManifoldCFException {
String finalUsername = userName;
// If the username contains the domain, must clean it
if(finalUsername.indexOf("@") != -1) {
finalUsername = finalUsername.substring(0, finalUsername.indexOf("@"));
}
if (Logging.authorityConnectors != null && Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Get Confluence autorizations for user '" + finalUsername + "'");
}
if(cacheManager != null) {
// Construct a cache description object
final ICacheDescription objectDescription = new AuthorizationResponseDescription(finalUsername, this.responseLifetime, this.LRUsize);
// Enter the cache
final ICacheHandle ch = cacheManager.enterCache(new ICacheDescription[] { objectDescription }, null, null);
try {
final ICacheCreateHandle createHandle = cacheManager.enterCreateSection(ch);
try {
// Lookup the object
AuthorizationResponse response = (AuthorizationResponse) cacheManager.lookupObject(createHandle, objectDescription);
if (response != null) {
if (Logging.authorityConnectors != null && Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Found cached Confluence autorizations for user '" + finalUsername + "'");
}
return response;
}
// Create the object.
response = getAuthorizationResponseUncached(finalUsername);
// Save it in the cache
cacheManager.saveObject(createHandle, objectDescription, response);
// And return it...
return response;
} finally {
cacheManager.leaveCreateSection(createHandle);
}
} finally {
cacheManager.leaveCache(ch);
}
} else {
return getAuthorizationResponseUncached(finalUsername);
}
}
private AuthorizationResponse getAuthorizationResponseUncached(final String userName) throws ManifoldCFException {
if (Logging.authorityConnectors != null && Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Get uncached Confluence autorizations for user '" + userName + "'");
}
try {
ConfluenceUser confluenceUser = confluenceClient.getUserAuthorities(userName);
if (confluenceUser.getUsername() == null
|| confluenceUser.getUsername().isEmpty()
|| confluenceUser.getAuthorities().isEmpty()) {
if (Logging.authorityConnectors != null && Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("No Confluence user found for user '" + userName + "'");
}
return RESPONSE_USERNOTFOUND;
} else {
if (Logging.authorityConnectors != null && Logging.authorityConnectors.isDebugEnabled()) {
Logging.authorityConnectors.debug("Found Confluence corresponding user for user '" + userName + "'");
}
return new AuthorizationResponse(
confluenceUser.getAuthorities().toArray(new String[confluenceUser.getAuthorities().size()]),
AuthorizationResponse.RESPONSE_OK);
}
} catch (Exception e) {
return RESPONSE_UNREACHABLE;
}
}
protected static StringSet emptyStringSet = new StringSet();
/**
* This is the cache object descriptor for cached access tokens from this connector.
*/
protected static class AuthorizationResponseDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription {
/** The user name */
protected String userName;
/** The response lifetime */
protected long responseLifetime;
/** The expiration time */
protected long expirationTime = -1;
/** Constructor. */
public AuthorizationResponseDescription(final String userName, final long responseLifetime, final int LRUsize) {
super("SharePointADAuthority", LRUsize);
this.userName = userName;
this.responseLifetime = responseLifetime;
}
/** Return the invalidation keys for this object. */
@Override
public StringSet getObjectKeys() {
return emptyStringSet;
}
/** Get the critical section name, used for synchronizing the creation of the object */
@Override
public String getCriticalSectionName() {
final StringBuilder sb = new StringBuilder(getClass().getName());
sb.append("-").append(userName);
return sb.toString();
}
/** Return the object expiration interval */
@Override
public long getObjectExpirationTime(final long currentTime) {
if (expirationTime == -1) {
expirationTime = currentTime + responseLifetime;
}
return expirationTime;
}
@Override
public int hashCode() {
final int rval = userName.hashCode();
return rval;
}
@Override
public boolean equals(final Object o) {
if (!(o instanceof AuthorizationResponseDescription)) {
return false;
}
final AuthorizationResponseDescription ard = (AuthorizationResponseDescription) o;
if (!ard.userName.equals(userName)) {
return false;
}
return true;
}
}
}