001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.hbase.security.access; 020 021import java.util.Collection; 022import java.util.Map; 023 024import org.apache.yetus.audience.InterfaceAudience; 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.security.User; 028import org.apache.hadoop.hbase.util.Bytes; 029 030import org.apache.hbase.thirdparty.com.google.common.base.Joiner; 031 032/** 033 * Represents the result of an authorization check for logging and error 034 * reporting. 035 */ 036@InterfaceAudience.Private 037public class AuthResult { 038 private boolean allowed; 039 private final String namespace; 040 private final TableName table; 041 private final Permission.Action action; 042 private final String request; 043 private String reason; 044 private final User user; 045 private AuthResult.Params params; 046 047 // "family" and "qualifier" should only be used if "families" is null. 048 private final byte[] family; 049 private final byte[] qualifier; 050 private final Map<byte[], ? extends Collection<?>> families; 051 052 public AuthResult(boolean allowed, String request, String reason, User user, 053 Permission.Action action, TableName table, byte[] family, byte[] qualifier) { 054 this.allowed = allowed; 055 this.request = request; 056 this.reason = reason; 057 this.user = user; 058 this.table = table; 059 this.family = family; 060 this.qualifier = qualifier; 061 this.action = action; 062 this.families = null; 063 this.namespace = null; 064 this.params = new Params().setTableName(table).setFamily(family).setQualifier(qualifier); 065 } 066 067 public AuthResult(boolean allowed, String request, String reason, User user, 068 Permission.Action action, TableName table, 069 Map<byte[], ? extends Collection<?>> families) { 070 this.allowed = allowed; 071 this.request = request; 072 this.reason = reason; 073 this.user = user; 074 this.table = table; 075 this.family = null; 076 this.qualifier = null; 077 this.action = action; 078 this.families = families; 079 this.namespace = null; 080 this.params = new Params().setTableName(table).setFamilies(families); 081 } 082 083 public AuthResult(boolean allowed, String request, String reason, User user, 084 Permission.Action action, String namespace) { 085 this.allowed = allowed; 086 this.request = request; 087 this.reason = reason; 088 this.user = user; 089 this.namespace = namespace; 090 this.action = action; 091 this.table = null; 092 this.family = null; 093 this.qualifier = null; 094 this.families = null; 095 this.params = new Params().setNamespace(namespace); 096 } 097 098 public boolean isAllowed() { 099 return allowed; 100 } 101 102 public User getUser() { 103 return user; 104 } 105 106 public String getReason() { 107 return reason; 108 } 109 110 public TableName getTableName() { 111 return table; 112 } 113 114 public byte[] getFamily() { 115 return family; 116 } 117 118 public byte[] getQualifier() { 119 return qualifier; 120 } 121 122 public Permission.Action getAction() { 123 return action; 124 } 125 126 public String getRequest() { 127 return request; 128 } 129 130 public Params getParams() { return this.params;} 131 132 public void setAllowed(boolean allowed) { 133 this.allowed = allowed; 134 } 135 136 public void setReason(String reason) { 137 this.reason = reason; 138 } 139 140 private static String toFamiliesString(Map<byte[], ? extends Collection<?>> families, 141 byte[] family, byte[] qual) { 142 StringBuilder sb = new StringBuilder(); 143 if (families != null) { 144 boolean first = true; 145 for (Map.Entry<byte[], ? extends Collection<?>> entry : families.entrySet()) { 146 String familyName = Bytes.toString(entry.getKey()); 147 if (entry.getValue() != null && !entry.getValue().isEmpty()) { 148 for (Object o : entry.getValue()) { 149 String qualifier; 150 if (o instanceof byte[]) { 151 qualifier = Bytes.toString((byte[])o); 152 } else if (o instanceof Cell) { 153 Cell c = (Cell) o; 154 qualifier = Bytes.toString(c.getQualifierArray(), c.getQualifierOffset(), 155 c.getQualifierLength()); 156 } else { 157 // Shouldn't really reach this? 158 qualifier = o.toString(); 159 } 160 if (!first) { 161 sb.append("|"); 162 } 163 first = false; 164 sb.append(familyName).append(":").append(qualifier); 165 } 166 } else { 167 if (!first) { 168 sb.append("|"); 169 } 170 first = false; 171 sb.append(familyName); 172 } 173 } 174 } else if (family != null) { 175 sb.append(Bytes.toString(family)); 176 if (qual != null) { 177 sb.append(":").append(Bytes.toString(qual)); 178 } 179 } 180 return sb.toString(); 181 } 182 183 public String toContextString() { 184 StringBuilder sb = new StringBuilder(); 185 String familiesString = toFamiliesString(families, family, qualifier); 186 sb.append("(user=") 187 .append(user != null ? user.getName() : "UNKNOWN") 188 .append(", "); 189 sb.append("scope=") 190 .append(namespace != null ? namespace : 191 table == null ? "GLOBAL" : table.getNameWithNamespaceInclAsString()) 192 .append(", "); 193 if(namespace == null && familiesString.length() > 0) { 194 sb.append("family=") 195 .append(familiesString) 196 .append(", "); 197 } 198 String paramsString = params.toString(); 199 if(paramsString.length() > 0) { 200 sb.append("params=[") 201 .append(paramsString) 202 .append("],"); 203 } 204 sb.append("action=") 205 .append(action != null ? action.toString() : "") 206 .append(")"); 207 return sb.toString(); 208 } 209 210 @Override 211 public String toString() { 212 return "AuthResult" + toContextString(); 213 } 214 215 public static AuthResult allow(String request, String reason, User user, 216 Permission.Action action, String namespace) { 217 return new AuthResult(true, request, reason, user, action, namespace); 218 } 219 220 public static AuthResult allow(String request, String reason, User user, 221 Permission.Action action, TableName table, byte[] family, byte[] qualifier) { 222 return new AuthResult(true, request, reason, user, action, table, family, qualifier); 223 } 224 225 public static AuthResult allow(String request, String reason, User user, 226 Permission.Action action, TableName table, 227 Map<byte[], ? extends Collection<?>> families) { 228 return new AuthResult(true, request, reason, user, action, table, families); 229 } 230 231 public static AuthResult deny(String request, String reason, User user, 232 Permission.Action action, String namespace) { 233 return new AuthResult(false, request, reason, user, action, namespace); 234 } 235 236 public static AuthResult deny(String request, String reason, User user, 237 Permission.Action action, TableName table, byte[] family, byte[] qualifier) { 238 return new AuthResult(false, request, reason, user, action, table, family, qualifier); 239 } 240 241 public static AuthResult deny(String request, String reason, User user, 242 Permission.Action action, TableName table, 243 Map<byte[], ? extends Collection<?>> families) { 244 return new AuthResult(false, request, reason, user, action, table, families); 245 } 246 247 public String toFamilyString() { 248 return toFamiliesString(families, family, qualifier); 249 } 250 251 public static class Params { 252 private String namespace = null; 253 private TableName tableName = null; 254 private Map<byte[], ? extends Collection<?>> families = null; 255 byte[] family = null; 256 byte[] qualifier = null; 257 258 public Params setNamespace(String namespace) { 259 this.namespace = namespace; 260 return this; 261 } 262 263 public Params setTableName(TableName table) { 264 this.tableName = table; 265 return this; 266 } 267 268 public Params setFamilies(Map<byte[], ? extends Collection<?>> families) { 269 this.families = families; 270 return this; 271 } 272 273 public Params setFamily(byte[] family) { 274 this.family = family; 275 return this; 276 } 277 278 public Params setQualifier(byte[] qualifier) { 279 this.qualifier = qualifier; 280 return this; 281 } 282 283 @Override 284 public String toString() { 285 String familiesString = toFamiliesString(families, family, qualifier); 286 String[] params = new String[] { 287 namespace != null ? "namespace=" + namespace : null, 288 tableName != null ? "table=" + tableName.getNameWithNamespaceInclAsString() : null, 289 familiesString.length() > 0 ? "family=" + familiesString : null 290 }; 291 return Joiner.on(",").skipNulls().join(params); 292 } 293 294 } 295}