defaultsecurityrealm.java

### 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