PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/common/ASC.Core.Common/Data/DbLoginEventsManager.cs

https://gitlab.com/rekby-archive/onlyoffice-CommunityServer
C# | 188 lines | 153 code | 20 blank | 15 comment | 4 complexity | 9056773eb4bd5cd77b7628ec2dd2a7a0 MD5 | raw file
  1. /*
  2. *
  3. * (c) Copyright Ascensio System Limited 2010-2021
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. *
  15. */
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using ASC.Common.Caching;
  20. using ASC.Common.Data;
  21. using ASC.Common.Data.Sql;
  22. using ASC.Common.Data.Sql.Expressions;
  23. using ASC.AuditTrail;
  24. using ASC.Core.Tenants;
  25. using ASC.MessagingSystem;
  26. namespace ASC.Core.Data
  27. {
  28. public class DbLoginEventsManager
  29. {
  30. private const string guidLoginEvent = "F4D8BBF6-EB63-4781-B55E-5885EAB3D759";
  31. private static readonly ICache cache = AscCache.Memory;
  32. private static readonly TimeSpan expirationTimeout = TimeSpan.FromMinutes(5);
  33. private static string dbId = "default";
  34. private static readonly List<MessageAction> loginActions = new List<MessageAction>
  35. {
  36. MessageAction.LoginSuccess,
  37. MessageAction.LoginSuccessViaSocialAccount,
  38. MessageAction.LoginSuccessViaSms,
  39. MessageAction.LoginSuccessViaApi,
  40. MessageAction.LoginSuccessViaSocialApp,
  41. MessageAction.LoginSuccessViaApiSms,
  42. MessageAction.LoginSuccessViaSSO,
  43. MessageAction.LoginSuccessViaApiSocialAccount,
  44. MessageAction.LoginSuccesViaTfaApp,
  45. MessageAction.LoginSuccessViaApiTfa
  46. };
  47. public static List<int> GetLoginEventIds(int tenantId, Guid userId)
  48. {
  49. var commonKey = GetCacheKey(tenantId, userId);
  50. var cacheKeys = cache.Get<List<int>>(commonKey);
  51. if (cacheKeys != null)
  52. {
  53. return cacheKeys;
  54. }
  55. using (var db = GetDbManager())
  56. {
  57. var where = GetActiveConnectionsWhere(tenantId, userId);
  58. var query = new SqlQuery("login_events")
  59. .Select("id")
  60. .Where(where);
  61. var resultList = db.ExecuteList(query).Select(row => (int)row[0]).ToList();
  62. if (resultList != null)
  63. {
  64. cache.Insert(commonKey, resultList, expirationTimeout);
  65. }
  66. return resultList;
  67. }
  68. }
  69. public static List<BaseEvent> GetLoginEvents(int tenantId, Guid userId)
  70. {
  71. using (var db = GetDbManager())
  72. {
  73. var where = GetActiveConnectionsWhere(tenantId, userId);
  74. var query = new SqlQuery("login_events")
  75. .Select("id", "substring_index(ip, ':', 1) ip", "platform", "browser", "date")
  76. .Where(where)
  77. .OrderBy("id", false);
  78. var loginInfo = db.ExecuteList(query).Select(row => new BaseEvent
  79. {
  80. Id = (int)row[0],
  81. IP = (string)row[1],
  82. Platform = (string)row[2],
  83. Browser = (string)row[3],
  84. Date = TenantUtil.DateTimeFromUtc((DateTime)row[4])
  85. }).ToList();
  86. return loginInfo;
  87. }
  88. }
  89. private static Exp GetActiveConnectionsWhere(int tenantId, Guid userId)
  90. {
  91. var exp = Exp.Empty;
  92. exp &= Exp.Eq("tenant_id", tenantId);
  93. exp &= Exp.Eq("user_id", userId);
  94. exp &= Exp.In("action", loginActions);
  95. exp &= Exp.Gt("date", DateTime.UtcNow.AddYears(-1));
  96. exp &= Exp.Eq("active", true);
  97. return exp;
  98. }
  99. public static void LogOutEvent(int loginEventId)
  100. {
  101. using (var db = GetDbManager())
  102. {
  103. var query = new SqlUpdate("login_events")
  104. .Set("active", false)
  105. .Where("id", loginEventId);
  106. db.ExecuteNonQuery(query);
  107. }
  108. ResetCache();
  109. }
  110. public static void LogOutAllActiveConnections(int tenantId, Guid userId)
  111. {
  112. using (var db = GetDbManager())
  113. {
  114. var query = new SqlUpdate("login_events")
  115. .Set("active", false)
  116. .Where("tenant_id", tenantId)
  117. .Where("user_id", userId)
  118. .Where("active", true);
  119. db.ExecuteNonQuery(query);
  120. }
  121. ResetCache(tenantId, userId);
  122. }
  123. public static void LogOutAllActiveConnectionsForTenant(int tenantId)
  124. {
  125. using (var db = GetDbManager())
  126. {
  127. var query = new SqlUpdate("login_events")
  128. .Set("active", false)
  129. .Where("tenant_id", tenantId)
  130. .Where("active", true);
  131. db.ExecuteNonQuery(query);
  132. }
  133. }
  134. public static void LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId)
  135. {
  136. using (var db = GetDbManager())
  137. {
  138. var query = new SqlUpdate("login_events")
  139. .Set("active", false)
  140. .Where("tenant_id", tenantId)
  141. .Where("user_id", userId)
  142. .Where(!Exp.Eq("id", loginEventId))
  143. .Where("active", true);
  144. db.ExecuteNonQuery(query);
  145. }
  146. ResetCache(tenantId, userId);
  147. }
  148. public static void ResetCache(int tenantId, Guid userId)
  149. {
  150. var key = GetCacheKey(tenantId, userId);
  151. cache.Remove(key);
  152. }
  153. public static void ResetCache()
  154. {
  155. var tenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId;
  156. var userId = SecurityContext.CurrentAccount.ID;
  157. ResetCache(tenantId, userId);
  158. }
  159. private static string GetCacheKey(int tenantId, Guid userId)
  160. {
  161. return string.Join("", guidLoginEvent, tenantId, userId);
  162. }
  163. private static IDbManager GetDbManager()
  164. {
  165. return DbManager.FromHttpContext(dbId);
  166. }
  167. }
  168. }