001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.shiro.authz.permission;
020
021 import org.apache.shiro.util.StringUtils;
022
023 import java.util.Set;
024
025 /**
026 * Provides a base Permission class from which type-safe/domain-specific subclasses may extend. Can be used
027 * as a base class for JPA/Hibernate persisted permissions that wish to store the parts of the permission string
028 * in separate columns (e.g. 'domain', 'actions' and 'targets' columns), which can be used in querying
029 * strategies.
030 *
031 * @since 1.0
032 */
033 public class DomainPermission extends WildcardPermission {
034
035 private String domain;
036 private Set<String> actions;
037 private Set<String> targets;
038
039 private static final long serialVersionUID = 1l;
040
041 /**
042 * Creates a domain permission with *all* actions for *all* targets;
043 */
044 public DomainPermission() {
045 this.domain = getDomain(getClass());
046 setParts(getDomain(getClass()));
047 }
048
049 public DomainPermission(String actions) {
050 domain = getDomain(getClass());
051 this.actions = StringUtils.splitToSet(actions, SUBPART_DIVIDER_TOKEN);
052 encodeParts(domain, actions, null);
053 }
054
055 public DomainPermission(String actions, String targets) {
056 this.domain = getDomain(getClass());
057 this.actions = StringUtils.splitToSet(actions, SUBPART_DIVIDER_TOKEN);
058 this.targets = StringUtils.splitToSet(targets, SUBPART_DIVIDER_TOKEN);
059 encodeParts(this.domain, actions, targets);
060 }
061
062 protected DomainPermission(Set<String> actions, Set<String> targets) {
063 this.domain = getDomain(getClass());
064 setParts(domain, actions, targets);
065 }
066
067 private void encodeParts(String domain, String actions, String targets) {
068 if (!StringUtils.hasText(domain)) {
069 throw new IllegalArgumentException("domain argument cannot be null or empty.");
070 }
071 StringBuilder sb = new StringBuilder(domain);
072
073 if (!StringUtils.hasText(actions)) {
074 if (StringUtils.hasText(targets)) {
075 sb.append(PART_DIVIDER_TOKEN).append(WILDCARD_TOKEN);
076 }
077 } else {
078 sb.append(PART_DIVIDER_TOKEN).append(actions);
079 }
080 if (StringUtils.hasText(targets)) {
081 sb.append(PART_DIVIDER_TOKEN).append(targets);
082 }
083 setParts(sb.toString());
084 }
085
086 protected void setParts(String domain, Set<String> actions, Set<String> targets) {
087 String actionsString = StringUtils.toDelimitedString(actions, SUBPART_DIVIDER_TOKEN);
088 String targetsString = StringUtils.toDelimitedString(targets, SUBPART_DIVIDER_TOKEN);
089 encodeParts(domain, actionsString, targetsString);
090 this.domain = domain;
091 this.actions = actions;
092 this.targets = targets;
093 }
094
095 protected String getDomain(Class<? extends DomainPermission> clazz) {
096 String domain = clazz.getSimpleName().toLowerCase();
097 //strip any trailing 'permission' text from the name (as all subclasses should have been named):
098 int index = domain.lastIndexOf("permission");
099 if (index != -1) {
100 domain = domain.substring(0, index);
101 }
102 return domain;
103 }
104
105 public String getDomain() {
106 return domain;
107 }
108
109 protected void setDomain(String domain) {
110 if (this.domain != null && this.domain.equals(domain)) {
111 return;
112 }
113 this.domain = domain;
114 setParts(domain, actions, targets);
115 }
116
117 public Set<String> getActions() {
118 return actions;
119 }
120
121 protected void setActions(Set<String> actions) {
122 if (this.actions != null && this.actions.equals(actions)) {
123 return;
124 }
125 this.actions = actions;
126 setParts(domain, actions, targets);
127 }
128
129 public Set<String> getTargets() {
130 return targets;
131 }
132
133 protected void setTargets(Set<String> targets) {
134 this.targets = targets;
135 if (this.targets != null && this.targets.equals(targets)) {
136 return;
137 }
138 this.targets = targets;
139 setParts(domain, actions, targets);
140 }
141 }