1 package fr.in2p3.jsaga.impl.permissions;
2
3 import fr.in2p3.jsaga.adaptor.data.DataAdaptor;
4 import fr.in2p3.jsaga.adaptor.data.permission.*;
5 import fr.in2p3.jsaga.adaptor.data.read.DataReaderAdaptor;
6 import fr.in2p3.jsaga.adaptor.data.read.FileAttributes;
7 import fr.in2p3.jsaga.helpers.StringArray;
8 import fr.in2p3.jsaga.impl.AbstractSagaObjectImpl;
9 import fr.in2p3.jsaga.impl.task.AbstractThreadedTask;
10 import fr.in2p3.jsaga.impl.url.AbstractURLImpl;
11 import fr.in2p3.jsaga.sync.namespace.SyncNSEntry;
12 import org.ogf.saga.SagaObject;
13 import org.ogf.saga.error.*;
14 import org.ogf.saga.namespace.NSEntry;
15 import org.ogf.saga.permissions.Permission;
16 import org.ogf.saga.permissions.Permissions;
17 import org.ogf.saga.session.Session;
18 import org.ogf.saga.task.Task;
19 import org.ogf.saga.task.TaskMode;
20 import org.ogf.saga.url.URL;
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public abstract class AbstractDataPermissionsImpl extends AbstractSagaObjectImpl implements Permissions<NSEntry>, SyncNSEntry {
35 protected URL m_url;
36 protected DataAdaptor m_adaptor;
37
38
39 public AbstractDataPermissionsImpl(Session session, URL url, DataAdaptor adaptor) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
40 super(session);
41
42
43 m_url = url;
44 String scheme = adaptor.getType();
45 if (! url.getScheme().equals(scheme)) {
46 m_url.setScheme(scheme);
47 }
48
49
50 m_adaptor = adaptor;
51 }
52
53
54 public SagaObject clone() throws CloneNotSupportedException {
55 AbstractDataPermissionsImpl clone = (AbstractDataPermissionsImpl) super.clone();
56 clone.m_url = m_url;
57 clone.m_adaptor = m_adaptor;
58 return clone;
59 }
60
61
62
63 public void permissionsAllow(String id, int permissions) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, TimeoutException, NoSuccessException {
64 if (m_adaptor instanceof PermissionAdaptor) {
65 PermissionAdaptor adaptor = (PermissionAdaptor) m_adaptor;
66 if (isSupportedScope(adaptor, id)) {
67 int _scope = getPermissionsScope(id);
68 String _identifier = getPermissionsIdentifier(id);
69 PermissionBytes _permissions = new PermissionBytes(permissions);
70
71
72 if (_permissions.contains(Permission.OWNER)) {
73 switch (_scope) {
74 case PermissionAdaptor.SCOPE_USER:
75 if (adaptor instanceof PermissionAdaptorFull) {
76 ((PermissionAdaptorFull)adaptor).setOwner(m_url.getPath(), _identifier);
77 } else {
78 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
79 }
80 break;
81 case PermissionAdaptor.SCOPE_GROUP:
82 try {
83 adaptor.setGroup(m_url.getPath(), _identifier);
84 } catch (DoesNotExistException e) {
85 throw new NoSuccessException("File not found: " +m_url.getPath(), this);
86 }
87 break;
88 case PermissionAdaptor.SCOPE_ANY:
89 throw new BadParameterException("Setting * as OWNER is not allowed");
90 }
91
92 _permissions = new PermissionBytes(permissions - Permission.OWNER.getValue());
93 }
94
95
96 if (adaptor instanceof PermissionAdaptorFull) {
97
98 ((PermissionAdaptorFull)adaptor).permissionsAllow(
99 m_url.getPath(), _scope, _permissions, _identifier);
100 } else if (adaptor instanceof PermissionAdaptorBasic) {
101
102 FileAttributes attrs;
103 try{attrs=this._getFileAttributes();} catch(IncorrectStateException e){throw new NoSuccessException(e);}
104
105
106 if (_identifier!=null && _scope==PermissionAdaptor.SCOPE_USER &&
107 (attrs.getOwner()==null || !attrs.getOwner().equals(_identifier)))
108 {
109 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
110 }
111
112
113 ((PermissionAdaptorBasic)adaptor).permissionsAllow(
114 m_url.getPath(), _scope, _permissions);
115 } else {
116 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
117 }
118 } else {
119 throw new BadParameterException("Not supported for this protocol: "+ m_url.getScheme(), this);
120 }
121
122 ((AbstractURLImpl)m_url).setCache(null);
123 } else {
124 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
125 }
126 }
127
128 public void permissionsDeny(String id, int permissions) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, TimeoutException, NoSuccessException {
129 if (m_adaptor instanceof PermissionAdaptor) {
130 PermissionAdaptor adaptor = (PermissionAdaptor) m_adaptor;
131 if (isSupportedScope(adaptor, id)) {
132 int _scope = getPermissionsScope(id);
133 String _identifier = getPermissionsIdentifier(id);
134 PermissionBytes _permissions = new PermissionBytes(permissions);
135
136
137 if (_permissions.contains(Permission.OWNER)) {
138 throw new BadParameterException("Unsetting OWNER permission is not allowed");
139 }
140
141
142 if (adaptor instanceof PermissionAdaptorFull) {
143
144 ((PermissionAdaptorFull)adaptor).permissionsDeny(
145 m_url.getPath(), _scope, _permissions, _identifier);
146 } else if (adaptor instanceof PermissionAdaptorBasic) {
147
148 FileAttributes attrs;
149 try{attrs=this._getFileAttributes();} catch(IncorrectStateException e){throw new NoSuccessException(e);}
150
151
152 if (_identifier != null) {
153 switch (_scope) {
154 case PermissionAdaptor.SCOPE_USER:
155 if (attrs.getOwner()==null || !attrs.getOwner().equals(_identifier)) {
156 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
157 }
158 break;
159 case PermissionAdaptor.SCOPE_GROUP:
160 if (attrs.getGroup()==null || !attrs.getGroup().equals(_identifier)) {
161 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
162 }
163 break;
164 }
165 }
166
167
168 ((PermissionAdaptorBasic)adaptor).permissionsDeny(
169 m_url.getPath(), _scope, _permissions);
170 } else {
171 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
172 }
173 } else {
174 throw new BadParameterException("Not supported for this protocol: "+ m_url.getScheme(), this);
175 }
176 } else {
177 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
178 }
179
180 ((AbstractURLImpl)m_url).setCache(null);
181 }
182
183 public boolean permissionsCheck(String id, int permissions) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, TimeoutException, NoSuccessException {
184 boolean checked = true;
185
186 final String ctxUserID = null;
187 int _scope = getPermissionsScope(id);
188 String _identifier = getPermissionsIdentifier(id);
189 PermissionBytes _permissions = new PermissionBytes(permissions);
190
191
192 FileAttributes attrs;
193 try{attrs=this._getFileAttributes();} catch(IncorrectStateException e){throw new NoSuccessException(e);}
194
195
196 if (_permissions.contains(Permission.OWNER)) {
197 switch (_scope) {
198 case PermissionAdaptor.SCOPE_USER:
199 if (attrs.getOwner() != null) {
200 checked = attrs.getOwner().equals(_identifier);
201 } else {
202 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
203 }
204 break;
205 case PermissionAdaptor.SCOPE_GROUP:
206 if (attrs.getGroup() != null) {
207 checked = attrs.getGroup().equals(_identifier);
208 } else {
209 throw new BadParameterException("Not supported for this protocol: "+m_url.getScheme(), this);
210 }
211 break;
212 case PermissionAdaptor.SCOPE_ANY:
213 throw new BadParameterException("* can not be OWNER of an entry");
214 }
215
216 _permissions = new PermissionBytes(permissions - Permission.OWNER.getValue());
217 }
218
219
220 if (m_adaptor instanceof PermissionAdaptor && !isSupportedScope((PermissionAdaptor)m_adaptor, id)) {
221 throw new BadParameterException("Not supported for this protocol: "+ m_url.getScheme(), this);
222 }
223
224
225 PermissionBytes cachedPerms;
226 if (id==null || id==ctxUserID ||
227 (_scope==PermissionAdaptor.SCOPE_USER && _identifier.equals(attrs.getOwner())))
228 cachedPerms = attrs.getUserPermission();
229 else if ((_scope==PermissionAdaptor.SCOPE_GROUP && _identifier.equals(attrs.getGroup())) ||
230 (_scope==PermissionAdaptor.SCOPE_USER && this.isMemberOf(_identifier, attrs.getGroup())))
231 cachedPerms = attrs.getGroupPermission();
232 else
233 cachedPerms = attrs.getAnyPermission();
234
235
236 if (m_adaptor instanceof PermissionAdaptorFull) {
237 return checked && ((PermissionAdaptorFull)m_adaptor).permissionsCheck(
238 m_url.getPath(), _scope, _permissions, _identifier);
239 } else if (cachedPerms != FileAttributes.PERMISSION_UNKNOWN) {
240 return checked && cachedPerms.containsAll(_permissions.getValue());
241 } else {
242 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
243 }
244 }
245 private boolean isMemberOf(String id, String groupOwner) throws BadParameterException, NoSuccessException {
246 if (m_adaptor instanceof PermissionAdaptorBasic) {
247 String[] groups = ((PermissionAdaptorBasic)m_adaptor).getGroupsOf(id);
248 return StringArray.arrayContains(groups, groupOwner);
249 } else {
250 return false;
251 }
252 }
253
254 private static boolean isSupportedScope(PermissionAdaptor adaptor, String id) {
255 int scope = getPermissionsScope(id);
256 for (int s : adaptor.getSupportedScopes()) {
257 if (scope == s) {
258 return true;
259 }
260 }
261 return false;
262 }
263 private static int getPermissionsScope(String id) {
264 if (id != null) {
265 if (id.equals("*")) {
266 return PermissionAdaptor.SCOPE_ANY;
267 } else if (id.startsWith("group-")) {
268 return PermissionAdaptor.SCOPE_GROUP;
269 }
270 }
271 return PermissionAdaptor.SCOPE_USER;
272 }
273 private static String getPermissionsIdentifier(String id) {
274 if (id != null) {
275 if (id.startsWith("group-") || id.startsWith("user-")) {
276 String realIdentifier = id.substring(id.indexOf('-')+1);
277 if (realIdentifier.equals("null")) {
278 return null;
279 } else {
280 return realIdentifier;
281 }
282 }
283 }
284 return id;
285 }
286
287 public String getOwner() throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, TimeoutException, NoSuccessException {
288 try {
289 FileAttributes attrs = this._getFileAttributes();
290 String owner = attrs.getOwner();
291 if (owner != null) {
292 return owner;
293 }
294 } catch (IncorrectStateException e) {
295 throw new NoSuccessException(e);
296 }
297 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
298 }
299
300 public String getGroup() throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, TimeoutException, NoSuccessException {
301 try {
302 FileAttributes attrs = this._getFileAttributes();
303 String group = attrs.getGroup();
304 if (group != null) {
305 return group;
306 }
307 } catch (IncorrectStateException e) {
308 throw new NoSuccessException(e);
309 }
310 throw new NotImplementedException("Not supported for this protocol: "+ m_url.getScheme(), this);
311 }
312
313
314
315 public Task<NSEntry, Void> permissionsAllow(TaskMode mode, final String id, final int permissions) throws NotImplementedException {
316 return new AbstractThreadedTask<NSEntry,Void>(mode) {
317 public Void invoke() throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException {
318 AbstractDataPermissionsImpl.this.permissionsAllow(id, permissions);
319 return null;
320 }
321 };
322 }
323
324 public Task<NSEntry, Void> permissionsDeny(TaskMode mode, final String id, final int permissions) throws NotImplementedException {
325 return new AbstractThreadedTask<NSEntry,Void>(mode) {
326 public Void invoke() throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException {
327 AbstractDataPermissionsImpl.this.permissionsDeny(id, permissions);
328 return null;
329 }
330 };
331 }
332
333 public Task<NSEntry, Boolean> permissionsCheck(TaskMode mode, final String id, final int permissions) throws NotImplementedException {
334 return new AbstractThreadedTask<NSEntry,Boolean>(mode) {
335 public Boolean invoke() throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException {
336 return AbstractDataPermissionsImpl.this.permissionsCheck(id, permissions);
337 }
338 };
339 }
340
341 public Task<NSEntry, String> getOwner(TaskMode mode) throws NotImplementedException {
342 return new AbstractThreadedTask<NSEntry,String>(mode) {
343 public String invoke() throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException {
344 return AbstractDataPermissionsImpl.this.getOwner();
345 }
346 };
347 }
348
349 public Task<NSEntry, String> getGroup(TaskMode mode) throws NotImplementedException {
350 return new AbstractThreadedTask<NSEntry,String>(mode) {
351 public String invoke() throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException {
352 return AbstractDataPermissionsImpl.this.getGroup();
353 }
354 };
355 }
356
357 protected FileAttributes _getFileAttributes() throws NotImplementedException, PermissionDeniedException, IncorrectStateException, TimeoutException, NoSuccessException {
358 FileAttributes attrs;
359 if ( ((AbstractURLImpl)m_url).hasCache() ) {
360
361 attrs = ((AbstractURLImpl)m_url).getCache();
362 } else if (m_adaptor instanceof DataReaderAdaptor) {
363
364 try {
365 attrs = ((DataReaderAdaptor)m_adaptor).getAttributes(
366 m_url.getPath(),
367 m_url.getQuery());
368 } catch (DoesNotExistException doesNotExist) {
369 throw new IncorrectStateException("Entry does not exist: "+m_url, doesNotExist);
370 }
371
372
373 ((AbstractURLImpl)m_url).setCache(attrs);
374 } else {
375 throw new NotImplementedException("Not supported for this protocol: "+m_url.getScheme(), this);
376 }
377 return attrs;
378 }
379 }