aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/General/ACL.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/General/ACL.cs')
-rw-r--r--OpenSim/Framework/General/ACL.cs257
1 files changed, 257 insertions, 0 deletions
diff --git a/OpenSim/Framework/General/ACL.cs b/OpenSim/Framework/General/ACL.cs
new file mode 100644
index 0000000..348f0ae
--- /dev/null
+++ b/OpenSim/Framework/General/ACL.cs
@@ -0,0 +1,257 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31
32namespace OpenSim.Framework
33{
34 // ACL Class
35 // Modelled after the structure of the Zend ACL Framework Library
36 // with one key difference - the tree will search for all matching
37 // permissions rather than just the first. Deny permissions will
38 // override all others.
39
40
41 #region ACL Core Class
42 /// <summary>
43 /// Access Control List Engine
44 /// </summary>
45 public class ACL
46 {
47 Dictionary<string, Role> Roles = new Dictionary<string, Role>();
48 Dictionary<string, Resource> Resources = new Dictionary<string, Resource>();
49
50 public ACL AddRole(Role role)
51 {
52 if (Roles.ContainsKey(role.Name))
53 throw new AlreadyContainsRoleException(role);
54
55 Roles.Add(role.Name, role);
56
57 return this;
58 }
59
60 public ACL AddResource(Resource resource)
61 {
62 Resources.Add(resource.Name, resource);
63
64 return this;
65 }
66
67 public Permission HasPermission(string role, string resource)
68 {
69 if (!Roles.ContainsKey(role))
70 throw new KeyNotFoundException();
71
72 if (!Resources.ContainsKey(resource))
73 throw new KeyNotFoundException();
74
75 return Roles[role].RequestPermission(resource);
76 }
77
78 public ACL GrantPermission(string role, string resource)
79 {
80 if (!Roles.ContainsKey(role))
81 throw new KeyNotFoundException();
82
83 if (!Resources.ContainsKey(resource))
84 throw new KeyNotFoundException();
85
86 Roles[role].GivePermission(resource, Permission.Allow);
87
88 return this;
89 }
90
91 public ACL DenyPermission(string role, string resource)
92 {
93 if (!Roles.ContainsKey(role))
94 throw new KeyNotFoundException();
95
96 if (!Resources.ContainsKey(resource))
97 throw new KeyNotFoundException();
98
99 Roles[role].GivePermission(resource, Permission.Deny);
100
101 return this;
102 }
103
104 public ACL ResetPermission(string role, string resource)
105 {
106 if (!Roles.ContainsKey(role))
107 throw new KeyNotFoundException();
108
109 if (!Resources.ContainsKey(resource))
110 throw new KeyNotFoundException();
111
112 Roles[role].GivePermission(resource, Permission.None);
113
114 return this;
115 }
116 }
117 #endregion
118
119 #region Exceptions
120 /// <summary>
121 /// Thrown when an ACL attempts to add a duplicate role.
122 /// </summary>
123 public class AlreadyContainsRoleException : Exception
124 {
125 protected Role m_role;
126
127 public Role ErrorRole
128 {
129 get { return m_role; }
130 }
131
132 public AlreadyContainsRoleException(Role role)
133 {
134 m_role = role;
135 }
136
137 public override string ToString()
138 {
139 return "This ACL already contains a role called '" + m_role.Name + "'.";
140 }
141 }
142 #endregion
143
144 #region Roles and Resources
145
146 /// <summary>
147 /// Does this Role have permission to access a specified Resource?
148 /// </summary>
149 public enum Permission { Deny, None, Allow };
150
151 /// <summary>
152 /// A role class, for use with Users or Groups
153 /// </summary>
154 public class Role
155 {
156 private string m_name;
157 private Role[] m_parents;
158 private Dictionary<string, Permission> m_resources = new Dictionary<string, Permission>();
159
160 public string Name
161 {
162 get { return m_name; }
163 }
164
165 public Permission RequestPermission(string resource)
166 {
167 return RequestPermission(resource, Permission.None);
168 }
169
170 public Permission RequestPermission(string resource, Permission current)
171 {
172 // Deny permissions always override any others
173 if (current == Permission.Deny)
174 return current;
175
176 Permission temp = Permission.None;
177
178 // Pickup non-None permissions
179 if (m_resources.ContainsKey(resource) && m_resources[resource] != Permission.None)
180 temp = m_resources[resource];
181
182 if (m_parents != null)
183 {
184 foreach (Role parent in m_parents)
185 {
186 temp = parent.RequestPermission(resource, temp);
187 }
188 }
189
190 return temp;
191 }
192
193 public void GivePermission(string resource, Permission perm)
194 {
195 m_resources[resource] = perm;
196 }
197
198 public Role(string name)
199 {
200 m_name = name;
201 m_parents = null;
202 }
203
204 public Role(string name, Role[] parents)
205 {
206 m_name = name;
207 m_parents = parents;
208 }
209 }
210
211 public class Resource
212 {
213 private string m_name;
214
215 public string Name
216 {
217 get { return m_name; }
218 }
219
220 public Resource(string name)
221 {
222 m_name = name;
223 }
224 }
225
226 #endregion
227
228 #region Tests
229
230 class ACLTester
231 {
232 public ACLTester()
233 {
234 ACL acl = new ACL();
235
236 Role Guests = new Role("Guests");
237 acl.AddRole(Guests);
238
239 Role[] parents = new Role[0];
240 parents[0] = Guests;
241
242 Role JoeGuest = new Role("JoeGuest", parents);
243 acl.AddRole(JoeGuest);
244
245 Resource CanBuild = new Resource("CanBuild");
246 acl.AddResource(CanBuild);
247
248
249 acl.GrantPermission("Guests", "CanBuild");
250
251 acl.HasPermission("JoeGuest", "CanBuild");
252
253 }
254 }
255
256 #endregion
257}