blob: 66bc8372e4c5d68deea14fcdf2ff48decda1f32a [file] [log] [blame]
<?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>TextConfigurationRealm.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 :: All (aggregate jar)</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">TextConfigurationRealm.java</span></div><h1>TextConfigurationRealm.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.authc.SimpleAccount;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleRole;
import org.apache.shiro.config.ConfigurationException;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.util.PermissionUtils;
import org.apache.shiro.util.StringUtils;
import java.text.ParseException;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
/**
* A SimpleAccountRealm that enables text-based configuration of the initial User, Role, and Permission objects
* created at startup.
* &lt;p/&gt;
* Each User account definition specifies the username, password, and roles for a user. Each Role definition
* specifies a name and an optional collection of assigned Permissions. Users can be assigned Roles, and Roles can be
* assigned Permissions. By transitive association, each User 'has' all of their Role's Permissions.
* &lt;p/&gt;
* User and user-to-role definitions are specified via the {@link #setUserDefinitions} method and
* Role-to-permission definitions are specified via the {@link #setRoleDefinitions} method.
*
* @since 0.9
*/
public class TextConfigurationRealm extends SimpleAccountRealm {
//TODO - complete JavaDoc
private volatile String userDefinitions;
private volatile String roleDefinitions;
public TextConfigurationRealm() {
<span class="fc" id="L59"> super();</span>
<span class="fc" id="L60"> }</span>
/**
* Will call 'processDefinitions' on startup.
*
* @since 1.2
* @see &lt;a href=&quot;https://issues.apache.org/jira/browse/SHIRO-223&quot;&gt;SHIRO-223&lt;/a&gt;
*/
@Override
protected void onInit() {
<span class="fc" id="L70"> super.onInit();</span>
<span class="fc" id="L71"> processDefinitions();</span>
<span class="fc" id="L72"> }</span>
public String getUserDefinitions() {
<span class="fc" id="L75"> return userDefinitions;</span>
}
/**
* &lt;p&gt;Sets a newline (\n) delimited String that defines user-to-password-and-role(s) key/value pairs according
* to the following format:
* &lt;p/&gt;
* &lt;p&gt;&lt;code&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;
* &lt;p&gt;Here are some examples of what these lines might look like:&lt;/p&gt;
* &lt;p/&gt;
* &lt;p&gt;&lt;code&gt;root = &lt;em&gt;reallyHardToGuessPassword&lt;/em&gt;, administrator&lt;br/&gt;
* jsmith = &lt;em&gt;jsmithsPassword&lt;/em&gt;, manager, engineer, employee&lt;br/&gt;
* abrown = &lt;em&gt;abrownsPassword&lt;/em&gt;, qa, employee&lt;br/&gt;
* djones = &lt;em&gt;djonesPassword&lt;/em&gt;, qa, contractor&lt;br/&gt;
* guest = &lt;em&gt;guestPassword&lt;/em&gt;&lt;/code&gt;&lt;/p&gt;
*
* @param userDefinitions the user definitions to be parsed and converted to Map.Entry elements
*/
public void setUserDefinitions(String userDefinitions) {
<span class="fc" id="L95"> this.userDefinitions = userDefinitions;</span>
<span class="fc" id="L96"> }</span>
public String getRoleDefinitions() {
<span class="fc" id="L99"> return roleDefinitions;</span>
}
/**
* Sets a newline (\n) delimited String that defines role-to-permission definitions.
* &lt;p/&gt;
* &lt;p&gt;Each line within the string must define a role-to-permission(s) key/value mapping with the
* equals character signifies the key/value separation, like so:&lt;/p&gt;
* &lt;p/&gt;
* &lt;p&gt;&lt;code&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;
* &lt;p/&gt;
* &lt;p&gt;where &lt;em&gt;permissionDefinition&lt;/em&gt; is an arbitrary String, but must people will want to use
* Strings that conform to the {@link org.apache.shiro.authz.permission.WildcardPermission WildcardPermission}
* format for ease of use and flexibility. Note that if an individual &lt;em&gt;permissionDefinition&lt;/em&gt; needs to
* be internally comma-delimited (e.g. &lt;code&gt;printer:5thFloor:print,info&lt;/code&gt;), you will need to surround that
* definition with double quotes (&amp;quot;) to avoid parsing errors (e.g.
* &lt;code&gt;&amp;quot;printer:5thFloor:print,info&amp;quot;&lt;/code&gt;).
* &lt;p/&gt;
* &lt;p&gt;&lt;b&gt;NOTE:&lt;/b&gt; if you have roles that don't require permission associations, don't include them in this
* definition - just defining the role name in the {@link #setUserDefinitions(String) userDefinitions} is
* enough to create the role if it does not yet exist. This property is really only for configuring realms that
* have one or more assigned Permission.
*
* @param roleDefinitions the role definitions to be parsed at initialization
*/
public void setRoleDefinitions(String roleDefinitions) {
<span class="fc" id="L125"> this.roleDefinitions = roleDefinitions;</span>
<span class="fc" id="L126"> }</span>
protected void processDefinitions() {
try {
<span class="fc" id="L130"> processRoleDefinitions();</span>
<span class="fc" id="L131"> processUserDefinitions();</span>
<span class="nc" id="L132"> } catch (ParseException e) {</span>
<span class="nc" id="L133"> String msg = &quot;Unable to parse user and/or role definitions.&quot;;</span>
<span class="nc" id="L134"> throw new ConfigurationException(msg, e);</span>
<span class="fc" id="L135"> }</span>
<span class="fc" id="L136"> }</span>
protected void processRoleDefinitions() throws ParseException {
<span class="fc" id="L139"> String roleDefinitions = getRoleDefinitions();</span>
<span class="fc bfc" id="L140" title="All 2 branches covered."> if (roleDefinitions == null) {</span>
<span class="fc" id="L141"> return;</span>
}
<span class="fc" id="L143"> Map&lt;String, String&gt; roleDefs = toMap(toLines(roleDefinitions));</span>
<span class="fc" id="L144"> processRoleDefinitions(roleDefs);</span>
<span class="fc" id="L145"> }</span>
protected void processRoleDefinitions(Map&lt;String, String&gt; roleDefs) {
<span class="pc bpc" id="L148" title="2 of 4 branches missed."> if (roleDefs == null || roleDefs.isEmpty()) {</span>
<span class="nc" id="L149"> return;</span>
}
<span class="fc bfc" id="L151" title="All 2 branches covered."> for (String rolename : roleDefs.keySet()) {</span>
<span class="fc" id="L152"> String value = roleDefs.get(rolename);</span>
<span class="fc" id="L154"> SimpleRole role = getRole(rolename);</span>
<span class="fc bfc" id="L155" title="All 2 branches covered."> if (role == null) {</span>
<span class="fc" id="L156"> role = new SimpleRole(rolename);</span>
<span class="fc" id="L157"> add(role);</span>
}
<span class="fc" id="L160"> Set&lt;Permission&gt; permissions = PermissionUtils.resolveDelimitedPermissions(value, getPermissionResolver());</span>
<span class="fc" id="L161"> role.setPermissions(permissions);</span>
<span class="fc" id="L162"> }</span>
<span class="fc" id="L163"> }</span>
protected void processUserDefinitions() throws ParseException {
<span class="fc" id="L166"> String userDefinitions = getUserDefinitions();</span>
<span class="fc bfc" id="L167" title="All 2 branches covered."> if (userDefinitions == null) {</span>
<span class="fc" id="L168"> return;</span>
}
<span class="fc" id="L171"> Map&lt;String, String&gt; userDefs = toMap(toLines(userDefinitions));</span>
<span class="fc" id="L173"> processUserDefinitions(userDefs);</span>
<span class="fc" id="L174"> }</span>
protected void processUserDefinitions(Map&lt;String, String&gt; userDefs) {
<span class="pc bpc" id="L177" title="2 of 4 branches missed."> if (userDefs == null || userDefs.isEmpty()) {</span>
<span class="nc" id="L178"> return;</span>
}
<span class="fc bfc" id="L180" title="All 2 branches covered."> for (String username : userDefs.keySet()) {</span>
<span class="fc" id="L182"> String value = userDefs.get(username);</span>
<span class="fc" id="L184"> String[] passwordAndRolesArray = StringUtils.split(value);</span>
<span class="fc" id="L186"> String password = passwordAndRolesArray[0];</span>
<span class="fc" id="L188"> SimpleAccount account = getUser(username);</span>
<span class="fc bfc" id="L189" title="All 2 branches covered."> if (account == null) {</span>
<span class="fc" id="L190"> account = new SimpleAccount(username, password, getName());</span>
<span class="fc" id="L191"> add(account);</span>
}
<span class="fc" id="L193"> account.setCredentials(password);</span>
<span class="fc bfc" id="L195" title="All 2 branches covered."> if (passwordAndRolesArray.length &gt; 1) {</span>
<span class="fc bfc" id="L196" title="All 2 branches covered."> for (int i = 1; i &lt; passwordAndRolesArray.length; i++) {</span>
<span class="fc" id="L197"> String rolename = passwordAndRolesArray[i];</span>
<span class="fc" id="L198"> account.addRole(rolename);</span>
<span class="fc" id="L200"> SimpleRole role = getRole(rolename);</span>
<span class="fc bfc" id="L201" title="All 2 branches covered."> if (role != null) {</span>
<span class="fc" id="L202"> account.addObjectPermissions(role.getPermissions());</span>
}
}
} else {
<span class="fc" id="L206"> account.setRoles(null);</span>
}
<span class="fc" id="L208"> }</span>
<span class="fc" id="L209"> }</span>
protected static Set&lt;String&gt; toLines(String s) {
<span class="fc" id="L212"> LinkedHashSet&lt;String&gt; set = new LinkedHashSet&lt;String&gt;();</span>
<span class="fc" id="L213"> Scanner scanner = new Scanner(s);</span>
<span class="fc bfc" id="L214" title="All 2 branches covered."> while (scanner.hasNextLine()) {</span>
<span class="fc" id="L215"> set.add(scanner.nextLine());</span>
}
<span class="fc" id="L217"> return set;</span>
}
protected static Map&lt;String, String&gt; toMap(Collection&lt;String&gt; keyValuePairs) throws ParseException {
<span class="pc bpc" id="L221" title="2 of 4 branches missed."> if (keyValuePairs == null || keyValuePairs.isEmpty()) {</span>
<span class="nc" id="L222"> return null;</span>
}
<span class="fc" id="L225"> Map&lt;String, String&gt; pairs = new HashMap&lt;String, String&gt;();</span>
<span class="fc bfc" id="L226" title="All 2 branches covered."> for (String pairString : keyValuePairs) {</span>
<span class="fc" id="L227"> String[] pair = StringUtils.splitKeyValue(pairString);</span>
<span class="pc bpc" id="L228" title="1 of 2 branches missed."> if (pair != null) {</span>
<span class="fc" id="L229"> pairs.put(pair[0].trim(), pair[1].trim());</span>
}
<span class="fc" id="L231"> }</span>
<span class="fc" id="L233"> return pairs;</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>