001package com.randomnoun.common.security;
002
003/* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a
004 * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html)
005 */
006
007import java.io.*;
008
009import com.randomnoun.common.security.ResourceCriteria;
010import com.randomnoun.common.security.User;
011
012/**
013 * A class encapsulating permission information. A 'permission' allows a user (or role)
014 * to perform an 'activity' on a 'resource'. Roles, activities and resources are
015 * all specified as Strings, a user is specified by a User object (identified by
016 * username and customerId).
017 * 
018 * <p>A resource may also have a criteria supplied; e.g. a user may have a view/account
019 * permission, but only accounts with a certain monetary value.
020 *
021 * <p>Two constructors are provided, one for users and one for roles. Note that there
022 * are no 'setter' methods in this class; permissions may only be altered through
023 * creating new ones.
024 * 
025 * @author knoxg
026 */
027public class Permission implements Serializable
028{
029     
030    /** generated serialVersionUID */
031        private static final long serialVersionUID = -3718647050573844606L;
032
033        /** The role for this permission. A permission may apply to a role or a user but not both. */
034    private String role;
035
036    /** The user for this permission. A permission may apply to a role or a user but not both. */
037    private User user;
038
039    /** The activity for this permission. */
040    private String activity;
041
042    /** The resource for this permission. */
043    private String resource;
044
045    /** The resourceCriteria for this permission. */
046    private ResourceCriteria resourceCriteria;
047
048    /** Create a new role-based permission.
049     *
050     * @param role  the name of this role this permission applies to
051     * @param activity  the name of the activity we are permitting
052     * @param resource  the resource we are permitting access to
053     * @param resourceCriteria   a criteria which limits the types of resources that this
054     *   permission applies to
055     */
056    public Permission(String role, String activity, String resource,
057        ResourceCriteria resourceCriteria)
058    {
059        if (role==null) { throw new NullPointerException("null role"); }
060        if (activity==null) { throw new NullPointerException("null activity"); }
061        if (resource==null) { throw new NullPointerException("null resource"); }
062
063        this.role = role;
064        this.user = null;
065        this.activity = activity;
066        this.resource = resource;
067        this.resourceCriteria = resourceCriteria;
068    }
069
070    /** Create a new role-based permission.
071     *
072     * @param user  the user this permission applies to
073     * @param activity  the name of the activity we are permitting
074     * @param resource  the resource we are permitting access to
075     * @param resourceCriteria   a criteria which limits the types of resources that this
076     *   permission applies to
077     */
078    public Permission(User user, String activity, String resource,
079        ResourceCriteria resourceCriteria)
080    {
081        if (user==null) { throw new NullPointerException("null user"); }
082        if (activity==null) { throw new NullPointerException("null activity"); }
083        if (resource==null) { throw new NullPointerException("null resource"); }
084        
085        this.user = user;
086        this.role = null;
087        this.activity = activity;
088        this.resource = resource;
089        this.resourceCriteria = resourceCriteria;
090    }
091    
092        /** Create a permission that is not assigned to either a user or role
093         * 
094         * @param activity the name of the activity we are permitting
095         * @param resource the resource we are permitting acess to
096         */
097    public Permission(String activity, String resource) {
098                if (activity==null) { throw new NullPointerException("null activity"); }
099                if (resource==null) { throw new NullPointerException("null resource"); }
100                this.activity = activity;
101                this.resource = resource;
102    }
103    
104    /** Create a permission that is not assigned to either a user or role
105         * 
106         * @param permission a permission in 'activity.resource' format
107         */
108    public Permission(String permission) {
109                if (permission==null) { throw new NullPointerException("null permission"); }
110                int pos = permission.indexOf('.');
111                if (pos==-1) { throw new IllegalArgumentException("permission must be in 'activity.resource' format"); }
112                this.activity = permission.substring(0,pos);
113                this.resource = permission.substring(pos+1);
114    }
115    
116    /** Create a permission that is not assigned to either a user or role, with a resource criteria
117         * 
118         * @param permission a permission in 'activity.resource' format
119         */
120    public Permission(String permission, ResourceCriteria resourceCriteria) {
121                if (permission==null) { throw new NullPointerException("null permission"); }
122                int pos = permission.indexOf('.');
123                if (pos==-1) { throw new IllegalArgumentException("permission must be in 'activity.resource' format"); }
124                this.activity = permission.substring(0,pos);
125                this.resource = permission.substring(pos+1);
126                this.resourceCriteria = resourceCriteria;
127    }
128    
129
130    /** Returns true if this permission is user-based (as opposed to role-based).
131     *
132     * @return true if this permission is user-based (as opposed to role-based)
133     * 
134     * @throws IllegalStateException if this permission is not assigned to a user or role
135     */
136    boolean isUserPermission()
137    {
138        if (user!=null) { 
139                return true;
140        } else if (role!=null) {
141                return false;
142        } else {
143                throw new IllegalStateException("Permission is not assigned to user or role");
144        }
145    }
146
147    /** Returns true if this permission is role-based (as opposed to user-based).
148     *
149     * @return true if this permission is role-based (as opposed to user-based)
150     * 
151     * @throws IllegalStateException if this permission is not assigned to a user or role
152     */
153    boolean isRolePermission()
154    {
155                if (role!=null) { 
156                        return true;
157                } else if (user!=null) {
158                        return false;
159                } else {
160                        throw new IllegalStateException("Permission is not assigned to user or role");
161                }
162    }
163
164    /** Returns the role this permission applies to, or null if it is a user-based role.
165     *
166     * @return the role this permission applies to, or null if it is a user-based role
167     */
168    public String getRole()
169    {
170        return role;
171    }
172
173    /** Returns the user this permission applies to, or null if it is a user-based role.
174     *
175     * @return the user this permission applies to, or null if it is a user-based role
176     */
177    public User getUser()
178    {
179        return user;
180    }
181
182    /** Returns the activity this permission applies to.
183     *
184     * @return the activity this permission applies to
185     */
186    public String getActivity()
187    {
188        return activity;
189    }
190
191    /** Returns the resource this permission applies to.
192     *
193     * @return the resource this permission applies to
194     */
195    public String getResource()
196    {
197        return resource;
198    }
199
200    /** Returns the resourceCriteria that applies to this permission.
201     *
202     * @return the resourceCriteria that applies to this permission
203     */
204    public ResourceCriteria getResourceCriteria()
205    {
206        return resourceCriteria;
207    }
208}