SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IUserModuleAssignment.cs
Go to the documentation of this file.
1 // SmartAPI - .Net programmatic access to RedDot servers
2 //
3 // Copyright (C) 2013 erminas GbR
4 //
5 // This program is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free Software Foundation,
7 // either version 3 of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 // See the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program.
14 // If not, see <http://www.gnu.org/licenses/>.
15 
16 using System;
17 using System.Collections;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Xml;
21 using erminas.SmartAPI.Utils;
22 using erminas.SmartAPI.Utils.CachedCollections;
23 
24 namespace erminas.SmartAPI.CMS.ServerManagement
25 {
26  [Flags]
27  public enum ServerManagerRights
28  {
29  None = 0,
30  CreateUsers = 262144,
31  EditUsers = 4194304,
32  DeleteUsers = 131072,
33  CreateGroups = 1048576,
34  DeleteGroups = 524288,
35  AssignUsersToGroups = 2097152,
36  AdministerUserDefinedJobs = 16777216,
37  AdministerPlugins = 8388608,
38  AdministerDatabaseServers = 33554432,
39  AdministerApplicationServers = 67108864,
40  AdministerDirectoryServices = 134217728,
41  AdministerProjects = 268435456,
42  AdministerXCMSProjects = 536870912,
43  AdministerDeliveryServer = 1073741824
44  }
45 
46  public interface IUserModuleAssignment : IEnumerable<IModule>, ICached, ISessionObject
47  {
48  void AddServerManagerRights(ServerManagerRights right);
49  bool HasAccessToAssetManager { get; set; }
50  bool HasAccessToSmartEdit { get; set; }
51  bool HasAccessToSmartTree { get; set; }
52  bool IsModuleAssigned(ModuleType moduleType);
53  bool IsServerManager { get; set; }
54  bool IsTemplateEditor { get; set; }
55  bool IsTranslationEditor { get; set; }
56  void RemoveServerManagerRights(ServerManagerRights right);
58  void SetIsModuleAssigned(ModuleType moduleType, bool assign);
59  void SetModuleAssignment(IUserModuleAssignment otherAssignment);
60  }
61 
68  internal class UserModuleAssignment : IUserModuleAssignment
69  {
70  private readonly IndexedRDList<ModuleType, IModule> _assignedModules;
71 
72  private readonly User _user;
73 
74  internal UserModuleAssignment(User user)
75  {
76  _user = user;
77  Session = _user.Session;
78  _assignedModules = new IndexedRDList<ModuleType, IModule>(GetAssignedModules, module => module.Type,
79  Caching.Enabled);
80  }
81 
82  public void AddServerManagerRights(ServerManagerRights right)
83  {
84  ServerManagerRights |= right;
85  }
86 
87  public IEnumerator<IModule> GetEnumerator()
88  {
89  return _assignedModules.GetEnumerator();
90  }
91 
92  public bool HasAccessToAssetManager
93  {
94  get { return IsModuleAssigned(ModuleType.Translation); }
95  set { SetIsModuleAssigned(ModuleType.Translation, value); }
96  }
97 
98  public bool HasAccessToSmartEdit
99  {
100  get { return IsModuleAssigned(ModuleType.SmartEdit); }
101  set { SetIsModuleAssigned(ModuleType.SmartEdit, value); }
102  }
103 
104  public bool HasAccessToSmartTree
105  {
106  get { return IsModuleAssigned(ModuleType.SmartTree); }
107  set { SetIsModuleAssigned(ModuleType.SmartTree, value); }
108  }
109 
110  public void InvalidateCache()
111  {
112  _assignedModules.InvalidateCache();
113  }
114 
115  public bool IsModuleAssigned(ModuleType moduleType)
116  {
117  return _assignedModules.ContainsKey(moduleType);
118  }
119 
120  public bool IsServerManager
121  {
122  get { return IsModuleAssigned(ModuleType.ServerManager); }
123  set { SetIsModuleAssigned(ModuleType.ServerManager, value); }
124  }
125 
126  public bool IsTemplateEditor
127  {
128  get { return IsModuleAssigned(ModuleType.TemplateEditor); }
129  set { SetIsModuleAssigned(ModuleType.TemplateEditor, value); }
130  }
131 
132  public bool IsTranslationEditor
133  {
134  get { return IsModuleAssigned(ModuleType.Translation); }
135  set { SetIsModuleAssigned(ModuleType.Translation, value); }
136  }
137 
138  public void Refresh()
139  {
140  _assignedModules.Refresh();
141  }
142 
143  public void RemoveServerManagerRights(ServerManagerRights right)
144  {
145  ServerManagerRights ^= right;
146  }
147 
149  {
150  get
151  {
152  IModule serverManagerModule;
153  if (!_assignedModules.TryGet(ModuleType.ServerManager, out serverManagerModule))
154  {
155  return ServerManagerRights.None;
156  }
157 
158  return GetServerManagerRights(serverManagerModule);
159  }
160  set
161  {
162  var serverManagerModule = _user.Session.ServerManager.Modules[ModuleType.ServerManager];
163 
164  ServerManagerRights rights = RightsWithResolvedDepenecies(value);
165 
166  const string SAVE_SERVER_MANAGER_RIGHTS =
167  @"<MODULE guid=""{0}"" checked=""{1}"" servermanagerflag=""{2}""/>";
168 
169  ExecuteSaveModules(SAVE_SERVER_MANAGER_RIGHTS.RQLFormat(serverManagerModule,
170  rights != ServerManagerRights.None, (int) rights));
171  _assignedModules.InvalidateCache();
172  }
173  }
174 
175  public ISession Session { get; private set; }
176 
177  public void SetIsModuleAssigned(ModuleType moduleType, bool assign)
178  {
179  var module = _user.Session.ServerManager.Modules[moduleType];
180 
181  var modulesToAssign = new List<IModule> {module};
182  if (IsModuleDependentOnSmartEdit(moduleType))
183  {
184  var smartEditModule = _user.Session.ServerManager.Modules[ModuleType.SmartEdit];
185  modulesToAssign.Add(smartEditModule);
186  }
187  string moduleAssignmentSubString = CreateModuleAssignmentSubString(modulesToAssign, assign);
188  ExecuteSaveModules(moduleAssignmentSubString);
189  }
190 
191  public void SetModuleAssignment(IUserModuleAssignment otherAssignment)
192  {
193  var modulesToUnassign = this.Except(otherAssignment, new NameEqualityComparer<IModule>());
194 
195  string unassign = CreateModuleAssignmentSubString(modulesToUnassign, false);
196  string assign = CreateModuleAssignmentSubString(otherAssignment, true);
197 
198  ExecuteSaveModules(unassign + assign);
199 
200  ServerManagerRights = otherAssignment.ServerManagerRights;
201  }
202 
203  private static string CreateModuleAssignmentSubString(IEnumerable<IModule> modulesToUnassign, bool value)
204  {
205  return modulesToUnassign.Aggregate("",
206  (s, module) =>
207  s + @"<MODULE guid=""{0}"" checked=""{1}"" />".RQLFormat(module, value));
208  }
209 
210  private void ExecuteSaveModules(string modules)
211  {
212  const string SAVE_MODULES =
213  @"<ADMINISTRATION><USER action=""save"" guid=""{0}""><MODULES>{1}</MODULES></USER></ADMINISTRATION>";
214  _user.Session.ExecuteRQL(SAVE_MODULES.RQLFormat(_user, modules));
215  _assignedModules.InvalidateCache();
216  }
217 
218  private List<IModule> GetAssignedModules()
219  {
220  const string LIST_ASSIGNED_MODULES =
221  @"<ADMINISTRATION><MODULES action=""list"" userguid=""{0}"" countlicense=""1""/></ADMINISTRATION>";
222  var xmlDoc = _user.Session.ExecuteRQL(LIST_ASSIGNED_MODULES.RQLFormat(_user));
223  //create a copy of the elements because the XmlNodeList returned by GetElementsByTagName would get modified during iteration in the linq/ToList() expression
224  //due to the cloning of XmlElement in the Module->AbstractAttributeContainer c'tor. This would lead to an InvalidOperationException.
225  var modules = xmlDoc.GetElementsByTagName("MODULE").Cast<XmlElement>().ToList();
226 
227  return
228  (from curModule in modules
229  where IsAssignedModule(curModule)
230  select (IModule) new Module(Session, curModule)).ToList();
231  }
232 
233  IEnumerator IEnumerable.GetEnumerator()
234  {
235  return GetEnumerator();
236  }
237 
238  private static ServerManagerRights GetServerManagerRights(IModule serverManagerModule)
239  {
240  return
242  ((Module) serverManagerModule).XmlElement.GetIntAttributeValue("servermanagerflag").GetValueOrDefault();
243  }
244 
245  private static bool IsAssignedModule(XmlElement curModule)
246  {
247  return curModule.GetBoolAttributeValue("checked").GetValueOrDefault();
248  }
249 
250  private static bool IsModuleDependentOnSmartEdit(ModuleType moduleType)
251  {
252  return moduleType == ModuleType.SmartTree || moduleType == ModuleType.TemplateEditor ||
253  moduleType == ModuleType.Translation || moduleType == ModuleType.Assets;
254  }
255 
256  private static ServerManagerRights ResolveAssignUsersToGroupDependencies(ServerManagerRights rights)
257  {
258  const ServerManagerRights DEPENDENT_ON_ASSIGN_USER_TO_GROUP =
259  ServerManagerRights.EditUsers | ServerManagerRights.CreateGroups | ServerManagerRights.CreateUsers;
260  if (!rights.HasFlag(ServerManagerRights.AssignUsersToGroups) &&
261  (rights & DEPENDENT_ON_ASSIGN_USER_TO_GROUP) != 0)
262  {
263  rights |= ServerManagerRights.AssignUsersToGroups;
264  }
265  return rights;
266  }
267 
268  private static ServerManagerRights ResolveDepenciesOfAdministerDirectoryServices(ServerManagerRights value)
269  {
270  if (value.HasFlag(ServerManagerRights.AdministerDirectoryServices))
271  {
272  value |= ServerManagerRights.CreateUsers | ServerManagerRights.EditUsers |
273  ServerManagerRights.DeleteUsers | ServerManagerRights.AssignUsersToGroups |
274  ServerManagerRights.DeleteGroups | ServerManagerRights.CreateGroups;
275  }
276  return value;
277  }
278 
279  private static ServerManagerRights ResolveEditUsersDependencies(ServerManagerRights value)
280  {
281  if (value.HasFlag(ServerManagerRights.CreateUsers))
282  {
283  value |= ServerManagerRights.EditUsers;
284  }
285  return value;
286  }
287 
288  private ServerManagerRights RightsWithResolvedDepenecies(ServerManagerRights value)
289  {
290  value = ResolveAssignUsersToGroupDependencies(value);
291  value = ResolveEditUsersDependencies(value);
292  value = ResolveDepenciesOfAdministerDirectoryServices(value);
293 
294  return value;
295  }
296  }
297 }