File Source: defaultsecurityrealm.java

         /* 
    P/P   *  Method: void net.sourceforge.pebble.security.DefaultSecurityRealm$1(DefaultSecurityRealm)
          */
     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   */
         /* 
    P/P   *  Method: void net.sourceforge.pebble.security.DefaultSecurityRealm()
          */
    20  public class DefaultSecurityRealm implements SecurityRealm {
    21  
           /* 
    P/P     *  Method: net.sourceforge.pebble.security.DefaultSecurityRealm__static_init
            * 
            *  Postconditions:
            *    init'ed(log)
            */
    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    public void init() {
    45      try {
               /* 
    P/P         *  Method: void init()
                * 
                *  Preconditions:
                *    (soft) this.configuration != null
                *    (soft) this.passwordEncoder != null
                *    (soft) this.saltSource != null
                * 
                *  Presumptions:
                *    org.apache.commons.logging.LogFactory:getLog(...)@22 != null
                *    defaultUser.grantedAuthories.length <= 232-1
                *    defaultUser.grantedAuthories[...] != null
                *    java.util.Set:toArray(...)@194 != null
                *    net.sourceforge.pebble.Constants.BLOG_ADMIN_ROLE != null
                *    ...
                * 
                *  Test Vectors:
                *    java.io.File:exists(...)@47: {1}, {0}
                */
    46        File realm = getFileForRealm();
    47        if (!realm.exists()) {
    48          realm.mkdirs();
    49          log.warn("*** Creating default user (username/password)");
    50          log.warn("*** Don't forget to delete this user in a production deployment!");
    51          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          createUser(defaultUser);
    53        }
    54      } catch (SecurityRealmException e) {
    55        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    public synchronized Collection<PebbleUserDetails> getUsers() throws SecurityRealmException {
             /* 
    P/P       *  Method: Collection getUsers()
              * 
              *  Preconditions:
              *    this.configuration != null
              * 
              *  Presumptions:
              *    Local_7[Local_5]@68 != null
              *    files.length@68 <= 232-1
              *    java.io.File:getName(...)@83 != null
              *    java.io.File:listFiles(...)@68 != null
              * 
              *  Postconditions:
              *    return_value == &new LinkedList(getUsers#1)
              *    new LinkedList(getUsers#1) num objects == 1
              */
    66      LinkedList<PebbleUserDetails> users = new LinkedList<PebbleUserDetails>();
    67      File realm = getFileForRealm();
    68      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        public boolean accept(File dir, String name) {
                 /* 
    P/P           *  Method: bool accept(File, String)
                  * 
                  *  Preconditions:
                  *    name != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
    78          return name.endsWith(".properties");
    79        }
    80      });
    81  
    82      for (File file : files) {
    83        PebbleUserDetails pud = getUser(file.getName().substring(0, file.getName().lastIndexOf(".")));
    84        if (pud != null) {
    85          users.add(pud);
    86        }
    87      }
    88  
    89      Collections.sort(users, new PebbleUserDetailsComparator());
    90  
    91      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    public synchronized PebbleUserDetails getUser(String username) throws SecurityRealmException {
             /* 
    P/P       *  Method: PebbleUserDetails getUser(String)
              * 
              *  Preconditions:
              *    this.configuration != null
              * 
              *  Presumptions:
              *    java.util.Iterator:next(...)@126 != null
              *    java.util.Properties:getProperty(...)@114 != null
              *    java.util.Properties:keySet(...)@126 != null
              *    roles.length@114 <= 232-1
              *    roles[...]@114 != null
              * 
              *  Postconditions:
              *    return_value in Addr_Set{null,&new PebbleUserDetails(getUser#4)}
              *    new HashMap(PebbleUserDetails#1) num objects <= 1
              *    new HashMap(getUser#3) num objects <= 1
              *    new PebbleUserDetails(getUser#4) num objects <= 1
              *    init'ed(new PebbleUserDetails(getUser#4).detailsUpdateable)
              *    init'ed(new PebbleUserDetails(getUser#4).emailAddress)
              *    init'ed(new PebbleUserDetails(getUser#4).grantedAuthories)
              *    init'ed(new PebbleUserDetails(getUser#4).name)
              *    init'ed(new PebbleUserDetails(getUser#4).password)
              *    new PebbleUserDetails(getUser#4).preferences == &new HashMap(getUser#3)
              *    ...
              * 
              *  Test Vectors:
              *    java.io.File:exists(...)@103: {1}, {0}
              *    java.lang.String:startsWith(...)@128: {0}, {1}
              *    java.util.Iterator:hasNext(...)@126: {1}, {0}
              *    java.util.Properties:getProperty(...)@119: Addr_Set{null}, Inverse{null}
              */
   102      File user = getFileForUser(username);
   103      if (!user.exists()) {
   104        return null;
   105      }
   106  
   107      try {
   108        FileInputStream in = new FileInputStream(user);
   109        Properties props = new Properties();
   110        props.load(in);
   111        in.close();
   112  
   113        String password = props.getProperty(PASSWORD);
   114        String[] roles = props.getProperty(ROLES).split(",");
   115        String name = props.getProperty(NAME);
   116        String emailAddress = props.getProperty(EMAIL_ADDRESS);
   117        String website = props.getProperty(WEBSITE);
   118        String profile = props.getProperty(PROFILE);
   119        String detailsUpdateableAsString = props.getProperty(DETAILS_UPDATEABLE);
   120        boolean detailsUpdateable = true;
   121        if (detailsUpdateableAsString != null) {
   122          detailsUpdateable = detailsUpdateableAsString.equalsIgnoreCase("true");
   123        }
   124  
   125        Map<String,String> preferences = new HashMap<String,String>();
   126        for (Object key : props.keySet()) {
   127          String propertyName = (String)key;
   128          if (propertyName.startsWith(PREFERENCE)) {
   129            preferences.put(propertyName.substring(PREFERENCE.length()), props.getProperty(propertyName));          
   130          }
   131        }
   132  
   133        return new PebbleUserDetails(username, password, name, emailAddress, website, profile, roles, preferences, detailsUpdateable);
   134      } catch (IOException ioe) {
   135        throw new SecurityRealmException(ioe);
   136      }
   137    }
   138  
   139    /**
   140     * Creates a new user.
   141     *
   142     * @param pud   a PebbleUserDetails instance
   143     */
   144    public synchronized void createUser(PebbleUserDetails pud) throws SecurityRealmException {
             /* 
    P/P       *  Method: void createUser(PebbleUserDetails)
              * 
              *  Preconditions:
              *    pud != null
              *    init'ed(pud.username)
              *    this.configuration != null
              * 
              *  Presumptions:
              *    java.io.File:exists(...)@103 == 0
              * 
              *  Preconditions:
              *    init'ed(pud.detailsUpdateable)
              *    init'ed(pud.emailAddress)
              *    pud.grantedAuthories != null
              *    pud.grantedAuthories.length <= 232-1
              *    init'ed(pud.name)
              *    init'ed(pud.preferences)
              *    init'ed(pud.profile)
              *    init'ed(pud.website)
              *    (soft) pud.grantedAuthories[...] != null
              *    (soft) init'ed(pud.password)
              *    ...
              */
   145      if (getUser(pud.getUsername()) == null) {
   146        updateUser(pud, true);
   147      } else {
   148        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    public synchronized void updateUser(PebbleUserDetails pud) throws SecurityRealmException {
             /* 
    P/P       *  Method: void updateUser(PebbleUserDetails)
              * 
              *  Preconditions:
              *    pud != null
              *    init'ed(pud.detailsUpdateable)
              *    init'ed(pud.emailAddress)
              *    pud.grantedAuthories != null
              *    pud.grantedAuthories.length <= 232-1
              *    init'ed(pud.name)
              *    init'ed(pud.preferences)
              *    init'ed(pud.profile)
              *    init'ed(pud.username)
              *    init'ed(pud.website)
              *    ...
              */
   158      updateUser(pud, false);
   159    }
   160  
   161    /**
   162     * Updates user details, except for the password
   163     *
   164     * @param pud   a PebbleUserDetails instance
   165     */
   166    private void updateUser(PebbleUserDetails pud, boolean updatePassword) throws SecurityRealmException {
   167      File user = getFileForUser(pud.getUsername());
   168      PebbleUserDetails currentDetails = getUser(pud.getUsername());
   169  
   170      Properties props = new Properties();
   171      if (updatePassword) {
               /* 
    P/P         *  Method: void updateUser(PebbleUserDetails, bool)
                * 
                *  Preconditions:
                *    pud != null
                *    init'ed(pud.detailsUpdateable)
                *    init'ed(pud.emailAddress)
                *    pud.grantedAuthories != null
                *    pud.grantedAuthories.length <= 232-1
                *    init'ed(pud.name)
                *    init'ed(pud.preferences)
                *    init'ed(pud.profile)
                *    init'ed(pud.username)
                *    init'ed(pud.website)
                *    ...
                * 
                *  Presumptions:
                *    java.io.File:exists(...)@103 == 1
                *    java.util.Iterator:hasNext(...)@126 == 0
                *    java.util.Map:keySet(...)@184 != null
                * 
                *  Test Vectors:
                *    updatePassword: {0}, {1}
                *    java.util.Iterator:hasNext(...)@184: {1}, {0}
                */
   172        props.setProperty(DefaultSecurityRealm.PASSWORD, passwordEncoder.encodePassword(pud.getPassword(), saltSource.getSalt(pud)));
   173      } else {
   174        props.setProperty(DefaultSecurityRealm.PASSWORD, currentDetails.getPassword());
   175      }
   176      props.setProperty(DefaultSecurityRealm.ROLES, pud.getRolesAsString());
   177      props.setProperty(DefaultSecurityRealm.NAME, pud.getName());
   178      props.setProperty(DefaultSecurityRealm.EMAIL_ADDRESS, pud.getEmailAddress());
   179      props.setProperty(DefaultSecurityRealm.WEBSITE, pud.getWebsite());
   180      props.setProperty(DefaultSecurityRealm.PROFILE, pud.getProfile());
   181      props.setProperty(DefaultSecurityRealm.DETAILS_UPDATEABLE, "" + pud.isDetailsUpdateable());
   182  
   183      Map<String,String> preferences = pud.getPreferences();
   184      for (String preference : preferences.keySet()) {
   185        props.setProperty(DefaultSecurityRealm.PREFERENCE + preference, preferences.get(preference));
   186      }
   187  
   188      try {
   189        FileOutputStream out = new FileOutputStream(user);
   190        props.store(out, "User : " + pud.getUsername());
   191        out.flush();
   192        out.close();
   193      } catch (IOException ioe) {
   194        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    public synchronized void changePassword(String username, String password) throws SecurityRealmException {
             /* 
    P/P       *  Method: void changePassword(String, String)
              * 
              *  Preconditions:
              *    (soft) this.configuration != null
              *    (soft) this.passwordEncoder != null
              *    (soft) this.saltSource != null
              * 
              *  Presumptions:
              *    pud.grantedAuthories.length@206 <= 232-1
              *    pud.grantedAuthories[...]@206 != null
              */
   206      PebbleUserDetails pud = getUser(username);
   207      if (pud != null) {
   208        pud.setPassword(password);
+  209        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    public synchronized void removeUser(String username) throws SecurityRealmException {
             /* 
    P/P       *  Method: void removeUser(String)
              * 
              *  Preconditions:
              *    this.configuration != null
              * 
              *  Presumptions:
              *    java.io.File:exists(...)@224 == 0
              * 
              *  Test Vectors:
              *    java.io.File:exists(...)@220: {0}, {1}
              */
   219      File user = getFileForUser(username);
   220      if (user.exists()) {
   221        user.delete();
   222      }
   223  
   224      if (user.exists()) {
   225        throw new SecurityRealmException("User " + username + " could not be deleted");
   226      }
   227    }
   228  
   229    protected File getFileForRealm() throws SecurityRealmException {
   230      // find the directory and file corresponding to the user, of the form
   231      // ${pebbleContext.dataDirectory}/realm/${username}.properties
             /* 
    P/P       *  Method: File getFileForRealm()
              * 
              *  Preconditions:
              *    this.configuration != null
              * 
              *  Postconditions:
              *    return_value == &new File(getFileForRealm#1)
              *    new File(getFileForRealm#1) num objects == 1
              */
   232      return new File(configuration.getDataDirectory(), DefaultSecurityRealm.REALM_DIRECTORY_NAME);
   233    }
   234  
   235    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
             /* 
    P/P       *  Method: File getFileForUser(String)
              * 
              *  Preconditions:
              *    this.configuration != null
              * 
              *  Postconditions:
              *    return_value == &new File(getFileForUser#1)
              *    new File(getFileForUser#1) num objects == 1
              */
   238      return new File(getFileForRealm(), username + ".properties");
   239    }
   240  
   241    public Configuration getConfiguration() {
             /* 
    P/P       *  Method: Configuration getConfiguration()
              * 
              *  Preconditions:
              *    init'ed(this.configuration)
              * 
              *  Postconditions:
              *    return_value == this.configuration
              *    init'ed(return_value)
              */
   242      return configuration;
   243    }
   244  
   245    public void setConfiguration(Configuration configuration) {
             /* 
    P/P       *  Method: void setConfiguration(Configuration)
              * 
              *  Postconditions:
              *    this.configuration == configuration
              *    init'ed(this.configuration)
              */
   246      this.configuration = configuration;
   247    }
   248  
   249    public PasswordEncoder getPasswordEncoder() {
             /* 
    P/P       *  Method: PasswordEncoder getPasswordEncoder()
              * 
              *  Preconditions:
              *    init'ed(this.passwordEncoder)
              * 
              *  Postconditions:
              *    return_value == this.passwordEncoder
              *    init'ed(return_value)
              */
   250      return passwordEncoder;
   251    }
   252  
   253    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
             /* 
    P/P       *  Method: void setPasswordEncoder(PasswordEncoder)
              * 
              *  Postconditions:
              *    this.passwordEncoder == passwordEncoder
              *    init'ed(this.passwordEncoder)
              */
   254      this.passwordEncoder = passwordEncoder;
   255    }
   256  
   257    public SaltSource getSaltSource() {
             /* 
    P/P       *  Method: SaltSource getSaltSource()
              * 
              *  Preconditions:
              *    init'ed(this.saltSource)
              * 
              *  Postconditions:
              *    return_value == this.saltSource
              *    init'ed(return_value)
              */
   258      return saltSource;
   259    }
   260  
   261    public void setSaltSource(SaltSource saltSource) {
             /* 
    P/P       *  Method: void setSaltSource(SaltSource)
              * 
              *  Postconditions:
              *    this.saltSource == saltSource
              *    init'ed(this.saltSource)
              */
   262      this.saltSource = saltSource;
   263    }
   264  
   265  }








SofCheck Inspector Build Version : 2.22510
defaultsecurityrealm.java 2010-Jun-25 19:40:32
defaultsecurityrealm.class 2010-Jul-19 20:23:38
defaultsecurityrealm$1.class 2010-Jul-19 20:23:38