/**
* Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
*
* 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 org.glite.security.voms.admin.operations;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
/**
* This class represents a VOMS permission that can be assigned to a VOMS-Admin
* administrator. A {@link VOMSPermission} is fixed-length sequence of
* permission flags that describe the set of permissions a VOMS Administrator
* has in a specific context.
*
* The currently defined flags are:
*
* <ul>
* <li> <code>CONTAINER_READ, CONTAINER_WRITE</code>: These flags are used to
* control access to the operations that list/alter the VO internal structure
* (groups and roles list/creations/deletions, user creations/deletions).</li>
* <li> <code>MEMBERSHIP_READ, MEMBERSHIP_WRITE</code>: These flags are used to
* control access to operations that manage/list membership in group and roles.</li>
* <li> <code>ATTRIBUTES_READ,ATTRIBUTES_WRITE</code>: These flags are used to
* control access to operations that mange generic attributes (at the user,
* group, or role level).</li>
* <li> <code>ACL_READ,ACL_WRITE,ACL_DEFAULT</code>: These flags are used to
* control access to operations that manage VO ACLs and default ACLs.</li>
* <li> <code>REQUESTS_READ, REQUESTS_WRITE</code>: These flags are used to
* control access to operations that manage subscription requests regarding the
* VO, group membership, role assignment etc...</li>
* <li> <code>PERSONAL_INFO_READ, PERSONAL_INFO_WRITE</code>: The flags are used
* to control access to user personal information stored in the database.</li>
* <li> <code>SUSPEND</code>: This flag controls who can suspend other users.</li>
* </ul>
*
* @author <a href="mailto:andrea.ceccanti@cnaf.infn.it">Andrea Ceccanti</a>
*
*/
public class VOMSPermission implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
public static final int CONTAINER_READ = 1;
public static final int CONTAINER_WRITE = 2;
public static final int MEMBERSHIP_READ = 4;
public static final int MEMBERSHIP_WRITE = 8;
public static final int ACL_READ = 16;
public static final int ACL_WRITE = 32;
public static final int ACL_DEFAULT = 64;
public static final int REQUESTS_READ = 128;
public static final int REQUESTS_WRITE = 256;
public static final int ATTRIBUTES_READ = 512;
public static final int ATTRIBUTES_WRITE = 1024;
public static final int PERSONAL_INFO_READ = 2048;
public static final int PERSONAL_INFO_WRITE = 4096;
public static final int SUSPEND = 8192;
private static final int NUM_PERMISSIONS = 14;
private static final int ALL_PERMISSION_MASK = ~0 >>> (32 - NUM_PERMISSIONS);
public static String asString(int bits) {
VOMSPermission p = new VOMSPermission(bits);
return p.toString();
}
public static VOMSPermission fromBits(int bits) {
if (bits < 0){
throw new IllegalArgumentException(
"Permission must be non-negative integer.");
}
if (bits == 0){
return VOMSPermission.getEmptyPermissions();
}
VOMSPermission perm = new VOMSPermission();
for (int i = 0; i < NUM_PERMISSIONS; i++) {
int PERM_MASK = 1 << i;
if ((bits & PERM_MASK) == PERM_MASK)
perm.set(PERM_MASK);
}
return perm;
}
public static VOMSPermission fromString(String permString) {
VOMSPermission perm = new VOMSPermission();
String[] perms = StringUtils.split(permString, '|');
if (perms.length == 1 && perms[0].equals(""))
return perm;
return fromStringArray(perms);
}
public static VOMSPermission fromStringArray(String[] perms) {
VOMSPermission perm = new VOMSPermission();
for (int i = 0; i < perms.length; i++) {
// Skip empty permissions
if (perms[i].trim().equals(""))
continue;
if (perms[i].equals("CONTAINER_READ"))
perm.setContainerReadPermission();
else if (perms[i].equals("CONTAINER_WRITE"))
perm.setContainerWritePermission();
else if (perms[i].equals("MEMBERSHIP_READ"))
perm.setMembershipReadPermission();
else if (perms[i].equals("MEMBERSHIP_WRITE"))
perm.setMembershipWritePermission();
else if (perms[i].equals("ACL_READ"))
perm.setACLReadPermission();
else if (perms[i].equals("ACL_WRITE"))
perm.setACLWritePermission();
else if (perms[i].equals("ACL_DEFAULT"))
perm.setACLDefaultPermission();
else if (perms[i].equals("REQUESTS_READ"))
perm.setRequestsReadPermission();
else if (perms[i].equals("REQUESTS_WRITE"))
perm.setRequestsWritePermission();
else if (perms[i].equals("ATTRIBUTES_READ"))
perm.setAttributesReadPermission();
else if (perms[i].equals("ATTRIBUTES_WRITE"))
perm.setAttributesWritePermission();
else if (perms[i].equals("PERSONAL_INFO_READ"))
perm.setPersonalInfoReadPermission();
else if (perms[i].equals("PERSONAL_INFO_WRITE"))
perm.setPersonalInfoWritePermission();
else if (perms[i].equals("SUSPEND"))
perm.setSuspendPermission();
else if (perms[i].equals("ALL"))
perm.setAllPermissions();
else if (perms[i].equals("NONE"))
perm.setEmptyPermissions();
else
throw new IllegalArgumentException(
"Unknown permission passed as argument: " + perms[i]);
}
return perm;
}
public static VOMSPermission getAllPermissions() {
return new VOMSPermission().setAllPermissions();
}
public static VOMSPermission getAttributesRWPermissions() {
return new VOMSPermission().setAttributesReadPermission()
.setAttributesWritePermission();
}
public static VOMSPermission getContainerReadPermission() {
return new VOMSPermission().setContainerReadPermission();
}
public static VOMSPermission getContainerRWPermissions() {
return new VOMSPermission().setContainerReadPermission()
.setContainerWritePermission();
}
public static VOMSPermission getEmptyPermissions() {
return new VOMSPermission().setEmptyPermissions();
}
public static VOMSPermission getMembershipRWPermissions() {
return new VOMSPermission().setMembershipReadPermission()
.setMembershipWritePermission();
}
public static VOMSPermission getRequestsRWPermissions() {
return new VOMSPermission().setRequestsReadPermission()
.setRequestsWritePermission();
}
public static VOMSPermission getSuspendPermissions() {
return new VOMSPermission().setSuspendPermission();
}
private int bits = 0;
public VOMSPermission() {
}
public VOMSPermission(int bits) {
this.bits = bits;
}
private List buildPermList() {
ArrayList permList = new ArrayList();
if (test(CONTAINER_READ))
permList.add("CONTAINER_READ");
if (test(CONTAINER_WRITE))
permList.add("CONTAINER_WRITE");
if (test(MEMBERSHIP_READ))
permList.add("MEMBERSHIP_READ");
if (test(MEMBERSHIP_WRITE))
permList.add("MEMBERSHIP_WRITE");
if (test(ACL_READ))
permList.add("ACL_READ");
if (test(ACL_WRITE))
permList.add("ACL_WRITE");
if (test(ACL_DEFAULT))
permList.add("ACL_DEFAULT");
if (test(REQUESTS_READ))
permList.add("REQUESTS_READ");
if (test(REQUESTS_WRITE))
permList.add("REQUESTS_WRITE");
if (test(ATTRIBUTES_READ))
permList.add("ATTRIBUTES_READ");
if (test(ATTRIBUTES_WRITE))
permList.add("ATTRIBUTES_WRITE");
if (test(PERSONAL_INFO_READ))
permList.add("PERSONAL_INFO_READ");
if (test(PERSONAL_INFO_WRITE))
permList.add("PERSONAL_INFO_WRITE");
if (test(SUSPEND))
permList.add("SUSPEND");
return permList;
}
public Object clone() throws CloneNotSupportedException {
VOMSPermission clone = (VOMSPermission) super.clone();
clone.bits = this.bits;
return clone;
}
public boolean equals(Object other) {
if (this == other)
return true;
if (!(other instanceof VOMSPermission))
return false;
VOMSPermission that = (VOMSPermission) other;
return (this.bits == that.bits);
}
public int getBits() {
return bits;
}
public String getCompactRepresentation() {
StringBuffer buf = new StringBuffer();
if (bits == 0)
return "NONE";
if (test(ALL_PERMISSION_MASK))
return "ALL";
// Container perms
buf.append("C:");
buf.append(test(CONTAINER_READ) ? "r" : "-");
buf.append(test(CONTAINER_WRITE) ? "w" : "-");
buf.append(" M:");
buf.append(test(MEMBERSHIP_READ) ? "r" : "-");
buf.append(test(MEMBERSHIP_WRITE) ? "w" : "-");
buf.append(" Acl:");
buf.append(test(ACL_READ) ? "r" : "-");
buf.append(test(ACL_WRITE) ? "w" : "-");
if (test(ACL_DEFAULT))
buf.append("d");
buf.append(" Attrs:");
buf.append(test(ATTRIBUTES_READ) ? "r" : "-");
buf.append(test(ATTRIBUTES_WRITE) ? "w" : "-");
buf.append(" Req:");
buf.append(test(REQUESTS_READ) ? "r" : "-");
buf.append(test(REQUESTS_WRITE) ? "w" : "-");
buf.append(" Info:");
buf.append(test(PERSONAL_INFO_READ) ? "r" : "-");
buf.append(test(PERSONAL_INFO_WRITE) ? "w" : "-");
buf.append(" Susp:");
buf.append(test(SUSPEND) ? "y" : "-");
return buf.toString();
}
public boolean has(String permString) {
if (permString == null)
return false;
if (permString.equals("CONTAINER_READ"))
return test(CONTAINER_READ);
else if (permString.equals("CONTAINER_WRITE"))
return test(CONTAINER_WRITE);
else if (permString.equals("MEMBERSHIP_READ"))
return test(MEMBERSHIP_READ);
else if (permString.equals("MEMBERSHIP_WRITE"))
return test(MEMBERSHIP_WRITE);
else if (permString.equals("ACL_READ"))
return test(ACL_READ);
else if (permString.equals("ACL_WRITE"))
return test(ACL_WRITE);
else if (permString.equals("ACL_DEFAULT"))
return test(ACL_DEFAULT);
else if (permString.equals("REQUESTS_READ"))
return test(REQUESTS_READ);
else if (permString.equals("REQUESTS_WRITE"))
return test(REQUESTS_WRITE);
else if (permString.equals("ATTRIBUTES_READ"))
return test(ATTRIBUTES_READ);
else if (permString.equals("ATTRIBUTES_WRITE"))
return test(ATTRIBUTES_WRITE);
else if (permString.equals("PERSONAL_INFO_READ"))
return test(PERSONAL_INFO_READ);
else if (permString.equals("PERSONAL_INFO_WRITE"))
return test(PERSONAL_INFO_WRITE);
else if (permString.equals("SUSPEND"))
return test(SUSPEND);
else
throw new IllegalArgumentException(
"Unknown permission passed as argument: " + permString);
}
public boolean hasACLDefaultPermission() {
return test(ACL_DEFAULT);
}
public boolean hasACLReadPermission() {
return test(ACL_READ);
}
public boolean hasACLWritePermission() {
return test(ACL_WRITE);
}
public boolean hasAttributeReadPermission() {
return test(ATTRIBUTES_READ);
}
public boolean hasAttributeWritePermission() {
return test(ATTRIBUTES_WRITE);
}
public boolean hasContainerReadPermission() {
return test(CONTAINER_READ);
}
public boolean hasContainerWritePermission() {
return test(CONTAINER_WRITE);
}
public int hashCode() {
return new Integer(bits).hashCode();
}
public boolean hasMembershipReadPermission() {
return test(MEMBERSHIP_READ);
}
public boolean hasMembershipWritePermission() {
return test(MEMBERSHIP_WRITE);
}
public boolean hasPersonalInfoReadPermission() {
return test(PERSONAL_INFO_READ);
}
public boolean hasPersonalInfoWritePermission() {
return test(PERSONAL_INFO_WRITE);
}
public boolean hasRequestReadPermission() {
return test(REQUESTS_READ);
}
public boolean hasRequestWritePermission() {
return test(REQUESTS_WRITE);
}
public boolean hasSuspendPermission() {
return test(SUSPEND);
}
public boolean satisfies(VOMSPermission other) {
int perms = bits & other.getBits();
return (perms == other.getBits());
}
protected VOMSPermission set(int permission) {
if (permission <= 0)
throw new IllegalArgumentException(
"Permission must be a positive integer.");
bits |= permission;
return this;
}
public VOMSPermission setACLDefaultPermission() {
set(ACL_DEFAULT);
return this;
}
public VOMSPermission setACLReadPermission() {
set(ACL_READ);
return this;
}
public VOMSPermission setACLWritePermission() {
set(ACL_WRITE);
return this;
}
public VOMSPermission setAllPermissions() {
set(ALL_PERMISSION_MASK);
return this;
}
public VOMSPermission setAttributesReadPermission() {
set(ATTRIBUTES_READ);
return this;
}
public VOMSPermission setAttributesWritePermission() {
set(ATTRIBUTES_WRITE);
return this;
}
public VOMSPermission setContainerReadPermission() {
set(CONTAINER_READ);
return this;
}
public VOMSPermission setContainerWritePermission() {
set(CONTAINER_WRITE);
return this;
}
public VOMSPermission setEmptyPermissions() {
bits = 0;
return this;
}
public VOMSPermission setMembershipReadPermission() {
set(MEMBERSHIP_READ);
return this;
}
public VOMSPermission setMembershipRWPermission() {
set(MEMBERSHIP_READ);
set(MEMBERSHIP_WRITE);
return this;
}
public VOMSPermission setMembershipWritePermission() {
set(MEMBERSHIP_WRITE);
return this;
}
public VOMSPermission setPermissions(int bits) {
set(bits);
return this;
}
public VOMSPermission setPersonalInfoReadPermission() {
set(PERSONAL_INFO_READ);
return this;
}
public VOMSPermission setPersonalInfoWritePermission() {
set(PERSONAL_INFO_WRITE);
return this;
}
public VOMSPermission setRequestsReadPermission() {
set(REQUESTS_READ);
return this;
}
public VOMSPermission setRequestsWritePermission() {
set(REQUESTS_WRITE);
return this;
}
public VOMSPermission setSuspendPermission() {
set(SUSPEND);
return this;
}
protected boolean test(int permission) {
if (permission <= 0)
throw new IllegalArgumentException(
"Permission must be a positive integer.");
return ((bits & permission) == permission);
}
public String toBinaryString() {
return Integer.toBinaryString(bits);
}
public String toString() {
if (test(ALL_PERMISSION_MASK))
return "ALL";
if (bits == 0)
return "NONE";
List permList = buildPermList();
String result = StringUtils.join(permList.iterator(), ",");
permList.clear();
permList = null;
return result;
}
public String[] toStringArray() {
if (bits == 0)
return null;
List permList = buildPermList();
String[] result = new String[permList.size()];
permList.toArray(result);
permList.clear();
permList = null;
return result;
}
public List<String> toStringList() {
List<String> result = new ArrayList<String>();
if (bits == 0)
return result;
return buildPermList();
}
protected VOMSPermission unset(int permission) {
if (permission <= 0)
throw new IllegalArgumentException(
"Permission must be a positive integer.");
bits &= ~permission;
return this;
}
public VOMSPermission unsetACLDefaultPermission() {
unset(ACL_DEFAULT);
return this;
}
public VOMSPermission unsetACLReadPermission() {
unset(ACL_READ);
return this;
}
public VOMSPermission unsetACLWritePermission() {
unset(ACL_WRITE);
return this;
}
public VOMSPermission unsetAttributesReadPermission() {
unset(ATTRIBUTES_READ);
return this;
}
public VOMSPermission unsetAttributesWritePermission() {
unset(ATTRIBUTES_WRITE);
return this;
}
public VOMSPermission unsetContainerReadPermission() {
unset(CONTAINER_READ);
return this;
}
public VOMSPermission unsetContainerWritePermission() {
unset(CONTAINER_WRITE);
return this;
}
public VOMSPermission unsetMembershipReadPermission() {
unset(MEMBERSHIP_READ);
return this;
}
public VOMSPermission unsetMembershipWritePermission() {
unset(MEMBERSHIP_WRITE);
return this;
}
public VOMSPermission unsetRequestsReadPermission() {
unset(REQUESTS_READ);
return this;
}
public VOMSPermission unsetRequestsWritePermission() {
unset(REQUESTS_WRITE);
return this;
}
public void limitToPermissions(VOMSPermission limit) {
if (limit == null)
return;
bits &= limit.getBits();
}
}