Clover icon

sunshower-core

  1. Project Clover database Fri Apr 6 2018 03:27:42 UTC
  2. Package io.sunshower.service.security

File IdentifierEnabledLookupStrategy.java

 

Coverage histogram

../../../../img/srcFileCovDistChart1.png
59% of files have more coverage

Code metrics

50
166
31
3
649
392
63
0.38
5.35
10.33
2.03

Classes

Class Line # Actions
IdentifierEnabledLookupStrategy 39 118 42
0.0994152059.9%
IdentifierEnabledLookupStrategy.ProcessResultSet 457 39 12
0.00%
IdentifierEnabledLookupStrategy.StubAclParent 575 9 9
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package io.sunshower.service.security;
17   
18    import static java.lang.String.format;
19   
20    import io.sunshower.common.Identifier;
21    import java.io.Serializable;
22    import java.lang.reflect.Field;
23    import java.sql.ResultSet;
24    import java.sql.SQLException;
25    import java.util.*;
26    import javax.sql.DataSource;
27    import org.springframework.jdbc.core.JdbcTemplate;
28    import org.springframework.jdbc.core.ResultSetExtractor;
29    import org.springframework.security.acls.domain.*;
30    import org.springframework.security.acls.jdbc.LookupStrategy;
31    import org.springframework.security.acls.model.*;
32    import org.springframework.security.util.FieldUtils;
33    import org.springframework.util.Assert;
34   
35    /**
36    * Pretty much copied verbatim from Spring's implementation. It's beyond me why they do not support
37    * Identifier OOTB
38    */
 
39    public class IdentifierEnabledLookupStrategy implements LookupStrategy {
40   
41    public final String DEFAULT_SELECT_CLAUSE;
42   
43    private static final String DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE = "(acl_object_identity.id = ?)";
44   
45    private static final String DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE =
46    "(acl_object_identity.object_id_identity = ? and acl_class.class = ?)";
47   
48    public static final String DEFAULT_ORDER_BY_CLAUSE =
49    ") order by acl_object_identity.object_id_identity" + " asc, acl_entry.ace_order asc";
50   
51    // ~ Instance fields
52    // ================================================================================================
53   
54    private final AclAuthorizationStrategy aclAuthorizationStrategy;
55    private final String schemaPrefix;
56    private PermissionFactory permissionFactory = new DefaultPermissionFactory();
57    private final AclCache aclCache;
58    private final PermissionGrantingStrategy grantingStrategy;
59    private final JdbcTemplate jdbcTemplate;
60    private int batchSize = 50;
61   
62    private final Field fieldAces = FieldUtils.getField(AclImpl.class, "aces");
63    private final Field fieldAcl = FieldUtils.getField(AccessControlEntryImpl.class, "acl");
64   
65    // SQL Customization fields
66    private String selectClause;
67    private String lookupPrimaryKeysWhereClause = DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE;
68    private String lookupObjectIdentitiesWhereClause = DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE;
69    private String orderByClause = DEFAULT_ORDER_BY_CLAUSE;
70   
71    // ~ Constructors
72    // ===================================================================================================
73   
74    /**
75    * Constructor accepting mandatory arguments
76    *
77    * @param dataSource to access the database
78    * @param aclCache the cache where fully-loaded elements can be stored
79    * @param aclAuthorizationStrategy authorization strategy (required)
80    */
 
81  0 toggle public IdentifierEnabledLookupStrategy(
82    String schema,
83    DataSource dataSource,
84    AclCache aclCache,
85    AclAuthorizationStrategy aclAuthorizationStrategy,
86    AuditLogger auditLogger) {
87  0 this(
88    schema,
89    dataSource,
90    aclCache,
91    aclAuthorizationStrategy,
92    new DefaultPermissionGrantingStrategy(auditLogger));
93    }
94   
95    /**
96    * Creates a new instance
97    *
98    * @param dataSource to access the database
99    * @param aclCache the cache where fully-loaded elements can be stored
100    * @param aclAuthorizationStrategy authorization strategy (required)
101    * @param grantingStrategy the PermissionGrantingStrategy
102    */
 
103  1 toggle public IdentifierEnabledLookupStrategy(
104    String schema,
105    DataSource dataSource,
106    AclCache aclCache,
107    AclAuthorizationStrategy aclAuthorizationStrategy,
108    PermissionGrantingStrategy grantingStrategy) {
109  1 this.schemaPrefix = schema == null || schema.isEmpty() ? "" : schema + ".";
110  1 Assert.notNull(dataSource, "DataSource required");
111  1 Assert.notNull(aclCache, "AclCache required");
112  1 Assert.notNull(aclAuthorizationStrategy, "AclAuthorizationStrategy required");
113  1 Assert.notNull(grantingStrategy, "grantingStrategy required");
114  1 jdbcTemplate = new JdbcTemplate(dataSource);
115  1 this.aclCache = aclCache;
116  1 this.aclAuthorizationStrategy = aclAuthorizationStrategy;
117  1 this.grantingStrategy = grantingStrategy;
118  1 fieldAces.setAccessible(true);
119  1 fieldAcl.setAccessible(true);
120  1 DEFAULT_SELECT_CLAUSE = createSelectQuery();
121  1 selectClause = DEFAULT_SELECT_CLAUSE;
122    }
123   
124    // ~ Methods
125    // ========================================================================================================
126   
 
127  0 toggle private String computeRepeatingSql(String repeatingSql, int requiredRepetitions) {
128  0 assert requiredRepetitions > 0 : "requiredRepetitions must be > 0";
129   
130  0 final String startSql = selectClause;
131   
132  0 final String endSql = orderByClause;
133   
134  0 StringBuilder sqlStringBldr =
135    new StringBuilder(
136    startSql.length()
137    + endSql.length()
138    + requiredRepetitions * (repeatingSql.length() + 4));
139  0 sqlStringBldr.append(startSql);
140   
141  0 for (int i = 1; i <= requiredRepetitions; i++) {
142  0 sqlStringBldr.append(repeatingSql);
143   
144  0 if (i != requiredRepetitions) {
145  0 sqlStringBldr.append(" or ");
146    }
147    }
148   
149  0 sqlStringBldr.append(endSql);
150   
151  0 return sqlStringBldr.toString();
152    }
153   
 
154  0 toggle @SuppressWarnings("unchecked")
155    private List<AccessControlEntryImpl> readAces(AclImpl acl) {
156  0 try {
157  0 return (List<AccessControlEntryImpl>) fieldAces.get(acl);
158    } catch (IllegalAccessException e) {
159  0 throw new IllegalStateException("Could not obtain AclImpl.aces field", e);
160    }
161    }
162   
 
163  0 toggle private void setAclOnAce(AccessControlEntryImpl ace, AclImpl acl) {
164  0 try {
165  0 fieldAcl.set(ace, acl);
166    } catch (IllegalAccessException e) {
167  0 throw new IllegalStateException(
168    "Could not or set AclImpl on AccessControlEntryImpl fields", e);
169    }
170    }
171   
 
172  0 toggle private void setAces(AclImpl acl, List<AccessControlEntryImpl> aces) {
173  0 try {
174  0 fieldAces.set(acl, aces);
175    } catch (IllegalAccessException e) {
176  0 throw new IllegalStateException("Could not set AclImpl entries", e);
177    }
178    }
179   
 
180  0 toggle private void lookupPrimaryKeys(
181    final Map<Serializable, Acl> acls, final Set<Identifier> findNow, final List<Sid> sids) {
182  0 Assert.notNull(acls, "ACLs are required");
183  0 Assert.notEmpty(findNow, "Items to find now required");
184   
185  0 String sql = computeRepeatingSql(lookupPrimaryKeysWhereClause, findNow.size());
186   
187  0 Set<Identifier> parentsToLookup =
188    jdbcTemplate.query(
189    sql,
190    ps -> {
191  0 int i = 0;
192   
193  0 for (Identifier toFind : findNow) {
194  0 i++;
195  0 ps.setBytes(i, toFind.value());
196    }
197    },
198    new ProcessResultSet(acls, sids));
199   
200    // Lookup the parents, now that our JdbcTemplate has released the database
201    // connection (SEC-547)
202  0 if (parentsToLookup.size() > 0) {
203  0 lookupPrimaryKeys(acls, parentsToLookup, sids);
204    }
205    }
206   
 
207  0 toggle public final Map<ObjectIdentity, Acl> readAclsById(List<ObjectIdentity> objects, List<Sid> sids) {
208  0 Assert.isTrue(batchSize >= 1, "BatchSize must be >= 1");
209  0 Assert.notEmpty(objects, "Objects to lookup required");
210   
211    // Map<ObjectIdentity,Acl>
212  0 Map<ObjectIdentity, Acl> result = new HashMap<ObjectIdentity, Acl>(); // contains
213    // FULLY
214    // loaded
215    // Acl
216    // objects
217   
218  0 Set<ObjectIdentity> currentBatchToLoad = new HashSet<ObjectIdentity>();
219   
220  0 for (int i = 0; i < objects.size(); i++) {
221  0 final ObjectIdentity oid = objects.get(i);
222  0 boolean aclFound = false;
223   
224    // Check we don't already have this ACL in the results
225  0 if (result.containsKey(oid)) {
226  0 aclFound = true;
227    }
228   
229    // Check cache for the present ACL entry
230  0 if (!aclFound) {
231  0 Acl acl = aclCache.getFromCache(oid);
232   
233    // Ensure any cached element supports all the requested SIDs
234    // (they should always, as our base impl doesn't filter on SID)
235  0 if (acl != null) {
236  0 if (acl.isSidLoaded(sids)) {
237  0 result.put(acl.getObjectIdentity(), acl);
238  0 aclFound = true;
239    } else {
240  0 throw new IllegalStateException(
241    "Error: SID-filtered element detected when implementation does not perform SID filtering "
242    + "- have you added something to the cache manually?");
243    }
244    }
245    }
246   
247    // Load the ACL from the database
248  0 if (!aclFound) {
249  0 currentBatchToLoad.add(oid);
250    }
251   
252    // Is it time to load from JDBC the currentBatchToLoad?
253  0 if ((currentBatchToLoad.size() == this.batchSize) || ((i + 1) == objects.size())) {
254  0 if (currentBatchToLoad.size() > 0) {
255  0 Map<ObjectIdentity, Acl> loadedBatch = lookupObjectIdentities(currentBatchToLoad, sids);
256   
257    // Add loaded batch (all elements 100% initialized) to results
258  0 result.putAll(loadedBatch);
259   
260    // Add the loaded batch to the cache
261   
262  0 for (Acl loadedAcl : loadedBatch.values()) {
263  0 aclCache.putInCache((AclImpl) loadedAcl);
264    }
265   
266  0 currentBatchToLoad.clear();
267    }
268    }
269    }
270   
271  0 return result;
272    }
273   
274    /**
275    * Looks up a batch of <code>ObjectIdentity</code>s directly from the database.
276    *
277    * <p>The caller is responsible for optimization issues, such as selecting the identities to
278    * lookup, ensuring the cache doesn't contain them already, and adding the returned elements to
279    * the cache etc.
280    *
281    * <p>This subclass is required to return fully valid <code>Acl</code>s, including
282    * properly-configured parent ACLs.
283    */
 
284  0 toggle private Map<ObjectIdentity, Acl> lookupObjectIdentities(
285    final Collection<ObjectIdentity> objectIdentities, List<Sid> sids) {
286  0 Assert.notEmpty(objectIdentities, "Must provide identities to lookup");
287   
288  0 final Map<Serializable, Acl> acls = new HashMap<Serializable, Acl>(); // contains
289    // Acls
290    // with
291    // StubAclParents
292   
293    // Make the "acls" map contain all requested objectIdentities
294    // (including markers to each parent in the hierarchy)
295  0 String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause, objectIdentities.size());
296   
297  0 Set<Identifier> parentsToLookup =
298    jdbcTemplate.query(
299    sql,
300    ps -> {
301  0 int i = 0;
302  0 for (ObjectIdentity oid : objectIdentities) {
303    // Determine prepared statement values for this iteration
304  0 String type = oid.getType();
305   
306    // No need to check for nulls, as guaranteed non-null by
307    // ObjectIdentity.getIdentifier() interface contract
308  0 Identifier identifier = (Identifier) oid.getIdentifier();
309   
310  0 ps.setBytes((2 * i) + 1, identifier.value());
311    // Inject values
312    // ps.setLong((2 * i) + 1, id);
313  0 ps.setString((2 * i) + 2, type);
314  0 i++;
315    }
316    },
317    new ProcessResultSet(acls, sids));
318   
319    // Lookup the parents, now that our JdbcTemplate has released the database
320    // connection (SEC-547)
321  0 if (parentsToLookup.size() > 0) {
322  0 lookupPrimaryKeys(acls, parentsToLookup, sids);
323    }
324   
325    // Finally, convert our "acls" containing StubAclParents into true Acls
326  0 Map<ObjectIdentity, Acl> resultMap = new HashMap<>();
327   
328  0 for (Acl inputAcl : acls.values()) {
329  0 Assert.isInstanceOf(AclImpl.class, inputAcl, "Map should have contained an AclImpl");
330   
331  0 Acl result = convert(acls, (Identifier) ((AclImpl) inputAcl).getId());
332  0 resultMap.put(result.getObjectIdentity(), result);
333    }
334   
335  0 return resultMap;
336    }
337   
338    /**
339    * The final phase of converting the <code>Map</code> of <code>AclImpl</code> instances which
340    * contain <code>StubAclParent</code>s into proper, valid <code>AclImpl</code>s with correct ACL
341    * parents.
342    *
343    * @param inputMap the unconverted <code>AclImpl</code>s
344    * @param currentIdentity the current<code>Acl</code> that we wish to convert (this may be
345    */
 
346  0 toggle private AclImpl convert(Map<Serializable, Acl> inputMap, Identifier currentIdentity) {
347  0 Assert.notEmpty(inputMap, "InputMap required");
348  0 Assert.notNull(currentIdentity, "CurrentIdentity required");
349   
350    // Retrieve this Acl from the InputMap
351  0 Acl uncastAcl = inputMap.get(currentIdentity);
352  0 Assert.isInstanceOf(AclImpl.class, uncastAcl, "The inputMap contained a non-AclImpl");
353   
354  0 AclImpl inputAcl = (AclImpl) uncastAcl;
355   
356  0 Acl parent = inputAcl.getParentAcl();
357   
358  0 if ((parent != null) && parent instanceof StubAclParent) {
359    // Lookup the parent
360  0 StubAclParent stubAclParent = (StubAclParent) parent;
361  0 parent = convert(inputMap, stubAclParent.getId());
362    }
363   
364    // Now we have the parent (if there is one), create the true AclImpl
365  0 AclImpl result =
366    new AclImpl(
367    inputAcl.getObjectIdentity(),
368    inputAcl.getId(),
369    aclAuthorizationStrategy,
370    grantingStrategy,
371    parent,
372    null,
373    inputAcl.isEntriesInheriting(),
374    inputAcl.getOwner());
375   
376    // Copy the "aces" from the input to the destination
377   
378    // Obtain the "aces" from the input ACL
379  0 List<AccessControlEntryImpl> aces = readAces(inputAcl);
380   
381    // Create a list in which to store the "aces" for the "result" AclImpl instance
382  0 List<AccessControlEntryImpl> acesNew = new ArrayList<AccessControlEntryImpl>();
383   
384    // Iterate over the "aces" input and replace each nested
385    // AccessControlEntryImpl.getAcl() with the new "result" AclImpl instance
386    // This ensures StubAclParent instances are removed, as per SEC-951
387  0 for (AccessControlEntryImpl ace : aces) {
388  0 setAclOnAce(ace, result);
389  0 acesNew.add(ace);
390    }
391   
392    // Finally, now that the "aces" have been converted to have the "result" AclImpl
393    // instance, modify the "result" AclImpl instance
394  0 setAces(result, acesNew);
395   
396  0 return result;
397    }
398   
399    /**
400    * Creates a particular implementation of {@link Sid} depending on the arguments.
401    *
402    * @param sid the name of the sid representing its unique identifier. In typical ACL database
403    * schema it's located in table {@code acl_sid} table, {@code sid} column.
404    * @param isPrincipal whether it's a user or granted authority like role
405    * @return the instance of Sid with the {@code sidName} as an identifier
406    */
 
407  0 toggle protected Sid createSid(boolean isPrincipal, String sid) {
408  0 if (isPrincipal) {
409  0 return new PrincipalSid(sid);
410    } else {
411  0 return new GrantedAuthoritySid(sid);
412    }
413    }
414   
415    /**
416    * Sets the {@code PermissionFactory} instance which will be used to convert loaded permission
417    * data values to {@code Permission}s. A {@code DefaultPermissionFactory} will be used by default.
418    *
419    * @param permissionFactory
420    */
 
421  0 toggle public final void setPermissionFactory(PermissionFactory permissionFactory) {
422  0 this.permissionFactory = permissionFactory;
423    }
424   
 
425  0 toggle public final void setBatchSize(int batchSize) {
426  0 this.batchSize = batchSize;
427    }
428   
429    /**
430    * The SQL for the select clause. If customizing in order to modify column names, schema etc, the
431    * other SQL customization fields must also be set to match.
432    *
433    * @param selectClause the select clause, which defaults to {@link #DEFAULT_SELECT_CLAUSE}.
434    */
 
435  0 toggle public final void setSelectClause(String selectClause) {
436  0 this.selectClause = selectClause;
437    }
438   
439    /** The SQL for the where clause used in the <tt>lookupPrimaryKey</tt> method. */
 
440  0 toggle public final void setLookupPrimaryKeysWhereClause(String lookupPrimaryKeysWhereClause) {
441  0 this.lookupPrimaryKeysWhereClause = lookupPrimaryKeysWhereClause;
442    }
443   
444    /** The SQL for the where clause used in the <tt>lookupObjectIdentities</tt> method. */
 
445  0 toggle public final void setLookupObjectIdentitiesWhereClause(String lookupObjectIdentitiesWhereClause) {
446  0 this.lookupObjectIdentitiesWhereClause = lookupObjectIdentitiesWhereClause;
447    }
448   
449    /** The SQL for the "order by" clause used in both queries. */
 
450  0 toggle public final void setOrderByClause(String orderByClause) {
451  0 this.orderByClause = orderByClause;
452    }
453   
454    // ~ Inner Classes
455    // ==================================================================================================
456   
 
457    private class ProcessResultSet implements ResultSetExtractor<Set<Identifier>> {
458    private final Map<Serializable, Acl> acls;
459    private final List<Sid> sids;
460   
 
461  0 toggle public ProcessResultSet(Map<Serializable, Acl> acls, List<Sid> sids) {
462  0 Assert.notNull(acls, "ACLs cannot be null");
463  0 this.acls = acls;
464  0 this.sids = sids; // can be null
465    }
466   
 
467  0 toggle public Set<Identifier> extractData(ResultSet rs) throws SQLException {
468  0 Set<Identifier> parentIdsToLookup = new HashSet<>(); // Set of parent_id Longs
469   
470  0 while (rs.next()) {
471    // Convert current row into an Acl (albeit with a StubAclParent)
472  0 convertCurrentResultIntoObject(acls, rs);
473   
474    // Figure out if this row means we need to lookup another parent
475  0 Identifier parentId = fromBytes(rs.getBytes("parent_object"));
476   
477  0 if (parentId != null) {
478    // See if it's already in the "acls"
479   
480  0 if (acls.containsKey(parentId)) {
481  0 continue; // skip this while iteration
482    }
483   
484    // Now try to find it in the cache
485  0 MutableAcl cached = aclCache.getFromCache(parentId);
486   
487  0 if ((cached == null) || !cached.isSidLoaded(sids)) {
488  0 parentIdsToLookup.add(parentId);
489    } else {
490    // Pop into the acls map, so our convert method doesn't
491    // need to deal with an unsynchronized AclCache
492  0 acls.put(cached.getId(), cached);
493    }
494    }
495    }
496   
497    // Return the parents left to lookup to the caller
498  0 return parentIdsToLookup;
499    }
500   
501    /**
502    * Accepts the current <code>ResultSet</code> row, and converts it into an <code>AclImpl</code>
503    * that contains a <code>StubAclParent</code>
504    *
505    * @param acls the Map we should add the converted Acl to
506    * @param rs the ResultSet focused on a current row
507    * @throws SQLException if something goes wrong converting values
508    */
 
509  0 toggle private void convertCurrentResultIntoObject(Map<Serializable, Acl> acls, ResultSet rs)
510    throws SQLException {
511  0 Identifier id = fromBytes(rs.getBytes("acl_id"));
512   
513    // If we already have an ACL for this ID, just create the ACE
514  0 Acl acl = acls.get(id);
515   
516  0 if (acl == null) {
517    // Make an AclImpl and pop it into the Map
518  0 ObjectIdentity objectIdentity =
519    new ObjectIdentityImpl(
520    rs.getString("class"), fromBytes(rs.getBytes("object_id_identity")));
521   
522  0 Acl parentAcl = null;
523  0 Identifier parentAclId = fromBytes(rs.getBytes("parent_object"));
524   
525  0 if (parentAclId != null) {
526  0 parentAcl = new StubAclParent(parentAclId);
527    }
528   
529  0 boolean entriesInheriting = rs.getBoolean("entries_inheriting");
530  0 Sid owner = createSid(rs.getBoolean("acl_principal"), rs.getString("acl_sid"));
531   
532  0 acl =
533    new AclImpl(
534    objectIdentity,
535    id,
536    aclAuthorizationStrategy,
537    grantingStrategy,
538    parentAcl,
539    null,
540    entriesInheriting,
541    owner);
542   
543  0 acls.put(id, acl);
544    }
545   
546    // Add an extra ACE to the ACL (ORDER BY maintains the ACE list order)
547    // It is permissible to have no ACEs in an ACL (which is detected by a null
548    // ACE_SID)
549  0 if (rs.getString("ace_sid") != null) {
550    // Long aceId = new Long(rs.getLong("ace_id"));
551  0 Identifier aceId = fromBytes(rs.getBytes("ace_id"));
552  0 Sid recipient = createSid(rs.getBoolean("ace_principal"), rs.getString("ace_sid"));
553   
554  0 int mask = rs.getInt("mask");
555  0 Permission permission = permissionFactory.buildFromMask(mask);
556  0 boolean granting = rs.getBoolean("granting");
557  0 boolean auditSuccess = rs.getBoolean("audit_success");
558  0 boolean auditFailure = rs.getBoolean("audit_failure");
559   
560  0 AccessControlEntryImpl ace =
561    new AccessControlEntryImpl(
562    aceId, acl, recipient, permission, granting, auditSuccess, auditFailure);
563   
564    // Field acesField = FieldUtils.getField(AclImpl.class, "aces");
565  0 List<AccessControlEntryImpl> aces = readAces((AclImpl) acl);
566   
567    // Add the ACE if it doesn't already exist in the ACL.aces field
568  0 if (!aces.contains(ace)) {
569  0 aces.add(ace);
570    }
571    }
572    }
573    }
574   
 
575    private static class StubAclParent implements Acl {
576    private final Identifier id;
577   
 
578  0 toggle public StubAclParent(Identifier id) {
579  0 this.id = id;
580    }
581   
 
582  0 toggle public List<AccessControlEntry> getEntries() {
583  0 throw new UnsupportedOperationException("Stub only");
584    }
585   
 
586  0 toggle public Identifier getId() {
587  0 return id;
588    }
589   
 
590  0 toggle public ObjectIdentity getObjectIdentity() {
591  0 throw new UnsupportedOperationException("Stub only");
592    }
593   
 
594  0 toggle public Sid getOwner() {
595  0 throw new UnsupportedOperationException("Stub only");
596    }
597   
 
598  0 toggle public Acl getParentAcl() {
599  0 throw new UnsupportedOperationException("Stub only");
600    }
601   
 
602  0 toggle public boolean isEntriesInheriting() {
603  0 throw new UnsupportedOperationException("Stub only");
604    }
605   
 
606  0 toggle public boolean isGranted(
607    List<Permission> permission, List<Sid> sids, boolean administrativeMode)
608    throws NotFoundException, UnloadedSidException {
609  0 throw new UnsupportedOperationException("Stub only");
610    }
611   
 
612  0 toggle public boolean isSidLoaded(List<Sid> sids) {
613  0 throw new UnsupportedOperationException("Stub only");
614    }
615    }
616   
 
617  0 toggle static Identifier fromBytes(byte[] bytes) {
618  0 if (bytes == null) {
619  0 return null;
620    }
621  0 return Identifier.valueOf(bytes);
622    }
623   
 
624  1 toggle private String createSelectQuery() {
625  1 return format(
626    "select acl_object_identity.object_id_identity, "
627    + "acl_entry.ace_order, "
628    + "acl_object_identity.id as acl_id, "
629    + "acl_object_identity.parent_object, "
630    + "acl_object_identity.entries_inheriting, "
631    + "acl_entry.id as ace_id, "
632    + "acl_entry.mask, "
633    + "acl_entry.granting, "
634    + "acl_entry.audit_success, "
635    + "acl_entry.audit_failure, "
636    + "acl_sid.principal as ace_principal, "
637    + "acl_sid.sid as ace_sid, "
638    + "acli_sid.principal as acl_principal, "
639    + "acli_sid.sid as acl_sid, "
640    + "acl_class.class "
641    + "from %sacl_object_identity "
642    + "left join %sacl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid "
643    + "left join %sacl_class on acl_class.id = acl_object_identity.object_id_class "
644    + "left join %sacl_entry on acl_object_identity.id = acl_entry.acl_object_identity "
645    + "left join %sacl_sid on acl_entry.sid = acl_sid.id "
646    + "where ( ",
647    schemaPrefix, schemaPrefix, schemaPrefix, schemaPrefix, schemaPrefix);
648    }
649    }