SmartAPI
Open Source .NET RQL library for RedDot CMS / OpenText WSM Management Server
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
IUserProjectAssignment.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.Xml;
18 using erminas.SmartAPI.CMS.Project;
19 using erminas.SmartAPI.Exceptions;
20 using erminas.SmartAPI.Utils;
21 using erminas.SmartAPI.Utils.CachedCollections;
22 
23 namespace erminas.SmartAPI.CMS.ServerManagement
24 {
25  [Flags]
26  public enum ExtendedUserRoles
27  {
28  None = 0,
29  TemplateEditor = 1,
30  TranslationEditor = 2
31  }
32 
33  public enum UserRole
34  {
35  None = 0,
36  Administrator = 1,
37  SiteBuilder = 2,
38  Editor = 3,
39  Author = 4,
40  Visitor = 5
41  }
42 
44  {
45  void Commit();
46  bool IsTemplateEditor { get; set; }
47  bool IsTranslationEditor { get; set; }
48  IProject Project { get; }
49  IUserProjectAssignment Refreshed();
50  IUser User { get; }
51  UserRole UserRole { get; set; }
52  }
53 
54  internal class UserProjectAssignment : IUserProjectAssignment
55  {
56  private readonly ISession _session;
57  private readonly IUser _user;
58  private bool _isInitialized;
59  private bool? _isTemplateEditor;
60  private bool? _isTranslationEditor;
61  private UserRole? _userRole;
62 
63  internal UserProjectAssignment(IUser user, IProject project)
64  {
65  Project = project;
66  _user = user;
67  _session = _user.Session;
68  }
69 
70  internal UserProjectAssignment(IUser user, XmlElement projectAssignment)
71  {
72  _user = user;
73  _session = _user.Session;
74  LoadXml(projectAssignment);
75  _isInitialized = true;
76  }
77 
78  private UserProjectAssignment(IUser user, IProject project, UserRole role, ExtendedUserRoles extendedUserRoles)
79  {
80  Project = project;
81  _user = user;
82  _session = _user.Session;
83  UserRole = role;
84  IsTemplateEditor = extendedUserRoles.HasFlag(ExtendedUserRoles.TemplateEditor);
85  IsTranslationEditor = extendedUserRoles.HasFlag(ExtendedUserRoles.TranslationEditor);
86  _isInitialized = true;
87  }
88 
89  public void Commit()
90  {
91  EnsureInitialization();
92  const string SAVE_USER_RIGHTS =
93  @"<ADMINISTRATION><USER action=""save"" guid=""{0}""><PROJECTS><PROJECT guid=""{1}"" checked=""1"" lm=""{2}"" te=""{3}"" userlevel=""{4}""/></PROJECTS></USER></ADMINISTRATION>";
94 
95  User.Session.ExecuteRQL(SAVE_USER_RIGHTS.RQLFormat(User, Project, IsTranslationEditor, IsTemplateEditor,
96  (int) UserRole));
97  }
98 
99  public void Delete()
100  {
101  Delete(Project, User);
102  }
103 
104  public void InvalidateCache()
105  {
106  _userRole = null;
107  _isTemplateEditor = null;
108  _isTranslationEditor = null;
109  _isInitialized = false;
110  }
111 
112  public bool IsTemplateEditor
113  {
114  get
115  {
116  EnsureInitialization();
117 // ReSharper disable PossibleInvalidOperationException
118  return _isTemplateEditor.Value;
119 // ReSharper restore PossibleInvalidOperationException
120  }
121  set { _isTemplateEditor = value; }
122  }
123 
124  public bool IsTranslationEditor
125  {
126  get
127  {
128  EnsureInitialization();
129 // ReSharper disable PossibleInvalidOperationException
130  return _isTranslationEditor.Value;
131 // ReSharper restore PossibleInvalidOperationException
132  }
133  set { _isTranslationEditor = value; }
134  }
135 
136  public IProject Project { get; private set; }
137 
138  public void Refresh()
139  {
140  InvalidateCache();
141  EnsureInitialization();
142  }
143 
144  public IUserProjectAssignment Refreshed()
145  {
146  Refresh();
147  return this;
148  }
149 
150  public ISession Session
151  {
152  get { return _session; }
153  }
154 
155  public IUser User
156  {
157  get { return _user; }
158  }
159 
160  public UserRole UserRole
161  {
162  get
163  {
164  EnsureInitialization();
165 // ReSharper disable PossibleInvalidOperationException
166  return _userRole.Value;
167 // ReSharper restore PossibleInvalidOperationException
168  }
169  set { _userRole = value; }
170  }
171 
172  internal static IUserProjectAssignment Create(IUser user, IProject project, UserRole role,
173  ExtendedUserRoles extendedUserRoles)
174  {
175  var assignment = new UserProjectAssignment(user, project, role, extendedUserRoles);
176  assignment.Commit();
177 
178  user.Projects.InvalidateCache();
179  project.Users.InvalidateCache();
180 
181  return assignment;
182  }
183 
184  internal static void Delete(IProject project, IUser user)
185  {
186  const string UNASSING_PROJECT =
187  @"<ADMINISTRATION><USER action=""save"" guid=""{0}""><PROJECTS><PROJECT guid=""{1}"" checked=""0""/></PROJECTS><CCSCONNECTIONS/></USER></ADMINISTRATION>";
188 
189  project.Session.ExecuteRQL(UNASSING_PROJECT.RQLFormat(user, project));
190 
191  project.Users.InvalidateCache();
192  user.Projects.InvalidateCache();
193  }
194 
195  private void EnsureInitialization()
196  {
197  if (!_isInitialized)
198  {
199  var xml = RetrieveObjectElement();
200  LoadXml(xml);
201  _isInitialized = true;
202  }
203  }
204 
205  private bool HasRight(XmlElement projectElement, string attributeName)
206  {
207  var intAttributeValue = projectElement.GetIntAttributeValue(attributeName);
208  if (intAttributeValue == null)
209  {
210  throw new SmartAPIException(Session.ServerLogin,
211  string.Format("Missing attribute '{0}' in user/project assignment",
212  attributeName));
213  }
214 
215  return intAttributeValue.Value == -1;
216  }
217 
218  private void LoadXml(XmlElement projectAssignment)
219  {
220  if (Project == null)
221  {
222  Project = new Project.Project(_user.Session, projectAssignment.GetGuid())
223  {
224  Name = projectAssignment.GetName()
225  };
226  }
227  // we check for null, because a properties could have been set by the user, before the element was initialized
228  // and those values should not get lost on loading of the other values
229  if (_userRole == null)
230  {
231  _userRole = (UserRole) projectAssignment.GetIntAttributeValue("userlevel").GetValueOrDefault();
232  }
233  if (_isTemplateEditor == null)
234  {
235  _isTemplateEditor = HasRight(projectAssignment, "templateeditorright");
236  }
237  if (_isTranslationEditor == null)
238  {
239  _isTranslationEditor = HasRight(projectAssignment, "languagemanagerright");
240  }
241  }
242 
243  private XmlElement RetrieveObjectElement()
244  {
245  const string LOAD_ACCESS_LEVEL =
246  @"<ADMINISTRATION><USER guid=""{0}"" ><PROJECT guid=""{1}"" action=""load"" extendedinfo=""1""/></USER></ADMINISTRATION>";
247  var xmlDoc = Project.ExecuteRQL(LOAD_ACCESS_LEVEL.RQLFormat(User, Project));
248  return xmlDoc.GetSingleElement("PROJECT");
249  }
250  }
251 }