DocSpace-buildtools/web/ASC.Web.Core/Mail/MailServiceHelper.cs

337 lines
12 KiB
C#
Raw Normal View History

2019-06-07 08:59:07 +00:00
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Linq;
using System.Net;
2019-08-15 12:04:42 +00:00
using System.Security;
2019-12-13 11:37:58 +00:00
2019-06-07 08:59:07 +00:00
using ASC.Common.Caching;
2019-12-13 11:37:58 +00:00
using ASC.Common.Logging;
2019-06-07 08:59:07 +00:00
using ASC.Core;
2019-12-13 11:37:58 +00:00
using ASC.Core.Common.EF;
using ASC.Core.Common.EF.Context;
using ASC.Core.Common.EF.Model.Mail;
2019-08-15 12:04:42 +00:00
using ASC.Core.Users;
2019-12-13 11:37:58 +00:00
using Microsoft.EntityFrameworkCore;
2019-09-23 12:20:08 +00:00
using Microsoft.Extensions.Configuration;
2019-06-07 08:59:07 +00:00
namespace ASC.Web.Core.Mail
2019-10-11 15:03:03 +00:00
{
public class MailServiceHelperStorage
{
2020-08-12 09:58:08 +00:00
private ICacheNotify<MailServiceHelperCache> CacheNotify { get; }
2019-10-11 15:03:03 +00:00
public ICache Cache { get; }
2021-01-12 17:51:14 +00:00
public MailServiceHelperStorage(ICacheNotify<MailServiceHelperCache> cacheNotify, ICache cache)
2019-10-11 15:03:03 +00:00
{
2021-01-12 17:51:14 +00:00
Cache = cache;
2019-10-11 15:03:03 +00:00
CacheNotify = cacheNotify;
CacheNotify.Subscribe(r => Cache.Remove(r.Key), CacheNotifyAction.Remove);
}
public void Remove()
{
CacheNotify.Publish(new MailServiceHelperCache() { Key = MailServiceHelper.CacheKey }, CacheNotifyAction.Remove);
}
}
2019-09-09 12:56:33 +00:00
public class MailServiceHelper
2019-06-07 08:59:07 +00:00
{
2020-01-22 13:59:49 +00:00
public readonly string ConnectionStringFormat;
2019-06-07 08:59:07 +00:00
public const string MailServiceDbId = "mailservice";
2019-09-23 12:20:08 +00:00
public readonly string DefaultDatabase;
2019-06-07 08:59:07 +00:00
public const string DefaultUser = "mail_admin";
public const string DefaultPassword = "Isadmin123";
public const string DefaultProtocol = "http";
public const int DefaultPort = 8081;
public const string DefaultVersion = "v1";
2019-10-11 15:03:03 +00:00
internal const string CacheKey = "mailserverinfo";
2019-09-09 12:56:33 +00:00
2020-08-12 09:58:08 +00:00
private UserManager UserManager { get; }
private AuthContext AuthContext { get; }
private IConfiguration Configuration { get; }
private CoreBaseSettings CoreBaseSettings { get; }
2019-10-11 15:03:03 +00:00
public MailServiceHelperStorage MailServiceHelperStorage { get; }
2020-08-12 09:58:08 +00:00
private EFLoggerFactory LoggerFactory { get; }
private MailDbContext MailDbContext { get; }
2021-01-13 09:41:29 +00:00
private ICache Cache { get; }
2019-09-09 12:56:33 +00:00
2019-10-11 15:03:03 +00:00
public MailServiceHelper(
UserManager userManager,
AuthContext authContext,
IConfiguration configuration,
CoreBaseSettings coreBaseSettings,
2019-10-21 12:33:02 +00:00
MailServiceHelperStorage mailServiceHelperStorage,
2019-12-13 11:37:58 +00:00
DbContextManager<MailDbContext> dbContext,
EFLoggerFactory loggerFactory)
2019-09-09 12:56:33 +00:00
{
2020-01-22 13:59:49 +00:00
ConnectionStringFormat = GetConnectionStringFormat(configuration);
2019-09-09 12:56:33 +00:00
UserManager = userManager;
AuthContext = authContext;
2019-09-23 12:20:08 +00:00
Configuration = configuration;
2019-10-10 13:18:12 +00:00
CoreBaseSettings = coreBaseSettings;
2019-10-11 15:03:03 +00:00
MailServiceHelperStorage = mailServiceHelperStorage;
2019-12-13 11:37:58 +00:00
LoggerFactory = loggerFactory;
MailDbContext = dbContext.Get("webstudio");
2019-10-11 15:03:03 +00:00
Cache = mailServiceHelperStorage.Cache;
2019-09-23 12:20:08 +00:00
DefaultDatabase = GetDefaultDatabase();
2019-09-09 12:56:33 +00:00
}
2020-01-22 13:59:49 +00:00
private string GetConnectionStringFormat(IConfiguration configuration)
{
var value = configuration["mailservice:connection-string-format"];
return string.IsNullOrEmpty(value) ? "Server={0};Database={1};User ID={2};Password={3};Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=true" : value;
}
2019-06-07 08:59:07 +00:00
2019-09-23 12:20:08 +00:00
private string GetDefaultDatabase()
2019-06-07 08:59:07 +00:00
{
2019-09-23 12:20:08 +00:00
var value = Configuration["mail:database-name"];
2019-06-07 08:59:07 +00:00
return string.IsNullOrEmpty(value) ? "onlyoffice_mailserver" : value;
}
2019-09-09 12:56:33 +00:00
private void DemandPermission()
2019-06-07 08:59:07 +00:00
{
2019-10-10 13:18:12 +00:00
if (!CoreBaseSettings.Standalone)
2019-06-07 08:59:07 +00:00
throw new NotSupportedException("Method for server edition only.");
if (!UserManager.IsUserInGroup(AuthContext.CurrentAccount.ID, Constants.GroupAdmin.ID))
2019-06-07 08:59:07 +00:00
throw new SecurityException();
}
2019-10-10 08:52:21 +00:00
public bool IsMailServerAvailable()
2019-06-07 08:59:07 +00:00
{
2020-09-29 12:27:28 +00:00
return InnerGetMailServerInfo() != null;
2019-06-07 08:59:07 +00:00
}
2019-09-09 12:56:33 +00:00
public MailServerInfo GetMailServerInfo()
2019-06-07 08:59:07 +00:00
{
DemandPermission();
2020-09-29 12:27:28 +00:00
return InnerGetMailServerInfo();
2019-06-07 08:59:07 +00:00
}
2020-09-29 12:27:28 +00:00
private MailServerInfo InnerGetMailServerInfo()
2019-06-07 08:59:07 +00:00
{
var cachedData = Cache.Get<Tuple<MailServerInfo>>(CacheKey);
if (cachedData != null)
return cachedData.Item1;
2019-12-13 11:37:58 +00:00
var value = MailDbContext.ServerServer.Select(r => r.ConnectionString).FirstOrDefault();
2019-06-07 08:59:07 +00:00
2019-12-13 11:37:58 +00:00
cachedData =
new Tuple<MailServerInfo>(string.IsNullOrEmpty(value)
? null
: Newtonsoft.Json.JsonConvert.DeserializeObject<MailServerInfo>(value));
2019-06-07 08:59:07 +00:00
Cache.Insert(CacheKey, cachedData, DateTime.UtcNow.Add(TimeSpan.FromDays(1)));
return cachedData.Item1;
}
2020-01-22 13:59:49 +00:00
public string GetTokenFromExternalDatabase(string connectionString)
2019-06-07 08:59:07 +00:00
{
2019-12-13 11:37:58 +00:00
DemandPermission();
2019-12-16 14:55:59 +00:00
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MailDbContext>();
var options = dbContextOptionsBuilder
2020-09-02 15:23:39 +00:00
//.UseMySql(connectionString)
2020-08-21 02:34:37 +00:00
.UseNpgsql(connectionString)
2019-12-13 11:37:58 +00:00
.UseLoggerFactory(LoggerFactory)
.Options;
using var mailDbContext = new MailDbContext(options);
2019-12-13 13:05:24 +00:00
2019-12-13 11:37:58 +00:00
var token = mailDbContext.ApiKeys
.Where(r => r.Id == 1)
.Select(r => r.AccessToken)
2019-08-15 15:08:40 +00:00
.FirstOrDefault();
2020-01-22 13:59:49 +00:00
return token;
}
2019-08-15 15:08:40 +00:00
2020-01-22 13:59:49 +00:00
public string GetHostnameFromExternalDatabase(string connectionString, string ip)
{
DemandPermission();
2019-08-15 15:08:40 +00:00
2020-01-22 13:59:49 +00:00
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MailDbContext>();
var options = dbContextOptionsBuilder
2020-09-02 15:23:39 +00:00
//.UseMySql(connectionString)
2020-08-21 02:34:37 +00:00
.UseNpgsql(connectionString)
2020-01-22 13:59:49 +00:00
.UseLoggerFactory(LoggerFactory)
.Options;
using var mailDbContext = new MailDbContext(options);
if (!IPAddress.TryParse(ip, out var ipAddress))
return ip;
var hostname = mailDbContext.GreyListingWhiteList
.Where(r => r.Source == "SenderIP:" + ip)
.Select(r => r.Comment)
.FirstOrDefault();
2019-08-15 15:08:40 +00:00
2020-01-22 13:59:49 +00:00
return hostname;
2019-06-07 08:59:07 +00:00
}
2019-09-09 12:56:33 +00:00
public void UpdateDataFromInternalDatabase(string hostname, MailServerInfo mailServer)
2019-06-07 08:59:07 +00:00
{
DemandPermission();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
using var transaction = MailDbContext.Database.BeginTransaction();
var mailboxProvider = new MailboxProvider
{
Id = 0,
Name = hostname
};
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var pReq = MailDbContext.MailboxProvider.Add(mailboxProvider);
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-12-13 11:37:58 +00:00
mailboxProvider = pReq.Entity;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var providerId = mailboxProvider.Id;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var mailboxServer = new MailboxServer
2019-08-15 15:08:40 +00:00
{
2019-12-13 11:37:58 +00:00
Id = 0,
IdProvider = providerId,
Type = "smtp",
Hostname = hostname,
Port = 587,
SocketType = "STARTTLS",
UserName = "%EMAILADDRESS%",
Authentication = "",
IsUserData = false
};
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var req = MailDbContext.MailboxServer.Add(mailboxServer);
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
mailboxServer = req.Entity;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var smtpServerId = mailboxServer.Id;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
mailboxServer = new MailboxServer
{
Id = 0,
IdProvider = providerId,
Type = "imap",
Hostname = hostname,
Port = 143,
SocketType = "STARTTLS",
UserName = "%EMAILADDRESS%",
Authentication = "",
IsUserData = false
};
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
req = MailDbContext.MailboxServer.Add(mailboxServer);
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
mailboxServer = req.Entity;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var imapServerId = mailboxServer.Id;
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var mailServerData = MailDbContext.ServerServer.FirstOrDefault();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var connectionString = Newtonsoft.Json.JsonConvert.SerializeObject(mailServer);
var server = new ServerServer
{
Id = 0,
MxRecord = hostname,
ConnectionString = connectionString,
ServerType = 2,
SmtpSettingsId = smtpServerId,
ImapSettingsId = imapServerId
};
2020-10-12 19:39:23 +00:00
MailDbContext.ServerServer.Add(server);
MailDbContext.SaveChanges();
2019-12-13 11:37:58 +00:00
if (mailServerData != null)
{
server = MailDbContext.ServerServer.Where(r => r.Id == mailServerData.Id).FirstOrDefault();
2020-10-12 19:39:23 +00:00
MailDbContext.ServerServer.Remove(server);
MailDbContext.SaveChanges();
2019-12-13 11:37:58 +00:00
providerId = MailDbContext.MailboxServer
.Where(r => r.Id == mailServerData.SmtpSettingsId)
.Select(r => r.IdProvider)
.FirstOrDefault();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
var providers = MailDbContext.MailboxProvider.Where(r => r.Id == providerId).ToList();
MailDbContext.MailboxProvider.RemoveRange(providers);
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-12-13 11:37:58 +00:00
var servers = MailDbContext.MailboxServer
.Where(r => new[] { mailServerData.SmtpSettingsId, mailServerData.ImapSettingsId }.Any(a => a == r.Id))
.ToList();
MailDbContext.MailboxServer.RemoveRange(servers);
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-12-13 11:37:58 +00:00
var mailboxId = MailDbContext.Mailbox
.Where(r => r.IdSmtpServer == mailServerData.SmtpSettingsId)
.Where(r => r.IdInServer == mailServerData.ImapSettingsId)
.ToArray();
2019-08-15 15:08:40 +00:00
2019-12-13 11:37:58 +00:00
foreach (var m in mailboxId)
{
m.IdSmtpServer = smtpServerId;
m.IdInServer = imapServerId;
}
2020-10-12 19:39:23 +00:00
MailDbContext.SaveChanges();
2019-08-15 15:08:40 +00:00
}
transaction.Commit();
2019-10-11 15:03:03 +00:00
MailServiceHelperStorage.Remove();
2019-06-07 08:59:07 +00:00
}
}
public class MailServerInfo
{
public string DbConnection { get; set; }
public MailServerApiInfo Api { get; set; }
}
public class MailServerApiInfo
{
public string Protocol { get; set; }
public string Server { get; set; }
public int Port { get; set; }
public string Version { get; set; }
public string Token { get; set; }
}
}