View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.authz.permission;
20  
21  import org.apache.shiro.util.StringUtils;
22  
23  import java.util.Set;
24  
25  /**
26   * Provides a base Permission class from which type-safe/domain-specific subclasses may extend.  Can be used
27   * as a base class for JPA/Hibernate persisted permissions that wish to store the parts of the permission string
28   * in separate columns (e.g. 'domain', 'actions' and 'targets' columns), which can be used in querying
29   * strategies.
30   *
31   * @since 1.0
32   */
33  public class DomainPermission extends WildcardPermission {
34  
35      private String domain;
36      private Set<String> actions;
37      private Set<String> targets;
38  
39      private static final long serialVersionUID = 1l;
40  
41      /**
42       * Creates a domain permission with *all* actions for *all* targets;
43       */
44      public DomainPermission() {
45          this.domain = getDomain(getClass());
46          setParts(getDomain(getClass()));
47      }
48  
49      public DomainPermission(String actions) {
50          domain = getDomain(getClass());
51          this.actions = StringUtils.splitToSet(actions, SUBPART_DIVIDER_TOKEN);
52          encodeParts(domain, actions, null);
53      }
54  
55      public DomainPermission(String actions, String targets) {
56          this.domain = getDomain(getClass());
57          this.actions = StringUtils.splitToSet(actions, SUBPART_DIVIDER_TOKEN);
58          this.targets = StringUtils.splitToSet(targets, SUBPART_DIVIDER_TOKEN);
59          encodeParts(this.domain, actions, targets);
60      }
61  
62      protected DomainPermission(Set<String> actions, Set<String> targets) {
63          this.domain = getDomain(getClass());
64          setParts(domain, actions, targets);
65      }
66  
67      private void encodeParts(String domain, String actions, String targets) {
68          if (!StringUtils.hasText(domain)) {
69              throw new IllegalArgumentException("domain argument cannot be null or empty.");
70          }
71          StringBuilder sb = new StringBuilder(domain);
72  
73          if (!StringUtils.hasText(actions)) {
74              if (StringUtils.hasText(targets)) {
75                  sb.append(PART_DIVIDER_TOKEN).append(WILDCARD_TOKEN);
76              }
77          } else {
78              sb.append(PART_DIVIDER_TOKEN).append(actions);
79          }
80          if (StringUtils.hasText(targets)) {
81              sb.append(PART_DIVIDER_TOKEN).append(targets);
82          }
83          setParts(sb.toString());
84      }
85  
86      protected void setParts(String domain, Set<String> actions, Set<String> targets) {
87          String actionsString = StringUtils.toDelimitedString(actions, SUBPART_DIVIDER_TOKEN);
88          String targetsString = StringUtils.toDelimitedString(targets, SUBPART_DIVIDER_TOKEN);
89          encodeParts(domain, actionsString, targetsString);
90          this.domain = domain;
91          this.actions = actions;
92          this.targets = targets;
93      }
94  
95      protected String getDomain(Class<? extends DomainPermission> clazz) {
96          String domain = clazz.getSimpleName().toLowerCase();
97          //strip any trailing 'permission' text from the name (as all subclasses should have been named):
98          int index = domain.lastIndexOf("permission");
99          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 }