api system

-fix api system
-TenantName from resources
This commit is contained in:
Anton Suhorukov 2022-10-05 14:23:53 +03:00
parent 6682ca850e
commit 400fc49bb6
21 changed files with 239 additions and 68 deletions

View File

@ -226,7 +226,7 @@ public abstract class BaseStartup
}
}
private IEnumerable<Assembly> GetAutoMapperProfileAssemblies()
protected IEnumerable<Assembly> GetAutoMapperProfileAssemblies()
{
return AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name.StartsWith("ASC."));
}

View File

@ -218,7 +218,7 @@ public class DbTenantService : ITenantService
tenant.LastModified = DateTime.UtcNow;
var dbTenant = _mapper.Map<Tenant, DbTenant>(tenant);
dbTenant.Id = 0;
dbTenant = tenantDbContext.Tenants.Add(dbTenant).Entity;
tenantDbContext.SaveChanges();
tenant.Id = dbTenant.Id;
@ -235,7 +235,7 @@ public class DbTenantService : ITenantService
dbTenant.MappedDomain = !string.IsNullOrEmpty(tenant.MappedDomain) ? tenant.MappedDomain.ToLowerInvariant() : null;
dbTenant.Version = tenant.Version;
dbTenant.VersionChanged = tenant.VersionChanged;
dbTenant.Name = tenant.Name ?? tenant.Alias;
dbTenant.Name = tenant.Name ?? "";
dbTenant.Language = tenant.Language;
dbTenant.TimeZone = tenant.TimeZone;
dbTenant.TrustedDomainsRaw = tenant.GetTrustedDomains();

View File

@ -69,7 +69,7 @@ public class DbTenant : IMapFrom<Tenant>
.ForMember(dest => dest.TrustedDomainsRaw, opt => opt.MapFrom(dest => dest.GetTrustedDomains()))
.ForMember(dest => dest.Alias, opt => opt.MapFrom(dest => dest.Alias.ToLowerInvariant()))
.ForMember(dest => dest.LastModified, opt => opt.MapFrom(dest => DateTime.UtcNow))
.ForMember(dest => dest.Name, opt => opt.MapFrom(dest => dest.Name ?? dest.Alias))
.ForMember(dest => dest.Name, opt => opt.MapFrom(dest => dest.Name ?? ""))
.ForMember(dest => dest.MappedDomain, opt => opt.MapFrom(dest =>
!string.IsNullOrEmpty(dest.MappedDomain) ? dest.MappedDomain.ToLowerInvariant() : null));
}

View File

@ -42,9 +42,33 @@ public class HostedSolution
internal DbSettingsManager SettingsManager { get; set; }
internal CoreSettings CoreSettings { get; set; }
public string Region { get; set; }
public string Region { get; private set; }
public HostedSolution() { }
public HostedSolution(ITenantService tenantService,
IUserService userService,
IQuotaService quotaService,
ITariffService tariffService,
UserFormatter userFormatter,
TenantManager clientTenantManager,
TenantUtil tenantUtil,
DbSettingsManager settingsManager,
CoreSettings coreSettings)
{
TenantService = tenantService;
UserService = userService;
QuotaService = quotaService;
TariffService = tariffService;
UserFormatter = userFormatter;
ClientTenantManager = clientTenantManager;
TenantUtil = tenantUtil;
SettingsManager = settingsManager;
CoreSettings = coreSettings;
}
public void Init(string region)
{
Region = region;
}
public List<Tenant> GetTenants(DateTime from)
{

View File

@ -25,6 +25,10 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using System.Threading;
using ASC.Common.Security.Authorizing;
namespace ASC.ApiSystem.Classes;
[Scope]
@ -68,8 +72,8 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
if (Convert.ToBoolean(Configuration[Scheme.Name] ?? "false"))
{
Log.LogDebug("Auth for {0} skipped", Scheme.Name);
Log.LogDebug("Auth for {0} skipped", Scheme.Name);
Authenticate();
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, new AuthenticationProperties(), Scheme.Name)));
}
@ -95,7 +99,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
if (splitted.Length < 3)
{
Log.LogDebug("Auth failed: invalid token {0}.", header);
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Unauthorized))));
}
@ -147,7 +151,23 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
var identity = new ClaimsIdentity(Scheme.Name);
Log.LogInformation("Auth success {0}", Scheme.Name);
if (HttpContextAccessor?.HttpContext != null) HttpContextAccessor.HttpContext.User = new CustomClaimsPrincipal(new ClaimsIdentity(Scheme.Name), identity);
if (HttpContextAccessor?.HttpContext != null) HttpContextAccessor.HttpContext.User = new CustomClaimsPrincipal(new ClaimsIdentity(Scheme.Name), identity);
Authenticate();
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, new AuthenticationProperties(), Scheme.Name)));
}
private void Authenticate()
{
var account = Core.Configuration.Constants.SystemAccounts.FirstOrDefault(a => a.ID == Core.Configuration.Constants.CoreSystem.ID);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Sid, account.ID.ToString()),
new Claim(ClaimTypes.Name, account.Name),
new Claim(ClaimTypes.Role, Role.System)
};
HttpContextAccessor.HttpContext.User = new CustomClaimsPrincipal(new ClaimsIdentity(account, claims), account);
}
}

View File

@ -52,6 +52,8 @@
using ASC.Web.Core.PublicResources;
namespace ASC.ApiSystem.Controllers;
[Scope]
@ -92,7 +94,7 @@ public class CommonMethods
EmailValidationKeyProvider emailValidationKeyProvider,
TimeZoneConverter timeZoneConverter, CommonConstants commonConstants,
IMemoryCache memoryCache,
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
HostedSolution hostedSolution,
CoreBaseSettings coreBaseSettings,
TenantManager tenantManager,
IHttpClientFactory clientFactory)
@ -121,7 +123,8 @@ public class CommonMethods
ClientFactory = clientFactory;
HostedSolution = hostedSolutionOptions.Get(CommonConstants.BaseDbConnKeyString);
HostedSolution = hostedSolution;
HostedSolution.Init(CommonConstants.BaseDbConnKeyString);
}
@ -134,7 +137,7 @@ public class CommonMethods
hostedRegion = t.HostedRegion,
industry = t.Industry,
language = t.Language,
name = t.Name,
name = t.Name == "" ? Resource.PortalName : t.Name,
ownerId = t.OwnerId,
partnerId = t.PartnerId,
paymentId = t.PaymentId,
@ -172,6 +175,7 @@ public class CommonMethods
var request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(url);
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/x-www-form-urlencoded"));
try

View File

@ -0,0 +1,43 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL 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 details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using Microsoft.Extensions.Hosting;
namespace ASC.ApiSystem;
public static class ConfigurationManagerExtension
{
public static ConfigurationManager AddApiSystemConfiguration(
this ConfigurationManager config,
IHostEnvironment env)
{
config.AddJsonFile($"appsettings.services.json", true)
.AddJsonFile("notify.json")
.AddJsonFile($"notify.{env.EnvironmentName}.json", true);
return config;
}
}

View File

@ -124,7 +124,7 @@ public class CalDavController : ControllerBase
}
[HttpGet("caldav_delete_event")]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult CaldavDeleteEvent(string eventInfo)
{
if (!GetTenant(eventInfo, out var tenant, out var error))
@ -153,7 +153,7 @@ public class CalDavController : ControllerBase
}
[HttpPost("is_caldav_authenticated")]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult IsCaldavAuthenticated(UserPassword userPassword)
{
if (userPassword == null || string.IsNullOrEmpty(userPassword.User) || string.IsNullOrEmpty(userPassword.Password))

View File

@ -58,7 +58,7 @@ public class PeopleController : ControllerBase
public PeopleController(
ILogger<PeopleController> option,
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
HostedSolution hostedSolution,
UserFormatter userFormatter,
ICache cache,
CoreSettings coreSettings,
@ -66,7 +66,7 @@ public class PeopleController : ControllerBase
IHttpContextAccessor httpContextAccessor)
{
Log = option;
HostedSolution = hostedSolutionOptions.Value;
HostedSolution = hostedSolution;
UserFormatter = userFormatter;
Cache = cache;
CoreSettings = coreSettings;
@ -91,10 +91,10 @@ public class PeopleController : ControllerBase
[HttpPost("find")]
[AllowCrossSiteJson]
public IActionResult Find(IEnumerable<Guid> userIds)
public IActionResult Find(FindPeopleModel model)
{
var sw = Stopwatch.StartNew();
userIds = userIds ?? new List<Guid>();
var userIds = model.UserIds ?? new List<Guid>();
var users = HostedSolution.FindUsers(userIds);

View File

@ -55,7 +55,7 @@ public class PortalController : ControllerBase
SettingsManager settingsManager,
ApiSystemHelper apiSystemHelper,
CommonMethods commonMethods,
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
HostedSolution hostedSolution,
CoreSettings coreSettings,
TenantDomainValidator tenantDomainValidator,
UserFormatter userFormatter,
@ -72,7 +72,7 @@ public class PortalController : ControllerBase
SettingsManager = settingsManager;
ApiSystemHelper = apiSystemHelper;
CommonMethods = commonMethods;
HostedSolution = hostedSolutionOptions.Value;
HostedSolution = hostedSolution;
CoreSettings = coreSettings;
TenantDomainValidator = tenantDomainValidator;
UserFormatter = userFormatter;
@ -100,8 +100,9 @@ public class PortalController : ControllerBase
#region API methods
[HttpPost("register")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip.registerportal")]
[AllowCrossSiteJson]
[AllowAnonymous]
[Authorize(AuthenticationSchemes = "auth:allowskip:registerportal")]
public Task<IActionResult> RegisterAsync(TenantModel model)
{
if (model == null)
@ -207,7 +208,7 @@ public class PortalController : ControllerBase
var info = new TenantRegistrationInfo
{
Name = Configuration["web:portal-name"] ?? "Cloud Office Applications",
Name = Configuration["web:portal-name"] ?? "",
Address = model.PortalName,
Culture = lang,
FirstName = model.FirstName,
@ -336,7 +337,7 @@ public class PortalController : ControllerBase
[HttpDelete("remove")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult Remove([FromQuery] TenantModel model)
{
if (!CommonMethods.GetTenant(model, out var tenant))
@ -371,7 +372,7 @@ public class PortalController : ControllerBase
[HttpPut("status")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult ChangeStatus(TenantModel model)
{
if (!CommonMethods.GetTenant(model, out var tenant))
@ -446,7 +447,7 @@ public class PortalController : ControllerBase
[HttpGet("get")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult GetPortals([FromQuery] TenantModel model)
{
try

View File

@ -86,7 +86,7 @@ public class SettingsController : ControllerBase
#region API methods
[HttpGet("get")]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult GetSettings([FromQuery] SettingsModel model)
{
if (!GetTenant(model, out var tenantId, out var error))
@ -112,7 +112,7 @@ public class SettingsController : ControllerBase
}
[HttpPost("save")]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult SaveSettings([FromBody] SettingsModel model)
{
if (!GetTenant(model, out var tenantId, out var error))

View File

@ -61,12 +61,12 @@ public class TariffController : ControllerBase
private ILogger<TariffController> Log { get; }
public TariffController(
CommonMethods commonMethods,
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
HostedSolution hostedSolution,
ILogger<TariffController> option
)
{
CommonMethods = commonMethods;
HostedSolution = hostedSolutionOptions.Value;
HostedSolution = hostedSolution;
Log = option;
}
@ -87,7 +87,7 @@ public class TariffController : ControllerBase
[HttpPut("set")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult SetTariff(TariffModel model)
{
if (!CommonMethods.GetTenant(model, out var tenant))
@ -136,12 +136,12 @@ public class TariffController : ControllerBase
quota.MaxFileSize = model.MaxFileSize;
}
HostedSolution.SaveTenantQuota(quota);
HostedSolution.SaveTenantQuota(quota);
var tariff = new Tariff
{
QuotaId = quota.Tenant,
DueDate = model.DueDate != default ? model.DueDate : DateTime.MaxValue,
DueDate = model.DueDate != default ? model.DueDate : DateTime.MaxValue.AddSeconds(-1),
};
HostedSolution.SetTariff(tenant.Id, tariff);
@ -151,7 +151,7 @@ public class TariffController : ControllerBase
[HttpGet("get")]
[AllowCrossSiteJson]
[Authorize(AuthenticationSchemes = "auth.allowskip")]
[Authorize(AuthenticationSchemes = "auth:allowskip")]
public IActionResult GetTariff([FromQuery] TariffModel model)
{
if (!CommonMethods.GetTenant(model, out var tenant))

View File

@ -0,0 +1,32 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL 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 details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.ApiSystem.Models;
public class FindPeopleModel
{
public IEnumerable<Guid> UserIds { get; set; }
}

View File

@ -50,6 +50,8 @@
*/
using ASC.ApiSystem;
var options = new WebApplicationOptions
{
Args = args,
@ -58,34 +60,14 @@ var options = new WebApplicationOptions
var builder = WebApplication.CreateBuilder(options);
builder.Host.ConfigureDefault(args, (hostContext, config, env, path) =>
{
config.AddJsonFile($"appsettings.services.json", true)
.AddJsonFile("notify.json")
.AddJsonFile($"notify.{env.EnvironmentName}.json", true);
},
(hostContext, services, diHelper) =>
{
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
builder.Host.ConfigureDefault();
diHelper.TryAdd<AuthHandler>();
diHelper.AddControllers();
builder.Configuration.AddDefaultConfiguration(builder.Environment)
.AddApiSystemConfiguration(builder.Environment)
.AddEnvironmentVariables()
.AddCommandLine(args);
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.WriteIndented = false;
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
services.AddAutoMapper(Assembly.GetAssembly(typeof(MappingProfile)));
services.AddAuthentication()
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth.allowskip", _ => { })
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth.allowskip.registerportal", _ => { });
});
var startup = new BaseWorkerStartup(builder.Configuration);
var startup = new Startup(builder.Configuration, builder.Environment);
startup.ConfigureServices(builder.Services);
@ -96,6 +78,6 @@ builder.Host.ConfigureContainer<ContainerBuilder>((context, builder) =>
var app = builder.Build();
startup.Configure(app);
startup.Configure(app, app.Environment);
await app.RunAsync();

View File

@ -0,0 +1,53 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL 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 details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace ASC.ApiSystem;
public class Startup : BaseStartup
{
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base (configuration, hostEnvironment)
{
}
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
DIHelper.TryAdd<AuthHandler>();
services.AddAuthentication()
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth:allowskip", _ => { })
.AddScheme<AuthenticationSchemeOptions, AuthHandler>("auth:allowskip:registerportal", _ => { });
}
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
base.Configure(app, env);
}
}

View File

@ -54,7 +54,7 @@ public class GreetingSettingsController : BaseSettingsController
[HttpGet("greetingsettings")]
public ContentResult GetGreetingSettings()
{
return new ContentResult { Content = Tenant.Name };
return new ContentResult { Content = Tenant.Name == "" ? Resource.PortalName : Tenant.Name };
}
[HttpPost("greetingsettings")]
@ -79,7 +79,7 @@ public class GreetingSettingsController : BaseSettingsController
return new ContentResult
{
Content = Tenant.Name
Content = Tenant.Name == "" ? Resource.PortalName : Tenant.Name
};
}
}

View File

@ -145,7 +145,7 @@ public class SettingsController : BaseSettingsController
var settings = new SettingsDto
{
Culture = Tenant.GetCulture().ToString(),
GreetingSettings = Tenant.Name,
GreetingSettings = Tenant.Name == "" ? Resource.PortalName : Tenant.Name,
Personal = _coreBaseSettings.Personal,
DocSpace = !_coreBaseSettings.DisableDocSpace,
Version = _configuration["version:number"] ?? "",

View File

@ -356,7 +356,7 @@ public class NotifyTransferRequest : INotifyEngineAction
request.Arguments.Add(new TagValue(CommonTags.HelpLink, _commonLinkUtility.GetHelpLink(_settingsManager, _additionalWhiteLabelSettingsHelper, false)));
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, logoText));
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance(_settingsManager)));
request.Arguments.Add(new TagValue(CommonTags.SendFrom, tenant.Name));
request.Arguments.Add(new TagValue(CommonTags.SendFrom, tenant.Name == "" ? Resource.PortalName : tenant.Name));
request.Arguments.Add(new TagValue(CommonTags.ImagePath, _studioNotifyHelper.GetNotificationImageUrl("").TrimEnd('/')));
AddLetterLogo(request);

View File

@ -19,7 +19,7 @@ namespace ASC.Web.Core.PublicResources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resource {
@ -1995,6 +1995,15 @@ namespace ASC.Web.Core.PublicResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cloud space for your office docs.
/// </summary>
public static string PortalName {
get {
return ResourceManager.GetString("PortalName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Portal Access.
/// </summary>

View File

@ -828,4 +828,7 @@
<data name="MessageRoomInvitationsSentOnEmail" xml:space="preserve">
<value>Virtual room {0} invitations sent successfully.</value>
</data>
<data name="PortalName" xml:space="preserve">
<value>Cloud space for your office docs</value>
</data>
</root>

View File

@ -81,7 +81,7 @@ public class TenantInfoSettingsHelper
public void RestoreDefaultTenantName()
{
var currentTenant = _tenantManager.GetCurrentTenant();
currentTenant.Name = _configuration["web:portal-name"] ?? "Cloud Office Applications";
currentTenant.Name = _configuration["web:portal-name"] ?? "";
_tenantManager.SaveTenant(currentTenant);
}