source: java/net/deterlab/abac/Role.java @ 327a740

abac0-leakabac0-mei
Last change on this file since 327a740 was a1a9a47, checked in by Ted Faber <faber@…>, 11 years ago

Bump version

  • Property mode set to 100644
File size: 8.2 KB
RevLine 
[31b67d5]1package net.deterlab.abac;
2
[de63a31]3import java.util.*;
4
[31b67d5]5/**
6 * Represents a role, which is a vertex in a Credential graph.
[e36ea1d]7 * @author <a href="http://abac.deterlab.net">ISI ABAC team</a>
[a1a9a47]8 * @version 1.5
[31b67d5]9 */
[88e139a]10public class Role implements Comparable {
[e36ea1d]11    /** The role represnetation */
[d69593c]12    protected String m_string;
[e36ea1d]13    /** The role broken into parts between dots */
[d69593c]14    protected String[] m_parts;
[e36ea1d]15    /** The linking role from a linking Role */
[d69593c]16    protected String m_A_r1;
[e36ea1d]17    /** The linked role from a linked Role */
[d69593c]18    protected String m_r2;
[e36ea1d]19    /** A prefix of the role */
[d69593c]20    protected String m_prefix;
[e36ea1d]21    /** Prerequisite roles for an intersection role. */
[d69593c]22    protected Role[] m_prereqs;
[31b67d5]23
24    /**
[cac4c76]25     * Create a role from a string. A single role must be of the format "A",
[31b67d5]26     * "A.r1", or "A.r1.r2", where A is a principal and r1 and r2 are role
[cac4c76]27     * names. This constructor also supports intersection roles: a sequence of
[bcf7370]28     * two or more roles separated by "&amp;". The whitespace surrounding &amp;
29     * is arbitrary.
[cac4c76]30     *
31     * If the string does not have this format, the constructor throws a
32     * RuntimeException.
[e36ea1d]33     *
34     * @param s a String with the role name
35     * @throws RuntimeException if the string is badly formatted
[31b67d5]36     */
[e36ea1d]37    public Role(String s) {
[31b67d5]38        m_string = s;
39
[bcf7370]40        // intersection roles have at least two roles separated by "&"
41        String[] isect_roles = s.split("&");
[cac4c76]42
43        // ordinary role
44        if (isect_roles.length == 1)
45            single_role();
46
47        // intersection role: make a list of prereqs
48        else {
49            m_prereqs = new Role[isect_roles.length];
[53f5c27]50
51            // trim() handles arbitrary whitespace
[cac4c76]52            for (int i = 0; i < isect_roles.length; ++i)
[53f5c27]53                m_prereqs[i] = new Role(isect_roles[i].trim());
[cac4c76]54
55            // this make is_principal etc. work properly
56            m_parts = new String[0];
57        }
58    }
59
[e36ea1d]60    /**
61     * Create a role from the given string, converted from mnemonic strings to
62     * key IDs that are known from the Context.  This is a jabac extension.
63     * @param s the String containing the rile name.
64     * @param c the Context in which to expand mnemonics
65     * @throws RuntimeException if the string is badly formatted.
66     */
[84f0e7a]67    public Role(String s, Context c) {
68        this(c.expandKeyID(s));
[de63a31]69    }
70
[e36ea1d]71    /**
72     * Copy an existing role.
73     * @param r the Role to copy
74     */
[d69593c]75    public Role(Role r) {
76        m_string = r.m_string;
77        m_A_r1 = r.m_A_r1;
78        m_r2 = r.m_r2;
79        m_prefix = r.m_prefix;
80        m_parts = new String[r.m_parts.length];
81        for (int i = 0; i < r.m_parts.length; i++) 
82            m_parts[i] = r.m_parts[i];
83        m_prereqs = new Role[m_prereqs.length];
84        for (int i = 0; i < r.m_prereqs.length; i++) 
85            m_prereqs[i] = new Role(r.m_prereqs[i]);
86    }
87
[cac4c76]88    /**
[e36ea1d]89     * Initialize a single non-intersection role. See constructor for details
90     * of role format. Will throw RuntimeException if the role is invalid.
91     * @throws RuntimeException if a role is invalid.
[cac4c76]92     */
[e36ea1d]93    private void single_role() {
[cac4c76]94        m_parts = m_string.split("\\.");
[31b67d5]95        if (m_parts.length > 3)
96            throw new RuntimeException("Not a valid role: " + m_string);
97
98        // linking role: prefix is A.r1 from A.r1.r2
99        if (is_linking()) {
100            m_A_r1 = m_parts[0] + "." + m_parts[1];
101            m_r2 = m_parts[2];
102            m_prefix = m_A_r1;
103        }
104
105        // role: prefix is A from A.r1
106        else if (is_role())
107            m_prefix = m_parts[0];
108
109        // principal: prefix is the whole thing
110        else
111            m_prefix = m_string;
112    }
113
114    /**
115     * Returns true iff the role is a principal.
[a5cfe93]116     * @return true iff the role is a principal.
[31b67d5]117     */
118    public boolean is_principal() { return m_parts.length == 1; }
119
120    /**
121     * Returns true iff the role is a role (i.e., A.r1).
[a5cfe93]122     * @return true iff the role is a role (i.e., A.r1).
[31b67d5]123     */
124    public boolean is_role() { return m_parts.length == 2; }
125
126    /**
127     * Returns true iff the role is a linking role (i.e., A.r1.r2).
[a5cfe93]128     * @return true iff the role is a linking role (i.e., A.r1.r2).
[31b67d5]129     */
130    public boolean is_linking() { return m_parts.length == 3; }
131
[cac4c76]132    /**
133     * Returns true iff the role represents an intersection role.
[a5cfe93]134     * @return true iff the role represents an intersection role.
[cac4c76]135     */
136    public boolean is_intersection() { return m_prereqs != null; }
137
[31b67d5]138    /**
139     * Returns the first two elements of a linking role's name. This typically
140     * refers to another role in the graph. This will throw a runtime
141     * exception if the node is not a linking role.
[a5cfe93]142     * @return the first two elements of a linking role's name.
[e36ea1d]143     * @throws RuntimeException if the role is not linking
[31b67d5]144     */
[5129e3e]145    String A_r1() throws RuntimeException {
[31b67d5]146        if (!is_linking())
147            throw new RuntimeException("Not a linking role");
148        return m_A_r1;
149    }
150
151    /**
152     * Return the last element of a linking role's name. This will throw a
153     * runtime exception if the node is not a linking role.
[e36ea1d]154     * @return the last element of a linking role's name.
155     * @throws RuntimeException if the node is not a linking role.
[31b67d5]156     */
[5129e3e]157    String r2() throws RuntimeException {
[31b67d5]158        if (!is_linking())
159            throw new RuntimeException("Not a linking role");
160        return m_r2;
161    }
162
163    /**
164     * Returns the principal part of a role or principal. This is everything
[e36ea1d]165     * except the last element of the name.  Used by Query.
[a5cfe93]166     * @return the principal part of a role or principal.
[31b67d5]167     */
[e36ea1d]168    String principal_part() {
[31b67d5]169        return m_prefix;
170    }
171
[e36ea1d]172    /**
173     * Return the principal
174     * @return the principal
175     */
[d69593c]176    public String principal() { return m_parts.length > 0 ? m_parts[0] : null; }
[e36ea1d]177    /**
[3b38c41]178     * Return the role name after the last dot
[e36ea1d]179     * @return the role name
180     */
[5a16edf]181    public String role_name() { 
182        return m_parts.length > 1 ? m_parts[m_parts.length-1] : null;
183    }
[e36ea1d]184    /**
185     * Return the linked role (first two parts of a linking role)
186     * @return the linked role
187     */
[d69593c]188    public String linked_role() { return A_r1(); }
[281158a]189
[5a16edf]190    /**
191     * Return the linking role (the middle role of a linking role)
192     * @return a String, the linking role (the middle role of a linking role)
193     */
194    public String linking_role() {
195        return m_parts.length > 2 ? m_parts[1] : null;
196    }
197
[cac4c76]198    /**
199     * Get the roles that form the prerequisites to this intersection. Throws
200     * a runtime exception if this is not an intersection role.
[e36ea1d]201     * @return a Role[] of prerequisites
[b89cfd8]202     * @throws ABACException if this is not an intersection role
[cac4c76]203     */
[b89cfd8]204    public Role[] prereqs() throws ABACException {
[cac4c76]205        if (!is_intersection())
[b89cfd8]206            throw new ABACException("Not an intersection role.");
[cac4c76]207
208        return m_prereqs;
209    }
210
[a5cfe93]211    /**
212     * Returns a string representation of the Role.
213     * @return a string representation of the Role.
214     */
[31b67d5]215    public String toString() {
216        return m_string;
217    }
218
[a5cfe93]219    /**
220     * Returns a string representation of the Role with mnemonic names from the
221     * given Context.  A jabac extension.
222     * @param c A Context used to look up mnemonic names.
223     * @return a string representation of the Role with mnemonic names from the
224     * given Context.
225     */
[84f0e7a]226    public String simpleString(Context c) {
227        return c.expandNickname(m_string);
[de63a31]228    }
229
[a5cfe93]230    /**
[a7f73b5]231     * Return true if the two roles are the same.  Two Roles are the same if
232     * their string representations are equal.
[a5cfe93]233     * @param v2 an Object to compare
234     * @return a boolean, true if the two Roles are equal.
235     */
[31b67d5]236    public boolean equals(Object v2) {
237        if (v2 instanceof Role)
238            return m_string.equals(((Role)v2).m_string);
239        return false;
240    }
241
[a5cfe93]242    /**
[a7f73b5]243     * Order the roles for sorting.  Return a lexical comparison of the two
244     * Roles
[a5cfe93]245     * @param o an Object to compare against
246     * @return -1 if this Role is before, 0 if they are the same, and 1
247     *              if this Role is after the given object.
248     */
[88e139a]249    public int compareTo(Object o) {
250        if (o instanceof Role) 
251            return m_string.compareTo(((Role)o).m_string);
252        else return 1;
253    }
254
[a5cfe93]255    /**
256     * Returns a hash code value for the object.  It is the hash of the string
257     * representation.
258     * @return a hash code value for the object.
259     */
[31b67d5]260    public int hashCode() {
261        return m_string.hashCode();
262    }
[de63a31]263
[31b67d5]264}
Note: See TracBrowser for help on using the repository browser.