<?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>IniRealm.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 :: Core</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.realm.text</a> &gt; <span class="el_source">IniRealm.java</span></div><h1>IniRealm.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.config.Ini;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A {@link org.apache.shiro.realm.Realm Realm} implementation that creates
 * {@link org.apache.shiro.authc.SimpleAccount SimpleAccount} instances based on
 * {@link Ini} configuration.
 * &lt;p/&gt;
 * This implementation looks for two {@link Ini.Section sections} in the {@code Ini} configuration:
 * &lt;pre&gt;
 * [users]
 * # One or more {@link org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions(String) user definitions}
 * ...
 * [roles]
 * # One or more {@link org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions(String) role definitions}&lt;/pre&gt;
 * &lt;p/&gt;
 * This class also supports setting the {@link #setResourcePath(String) resourcePath} property to create account
 * data from an .ini resource.  This will only be used if there isn't already account data in the Realm.
 *
 * @since 1.0
 */
public class IniRealm extends TextConfigurationRealm {

    public static final String USERS_SECTION_NAME = &quot;users&quot;;
    public static final String ROLES_SECTION_NAME = &quot;roles&quot;;

<span class="fc" id="L50">    private static transient final Logger log = LoggerFactory.getLogger(IniRealm.class);</span>

    private String resourcePath;
    private Ini ini; //reference added in 1.2 for SHIRO-322

    public IniRealm() {
<span class="fc" id="L56">        super();</span>
<span class="fc" id="L57">    }</span>

    /**
     * This constructor will immediately process the definitions in the {@code Ini} argument.  If you need to perform
     * additional configuration before processing (e.g. setting a permissionResolver, etc), do not call this
     * constructor.  Instead, do the following:
     * &lt;ol&gt;
     * &lt;li&gt;Call the default no-arg constructor&lt;/li&gt;
     * &lt;li&gt;Set the Ini instance you wish to use via {@code #setIni}&lt;/li&gt;
     * &lt;li&gt;Set any other configuration properties&lt;/li&gt;
     * &lt;li&gt;Call {@link #init()}&lt;/li&gt;
     * &lt;/ol&gt;
     *
     * @param ini the Ini instance which will be inspected to create accounts, groups and permissions for this realm.
     */
    public IniRealm(Ini ini) {
<span class="fc" id="L73">        this();</span>
<span class="fc" id="L74">        processDefinitions(ini);</span>
<span class="fc" id="L75">    }</span>

    /**
     * This constructor will immediately process the definitions in the {@code Ini} resolved from the specified
     * {@code resourcePath}.  If you need to perform additional configuration before processing (e.g. setting a
     * permissionResolver, etc), do not call this constructor.  Instead, do the following:
     * &lt;ol&gt;
     * &lt;li&gt;Call the default no-arg constructor&lt;/li&gt;
     * &lt;li&gt;Set the Ini instance you wish to use via {@code #setIni}&lt;/li&gt;
     * &lt;li&gt;Set any other configuration properties&lt;/li&gt;
     * &lt;li&gt;Call {@link #init()}&lt;/li&gt;
     * &lt;/ol&gt;
     *
     * @param resourcePath the resource path of the Ini config which will be inspected to create accounts, groups and
     *                     permissions for this realm.
     */
    public IniRealm(String resourcePath) {
<span class="nc" id="L92">        this();</span>
<span class="nc" id="L93">        Ini ini = Ini.fromResourcePath(resourcePath);</span>
<span class="nc" id="L94">        this.ini = ini;</span>
<span class="nc" id="L95">        this.resourcePath = resourcePath;</span>
<span class="nc" id="L96">        processDefinitions(ini);</span>
<span class="nc" id="L97">    }</span>

    public String getResourcePath() {
<span class="fc" id="L100">        return resourcePath;</span>
    }

    public void setResourcePath(String resourcePath) {
<span class="fc" id="L104">        this.resourcePath = resourcePath;</span>
<span class="fc" id="L105">    }</span>

    /**
     * Returns the Ini instance used to configure this realm.  Provided for JavaBeans-style configuration of this
     * realm, particularly useful in Dependency Injection environments.
     * 
     * @return the Ini instance which will be inspected to create accounts, groups and permissions for this realm.
     */
    public Ini getIni() {
<span class="fc" id="L114">        return ini;</span>
    }

    /**
     * Sets the Ini instance used to configure this realm.  Provided for JavaBeans-style configuration of this
     * realm, particularly useful in Dependency Injection environments.
     * 
     * @param ini the Ini instance which will be inspected to create accounts, groups and permissions for this realm.
     */
    public void setIni(Ini ini) {
<span class="fc" id="L124">        this.ini = ini;</span>
<span class="fc" id="L125">    }</span>

    @Override
    protected void onInit() {
<span class="fc" id="L129">        super.onInit();</span>

        // This is an in-memory realm only - no need for an additional cache when we're already
        // as memory-efficient as we can be.
        
<span class="fc" id="L134">        Ini ini = getIni();</span>
<span class="fc" id="L135">        String resourcePath = getResourcePath();</span>
                
<span class="pc bpc" id="L137" title="1 of 4 branches missed.">        if (!CollectionUtils.isEmpty(this.users) || !CollectionUtils.isEmpty(this.roles)) {</span>
<span class="pc bpc" id="L138" title="1 of 2 branches missed.">            if (!CollectionUtils.isEmpty(ini)) {</span>
<span class="fc" id="L139">                log.warn(&quot;Users or Roles are already populated.  Configured Ini instance will be ignored.&quot;);</span>
            }
<span class="pc bpc" id="L141" title="1 of 2 branches missed.">            if (StringUtils.hasText(resourcePath)) {</span>
<span class="nc" id="L142">                log.warn(&quot;Users or Roles are already populated.  resourcePath '{}' will be ignored.&quot;, resourcePath);</span>
            }
            
<span class="fc" id="L145">            log.debug(&quot;Instance is already populated with users or roles.  No additional user/role population &quot; +</span>
                    &quot;will be performed.&quot;);
<span class="fc" id="L147">            return;</span>
        }
        
<span class="fc bfc" id="L150" title="All 2 branches covered.">        if (CollectionUtils.isEmpty(ini)) {</span>
<span class="fc" id="L151">            log.debug(&quot;No INI instance configuration present.  Checking resourcePath...&quot;);</span>
            
<span class="fc bfc" id="L153" title="All 2 branches covered.">            if (StringUtils.hasText(resourcePath)) {</span>
<span class="fc" id="L154">                log.debug(&quot;Resource path {} defined.  Creating INI instance.&quot;, resourcePath);</span>
<span class="fc" id="L155">                ini = Ini.fromResourcePath(resourcePath);</span>
<span class="pc bpc" id="L156" title="1 of 2 branches missed.">                if (!CollectionUtils.isEmpty(ini)) {</span>
<span class="fc" id="L157">                    setIni(ini);</span>
                }
            }
        }
        
<span class="fc bfc" id="L162" title="All 2 branches covered.">        if (CollectionUtils.isEmpty(ini)) {</span>
<span class="fc" id="L163">            String msg = &quot;Ini instance and/or resourcePath resulted in null or empty Ini configuration.  Cannot &quot; +</span>
                    &quot;load account data.&quot;;
<span class="fc" id="L165">            throw new IllegalStateException(msg);</span>
        }

<span class="fc" id="L168">        processDefinitions(ini);</span>
<span class="fc" id="L169">    }</span>

    private void processDefinitions(Ini ini) {
<span class="fc bfc" id="L172" title="All 2 branches covered.">        if (CollectionUtils.isEmpty(ini)) {</span>
<span class="fc" id="L173">            log.warn(&quot;{} defined, but the ini instance is null or empty.&quot;, getClass().getSimpleName());</span>
<span class="fc" id="L174">            return;</span>
        }

<span class="fc" id="L177">        Ini.Section rolesSection = ini.getSection(ROLES_SECTION_NAME);</span>
<span class="fc bfc" id="L178" title="All 2 branches covered.">        if (!CollectionUtils.isEmpty(rolesSection)) {</span>
<span class="fc" id="L179">            log.debug(&quot;Discovered the [{}] section.  Processing...&quot;, ROLES_SECTION_NAME);</span>
<span class="fc" id="L180">            processRoleDefinitions(rolesSection);</span>
        }

<span class="fc" id="L183">        Ini.Section usersSection = ini.getSection(USERS_SECTION_NAME);</span>
<span class="fc bfc" id="L184" title="All 2 branches covered.">        if (!CollectionUtils.isEmpty(usersSection)) {</span>
<span class="fc" id="L185">            log.debug(&quot;Discovered the [{}] section.  Processing...&quot;, USERS_SECTION_NAME);</span>
<span class="fc" id="L186">            processUserDefinitions(usersSection);</span>
        } else {
<span class="fc" id="L188">            log.info(&quot;{} defined, but there is no [{}] section defined.  This realm will not be populated with any &quot; +</span>
                    &quot;users and it is assumed that they will be populated programatically.  Users must be defined &quot; +
<span class="fc" id="L190">                    &quot;for this Realm instance to be useful.&quot;, getClass().getSimpleName(), USERS_SECTION_NAME);</span>
        }
<span class="fc" id="L192">    }</span>
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>