<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>PropertiesRealm.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: Jar Bundle</a> &gt; <a href="../index.html" class="el_bundle">shiro-core</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.realm.text</a> &gt; <span class="el_source">PropertiesRealm.java</span></div><h1>PropertiesRealm.java</h1><pre class="source lang-java linenums">/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * &quot;License&quot;); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.shiro.realm.text;

import org.apache.shiro.ShiroException;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.util.Destroyable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * A {@link TextConfigurationRealm} that defers all logic to the parent class, but just enables
 * {@link java.util.Properties Properties} based configuration in addition to the parent class's String configuration.
 * &lt;p/&gt;
 * This class allows processing of a single .properties file for user, role, and
 * permission configuration.
 * &lt;p/&gt;
 * The {@link #setResourcePath resourcePath} &lt;em&gt;MUST&lt;/em&gt; be set before this realm can be initialized.  You
 * can specify any resource path supported by
 * {@link ResourceUtils#getInputStreamForPath(String) ResourceUtils.getInputStreamForPath} method.
 * &lt;p/&gt;
 * The Properties format understood by this implementation must be written as follows:
 * &lt;p/&gt;
 * Each line's key/value pair represents either a user-to-role(s) mapping &lt;em&gt;or&lt;/em&gt; a role-to-permission(s)
 * mapping.
 * &lt;p/&gt;
 * The user-to-role(s) lines have this format:&lt;/p&gt;
 * &lt;p/&gt;
 * &lt;code&gt;&lt;b&gt;user.&lt;/b&gt;&lt;em&gt;username&lt;/em&gt; = &lt;em&gt;password&lt;/em&gt;,role1,role2,...&lt;/code&gt;&lt;/p&gt;
 * &lt;p/&gt;
 * Note that each key is prefixed with the token &lt;b&gt;{@code user.}&lt;/b&gt;  Each value must adhere to the
 * the {@link #setUserDefinitions(String) setUserDefinitions(String)} JavaDoc.
 * &lt;p/&gt;
 * The role-to-permission(s) lines have this format:&lt;/p&gt;
 * &lt;p/&gt;
 * &lt;code&gt;&lt;b&gt;role.&lt;/b&gt;&lt;em&gt;rolename&lt;/em&gt; = &lt;em&gt;permissionDefinition1&lt;/em&gt;, &lt;em&gt;permissionDefinition2&lt;/em&gt;, ...&lt;/code&gt;
 * &lt;p/&gt;
 * where each key is prefixed with the token &lt;b&gt;{@code role.}&lt;/b&gt; and the value adheres to the format specified in
 * the {@link #setRoleDefinitions(String) setRoleDefinitions(String)} JavaDoc.
 * &lt;p/&gt;
 * Here is an example of a very simple properties definition that conforms to the above format rules and corresponding
 * method JavaDocs:
 * &lt;p/&gt;
 * &lt;code&gt;user.root = &lt;em&gt;rootPassword&lt;/em&gt;,administrator&lt;br/&gt;
 * user.jsmith = &lt;em&gt;jsmithPassword&lt;/em&gt;,manager,engineer,employee&lt;br/&gt;
 * user.abrown = &lt;em&gt;abrownPassword&lt;/em&gt;,qa,employee&lt;br/&gt;
 * user.djones = &lt;em&gt;djonesPassword&lt;/em&gt;,qa,contractor&lt;br/&gt;
 * &lt;br/&gt;
 * role.administrator = *&lt;br/&gt;
 * role.manager = &amp;quot;user:read,write&amp;quot;, file:execute:/usr/local/emailManagers.sh&lt;br/&gt;
 * role.engineer = &amp;quot;file:read,execute:/usr/local/tomcat/bin/startup.sh&amp;quot;&lt;br/&gt;
 * role.employee = application:use:wiki&lt;br/&gt;
 * role.qa = &amp;quot;server:view,start,shutdown,restart:someQaServer&amp;quot;, server:view:someProductionServer&lt;br/&gt;
 * role.contractor = application:use:timesheet&lt;/code&gt;
 *
 * @since 0.2
 */
public class PropertiesRealm extends TextConfigurationRealm implements Destroyable, Runnable {

    //TODO - complete JavaDoc

    /*-------------------------------------------
    |             C O N S T A N T S             |
    ============================================*/
    private static final int DEFAULT_RELOAD_INTERVAL_SECONDS = 10;
    private static final String USERNAME_PREFIX = &quot;user.&quot;;
    private static final String ROLENAME_PREFIX = &quot;role.&quot;;
    private static final String DEFAULT_RESOURCE_PATH = &quot;classpath:shiro-users.properties&quot;;

    /*-------------------------------------------
    |    I N S T A N C E   V A R I A B L E S    |
    ============================================*/
<span class="fc" id="L99">    private static final Logger log = LoggerFactory.getLogger(PropertiesRealm.class);</span>

<span class="fc" id="L101">    protected ExecutorService scheduler = null;</span>
<span class="fc" id="L102">    protected boolean useXmlFormat = false;</span>
<span class="fc" id="L103">    protected String resourcePath = DEFAULT_RESOURCE_PATH;</span>
    protected long fileLastModified;
<span class="fc" id="L105">    protected int reloadIntervalSeconds = DEFAULT_RELOAD_INTERVAL_SECONDS;</span>

    public PropertiesRealm() {
<span class="fc" id="L108">        super();</span>
<span class="fc" id="L109">    }</span>

    /*--------------------------------------------
    |  A C C E S S O R S / M O D I F I E R S    |
    ============================================*/

    /**
     * Determines whether or not the properties XML format should be used.  For more information, see
     * {@link Properties#loadFromXML(java.io.InputStream)}
     *
     * @param useXmlFormat true to use XML or false to use the normal format.  Defaults to false.
     */
    public void setUseXmlFormat(boolean useXmlFormat) {
<span class="nc" id="L122">        this.useXmlFormat = useXmlFormat;</span>
<span class="nc" id="L123">    }</span>

    /**
     * Sets the path of the properties file to load user, role, and permission information from.  The properties
     * file will be loaded using {@link ResourceUtils#getInputStreamForPath(String)} so any convention recongized
     * by that method is accepted here.  For example, to load a file from the classpath use
     * {@code classpath:myfile.properties}; to load a file from disk simply specify the full path; to load
     * a file from a URL use {@code url:www.mysite.com/myfile.properties}.
     *
     * @param resourcePath the path to load the properties file from.  This is a required property.
     */
    public void setResourcePath(String resourcePath) {
<span class="fc" id="L135">        this.resourcePath = resourcePath;</span>
<span class="fc" id="L136">    }</span>

    /**
     * Sets the interval in seconds at which the property file will be checked for changes and reloaded.  If this is
     * set to zero or less, property file reloading will be disabled.  If it is set to 1 or greater, then a
     * separate thread will be created to monitor the propery file for changes and reload the file if it is updated.
     *
     * @param reloadIntervalSeconds the interval in seconds at which the property file should be examined for changes.
     *                              If set to zero or less, reloading is disabled.
     */
    public void setReloadIntervalSeconds(int reloadIntervalSeconds) {
<span class="nc" id="L147">        this.reloadIntervalSeconds = reloadIntervalSeconds;</span>
<span class="nc" id="L148">    }</span>

    /*--------------------------------------------
    |               M E T H O D S               |
    ============================================*/

    @Override
    public void onInit() {
<span class="fc" id="L156">        super.onInit();</span>
        //TODO - cleanup - this method shouldn't be necessary
<span class="fc" id="L158">        afterRoleCacheSet();</span>
<span class="fc" id="L159">    }</span>

    protected void afterRoleCacheSet() {
<span class="fc" id="L162">        loadProperties();</span>
        //we can only determine if files have been modified at runtime (not classpath entries or urls), so only
        //start the thread in this case:
<span class="pc bpc" id="L165" title="3 of 4 branches missed.">        if (this.resourcePath.startsWith(ResourceUtils.FILE_PREFIX) &amp;&amp; scheduler == null) {</span>
<span class="nc" id="L166">            startReloadThread();</span>
        }
<span class="fc" id="L168">    }</span>

    /**
     * Destroy reload scheduler if one exists.
     */
    public void destroy() {
        try {
<span class="nc bnc" id="L175" title="All 2 branches missed.">            if (scheduler != null) {</span>
<span class="nc" id="L176">                scheduler.shutdown();</span>
            }
<span class="nc" id="L178">        } catch (Exception e) {</span>
<span class="nc bnc" id="L179" title="All 2 branches missed.">            if (log.isInfoEnabled()) {</span>
<span class="nc" id="L180">                log.info(&quot;Unable to cleanly shutdown Scheduler.  Ignoring (shutting down)...&quot;, e);</span>
            }
        } finally {
<span class="nc" id="L183">            scheduler = null;</span>
<span class="nc" id="L184">        }</span>
<span class="nc" id="L185">    }</span>

    protected void startReloadThread() {
<span class="nc bnc" id="L188" title="All 2 branches missed.">        if (this.reloadIntervalSeconds &gt; 0) {</span>
<span class="nc" id="L189">            this.scheduler = Executors.newSingleThreadScheduledExecutor();</span>
<span class="nc" id="L190">            ((ScheduledExecutorService) this.scheduler).scheduleAtFixedRate(this, reloadIntervalSeconds, reloadIntervalSeconds, TimeUnit.SECONDS);</span>
        }
<span class="nc" id="L192">    }</span>

    public void run() {
        try {
<span class="nc" id="L196">            reloadPropertiesIfNecessary();</span>
<span class="nc" id="L197">        } catch (Exception e) {</span>
<span class="nc bnc" id="L198" title="All 2 branches missed.">            if (log.isErrorEnabled()) {</span>
<span class="nc" id="L199">                log.error(&quot;Error while reloading property files for realm.&quot;, e);</span>
            }
<span class="nc" id="L201">        }</span>
<span class="nc" id="L202">    }</span>

    private void loadProperties() {
<span class="pc bpc" id="L205" title="2 of 4 branches missed.">        if (resourcePath == null || resourcePath.length() == 0) {</span>
<span class="nc" id="L206">            throw new IllegalStateException(&quot;The resourcePath property is not set.  &quot; +</span>
                    &quot;It must be set prior to this realm being initialized.&quot;);
        }

<span class="pc bpc" id="L210" title="1 of 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="fc" id="L211">            log.debug(&quot;Loading user security information from file [&quot; + resourcePath + &quot;]...&quot;);</span>
        }

<span class="fc" id="L214">        Properties properties = loadProperties(resourcePath);</span>
<span class="fc" id="L215">        createRealmEntitiesFromProperties(properties);</span>
<span class="fc" id="L216">    }</span>

    private Properties loadProperties(String resourcePath) {
<span class="fc" id="L219">        Properties props = new Properties();</span>

<span class="fc" id="L221">        InputStream is = null;</span>
        try {

<span class="pc bpc" id="L224" title="1 of 2 branches missed.">            if (log.isDebugEnabled()) {</span>
<span class="fc" id="L225">                log.debug(&quot;Opening input stream for path [&quot; + resourcePath + &quot;]...&quot;);</span>
            }

<span class="fc" id="L228">            is = ResourceUtils.getInputStreamForPath(resourcePath);</span>
<span class="pc bpc" id="L229" title="1 of 2 branches missed.">            if (useXmlFormat) {</span>

<span class="nc bnc" id="L231" title="All 2 branches missed.">                if (log.isDebugEnabled()) {</span>
<span class="nc" id="L232">                    log.debug(&quot;Loading properties from path [&quot; + resourcePath + &quot;] in XML format...&quot;);</span>
                }

<span class="nc" id="L235">                props.loadFromXML(is);</span>
            } else {

<span class="pc bpc" id="L238" title="1 of 2 branches missed.">                if (log.isDebugEnabled()) {</span>
<span class="fc" id="L239">                    log.debug(&quot;Loading properties from path [&quot; + resourcePath + &quot;]...&quot;);</span>
                }

<span class="fc" id="L242">                props.load(is);</span>
            }

<span class="nc" id="L245">        } catch (IOException e) {</span>
<span class="nc" id="L246">            throw new ShiroException(&quot;Error reading properties path [&quot; + resourcePath + &quot;].  &quot; +</span>
                    &quot;Initializing of the realm from this file failed.&quot;, e);
        } finally {
<span class="pc" id="L249">            ResourceUtils.close(is);</span>
<span class="fc" id="L250">        }</span>

<span class="fc" id="L252">        return props;</span>
    }


    private void reloadPropertiesIfNecessary() {
<span class="nc bnc" id="L257" title="All 2 branches missed.">        if (isSourceModified()) {</span>
<span class="nc" id="L258">            restart();</span>
        }
<span class="nc" id="L260">    }</span>

    private boolean isSourceModified() {
        //we can only check last modified times on files - classpath and URL entries can't tell us modification times
<span class="nc bnc" id="L264" title="All 4 branches missed.">        return this.resourcePath.startsWith(ResourceUtils.FILE_PREFIX) &amp;&amp; isFileModified();</span>
    }

    private boolean isFileModified() {
        //SHIRO-394: strip file prefix before constructing the File instance:
<span class="nc" id="L269">        String fileNameWithoutPrefix = this.resourcePath.substring(this.resourcePath.indexOf(&quot;:&quot;) + 1);</span>
<span class="nc" id="L270">        File propertyFile = new File(fileNameWithoutPrefix);</span>
<span class="nc" id="L271">        long currentLastModified = propertyFile.lastModified();</span>
<span class="nc bnc" id="L272" title="All 2 branches missed.">        if (currentLastModified &gt; this.fileLastModified) {</span>
<span class="nc" id="L273">            this.fileLastModified = currentLastModified;</span>
<span class="nc" id="L274">            return true;</span>
        } else {
<span class="nc" id="L276">            return false;</span>
        }
    }

    @SuppressWarnings(&quot;unchecked&quot;)
    private void restart() {
<span class="nc bnc" id="L282" title="All 4 branches missed.">        if (resourcePath == null || resourcePath.length() == 0) {</span>
<span class="nc" id="L283">            throw new IllegalStateException(&quot;The resourcePath property is not set.  &quot; +</span>
                    &quot;It must be set prior to this realm being initialized.&quot;);
        }

<span class="nc bnc" id="L287" title="All 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="nc" id="L288">            log.debug(&quot;Loading user security information from file [&quot; + resourcePath + &quot;]...&quot;);</span>
        }

        try {
<span class="nc" id="L292">            destroy();</span>
<span class="nc" id="L293">        } catch (Exception e) {</span>
            //ignored
<span class="nc" id="L295">        }</span>
<span class="nc" id="L296">        init();</span>
<span class="nc" id="L297">    }</span>

    @SuppressWarnings(&quot;unchecked&quot;)
    private void createRealmEntitiesFromProperties(Properties properties) {

<span class="fc" id="L302">        StringBuilder userDefs = new StringBuilder();</span>
<span class="fc" id="L303">        StringBuilder roleDefs = new StringBuilder();</span>

<span class="fc" id="L305">        Enumeration&lt;String&gt; propNames = (Enumeration&lt;String&gt;) properties.propertyNames();</span>

<span class="fc bfc" id="L307" title="All 2 branches covered.">        while (propNames.hasMoreElements()) {</span>

<span class="fc" id="L309">            String key = propNames.nextElement().trim();</span>
<span class="fc" id="L310">            String value = properties.getProperty(key).trim();</span>
<span class="pc bpc" id="L311" title="1 of 2 branches missed.">            if (log.isTraceEnabled()) {</span>
<span class="fc" id="L312">                log.trace(&quot;Processing properties line - key: [&quot; + key + &quot;], value: [&quot; + value + &quot;].&quot;);</span>
            }

<span class="fc bfc" id="L315" title="All 2 branches covered.">            if (isUsername(key)) {</span>
<span class="fc" id="L316">                String username = getUsername(key);</span>
<span class="fc" id="L317">                userDefs.append(username).append(&quot; = &quot;).append(value).append(&quot;\n&quot;);</span>
<span class="pc bpc" id="L318" title="1 of 2 branches missed.">            } else if (isRolename(key)) {</span>
<span class="fc" id="L319">                String rolename = getRolename(key);</span>
<span class="fc" id="L320">                roleDefs.append(rolename).append(&quot; = &quot;).append(value).append(&quot;\n&quot;);</span>
<span class="fc" id="L321">            } else {</span>
<span class="nc" id="L322">                String msg = &quot;Encountered unexpected key/value pair.  All keys must be prefixed with either '&quot; +</span>
                        USERNAME_PREFIX + &quot;' or '&quot; + ROLENAME_PREFIX + &quot;'.&quot;;
<span class="nc" id="L324">                throw new IllegalStateException(msg);</span>
            }
<span class="fc" id="L326">        }</span>

<span class="fc" id="L328">        setUserDefinitions(userDefs.toString());</span>
<span class="fc" id="L329">        setRoleDefinitions(roleDefs.toString());</span>
<span class="fc" id="L330">        processDefinitions();</span>
<span class="fc" id="L331">    }</span>

    protected String getName(String key, String prefix) {
<span class="fc" id="L334">        return key.substring(prefix.length(), key.length());</span>
    }

    protected boolean isUsername(String key) {
<span class="pc bpc" id="L338" title="1 of 4 branches missed.">        return key != null &amp;&amp; key.startsWith(USERNAME_PREFIX);</span>
    }

    protected boolean isRolename(String key) {
<span class="pc bpc" id="L342" title="2 of 4 branches missed.">        return key != null &amp;&amp; key.startsWith(ROLENAME_PREFIX);</span>
    }

    protected String getUsername(String key) {
<span class="fc" id="L346">        return getName(key, USERNAME_PREFIX);</span>
    }

    protected String getRolename(String key) {
<span class="fc" id="L350">        return getName(key, ROLENAME_PREFIX);</span>
    }
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html>