source: java/net/deterlab/abac/Role.java @ de63a31

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since de63a31 was de63a31, checked in by Ted Faber <faber@…>, 13 years ago

Move keyid to cn translation down into role objects.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1package net.deterlab.abac;
2
3import java.util.*;
4
5/**
6 * Represents a role, which is a vertex in a Credential graph.
7 */
8public class Role {
9    private String m_string;
10    private String[] m_parts;
11    private String m_A_r1, m_r2;
12    private String m_prefix;
13    private Role[] m_prereqs;
14
15    protected static TreeMap<String, String> nicknames = 
16        new TreeMap<String, String>();
17    protected static TreeMap<String, String> keys = 
18        new TreeMap<String, String>();
19
20    /**
21     * Create a role from a string. A single role must be of the format "A",
22     * "A.r1", or "A.r1.r2", where A is a principal and r1 and r2 are role
23     * names. This constructor also supports intersection roles: a sequence of
24     * two or more roles separated by "&amp;". The whitespace surrounding &amp;
25     * is arbitrary.
26     *
27     * If the string does not have this format, the constructor throws a
28     * RuntimeException.
29     */
30    public Role(String s) throws RuntimeException {
31        m_string = s;
32
33        // intersection roles have at least two roles separated by "&"
34        String[] isect_roles = s.split("&");
35
36        // ordinary role
37        if (isect_roles.length == 1)
38            single_role();
39
40        // intersection role: make a list of prereqs
41        else {
42            m_prereqs = new Role[isect_roles.length];
43            for (int i = 0; i < isect_roles.length; ++i)
44                m_prereqs[i] = new Role(isect_roles[i].trim()); // trim() handles arbitrary whitespace
45
46            // this make is_principal etc. work properly
47            m_parts = new String[0];
48        }
49    }
50
51    public Role(String s, boolean translate) {
52        this(translate ? replace(s, nicknames) : s);
53    }
54
55    /**
56     * Initialize a single non-intersection role. See constructor for details of
57     * role format. Will throw RuntimeException if the role is invalid.
58     */
59    private void single_role() throws RuntimeException {
60        m_parts = m_string.split("\\.");
61        if (m_parts.length > 3)
62            throw new RuntimeException("Not a valid role: " + m_string);
63
64        // linking role: prefix is A.r1 from A.r1.r2
65        if (is_linking()) {
66            m_A_r1 = m_parts[0] + "." + m_parts[1];
67            m_r2 = m_parts[2];
68            m_prefix = m_A_r1;
69        }
70
71        // role: prefix is A from A.r1
72        else if (is_role())
73            m_prefix = m_parts[0];
74
75        // principal: prefix is the whole thing
76        else
77            m_prefix = m_string;
78    }
79
80    /**
81     * Returns true iff the role is a principal.
82     */
83    public boolean is_principal() { return m_parts.length == 1; }
84
85    /**
86     * Returns true iff the role is a role (i.e., A.r1).
87     */
88    public boolean is_role() { return m_parts.length == 2; }
89
90    /**
91     * Returns true iff the role is a linking role (i.e., A.r1.r2).
92     */
93    public boolean is_linking() { return m_parts.length == 3; }
94
95    /**
96     * Returns true iff the role represents an intersection role.
97     */
98    public boolean is_intersection() { return m_prereqs != null; }
99
100    /**
101     * Returns the first two elements of a linking role's name. This typically
102     * refers to another role in the graph. This will throw a runtime
103     * exception if the node is not a linking role.
104     */
105    public String A_r1() throws RuntimeException {
106        if (!is_linking())
107            throw new RuntimeException("Not a linking role");
108        return m_A_r1;
109    }
110
111    /**
112     * Return the last element of a linking role's name. This will throw a
113     * runtime exception if the node is not a linking role.
114     */
115    public String r2() throws RuntimeException {
116        if (!is_linking())
117            throw new RuntimeException("Not a linking role");
118        return m_r2;
119    }
120
121    /**
122     * Returns the principal part of a role or principal. This is everything
123     * except the last element of the name.
124     */
125    public String principal_part() {
126        return m_prefix;
127    }
128
129    /**
130     * Returns true if the principal part of the name matches a prefix. This
131     * is used when filtering graphs.
132     */
133    public boolean matches(String prefix) {
134        return prefix.length() == 0 || m_prefix.equals(prefix);
135    }
136
137    /**
138     * Get the roles that form the prerequisites to this intersection. Throws
139     * a runtime exception if this is not an intersection role.
140     */
141    public Role[] prereqs() throws RuntimeException {
142        if (!is_intersection())
143            throw new RuntimeException("Not an intersection role.");
144
145        return m_prereqs;
146    }
147
148    public String toString() {
149        return m_string;
150    }
151
152    public String simpleString() {
153        return replace(m_string, keys);
154    }
155
156    public boolean equals(Object v2) {
157        if (v2 instanceof Role)
158            return m_string.equals(((Role)v2).m_string);
159        return false;
160    }
161
162    public int hashCode() {
163        return m_string.hashCode();
164    }
165
166    /**
167     * Translate either keys to nicknames or vice versa.  Break the string into
168     * space separated tokens and then each of them into period separated
169     * strings.  If any of the smallest strings is in the map, replace it with
170     * the value.
171     */
172    protected static String replace(String is, Map<String, String> m) {
173        String rv = "";
174        for (String tok: is.split(" ")) {
175            String term = "";
176            for (String s: tok.split("\\.")) {
177                String next = m.containsKey(s) ? m.get(s) : s;
178
179                if (term.isEmpty()) term = next;
180                else term += "." + next;
181            }
182            if (rv.isEmpty()) rv = term;
183            else rv += " " + term;
184        }
185        return rv;
186    }
187    public static void add_mapping(String name, String key) {
188        nicknames.put(name, key);
189        keys.put(key,name);
190    }
191
192}
Note: See TracBrowser for help on using the repository browser.