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