Clover Coverage Report - Pebble 2.5-SNAPSHOT
Coverage timestamp: Sat Jun 12 2010 09:39:29 EST
../../../../img/srcFileCovDistChart7.png 33% of files have more coverage
86   265   30   5,06
20   166   0,35   17
17     1,76  
1    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  DefaultSecurityRealm       Line # 20 86 0% 30 36 70,7% 0.70731705
 
  (10)
 
1    package net.sourceforge.pebble.security;
2   
3    import net.sourceforge.pebble.Configuration;
4    import net.sourceforge.pebble.Constants;
5    import net.sourceforge.pebble.comparator.PebbleUserDetailsComparator;
6    import org.acegisecurity.providers.dao.SaltSource;
7    import org.acegisecurity.providers.encoding.PasswordEncoder;
8    import org.apache.commons.logging.Log;
9    import org.apache.commons.logging.LogFactory;
10   
11    import java.io.*;
12    import java.util.*;
13   
14    /**
15    * Implementation of the SecurityRealm that gets authentication
16    * credentials from the blog directory.
17    *
18    * @author Simon Brown
19    */
 
20    public class DefaultSecurityRealm implements SecurityRealm {
21   
22    private static final Log log = LogFactory.getLog(DefaultSecurityRealm.class);
23   
24    private static final String REALM_DIRECTORY_NAME = "realm";
25   
26    protected static final String PASSWORD = "password";
27    protected static final String ROLES = "roles";
28    protected static final String NAME = "name";
29    protected static final String EMAIL_ADDRESS = "emailAddress";
30    protected static final String WEBSITE = "website";
31    protected static final String PROFILE = "profile";
32    protected static final String DETAILS_UPDATEABLE = "detailsUpdateable";
33    protected static final String PREFERENCE = "preference.";
34   
35    private Configuration configuration;
36   
37    private PasswordEncoder passwordEncoder;
38   
39    private SaltSource saltSource;
40   
41    /**
42    * Creates the underlying security realm upon creation, if necessary.
43    */
 
44  10 toggle public void init() {
45  10 try {
46  10 File realm = getFileForRealm();
47  10 if (!realm.exists()) {
48  10 realm.mkdirs();
49  10 log.warn("*** Creating default user (username/password)");
50  10 log.warn("*** Don't forget to delete this user in a production deployment!");
51  10 PebbleUserDetails defaultUser = new PebbleUserDetails("username", "password", "Default User", "username@domain.com", "http://www.domain.com", "Default User...", new String[] {Constants.BLOG_OWNER_ROLE, Constants.BLOG_PUBLISHER_ROLE, Constants.BLOG_CONTRIBUTOR_ROLE, Constants.BLOG_ADMIN_ROLE}, new HashMap<String,String>(), true);
52  10 createUser(defaultUser);
53    }
54    } catch (SecurityRealmException e) {
55  0 log.error("Error while creating security realm", e);
56    }
57   
58    }
59   
60    /**
61    * Looks up and returns a collection of all users.
62    *
63    * @return a Collection of PebbleUserDetails objects
64    */
 
65  0 toggle public synchronized Collection<PebbleUserDetails> getUsers() throws SecurityRealmException {
66  0 LinkedList<PebbleUserDetails> users = new LinkedList<PebbleUserDetails>();
67  0 File realm = getFileForRealm();
68  0 File files[] = realm.listFiles(new FilenameFilter() {
69    /**
70    * Tests if a specified file should be included in a file list.
71    *
72    * @param dir the directory in which the file was found.
73    * @param name the name of the file.
74    * @return <code>true</code> if and only if the name should be
75    * included in the file list; <code>false</code> otherwise.
76    */
 
77  0 toggle public boolean accept(File dir, String name) {
78  0 return name.endsWith(".properties");
79    }
80    });
81   
82  0 for (File file : files) {
83  0 PebbleUserDetails pud = getUser(file.getName().substring(0, file.getName().lastIndexOf(".")));
84  0 if (pud != null) {
85  0 users.add(pud);
86    }
87    }
88   
89  0 Collections.sort(users, new PebbleUserDetailsComparator());
90   
91  0 return users;
92    }
93   
94    /**
95    * Looks up and returns user details for the given username.
96    *
97    * @param username the username to find details for
98    * @return a PebbleUserDetails instance
99    *
100    */
 
101  40 toggle public synchronized PebbleUserDetails getUser(String username) throws SecurityRealmException {
102  40 File user = getFileForUser(username);
103  40 if (!user.exists()) {
104  36 return null;
105    }
106   
107  4 try {
108  4 FileInputStream in = new FileInputStream(user);
109  4 Properties props = new Properties();
110  4 props.load(in);
111  4 in.close();
112   
113  4 String password = props.getProperty(PASSWORD);
114  4 String[] roles = props.getProperty(ROLES).split(",");
115  4 String name = props.getProperty(NAME);
116  4 String emailAddress = props.getProperty(EMAIL_ADDRESS);
117  4 String website = props.getProperty(WEBSITE);
118  4 String profile = props.getProperty(PROFILE);
119  4 String detailsUpdateableAsString = props.getProperty(DETAILS_UPDATEABLE);
120  4 boolean detailsUpdateable = true;
121  4 if (detailsUpdateableAsString != null) {
122  4 detailsUpdateable = detailsUpdateableAsString.equalsIgnoreCase("true");
123    }
124   
125  4 Map<String,String> preferences = new HashMap<String,String>();
126  4 for (Object key : props.keySet()) {
127  30 String propertyName = (String)key;
128  30 if (propertyName.startsWith(PREFERENCE)) {
129  2 preferences.put(propertyName.substring(PREFERENCE.length()), props.getProperty(propertyName));
130    }
131    }
132   
133  4 return new PebbleUserDetails(username, password, name, emailAddress, website, profile, roles, preferences, detailsUpdateable);
134    } catch (IOException ioe) {
135  0 throw new SecurityRealmException(ioe);
136    }
137    }
138   
139    /**
140    * Creates a new user.
141    *
142    * @param pud a PebbleUserDetails instance
143    */
 
144  14 toggle public synchronized void createUser(PebbleUserDetails pud) throws SecurityRealmException {
145  14 if (getUser(pud.getUsername()) == null) {
146  14 updateUser(pud, true);
147    } else {
148  0 throw new SecurityRealmException("User " + pud.getUsername() + " already exists");
149    }
150    }
151   
152    /**
153    * Updates user details.
154    *
155    * @param pud a PebbleUserDetails instance
156    */
 
157  0 toggle public synchronized void updateUser(PebbleUserDetails pud) throws SecurityRealmException {
158  0 updateUser(pud, false);
159    }
160   
161    /**
162    * Updates user details, except for the password
163    *
164    * @param pud a PebbleUserDetails instance
165    */
 
166  14 toggle private void updateUser(PebbleUserDetails pud, boolean updatePassword) throws SecurityRealmException {
167  14 File user = getFileForUser(pud.getUsername());
168  14 PebbleUserDetails currentDetails = getUser(pud.getUsername());
169   
170  14 Properties props = new Properties();
171  14 if (updatePassword) {
172  14 props.setProperty(DefaultSecurityRealm.PASSWORD, passwordEncoder.encodePassword(pud.getPassword(), saltSource.getSalt(pud)));
173    } else {
174  0 props.setProperty(DefaultSecurityRealm.PASSWORD, currentDetails.getPassword());
175    }
176  14 props.setProperty(DefaultSecurityRealm.ROLES, pud.getRolesAsString());
177  14 props.setProperty(DefaultSecurityRealm.NAME, pud.getName());
178  14 props.setProperty(DefaultSecurityRealm.EMAIL_ADDRESS, pud.getEmailAddress());
179  14 props.setProperty(DefaultSecurityRealm.WEBSITE, pud.getWebsite());
180  14 props.setProperty(DefaultSecurityRealm.PROFILE, pud.getProfile());
181  14 props.setProperty(DefaultSecurityRealm.DETAILS_UPDATEABLE, "" + pud.isDetailsUpdateable());
182   
183  14 Map<String,String> preferences = pud.getPreferences();
184  14 for (String preference : preferences.keySet()) {
185  2 props.setProperty(DefaultSecurityRealm.PREFERENCE + preference, preferences.get(preference));
186    }
187   
188  14 try {
189  14 FileOutputStream out = new FileOutputStream(user);
190  14 props.store(out, "User : " + pud.getUsername());
191  14 out.flush();
192  14 out.close();
193    } catch (IOException ioe) {
194  0 throw new SecurityRealmException(ioe);
195    }
196    }
197   
198    /**
199    * Changes a user's password.
200    *
201    * @param username the username of the user
202    * @param password the new password
203    * @throws SecurityRealmException
204    */
 
205  0 toggle public synchronized void changePassword(String username, String password) throws SecurityRealmException {
206  0 PebbleUserDetails pud = getUser(username);
207  0 if (pud != null) {
208  0 pud.setPassword(password);
209  0 updateUser(pud, true);
210    }
211    }
212   
213    /**
214    * Removes user details for the given username.
215    *
216    * @param username the username of the user to remove
217    */
 
218  14 toggle public synchronized void removeUser(String username) throws SecurityRealmException {
219  14 File user = getFileForUser(username);
220  14 if (user.exists()) {
221  2 user.delete();
222    }
223   
224  14 if (user.exists()) {
225  0 throw new SecurityRealmException("User " + username + " could not be deleted");
226    }
227    }
228   
 
229  78 toggle protected File getFileForRealm() throws SecurityRealmException {
230    // find the directory and file corresponding to the user, of the form
231    // ${pebbleContext.dataDirectory}/realm/${username}.properties
232  78 return new File(configuration.getDataDirectory(), DefaultSecurityRealm.REALM_DIRECTORY_NAME);
233    }
234   
 
235  68 toggle protected File getFileForUser(String username) throws SecurityRealmException {
236    // find the directory and file corresponding to the user, of the form
237    // ${pebbleContext.dataDirectory}/realm/${username}.properties
238  68 return new File(getFileForRealm(), username + ".properties");
239    }
240   
 
241  0 toggle public Configuration getConfiguration() {
242  0 return configuration;
243    }
244   
 
245  10 toggle public void setConfiguration(Configuration configuration) {
246  10 this.configuration = configuration;
247    }
248   
 
249  2 toggle public PasswordEncoder getPasswordEncoder() {
250  2 return passwordEncoder;
251    }
252   
 
253  10 toggle public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
254  10 this.passwordEncoder = passwordEncoder;
255    }
256   
 
257  2 toggle public SaltSource getSaltSource() {
258  2 return saltSource;
259    }
260   
 
261  10 toggle public void setSaltSource(SaltSource saltSource) {
262  10 this.saltSource = saltSource;
263    }
264   
265    }