1
18
19 package org.wildfly.common.context;
20
21 import java.security.Permission;
22 import java.security.PermissionCollection;
23 import java.util.function.Supplier;
24
25 import org.wildfly.common.Assert;
26 import org.wildfly.common._private.CommonMessages;
27 import org.wildfly.common.annotation.NotNull;
28
29
52 public final class ContextPermission extends Permission {
53
54 private static final long serialVersionUID = 2149744699461086708L;
55
56 private static final int ACTION_GET = 0b00000000001;
57 private static final int ACTION_GET_PRIV_SUP = 0b00000000010;
58 private static final int ACTION_GET_GLOBAL_DEF = 0b00000000100;
59 private static final int ACTION_SET_GLOBAL_DEF = 0b00000001000;
60 private static final int ACTION_SET_GLOBAL_DEF_SUP = 0b00000010000;
61 private static final int ACTION_GET_THREAD_DEF = 0b00000100000;
62 private static final int ACTION_SET_THREAD_DEF = 0b00001000000;
63 private static final int ACTION_SET_THREAD_DEF_SUP = 0b00010000000;
64 private static final int ACTION_GET_CLASSLOADER_DEF = 0b00100000000;
65 private static final int ACTION_SET_CLASSLOADER_DEF = 0b01000000000;
66 private static final int ACTION_SET_CLASSLOADER_DEF_SUP = 0b10000000000;
67
68 private static final int ACTION_ALL = 0b11111111111;
69
70 static final String STR_GET = "get";
71 static final String STR_GET_PRIV_SUP = "getPrivilegedSupplier";
72 static final String STR_GET_GLOBAL_DEF = "getGlobalDefault";
73 static final String STR_SET_GLOBAL_DEF = "setGlobalDefault";
74 static final String STR_SET_GLOBAL_DEF_SUP = "setGlobalDefaultSupplier";
75 static final String STR_GET_THREAD_DEF = "getThreadDefault";
76 static final String STR_SET_THREAD_DEF = "setThreadDefault";
77 static final String STR_SET_THREAD_DEF_SUP = "setThreadDefaultSupplier";
78 static final String STR_GET_CLASSLOADER_DEF = "getClassLoaderDefault";
79 static final String STR_SET_CLASSLOADER_DEF = "setClassLoaderDefault";
80 static final String STR_SET_CLASSLOADER_DEF_SUP = "setClassLoaderDefaultSupplier";
81
82 private final transient int actionBits;
83
84 private transient String actionString;
85
86
92 public ContextPermission(final String name, final String actions) {
93 super(name);
94 Assert.checkNotNullParam("name", name);
95 Assert.checkNotNullParam("actions", actions);
96 actionBits = parseActions(actions);
97 }
98
99 ContextPermission(final String name, final int actionBits) {
100 super(name);
101 Assert.checkNotNullParam("name", name);
102 this.actionBits = actionBits & ACTION_ALL;
103 }
104
105 private static int parseActions(final String actions) throws IllegalArgumentException {
106 int bits = 0;
107 int start = 0;
108 int idx = actions.indexOf(',');
109 if (idx == -1) {
110 return parseAction(actions);
111 } else do {
112 bits |= parseAction(actions.substring(start, idx));
113 start = idx + 1;
114 idx = actions.indexOf(',', start);
115 } while (idx != -1);
116 bits |= parseAction(actions.substring(start));
117 return bits;
118 }
119
120 private static int parseAction(final String action) {
121 switch (action.trim()) {
122 case STR_GET: return ACTION_GET;
123 case STR_GET_PRIV_SUP: return ACTION_GET_PRIV_SUP;
124 case STR_GET_GLOBAL_DEF: return ACTION_GET_GLOBAL_DEF;
125 case STR_SET_GLOBAL_DEF: return ACTION_SET_GLOBAL_DEF;
126 case STR_SET_GLOBAL_DEF_SUP: return ACTION_SET_GLOBAL_DEF_SUP;
127 case STR_GET_THREAD_DEF: return ACTION_GET_THREAD_DEF;
128 case STR_SET_THREAD_DEF: return ACTION_SET_THREAD_DEF;
129 case STR_SET_THREAD_DEF_SUP: return ACTION_SET_THREAD_DEF_SUP;
130 case STR_GET_CLASSLOADER_DEF: return ACTION_GET_CLASSLOADER_DEF;
131 case STR_SET_CLASSLOADER_DEF: return ACTION_SET_CLASSLOADER_DEF;
132 case STR_SET_CLASSLOADER_DEF_SUP: return ACTION_SET_CLASSLOADER_DEF_SUP;
133 case "*": return ACTION_ALL;
134 case "": return 0;
135 default: {
136 throw CommonMessages.msg.invalidPermissionAction(action);
137 }
138 }
139 }
140
141
148 public boolean implies(final Permission permission) {
149 return permission instanceof ContextPermission && implies((ContextPermission) permission);
150 }
151
152
159 public boolean implies(final ContextPermission permission) {
160 return this == permission || permission != null && isSet(this.actionBits, permission.actionBits) && impliesName(permission.getName());
161 }
162
163 private boolean impliesName(String otherName) {
164 final String myName = getName();
165 return myName.equals("*") || myName.equals(otherName);
166 }
167
168 static boolean isSet(int mask, int test) {
169 return (mask & test) == test;
170 }
171
172
178 public boolean equals(final Object obj) {
179 return obj instanceof ContextPermission && equals((ContextPermission) obj);
180 }
181
182
188 public boolean equals(final ContextPermission permission) {
189 return this == permission || permission != null && actionBits == permission.actionBits && getName().equals(permission.getName());
190 }
191
192
197 public int hashCode() {
198 return getName().hashCode() * 17 + actionBits;
199 }
200
201
206 public String getActions() {
207 String actionString = this.actionString;
208 if (actionString == null) {
209 final int actionBits = this.actionBits;
210 if (isSet(actionBits, ACTION_ALL)) {
211 return this.actionString = "*";
212 } else if (actionBits == 0) {
213 return this.actionString = "";
214 }
215 final StringBuilder b = new StringBuilder();
216 if (isSet(actionBits, ACTION_GET)) b.append(STR_GET).append(',');
217 if (isSet(actionBits, ACTION_GET_PRIV_SUP)) b.append(STR_GET_PRIV_SUP).append(',');
218 if (isSet(actionBits, ACTION_GET_GLOBAL_DEF)) b.append(STR_GET_GLOBAL_DEF).append(',');
219 if (isSet(actionBits, ACTION_SET_GLOBAL_DEF)) b.append(STR_SET_GLOBAL_DEF).append(',');
220 if (isSet(actionBits, ACTION_SET_GLOBAL_DEF_SUP)) b.append(STR_SET_GLOBAL_DEF_SUP).append(',');
221 if (isSet(actionBits, ACTION_GET_THREAD_DEF)) b.append(STR_GET_THREAD_DEF).append(',');
222 if (isSet(actionBits, ACTION_SET_THREAD_DEF)) b.append(STR_SET_THREAD_DEF).append(',');
223 if (isSet(actionBits, ACTION_SET_THREAD_DEF_SUP)) b.append(STR_SET_THREAD_DEF_SUP).append(',');
224 if (isSet(actionBits, ACTION_GET_CLASSLOADER_DEF)) b.append(STR_GET_CLASSLOADER_DEF).append(',');
225 if (isSet(actionBits, ACTION_SET_CLASSLOADER_DEF)) b.append(STR_SET_CLASSLOADER_DEF).append(',');
226 if (isSet(actionBits, ACTION_SET_CLASSLOADER_DEF_SUP)) b.append(STR_SET_CLASSLOADER_DEF_SUP).append(',');
227 assert b.length() > 0;
228 b.setLength(b.length() - 1);
229 return this.actionString = b.toString();
230 }
231 return actionString;
232 }
233
234
240 @NotNull
241 public ContextPermission withActions(String actions) {
242 return withActionBits(parseActions(actions));
243 }
244
245 ContextPermission withActionBits(int actionBits) {
246 if (isSet(this.actionBits, actionBits)) {
247 return this;
248 } else {
249 return new ContextPermission(getName(), this.actionBits | actionBits);
250 }
251 }
252
253
259 @NotNull
260 public ContextPermission withoutActions(String actions) {
261 return withoutActionBits(parseActions(actions));
262 }
263
264 ContextPermission withoutActionBits(final int actionBits) {
265 if ((actionBits & this.actionBits) == 0) {
266 return this;
267 } else {
268 return new ContextPermission(getName(), this.actionBits & ~actionBits);
269 }
270 }
271
272
277 public PermissionCollection newPermissionCollection() {
278 return new ContextPermissionCollection();
279 }
280
281 int getActionBits() {
282 return actionBits;
283 }
284 }
285