/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.security.impl;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Represents a service access rule: identifies a service, a method, and the set of roles that are
* allowed to access it
*/
@SuppressWarnings("serial")
public class ServiceAccessRule implements Comparable<ServiceAccessRule>, Serializable {
/**
* Any service or method
*/
public static final String ANY = "*";
public static ServiceAccessRule READ_ALL = new ServiceAccessRule(ANY, ANY);
public static ServiceAccessRule WRITE_ALL = new ServiceAccessRule(ANY, ANY);
String service;
String method;
Set<String> roles;
/**
* Builds a new rule
*/
public ServiceAccessRule(String service, String method, Set<String> roles) {
super();
this.service = service;
this.method = method;
if (roles == null)
this.roles = new HashSet<String>();
else
this.roles = new HashSet<String>(roles);
}
/**
* Builds a new rule
*/
public ServiceAccessRule(String service, String method, String... roles) {
this(service, method, roles == null ? null : new HashSet<String>(Arrays.asList(roles)));
}
/**
* Copy constructor
*/
public ServiceAccessRule(ServiceAccessRule other) {
this.service = other.service;
this.method = other.method;
this.roles = new HashSet<String>(other.roles);
}
/**
* Builds the default rule: *.*.r=*
*/
public ServiceAccessRule() {
this(ANY, ANY);
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getMethod() {
return method;
}
public void setMethod(String layer) {
this.method = layer;
}
public Set<String> getRoles() {
return roles;
}
/**
* Returns the key for the current rule. No other rule should have the same
*
*
*/
public String getKey() {
return service + "." + method;
}
/**
* Returns the list of roles as a comma separated string for this rule
*
*
*/
public String getValue() {
if (roles.isEmpty()) {
return ServiceAccessRule.ANY;
} else {
StringBuffer sb = new StringBuffer();
for (String role : roles) {
sb.append(role);
sb.append(",");
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
}
/**
* Comparison implemented so that generic rules get first, specific one are compared by service
* and method
*/
public int compareTo(ServiceAccessRule other) {
int compareService = compareServiceItems(service, other.service);
if (compareService != 0)
return compareService;
return compareServiceItems(method, other.method);
}
/**
* Equality based on service/method only
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ServiceAccessRule))
return false;
return 0 == compareTo((ServiceAccessRule) obj);
}
/**
* Hashcode based on service/method only
*/
@Override
public int hashCode() {
return new HashCodeBuilder().append(service).append(method).toHashCode();
}
/**
* Generic string comparison that considers the use of {@link #ANY}
*/
public int compareServiceItems(String item, String otherItem) {
if (item.equals(otherItem))
return 0;
else if (ANY.equals(item))
return -1;
else if (ANY.equals(otherItem))
return 1;
else
return item.compareTo(otherItem);
}
@Override
public String toString() {
return getKey() + "=" + getValue();
}
}