View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.security.access;
20  
21  import java.util.Collection;
22  import java.util.Map;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.TableName;
27  import org.apache.hadoop.hbase.security.User;
28  import org.apache.hadoop.hbase.util.Bytes;
29  
30  import com.google.common.base.Joiner;
31  
32  /**
33   * Represents the result of an authorization check for logging and error
34   * reporting.
35   */
36  @InterfaceAudience.Private
37  public class AuthResult {
38    private boolean allowed;
39    private final String namespace;
40    private final TableName table;
41    private final Permission.Action action;
42    private final String request;
43    private String reason;
44    private final User user;
45    private AuthResult.Params params;
46  
47    // "family" and "qualifier" should only be used if "families" is null.
48    private final byte[] family;
49    private final byte[] qualifier;
50    private final Map<byte[], ? extends Collection<?>> families;
51  
52    public AuthResult(boolean allowed, String request, String reason, User user,
53        Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
54      this.allowed = allowed;
55      this.request = request;
56      this.reason = reason;
57      this.user = user;
58      this.table = table;
59      this.family = family;
60      this.qualifier = qualifier;
61      this.action = action;
62      this.families = null;
63      this.namespace = null;
64      this.params = new Params().setTableName(table).setFamily(family).setQualifier(qualifier);
65    }
66  
67    public AuthResult(boolean allowed, String request, String reason, User user,
68          Permission.Action action, TableName table,
69          Map<byte[], ? extends Collection<?>> families) {
70      this.allowed = allowed;
71      this.request = request;
72      this.reason = reason;
73      this.user = user;
74      this.table = table;
75      this.family = null;
76      this.qualifier = null;
77      this.action = action;
78      this.families = families;
79      this.namespace = null;
80      this.params = new Params().setTableName(table).setFamilies(families);
81    }
82  
83    public AuthResult(boolean allowed, String request, String reason, User user,
84          Permission.Action action, String namespace) {
85      this.allowed = allowed;
86      this.request = request;
87      this.reason = reason;
88      this.user = user;
89      this.namespace = namespace;
90      this.action = action;
91      this.table = null;
92      this.family = null;
93      this.qualifier = null;
94      this.families = null;
95      this.params = new Params().setNamespace(namespace);
96    }
97  
98    public boolean isAllowed() {
99      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   public String toString() {
211     return "AuthResult" + toContextString();
212   }
213 
214   public static AuthResult allow(String request, String reason, User user,
215       Permission.Action action, String namespace) {
216     return new AuthResult(true, request, reason, user, action, namespace);
217   }
218 
219   public static AuthResult allow(String request, String reason, User user,
220       Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
221     return new AuthResult(true, request, reason, user, action, table, family, qualifier);
222   }
223 
224   public static AuthResult allow(String request, String reason, User user,
225       Permission.Action action, TableName table,
226       Map<byte[], ? extends Collection<?>> families) {
227     return new AuthResult(true, request, reason, user, action, table, families);
228   }
229 
230   public static AuthResult deny(String request, String reason, User user,
231       Permission.Action action, String namespace) {
232     return new AuthResult(false, request, reason, user, action, namespace);
233   }
234 
235   public static AuthResult deny(String request, String reason, User user,
236       Permission.Action action, TableName table, byte[] family, byte[] qualifier) {
237     return new AuthResult(false, request, reason, user, action, table, family, qualifier);
238   }
239 
240   public static AuthResult deny(String request, String reason, User user,
241         Permission.Action action, TableName table,
242         Map<byte[], ? extends Collection<?>> families) {
243     return new AuthResult(false, request, reason, user, action, table, families);
244   }
245 
246   public String toFamilyString() {
247     return toFamiliesString(families, family, qualifier);
248   }
249 
250   public static class Params {
251     private String namespace = null;
252     private TableName tableName = null;
253     private Map<byte[], ? extends Collection<?>> families = null;
254     byte[] family = null;
255     byte[] qualifier = null;
256 
257     public Params setNamespace(String namespace) {
258       this.namespace = namespace;
259       return this;
260     }
261 
262     public Params setTableName(TableName table) {
263       this.tableName = table;
264       return this;
265     }
266 
267     public Params setFamilies(Map<byte[], ? extends Collection<?>> families) {
268       this.families = families;
269       return this;
270     }
271 
272     public Params setFamily(byte[] family) {
273       this.family = family;
274       return this;
275     }
276 
277     public Params setQualifier(byte[] qualifier) {
278       this.qualifier = qualifier;
279       return this;
280     }
281 
282     public String toString() {
283       String familiesString = toFamiliesString(families, family, qualifier);
284       String[] params = new String[] {
285           namespace != null ? "namespace=" + namespace : null,
286           tableName != null ? "table=" + tableName.getNameWithNamespaceInclAsString() : null,
287           familiesString.length() > 0 ? "family=" + familiesString : null
288       };
289       return Joiner.on(",").skipNulls().join(params);
290     }
291 
292   }
293 }