PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/module/ASC.Jabber/ASC.Xmpp.Server/Storage/ASCRosterStore.cs

https://github.com/dc0d/ONLYOFFICE-Server
C# | 250 lines | 195 code | 28 blank | 27 comment | 23 complexity | 496b5e8c77af563dc566b3ea50465341 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception
  1. /*
  2. (c) Copyright Ascensio System SIA 2010-2014
  3. This program is a free software product.
  4. You can redistribute it and/or modify it under the terms
  5. of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
  6. Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
  7. to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
  8. any third-party rights.
  9. This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty
  10. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
  11. the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
  12. You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
  13. The interactive user interfaces in modified source and object code versions of the Program must
  14. display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
  15. Pursuant to Section 7(b) of the License you must retain the original Product logo when
  16. distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
  17. trademark law for use of our trademarks.
  18. All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
  19. content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
  20. International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
  21. */
  22. using System;
  23. using System.Collections.Generic;
  24. using System.Configuration;
  25. using ASC.Core;
  26. using ASC.Xmpp.Server.Exceptions;
  27. using ASC.Xmpp.Server.storage.Interface;
  28. using UserRosterItemDic = System.Collections.Generic.Dictionary<string, ASC.Xmpp.Server.storage.UserRosterItem>;
  29. namespace ASC.Xmpp.Server.storage
  30. {
  31. using protocol.iq.roster;
  32. class ASCRosterStore : DbStoreBase, IRosterStore
  33. {
  34. private static readonly string GroupSeparator = "$@$;";
  35. private readonly object syncRoot = new object();
  36. private IDictionary<string, UserRosterItemDic> cache;
  37. private IDictionary<string, UserRosterItemDic> RosterItems
  38. {
  39. get
  40. {
  41. if (cache == null)
  42. {
  43. lock (syncRoot)
  44. {
  45. if (cache == null) cache = LoadRosterItems();
  46. }
  47. }
  48. return cache;
  49. }
  50. }
  51. protected override string[] CreateSchemaScript
  52. {
  53. get
  54. {
  55. return new[] {
  56. "create table Roster(UserName TEXT NOT NULL, Jid TEXT NOT NULL, Name TEXT, [Subscription] INTEGER, Ask INTEGER, Groups TEXT, primary key(UserName, Jid))",
  57. };
  58. }
  59. }
  60. protected override string[] DropSchemaScript
  61. {
  62. get
  63. {
  64. return new[] {
  65. "drop table Roster",
  66. };
  67. }
  68. }
  69. #region IRosterStore Members
  70. public ASCRosterStore(ConnectionStringSettings connectionSettings)
  71. : base(connectionSettings)
  72. {
  73. InitializeDbSchema(false);
  74. }
  75. public ASCRosterStore(string provider, string connectionString)
  76. : base(provider, connectionString)
  77. {
  78. InitializeDbSchema(false);
  79. }
  80. #endregion
  81. #region IRosterStore Members
  82. public List<UserRosterItem> GetRosterItems(string userName)
  83. {
  84. try
  85. {
  86. lock (syncRoot)
  87. {
  88. var items = GetASCRosterItems(userName);
  89. if (RosterItems.ContainsKey(userName)) items.AddRange(RosterItems[userName].Values);
  90. return items;
  91. }
  92. }
  93. catch (Exception e)
  94. {
  95. throw new JabberServiceUnavailableException("Could not get roster items.", e);
  96. }
  97. }
  98. public List<UserRosterItem> GetRosterItems(string userName, SubscriptionType subscriptionType)
  99. {
  100. lock (syncRoot)
  101. {
  102. return GetRosterItems(userName).FindAll(i => { return i.Subscribtion == subscriptionType; });
  103. }
  104. }
  105. public UserRosterItem GetRosterItem(string userName, string jid)
  106. {
  107. lock (syncRoot)
  108. {
  109. return GetRosterItems(userName).Find(i => { return string.Compare(new Jid(i.Jid).Bare, jid, true) == 0; });
  110. }
  111. }
  112. public UserRosterItem SaveOrUpdateRosterItem(string userName, UserRosterItem item)
  113. {
  114. if (item == null) throw new ArgumentNullException("item");
  115. if (IsASCRosterItem(userName, item.Jid)) throw new JabberForbiddenException();
  116. try
  117. {
  118. lock (syncRoot)
  119. {
  120. if (string.IsNullOrEmpty(item.Name)) item.Name = item.Jid;
  121. ExecuteNonQuery(
  122. "insert or replace into Roster(UserName, Jid, Name, Subscription, Ask, Groups) values (@userName, @jid, @name, @subscription, @ask, @groups)",
  123. new[] { "userName", "jid", "name", "subscription", "ask", "groups" },
  124. new object[] { userName, item.Jid, item.Name, (Int32)item.Subscribtion, (Int32)item.Ask, item.Groups != null ? item.Groups.ToArray() : null }
  125. );
  126. if (!RosterItems.ContainsKey(userName)) RosterItems[userName] = new UserRosterItemDic();
  127. RosterItems[userName][item.Jid] = item;
  128. return item;
  129. }
  130. }
  131. catch (Exception e)
  132. {
  133. throw new JabberServiceUnavailableException("Could not save or update roster item.", e);
  134. }
  135. }
  136. public void RemoveRosterItem(string userName, string jid)
  137. {
  138. if (IsASCRosterItem(userName, jid)) throw new JabberForbiddenException();
  139. try
  140. {
  141. lock (syncRoot)
  142. {
  143. if (RosterItems.ContainsKey(userName) && RosterItems[userName].ContainsKey(jid))
  144. {
  145. ExecuteNonQuery(
  146. "delete from Roster where UserName = @userName and Jid = @jid",
  147. new[] { "userName", "jid" },
  148. new object[] { userName, jid }
  149. );
  150. RosterItems[userName].Remove(jid);
  151. }
  152. }
  153. }
  154. catch (Exception e)
  155. {
  156. throw new JabberServiceUnavailableException("Could not remove roster item.", e);
  157. }
  158. }
  159. #endregion
  160. private IDictionary<string, UserRosterItemDic> LoadRosterItems()
  161. {
  162. var items = new Dictionary<string, UserRosterItemDic>();
  163. using (var connect = GetDbConnection())
  164. using (var command = connect.CreateCommand())
  165. {
  166. command.CommandText = "select Jid, Name, Subscription, Ask, Groups, UserName from Roster";
  167. using (var reader = command.ExecuteReader())
  168. {
  169. while (reader.Read())
  170. {
  171. var item = new UserRosterItem(reader.GetString(0))
  172. {
  173. Name = reader[1] as string,
  174. Subscribtion = !reader.IsDBNull(2) ? (SubscriptionType)reader.GetInt32(2) : default(SubscriptionType),
  175. Ask = !reader.IsDBNull(3) ? (AskType)reader.GetInt32(3) : default(AskType),
  176. Groups = !reader.IsDBNull(4) ?
  177. new List<string>(((string)reader[4]).Split(new[] { GroupSeparator }, StringSplitOptions.RemoveEmptyEntries)) :
  178. null
  179. };
  180. var userName = reader.GetString(5);
  181. if (!items.ContainsKey(userName)) items[userName] = new UserRosterItemDic();
  182. items[userName][item.Jid] = item;
  183. }
  184. }
  185. }
  186. return items;
  187. }
  188. private List<UserRosterItem> GetASCRosterItems(string userName)
  189. {
  190. var items = new List<UserRosterItem>();
  191. var domain = Core.Server.ServerDomain;
  192. foreach (var u in CoreContext.UserManager.GetUsers())
  193. {
  194. if (string.Compare(userName, u.UserName, true) == 0) continue;
  195. var item = new UserRosterItem(new Jid(u.UserName, domain, null).ToString())
  196. {
  197. Name = string.Format("{0} {1}", u.LastName, u.FirstName),
  198. Subscribtion = SubscriptionType.both,
  199. Ask = AskType.NONE,
  200. Groups = null
  201. };
  202. foreach (var g in CoreContext.UserManager.GetUserGroups(u.ID, CoreContext.GroupManager.MainGroupCategory.ID))
  203. {
  204. if (item.Groups == null) item.Groups = new List<string>();
  205. item.Groups.Add(g.Name);
  206. }
  207. items.Add(item);
  208. }
  209. return items;
  210. }
  211. private bool IsASCRosterItem(string userName, string jid)
  212. {
  213. return GetASCRosterItems(userName).Exists(i => { return string.Compare(new Jid(i.Jid).Bare, jid) == 0; });
  214. }
  215. }
  216. }