blob: bf05dc10b89e3288031c7cf6dde695b4bf37bc57 [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.hadoop.hbase.security.access;
import java.util.Collection;
import java.util.Map;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.Bytes;
import com.google.common.base.Joiner;
/**
* Represents the result of an authorization check for logging and error
* reporting.
*/
@InterfaceAudience.Private
public class AuthResult {
private boolean allowed;
private final String namespace;
private final TableName table;
private final Permission.Action action;
private final String request;
private String reason;
private final User user;
private AuthResult.Params params;
// "family" and "qualifier" should only be used if "families" is null.
private final byte[] family;
private final byte[] qualifier;
private final Map<byte[], ? extends Collection<?>> families;
public AuthResult(boolean allowed, String request, String reason, User user,
Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
this.allowed = allowed;
this.request = request;
this.reason = reason;
this.user = user;
this.table = table;
this.family = family;
this.qualifier = qualifier;
this.action = action;
this.families = null;
this.namespace = null;
this.params = new Params().setTableName(table).setFamily(family).setQualifier(qualifier);
}
public AuthResult(boolean allowed, String request, String reason, User user,
Permission.Action action, TableName table,
Map<byte[], ? extends Collection<?>> families) {
this.allowed = allowed;
this.request = request;
this.reason = reason;
this.user = user;
this.table = table;
this.family = null;
this.qualifier = null;
this.action = action;
this.families = families;
this.namespace = null;
this.params = new Params().setTableName(table).setFamilies(families);
}
public AuthResult(boolean allowed, String request, String reason, User user,
Permission.Action action, String namespace) {
this.allowed = allowed;
this.request = request;
this.reason = reason;
this.user = user;
this.namespace = namespace;
this.action = action;
this.table = null;
this.family = null;
this.qualifier = null;
this.families = null;
this.params = new Params().setNamespace(namespace);
}
public boolean isAllowed() {
return allowed;
}
public User getUser() {
return user;
}
public String getReason() {
return reason;
}
public TableName getTableName() {
return table;
}
public byte[] getFamily() {
return family;
}
public byte[] getQualifier() {
return qualifier;
}
public Permission.Action getAction() {
return action;
}
public String getRequest() {
return request;
}
public Params getParams() { return this.params;}
public void setAllowed(boolean allowed) {
this.allowed = allowed;
}
public void setReason(String reason) {
this.reason = reason;
}
private static String toFamiliesString(Map<byte[], ? extends Collection<?>> families,
byte[] family, byte[] qual) {
StringBuilder sb = new StringBuilder();
if (families != null) {
boolean first = true;
for (Map.Entry<byte[], ? extends Collection<?>> entry : families.entrySet()) {
String familyName = Bytes.toString(entry.getKey());
if (entry.getValue() != null && !entry.getValue().isEmpty()) {
for (Object o : entry.getValue()) {
String qualifier;
if (o instanceof byte[]) {
qualifier = Bytes.toString((byte[])o);
} else if (o instanceof Cell) {
Cell c = (Cell) o;
qualifier = Bytes.toString(c.getQualifierArray(), c.getQualifierOffset(),
c.getQualifierLength());
} else {
// Shouldn't really reach this?
qualifier = o.toString();
}
if (!first) {
sb.append("|");
}
first = false;
sb.append(familyName).append(":").append(qualifier);
}
} else {
if (!first) {
sb.append("|");
}
first = false;
sb.append(familyName);
}
}
} else if (family != null) {
sb.append(Bytes.toString(family));
if (qual != null) {
sb.append(":").append(Bytes.toString(qual));
}
}
return sb.toString();
}
public String toContextString() {
StringBuilder sb = new StringBuilder();
String familiesString = toFamiliesString(families, family, qualifier);
sb.append("(user=")
.append(user != null ? user.getName() : "UNKNOWN")
.append(", ");
sb.append("scope=")
.append(namespace != null ? namespace :
table == null ? "GLOBAL" : table.getNameWithNamespaceInclAsString())
.append(", ");
if(namespace == null && familiesString.length() > 0) {
sb.append("family=")
.append(familiesString)
.append(", ");
}
String paramsString = params.toString();
if(paramsString.length() > 0) {
sb.append("params=[")
.append(paramsString)
.append("],");
}
sb.append("action=")
.append(action != null ? action.toString() : "")
.append(")");
return sb.toString();
}
public String toString() {
return "AuthResult" + toContextString();
}
public static AuthResult allow(String request, String reason, User user,
Permission.Action action, String namespace) {
return new AuthResult(true, request, reason, user, action, namespace);
}
public static AuthResult allow(String request, String reason, User user,
Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
return new AuthResult(true, request, reason, user, action, table, family, qualifier);
}
public static AuthResult allow(String request, String reason, User user,
Permission.Action action, TableName table,
Map<byte[], ? extends Collection<?>> families) {
return new AuthResult(true, request, reason, user, action, table, families);
}
public static AuthResult deny(String request, String reason, User user,
Permission.Action action, String namespace) {
return new AuthResult(false, request, reason, user, action, namespace);
}
public static AuthResult deny(String request, String reason, User user,
Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
return new AuthResult(false, request, reason, user, action, table, family, qualifier);
}
public static AuthResult deny(String request, String reason, User user,
Permission.Action action, TableName table,
Map<byte[], ? extends Collection<?>> families) {
return new AuthResult(false, request, reason, user, action, table, families);
}
public String toFamilyString() {
return toFamiliesString(families, family, qualifier);
}
public static class Params {
private String namespace = null;
private TableName tableName = null;
private Map<byte[], ? extends Collection<?>> families = null;
byte[] family = null;
byte[] qualifier = null;
public Params setNamespace(String namespace) {
this.namespace = namespace;
return this;
}
public Params setTableName(TableName table) {
this.tableName = table;
return this;
}
public Params setFamilies(Map<byte[], ? extends Collection<?>> families) {
this.families = families;
return this;
}
public Params setFamily(byte[] family) {
this.family = family;
return this;
}
public Params setQualifier(byte[] qualifier) {
this.qualifier = qualifier;
return this;
}
public String toString() {
String familiesString = toFamiliesString(families, family, qualifier);
String[] params = new String[] {
namespace != null ? "namespace=" + namespace : null,
tableName != null ? "table=" + tableName.getNameWithNamespaceInclAsString() : null,
familiesString.length() > 0 ? "family=" + familiesString : null
};
return Joiner.on(",").skipNulls().join(params);
}
}
}