338 lines
12 KiB
C#
338 lines
12 KiB
C#
/*
|
|
*
|
|
* (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;
|
|
using System.Security;
|
|
|
|
using ASC.Common.Caching;
|
|
using ASC.Common.Logging;
|
|
using ASC.Core;
|
|
using ASC.Core.Common.EF;
|
|
using ASC.Core.Common.EF.Context;
|
|
using ASC.Core.Common.EF.Model.Mail;
|
|
using ASC.Core.Users;
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
namespace ASC.Web.Core.Mail
|
|
{
|
|
public class MailServiceHelperStorage
|
|
{
|
|
private ICacheNotify<MailServiceHelperCache> CacheNotify { get; }
|
|
public ICache Cache { get; }
|
|
public MailServiceHelperStorage(ICacheNotify<MailServiceHelperCache> cacheNotify, ICache cache)
|
|
{
|
|
Cache = cache;
|
|
CacheNotify = cacheNotify;
|
|
CacheNotify.Subscribe(r => Cache.Remove(r.Key), CacheNotifyAction.Remove);
|
|
}
|
|
|
|
public void Remove()
|
|
{
|
|
CacheNotify.Publish(new MailServiceHelperCache() { Key = MailServiceHelper.CacheKey }, CacheNotifyAction.Remove);
|
|
}
|
|
}
|
|
|
|
public class MailServiceHelper
|
|
{
|
|
public readonly string ConnectionStringFormat;
|
|
public const string MailServiceDbId = "mailservice";
|
|
public readonly string DefaultDatabase;
|
|
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";
|
|
|
|
internal const string CacheKey = "mailserverinfo";
|
|
|
|
private UserManager UserManager { get; }
|
|
private AuthContext AuthContext { get; }
|
|
private IConfiguration Configuration { get; }
|
|
private CoreBaseSettings CoreBaseSettings { get; }
|
|
public MailServiceHelperStorage MailServiceHelperStorage { get; }
|
|
private EFLoggerFactory LoggerFactory { get; }
|
|
private Lazy<MailDbContext> LazyMailDbContext { get; }
|
|
private MailDbContext MailDbContext { get => LazyMailDbContext.Value; }
|
|
private ICache Cache { get; }
|
|
|
|
public MailServiceHelper(
|
|
UserManager userManager,
|
|
AuthContext authContext,
|
|
IConfiguration configuration,
|
|
CoreBaseSettings coreBaseSettings,
|
|
MailServiceHelperStorage mailServiceHelperStorage,
|
|
DbContextManager<MailDbContext> dbContext,
|
|
EFLoggerFactory loggerFactory)
|
|
{
|
|
ConnectionStringFormat = GetConnectionStringFormat(configuration);
|
|
UserManager = userManager;
|
|
AuthContext = authContext;
|
|
Configuration = configuration;
|
|
CoreBaseSettings = coreBaseSettings;
|
|
MailServiceHelperStorage = mailServiceHelperStorage;
|
|
LoggerFactory = loggerFactory;
|
|
LazyMailDbContext = new Lazy<MailDbContext>(() => dbContext.Get("webstudio"));
|
|
Cache = mailServiceHelperStorage.Cache;
|
|
DefaultDatabase = GetDefaultDatabase();
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
private string GetDefaultDatabase()
|
|
{
|
|
var value = Configuration["mail:database-name"];
|
|
return string.IsNullOrEmpty(value) ? "onlyoffice_mailserver" : value;
|
|
}
|
|
|
|
private void DemandPermission()
|
|
{
|
|
if (!CoreBaseSettings.Standalone)
|
|
throw new NotSupportedException("Method for server edition only.");
|
|
|
|
if (!UserManager.IsUserInGroup(AuthContext.CurrentAccount.ID, Constants.GroupAdmin.ID))
|
|
throw new SecurityException();
|
|
}
|
|
|
|
|
|
public bool IsMailServerAvailable()
|
|
{
|
|
return InnerGetMailServerInfo() != null;
|
|
}
|
|
|
|
|
|
public MailServerInfo GetMailServerInfo()
|
|
{
|
|
DemandPermission();
|
|
|
|
return InnerGetMailServerInfo();
|
|
}
|
|
|
|
private MailServerInfo InnerGetMailServerInfo()
|
|
{
|
|
var cachedData = Cache.Get<Tuple<MailServerInfo>>(CacheKey);
|
|
|
|
if (cachedData != null)
|
|
return cachedData.Item1;
|
|
|
|
var value = MailDbContext.ServerServer.Select(r => r.ConnectionString).FirstOrDefault();
|
|
|
|
cachedData =
|
|
new Tuple<MailServerInfo>(string.IsNullOrEmpty(value)
|
|
? null
|
|
: Newtonsoft.Json.JsonConvert.DeserializeObject<MailServerInfo>(value));
|
|
|
|
Cache.Insert(CacheKey, cachedData, DateTime.UtcNow.Add(TimeSpan.FromDays(1)));
|
|
|
|
return cachedData.Item1;
|
|
}
|
|
|
|
|
|
public string GetTokenFromExternalDatabase(string connectionString)
|
|
{
|
|
DemandPermission();
|
|
|
|
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MailDbContext>();
|
|
var options = dbContextOptionsBuilder
|
|
//.UseMySql(connectionString)
|
|
.UseNpgsql(connectionString)
|
|
.UseLoggerFactory(LoggerFactory)
|
|
.Options;
|
|
|
|
using var mailDbContext = new MailDbContext(options);
|
|
|
|
var token = mailDbContext.ApiKeys
|
|
.Where(r => r.Id == 1)
|
|
.Select(r => r.AccessToken)
|
|
.FirstOrDefault();
|
|
return token;
|
|
}
|
|
|
|
public string GetHostnameFromExternalDatabase(string connectionString, string ip)
|
|
{
|
|
DemandPermission();
|
|
|
|
var dbContextOptionsBuilder = new DbContextOptionsBuilder<MailDbContext>();
|
|
var options = dbContextOptionsBuilder
|
|
//.UseMySql(connectionString)
|
|
.UseNpgsql(connectionString)
|
|
.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();
|
|
|
|
return hostname;
|
|
}
|
|
|
|
|
|
public void UpdateDataFromInternalDatabase(string hostname, MailServerInfo mailServer)
|
|
{
|
|
DemandPermission();
|
|
|
|
using var transaction = MailDbContext.Database.BeginTransaction();
|
|
|
|
var mailboxProvider = new MailboxProvider
|
|
{
|
|
Id = 0,
|
|
Name = hostname
|
|
};
|
|
|
|
var pReq = MailDbContext.MailboxProvider.Add(mailboxProvider);
|
|
MailDbContext.SaveChanges();
|
|
mailboxProvider = pReq.Entity;
|
|
|
|
var providerId = mailboxProvider.Id;
|
|
|
|
var mailboxServer = new MailboxServer
|
|
{
|
|
Id = 0,
|
|
IdProvider = providerId,
|
|
Type = "smtp",
|
|
Hostname = hostname,
|
|
Port = 587,
|
|
SocketType = "STARTTLS",
|
|
UserName = "%EMAILADDRESS%",
|
|
Authentication = "",
|
|
IsUserData = false
|
|
};
|
|
|
|
var req = MailDbContext.MailboxServer.Add(mailboxServer);
|
|
MailDbContext.SaveChanges();
|
|
|
|
mailboxServer = req.Entity;
|
|
|
|
var smtpServerId = mailboxServer.Id;
|
|
|
|
mailboxServer = new MailboxServer
|
|
{
|
|
Id = 0,
|
|
IdProvider = providerId,
|
|
Type = "imap",
|
|
Hostname = hostname,
|
|
Port = 143,
|
|
SocketType = "STARTTLS",
|
|
UserName = "%EMAILADDRESS%",
|
|
Authentication = "",
|
|
IsUserData = false
|
|
};
|
|
|
|
req = MailDbContext.MailboxServer.Add(mailboxServer);
|
|
MailDbContext.SaveChanges();
|
|
|
|
mailboxServer = req.Entity;
|
|
|
|
var imapServerId = mailboxServer.Id;
|
|
|
|
var mailServerData = MailDbContext.ServerServer.FirstOrDefault();
|
|
|
|
var connectionString = Newtonsoft.Json.JsonConvert.SerializeObject(mailServer);
|
|
|
|
var server = new ServerServer
|
|
{
|
|
Id = 0,
|
|
MxRecord = hostname,
|
|
ConnectionString = connectionString,
|
|
ServerType = 2,
|
|
SmtpSettingsId = smtpServerId,
|
|
ImapSettingsId = imapServerId
|
|
};
|
|
|
|
MailDbContext.ServerServer.Add(server);
|
|
MailDbContext.SaveChanges();
|
|
|
|
if (mailServerData != null)
|
|
{
|
|
server = MailDbContext.ServerServer.Where(r => r.Id == mailServerData.Id).FirstOrDefault();
|
|
MailDbContext.ServerServer.Remove(server);
|
|
MailDbContext.SaveChanges();
|
|
|
|
providerId = MailDbContext.MailboxServer
|
|
.Where(r => r.Id == mailServerData.SmtpSettingsId)
|
|
.Select(r => r.IdProvider)
|
|
.FirstOrDefault();
|
|
|
|
var providers = MailDbContext.MailboxProvider.Where(r => r.Id == providerId).ToList();
|
|
MailDbContext.MailboxProvider.RemoveRange(providers);
|
|
MailDbContext.SaveChanges();
|
|
|
|
var servers = MailDbContext.MailboxServer
|
|
.Where(r => new[] { mailServerData.SmtpSettingsId, mailServerData.ImapSettingsId }.Any(a => a == r.Id))
|
|
.ToList();
|
|
|
|
MailDbContext.MailboxServer.RemoveRange(servers);
|
|
MailDbContext.SaveChanges();
|
|
|
|
var mailboxId = MailDbContext.Mailbox
|
|
.Where(r => r.IdSmtpServer == mailServerData.SmtpSettingsId)
|
|
.Where(r => r.IdInServer == mailServerData.ImapSettingsId)
|
|
.ToArray();
|
|
|
|
foreach (var m in mailboxId)
|
|
{
|
|
m.IdSmtpServer = smtpServerId;
|
|
m.IdInServer = imapServerId;
|
|
}
|
|
MailDbContext.SaveChanges();
|
|
}
|
|
|
|
transaction.Commit();
|
|
|
|
MailServiceHelperStorage.Remove();
|
|
}
|
|
}
|
|
|
|
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; }
|
|
}
|
|
} |