package org.dcache.acl;
import java.io.Serializable;
import org.dcache.acl.enums.AccessMask;
import org.dcache.acl.enums.AceFlags;
import org.dcache.acl.enums.AceType;
import org.dcache.acl.enums.RsType;
import org.dcache.acl.enums.Who;
/**
* An access control list (ACL) is an array of access control entries (ACE).
*
* @author David Melkumyan, DESY Zeuthen
*
*/
public class ACE implements Serializable
{
private static final long serialVersionUID = -7088617639500399472L;
private static final String SPACE_SEPARATOR = " ";
private static final String SEPARATOR = ":";
/**
* Type of ACE (ALLOW / DENY)
*/
private final AceType _type;
/**
* The ACE flags (combination of values from AceFlags enumeration)
*/
private final int _flags;
/**
* The access mask (combination of values from AccessMask enumeration)
*/
private final int _accessMsk;
/**
* The subject (combination of values from Who enumeration)
*/
private final Who _who;
/**
* Virtual user or group ID (equals to -1 if who is special subject)
*/
private final int _whoID;
/**
* @param type
* Type of ACE (ALLOW / DENY)
* @param flags
* ACE flags
* @param accessMsk
* Access mask
* @param who
* Subject
* @param whoID
* Virtual user or group ID
*/
public ACE(AceType type, int flags, int accessMsk, Who who, int whoID) {
_type = type;
_flags = flags;
_accessMsk = accessMsk;
_who = who;
_whoID = whoID;
}
public int getAccessMsk() {
return _accessMsk;
}
public int getFlags() {
return _flags;
}
public AceType getType() {
return _type;
}
public Who getWho() {
return _who;
}
public int getWhoID() {
return _whoID;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ACE other = (ACE) obj;
if (_type != other._type) {
return false;
}
if (_flags != other._flags) {
return false;
}
if (_accessMsk != other._accessMsk) {
return false;
}
if (_who != other._who) {
return false;
}
if (_whoID != other._whoID) {
return false;
}
return true;
}
@Override
public int hashCode() {
return _type.hashCode() ^ _flags ^ _accessMsk ^ _who.hashCode() ^ _whoID ;
}
public String toNFSv4String(RsType rsType) {
StringBuilder sb = new StringBuilder();
sb.append(_who.getAbbreviation());
if (_who == Who.USER || _who == Who.GROUP) {
sb.append(SEPARATOR).append(_whoID);
}
sb.append(SEPARATOR).append(AccessMask.asString(_accessMsk, rsType));
if (_flags != 0) {
sb.append(SEPARATOR).append(AceFlags.asString(_flags));
}
sb.append(SEPARATOR).append(_type.getAbbreviation());
return sb.toString();
}
public String toOrgString() {
StringBuilder sb = new StringBuilder();
sb.append(_type.getValue()).append(SPACE_SEPARATOR);
sb.append(_flags).append(SPACE_SEPARATOR);
sb.append(_accessMsk).append(SPACE_SEPARATOR);
sb.append(_who.getValue()).append(SPACE_SEPARATOR);
sb.append(_whoID).append(SPACE_SEPARATOR);
return sb.toString();
}
@Override
public String toString() {
return toString(null);
}
public String toString(RsType rsType) {
StringBuilder sb = new StringBuilder();
sb.append("type = ")
.append(_type)
.append(", flags = ")
.append(AceFlags.asString(_flags))
.append(", accessMsk = ")
.append(AccessMask.asString(_accessMsk, rsType))
.append(", who = ")
.append(_who)
.append(", whoID = ").append(_whoID);
return sb.toString();
}
/**
* Represents ACE in the extra format.
* <p>
* Example: USER:12457:+lfsD
*
* @param rsType -
* resource type
* @return ACE in extra format
* @throws ACLException
* if ACE cannot be represented in extra format
*/
public String toExtraFormat(RsType rsType) throws ACLException {
StringBuilder sb = new StringBuilder();
sb.append(_who.getAbbreviation());
if (_who == Who.USER || _who == Who.GROUP) {
sb.append(SEPARATOR).append(_whoID);
}
sb.append(SEPARATOR);
switch (_type) {
case ACCESS_ALLOWED_ACE_TYPE:
sb.append("+");
break;
case ACCESS_DENIED_ACE_TYPE:
sb.append("-");
break;
default:
throw new ACLException("Unsupported access type: " + _type);
}
sb.append(AccessMask.asString(_accessMsk, rsType));
if (_flags != 0) {
sb.append(SEPARATOR).append(AceFlags.asString(_flags));
}
return sb.toString();
}
}