package org.dcache.auth;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.net.InetAddresses;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An object of type Origin contains information about the origin of a
* request.
*
* Principals such as this Origin may be associated with a particular
* Subject to augment that Subject with an additional identity. Refer
* to the Subject class for more information on how to achieve
* this. Authorization decisions can then be based upon the Principals
* associated with a Subject.
*
* @author David Melkumyan, DESY Zeuthen
*/
public class Origin implements Principal, Serializable
{
private static final long serialVersionUID = -6791417439972410727L;
/**
* Request origin Internet address.
*/
private final InetAddress _address;
/**
* The client chain: contains _address as the first item. If null,
* equivalent to a single item.
*/
private final ImmutableList<InetAddress> _clientChain;
/**
* @param address
* Request origin Internet address.
*/
public Origin(InetAddress address) {
_address = checkNotNull(address);
_clientChain = ImmutableList.of(address);
}
/**
* @param host
* Request origin host name. The host name can either be a machine name, such as
* "java.sun.com", or a textual representation of its IP address. If the
* <code>host</code> is null then an InetAddress representing an address of the
* loopback interface is returned.
*
* @throws UnknownHostException
*/
public Origin(String host) throws UnknownHostException {
_address = InetAddress.getByName(checkNotNull(host));
_clientChain = ImmutableList.of(_address);
}
/**
* The list of client addresses. The first address is that of the client
* making direct connection with dCache. The n+1 address is that of the
* client making direct connection to the service with the n address.
*/
public Origin(ImmutableList<InetAddress> addresses) {
checkArgument(!addresses.isEmpty(), "Empty client chain");
_address = addresses.get(0);
_clientChain = addresses;
}
public InetAddress getAddress() {
return _address;
}
public ImmutableList<InetAddress> getClientChain() {
return _clientChain == null ? ImmutableList.of(_address) : _clientChain;
}
@Override
public String toString() {
return getClass().getSimpleName() + '[' + getName() + ']';
}
@Override
public boolean equals(Object o)
{
if(o == this ) {
return true;
}
if (!(o instanceof Origin)) {
return false;
}
Origin other = (Origin) o;
return getClientChain().equals(other.getClientChain());
}
@Override
public String getName()
{
if (_clientChain == null || _clientChain.size() == 1) {
return InetAddresses.toAddrString(_address);
}
StringBuilder sb = new StringBuilder();
UnmodifiableIterator<InetAddress> i = _clientChain.iterator();
for (;;) {
sb.append(InetAddresses.toAddrString(i.next()));
if (!i.hasNext()) {
return sb.toString();
}
sb.append(',');
}
}
@Override
public int hashCode()
{
return _address.hashCode();
}
}