EMMA Coverage Report (generated Mon Aug 23 17:21:34 CEST 2010)
[all classes][diskCacheV111.util]

COVERAGE SUMMARY FOR SOURCE FILE [CheckStagePermission.java]

nameclass, %method, %block, %line, %
CheckStagePermission.java100% (1/1)14%  (1/7)8%   (29/378)9%   (8/90)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CheckStagePermission100% (1/1)14%  (1/7)8%   (29/378)9%   (8/90)
canPerformStaging (String, String, String): boolean 0%   (0/1)0%   (0/26)0%   (0/8)
canPerformStaging (Subject, StorageInfo): boolean 0%   (0/1)0%   (0/77)0%   (0/19)
fileNeedsRereading (): boolean 0%   (0/1)0%   (0/13)0%   (0/2)
readStageConfigFile (BufferedReader): List 0%   (0/1)0%   (0/111)0%   (0/30)
rereadConfig (): void 0%   (0/1)0%   (0/42)0%   (0/10)
userMatchesPredicates (String, String, String): boolean 0%   (0/1)0%   (0/70)0%   (0/10)
CheckStagePermission (String): void 100% (1/1)74%  (29/39)73%  (8/11)

1package diskCacheV111.util;
2 
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileReader;
6import java.io.IOException;
7import java.util.ArrayList;
8import java.util.List;
9import java.util.Collection;
10import java.util.NoSuchElementException;
11import java.util.concurrent.locks.Lock;
12import java.util.concurrent.locks.ReadWriteLock;
13import java.util.concurrent.locks.ReentrantReadWriteLock;
14import java.util.regex.Matcher;
15import java.util.regex.Pattern;
16import java.util.regex.PatternSyntaxException;
17 
18import javax.security.auth.Subject;
19import org.dcache.auth.Subjects;
20 
21import diskCacheV111.vehicles.StorageInfo;
22 
23public class CheckStagePermission {
24    private File _stageConfigFile;
25    private long _lastTimeReadingStageConfigFile = 0L;
26    private List<Pattern[]> _regexList;
27    private final boolean _isEnabled;
28 
29    private final ReadWriteLock _fileReadWriteLock = new ReentrantReadWriteLock();
30    private final Lock _fileReadLock = _fileReadWriteLock.readLock();
31    private final Lock _fileWriteLock = _fileReadWriteLock.writeLock();
32 
33    public CheckStagePermission(String stageConfigurationFilePath) {
34        if ( stageConfigurationFilePath == null || stageConfigurationFilePath.length() == 0 ) {
35            _isEnabled = false;
36            return;
37        }
38 
39        _stageConfigFile = new File(stageConfigurationFilePath);
40        _isEnabled = true;
41    }
42 
43    /**
44     * Check whether staging is allowed for a particular subject on a particular object.
45     *
46     * @param subject The subject
47     * @param storageInfo The storage info of the object
48     * @return true if and only if the subject is allowed to perform
49     * staging
50     */
51    public boolean canPerformStaging(Subject subject, StorageInfo storageInfo)
52        throws PatternSyntaxException, IOException
53    {
54        if (!_isEnabled || Subjects.isRoot(subject))
55            return true;
56 
57        try {
58            String dn = Subjects.getDn(subject);
59            Collection<String> fqans = Subjects.getFqans(subject);
60 
61            String storageClass = storageInfo.getStorageClass();
62            String hsm = storageInfo.getHsm();
63 
64            String storeUnit = "";
65            if (storageClass != null && hsm != null) {
66                storeUnit = storageClass+"@"+hsm;
67            }
68 
69            if (dn == null) {
70                dn = "";
71            }
72 
73            if (fqans.isEmpty()) {
74                return canPerformStaging(dn, "", storeUnit);
75            } else {
76                for (String fqan: fqans) {
77                    if (canPerformStaging(dn, fqan, storeUnit))
78                        return true;
79                }
80                return false;
81            }
82        } catch (NoSuchElementException e) {
83            throw new IllegalArgumentException("Subject has multiple DNs");
84        }
85    }
86 
87    /**
88     * Check whether staging is allowed for the user with given DN and FQAN
89     * for the object in the given storage group.
90     *
91     * @param  dn user's Distinguished Name
92     * @param  fqan user's Fully Qualified Attribute Name
93     * @param  storeUnit object's store unit
94     * @return true if the user is allowed to perform staging of the object
95     * @throws PatternSyntaxException
96     * @throws IOException
97     */
98     public boolean canPerformStaging(String dn, String fqan, String storeUnit) throws PatternSyntaxException, IOException {
99 
100         if ( !_isEnabled )
101             return true;
102 
103         if ( !_stageConfigFile.exists() ) {
104             //if file does not exist, staging is denied for all users
105             return false;
106         }
107 
108         if ( fileNeedsRereading() )
109             rereadConfig();
110 
111         if (fqan==null) fqan="";
112 
113         return userMatchesPredicates(dn, fqan, storeUnit);
114     }
115 
116     /**
117      * Reread the contents of the configuration file.
118      * @throws IOException
119      * @throws PatternSyntaxException
120      */
121      void rereadConfig() throws PatternSyntaxException, IOException {
122          try {
123              _fileWriteLock.lock();
124              if ( fileNeedsRereading() ) {
125                  BufferedReader reader = new BufferedReader(new FileReader(_stageConfigFile));
126                  try {
127                       _regexList = readStageConfigFile(reader);
128                       _lastTimeReadingStageConfigFile = System.currentTimeMillis();
129                  } finally {
130                       reader.close();
131                  }
132              }
133          } finally {
134              _fileWriteLock.unlock();
135          }
136      }
137 
138      /**
139       * Check whether the stageConfigFile needs rereading.
140       *
141       * @return true if the file should be reread.
142       */
143       boolean fileNeedsRereading() {
144           long modificationTimeStageConfigFile;
145           modificationTimeStageConfigFile = _stageConfigFile.lastModified();
146 
147           return modificationTimeStageConfigFile > _lastTimeReadingStageConfigFile;
148       }
149 
150      /**
151       * Check whether the user matches predicates, that is, whether the user is in the
152       * list of authorized users that are allowed to perform staging of the object in the
153       * given storage group.
154       *
155       * @param dn user's Distinguished Name
156       * @param fqan user's FQAN as a String
157       * @param storeUnit object's storage unit
158       * @return true if the user and object match predicates
159       */
160       boolean userMatchesPredicates(String dn, String fqanStr, String storeUnit) {
161           try {
162               _fileReadLock.lock();
163               for (Pattern[] regexLine : _regexList) {
164                   if ( regexLine[0].matcher(dn).matches() ) {
165 
166                       if ( regexLine[1] == null ) {
167                           return true; // line contains only DN; DN match -> STAGE allowed
168                       } else if ( regexLine[1].matcher(fqanStr).matches() && (regexLine[2] == null || regexLine[2].matcher(storeUnit).matches()) ) {
169                           return true;
170                           //two cases covered here:
171                           //line contains DN and FQAN; DN and FQAN match -> STAGE allowed
172                           //line contains DN, FQAN, storeUnit; DN, FQAN, storeUnit match -> STAGE allowed
173                       }
174                   }
175               }
176           } finally {
177               _fileReadLock.unlock();
178           }
179           return false;
180       }
181 
182       /**
183        * Read configuration file and create list of compiled patterns, containing DNs and FQANs(optionally)
184        * of the users that are allowed to perform staging,
185        * as well as storage group of the object to be staged (optionally).
186        *
187        * @param  reader
188        * @return list of compiled patterns
189        * @throws IOException
190        * @throws PatternSyntaxException
191        */
192        List<Pattern[]> readStageConfigFile(BufferedReader reader) throws IOException, PatternSyntaxException {
193 
194            String line = null;
195            Pattern linePattern = Pattern.compile("\"([^\"]*)\"([ \t]+\"([^\"]*)\"([ \t]+\"([^\"]*)\")?)?");
196            Matcher matcherLine;
197 
198            List<Pattern[]> regexList = new ArrayList<Pattern[]>();
199 
200            while ((line = reader.readLine()) != null) {
201 
202                line = line.trim();
203                matcherLine = linePattern.matcher(line);
204                if ( line.startsWith("#") || line.isEmpty() ) { //commented or empty line
205                    continue;
206                }
207 
208                if ( !matcherLine.matches() )
209                    continue;
210 
211                Pattern[] arrayPattern = new Pattern[3];
212 
213                String matchDN = matcherLine.group(1);
214                String matchFQAN = matcherLine.group(3);
215                String matchStoreUnit = matcherLine.group(5);
216 
217                if ( matchFQAN != null ) {
218                    if (matchStoreUnit != null) { //line: DN, FQAN, StoreUnit
219                        arrayPattern[0] = Pattern.compile(matchDN);
220                        arrayPattern[1] = Pattern.compile(matchFQAN);
221                        arrayPattern[2] = Pattern.compile(matchStoreUnit);
222                        regexList.add(arrayPattern);
223                    } else { //line: DN, FQAN
224                        arrayPattern[0] = Pattern.compile(matchDN);
225                        arrayPattern[1] = Pattern.compile(matchFQAN);
226                        arrayPattern[2] = null;
227                        regexList.add(arrayPattern);
228                    }
229                } else { //line: DN
230                    arrayPattern[0] = Pattern.compile(matchDN);
231                    arrayPattern[1] = null;
232                    arrayPattern[2] = null;
233                    regexList.add(arrayPattern);
234                }
235            }
236            return regexList;
237        }
238 
239}

[all classes][diskCacheV111.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov