1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.security.access;
20
21 import com.google.common.collect.Maps;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.classification.InterfaceStability;
26 import org.apache.hadoop.hbase.util.Bytes;
27 import org.apache.hadoop.io.VersionedWritable;
28
29 import java.io.DataInput;
30 import java.io.DataOutput;
31 import java.io.IOException;
32 import java.util.Arrays;
33 import java.util.Map;
34
35
36
37
38
39
40
41 @InterfaceAudience.Public
42 @InterfaceStability.Evolving
43 public class Permission extends VersionedWritable {
44 protected static final byte VERSION = 0;
45 public enum Action {
46 READ('R'), WRITE('W'), EXEC('X'), CREATE('C'), ADMIN('A');
47
48 private byte code;
49 Action(char code) {
50 this.code = (byte)code;
51 }
52
53 public byte code() { return code; }
54 }
55
56 private static final Log LOG = LogFactory.getLog(Permission.class);
57 protected static final Map<Byte,Action> ACTION_BY_CODE = Maps.newHashMap();
58
59 protected Action[] actions;
60
61 static {
62 for (Action a : Action.values()) {
63 ACTION_BY_CODE.put(a.code(), a);
64 }
65 }
66
67
68 public Permission() {
69 super();
70 }
71
72 public Permission(Action... assigned) {
73 if (assigned != null && assigned.length > 0) {
74 actions = Arrays.copyOf(assigned, assigned.length);
75 }
76 }
77
78 public Permission(byte[] actionCodes) {
79 if (actionCodes != null) {
80 Action acts[] = new Action[actionCodes.length];
81 int j = 0;
82 for (int i=0; i<actionCodes.length; i++) {
83 byte b = actionCodes[i];
84 Action a = ACTION_BY_CODE.get(b);
85 if (a == null) {
86 LOG.error("Ignoring unknown action code '"+
87 Bytes.toStringBinary(new byte[]{b})+"'");
88 continue;
89 }
90 acts[j++] = a;
91 }
92 this.actions = Arrays.copyOf(acts, j);
93 }
94 }
95
96 public Action[] getActions() {
97 return actions;
98 }
99
100 public boolean implies(Action action) {
101 if (this.actions != null) {
102 for (Action a : this.actions) {
103 if (a == action) {
104 return true;
105 }
106 }
107 }
108
109 return false;
110 }
111
112 @Override
113 public boolean equals(Object obj) {
114 if (!(obj instanceof Permission)) {
115 return false;
116 }
117 Permission other = (Permission)obj;
118
119 if (actions == null && other.getActions() == null) {
120 return true;
121 } else if (actions != null && other.getActions() != null) {
122 Action[] otherActions = other.getActions();
123 if (actions.length != otherActions.length) {
124 return false;
125 }
126
127 outer:
128 for (Action a : actions) {
129 for (Action oa : otherActions) {
130 if (a == oa) continue outer;
131 }
132 return false;
133 }
134 return true;
135 }
136
137 return false;
138 }
139
140 @Override
141 public int hashCode() {
142 final int prime = 37;
143 int result = 23;
144 for (Action a : actions) {
145 result = prime * result + a.code();
146 }
147 return result;
148 }
149
150 public String toString() {
151 StringBuilder str = new StringBuilder("[Permission: ")
152 .append("actions=");
153 if (actions != null) {
154 for (int i=0; i<actions.length; i++) {
155 if (i > 0)
156 str.append(",");
157 if (actions[i] != null)
158 str.append(actions[i].toString());
159 else
160 str.append("NULL");
161 }
162 }
163 str.append("]");
164
165 return str.toString();
166 }
167
168
169 public byte getVersion() {
170 return VERSION;
171 }
172
173 @Override
174 public void readFields(DataInput in) throws IOException {
175 super.readFields(in);
176 int length = (int)in.readByte();
177 if (length > 0) {
178 actions = new Action[length];
179 for (int i = 0; i < length; i++) {
180 byte b = in.readByte();
181 Action a = ACTION_BY_CODE.get(b);
182 if (a == null) {
183 throw new IOException("Unknown action code '"+
184 Bytes.toStringBinary(new byte[]{b})+"' in input");
185 }
186 this.actions[i] = a;
187 }
188 } else {
189 actions = new Action[0];
190 }
191 }
192
193 @Override
194 public void write(DataOutput out) throws IOException {
195 super.write(out);
196 out.writeByte(actions != null ? actions.length : 0);
197 if (actions != null) {
198 for (Action a: actions) {
199 out.writeByte(a.code());
200 }
201 }
202 }
203 }