Merge branch 'develop' into release/rc-v1.2.0

This commit is contained in:
Alexey Safronov 2022-12-07 16:20:29 +03:00
commit a03b50bd7c
17 changed files with 184 additions and 107 deletions

View File

@ -114,6 +114,7 @@ services:
- "9834"
onlyoffice-doceditor:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-doceditor:${DOCKER_TAG}"
container_name: ${DOCEDITOR_HOST}
restart: always
@ -121,6 +122,7 @@ services:
- "5013"
onlyoffice-login:
<<: *x-service-base
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-login:${DOCKER_TAG}"
container_name: ${LOGIN_HOST}
restart: always

View File

@ -61,7 +61,7 @@ public class CookieAuthHandler : AuthenticationHandler<AuthenticationSchemeOptio
{
try
{
var authorization = _httpContextAccessor.HttpContext.Request.Cookies["asc_auth_key"] ?? _httpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString();
var authorization = _httpContextAccessor.HttpContext.Request.Cookies[_cookiesManager.GetAscCookiesName()] ?? _httpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString();
if (string.IsNullOrEmpty(authorization))
{

View File

@ -30,11 +30,13 @@ namespace ASC.Api.Core;
public abstract class BaseStartup
{
private const string CustomCorsPolicyName = "Basic";
private const string BasicAuthScheme = "Basic";
private const string MultiAuthSchemes = "MultiAuthSchemes";
private readonly IConfiguration _configuration;
private readonly IHostEnvironment _hostEnvironment;
private readonly string _corsOrigin;
protected virtual JsonConverter[] Converters { get; }
protected virtual bool AddControllersAsServices { get; }
@ -48,6 +50,9 @@ public abstract class BaseStartup
{
_configuration = configuration;
_hostEnvironment = hostEnvironment;
_corsOrigin = _configuration["core:cors"];
DIHelper = new DIHelper();
if (bool.TryParse(_configuration["core:products"], out var loadProducts))
@ -117,6 +122,23 @@ public abstract class BaseStartup
DIHelper.TryAdd<CookieAuthHandler>();
DIHelper.TryAdd<WebhooksGlobalFilterAttribute>();
if (!string.IsNullOrEmpty(_corsOrigin))
{
services.AddCors(options =>
{
options.AddPolicy(name: CustomCorsPolicyName,
policy =>
{
policy.WithOrigins(_corsOrigin)
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
services.AddDistributedCache(_configuration);
services.AddEventBus(_configuration);
services.AddDistributedTaskQueue();
@ -252,6 +274,11 @@ public abstract class BaseStartup
app.UseRouting();
if (!string.IsNullOrEmpty(_corsOrigin))
{
app.UseCors(CustomCorsPolicyName);
}
if (AddAndUseSession)
{
app.UseSession();

View File

@ -24,6 +24,8 @@
// 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.Net.Http.Headers;
namespace ASC.Core;
@ -192,6 +194,19 @@ public class TenantManager
tenant = GetTenant(context.Request.GetUrlRewriter().Host);
context.Items[CurrentTenant] = tenant;
}
if (tenant == null && context.Request != null)
{
var origin = context.Request.Headers[HeaderNames.Origin].FirstOrDefault();
if (!string.IsNullOrEmpty(origin))
{
var originUri = new Uri(origin);
tenant = GetTenant(originUri.Host);
context.Items[CurrentTenant] = tenant;
}
}
}
if (tenant == null && throwIfNotFound)

View File

@ -42,15 +42,4 @@ public class Startup : BaseStartup
base.ConfigureServices(services);
}
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(builder =>
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
base.Configure(app, env);
}
}

View File

@ -28,16 +28,18 @@ namespace ASC.ApiSystem;
public class Startup
{
private const string CustomCorsPolicyName = "Basic";
private readonly IConfiguration _configuration;
private readonly IHostEnvironment _hostEnvironment;
private readonly DIHelper _diHelper;
private readonly string _corsOrigin;
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment)
{
_configuration = configuration;
_hostEnvironment = hostEnvironment;
_diHelper = new DIHelper();
_diHelper = new DIHelper();
_corsOrigin = _configuration["core:cors"];
}
public void ConfigureServices(IServiceCollection services)
@ -87,7 +89,23 @@ public class Startup
_diHelper.TryAdd<ConfirmAuthHandler>();
_diHelper.TryAdd<BasicAuthHandler>();
_diHelper.TryAdd<CookieAuthHandler>();
_diHelper.TryAdd<WebhooksGlobalFilterAttribute>();
_diHelper.TryAdd<WebhooksGlobalFilterAttribute>();
if (!string.IsNullOrEmpty(_corsOrigin))
{
services.AddCors(options =>
{
options.AddPolicy(name: CustomCorsPolicyName,
policy =>
{
policy.WithOrigins(_corsOrigin)
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
services.AddDistributedCache(_configuration);
services.AddEventBus(_configuration);
@ -115,7 +133,12 @@ public class Startup
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseRouting();
if (!string.IsNullOrEmpty(_corsOrigin))
{
app.UseCors(CustomCorsPolicyName);
}
app.UseAuthentication();
@ -129,7 +152,7 @@ public class Startup
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
});
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
{
Predicate = r => r.Name.Contains("self")

View File

@ -14,6 +14,7 @@
"AllowedHosts": "*",
"core": {
"base-domain": "",
"cors": "",
"machinekey": "1123askdasjklasbnd",
"notify": {
"postman": "log"

View File

@ -35,7 +35,6 @@ include /etc/nginx/includes/onlyoffice-*.conf;
server {
listen 8092;
add_header Access-Control-Allow-Origin *;
add_header X-Frame-Options $header_x_frame_options;
add_header Cache-Control $cache_control;
root $public_root;
@ -188,7 +187,6 @@ server {
location ~* portal/(.*)(backup|restore)(.*) {
rewrite (.*)/portal/(.*) $1/backup/$2 break;
proxy_redirect off;
proxy_pass http://127.0.0.1:5012;
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
}
@ -196,7 +194,6 @@ server {
location ~* authentication/register(.*) {
rewrite (.*)/authentication/register(.*) $1/people/register$2 break;
proxy_redirect off;
proxy_pass http://127.0.0.1:5004;
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
}
@ -260,6 +257,12 @@ server {
}
}
}
location /Products {
location ~* /Files {
rewrite ^/Products/Files(.*)$ $1 redirect;
}
}
location /apisystem {
rewrite apisystem/(.*) /$1 break;

View File

@ -72,7 +72,7 @@ class FilesListWrapper extends React.Component {
const options = getFolderOptions(folderId, this.newFilter);
const response = await axios
.get(combineUrl(AppServerConfig.apiPrefixURL, options.url), {
.get(combineUrl(AppServerConfig.apiPrefix, options.url), {
cancelToken: this.source.token,
})
.catch((thrown) => {

View File

@ -102,7 +102,7 @@ const PriceCalculation = ({
await axios
.put(
combineUrl(AppServerConfig.apiPrefixURL, "/portal/payment/url"),
combineUrl(AppServerConfig.apiPrefix, "/portal/payment/url"),
{ quantity: { admin: value } },
{
cancelToken: source.token,

View File

@ -4,7 +4,13 @@ const { proxy, api } = pks;
module.exports = {
proxyURL:
(proxy && proxy.url) || (window && window.APPSERVER_PROXY_URL) || "",
apiPrefixURL: (api && api.url) || "/api/2.0",
apiTimeout: (api && api.timeout) || 30000,
(proxy && proxy.url) ||
(typeof window !== "undefined" && window?.DOCSPACE_PROXY_URL) ||
"",
apiOrigin:
api?.origin ||
(typeof window !== "undefined" && window?.DOCSPACE_API_ORIGIN) ||
"",
apiPrefix: api?.prefix || "/api/2.0",
apiTimeout: api?.timeout || 30000,
};

View File

@ -48,7 +48,8 @@
"@welldone-software/why-did-you-render": "^6.2.1"
},
"api": {
"url": "/api/2.0",
"origin": "",
"prefix": "/api/2.0",
"timeout": "30000"
},
"proxy": {

View File

@ -2,7 +2,7 @@ import axios from "axios";
import { AppServerConfig } from "../constants";
import combineUrl from "./combineUrl";
const { proxyURL, apiPrefixURL, apiTimeout } = AppServerConfig;
const { proxyURL, apiOrigin, apiPrefix, apiTimeout } = AppServerConfig;
class AxiosClient {
constructor() {
@ -11,9 +11,16 @@ class AxiosClient {
initCSR = () => {
this.isSSR = false;
const origin = window.location.origin;
const origin = apiOrigin || window.location.origin;
let headers = null;
const apiBaseURL = combineUrl(origin, proxyURL, apiPrefixURL);
if (apiOrigin !== "") {
headers = {
'Access-Control-Allow-Credentials' : true
};
}
const apiBaseURL = combineUrl(origin, proxyURL, apiPrefix);
const paymentsURL = combineUrl(
proxyURL,
"/portal-settings/payments/portal-payments"
@ -24,23 +31,33 @@ class AxiosClient {
// ...window.AppServer,
// origin,
// proxyURL,
// apiPrefixURL,
// apiPrefix,
// apiBaseURL,
// apiTimeout,
// paymentsURL,
// };
this.client = axios.create({
const config = {
baseURL: apiBaseURL,
responseType: "json",
timeout: apiTimeout, // default is `0` (no timeout)
});
withCredentials: true
};
if (headers) {
config.headers = headers;
}
this.client = axios.create(config);
};
initSSR = (headers) => {
this.isSSR = true;
const xRewriterUrl = headers["x-rewriter-url"];
const apiBaseURL = combineUrl(xRewriterUrl, proxyURL, apiPrefixURL);
const origin = apiOrigin || xRewriterUrl;
const apiBaseURL = combineUrl(origin, proxyURL, apiPrefix);
this.client = axios.create({
baseURL: apiBaseURL,

View File

@ -72,12 +72,6 @@ public class Startup : BaseStartup
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(builder =>
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
base.Configure(app, env);
app.MapWhen(

View File

@ -1,6 +1,6 @@
{
"short_name": "AppServer",
"name": "Onlyoffice AppServer",
"short_name": "DocSpace",
"name": "Onlyoffice DocSpace",
"icons": [
{
"src": "icon.svg",

View File

@ -26,6 +26,8 @@
using ASC.Core.Data;
using Microsoft.Net.Http.Headers;
using Constants = ASC.Core.Users.Constants;
namespace ASC.Web.Core;
@ -71,29 +73,6 @@ public class CookiesManager
_messageService = messageService;
}
private static string GetCookiesName(CookiesType type)
{
return type switch
{
CookiesType.AuthKey => AuthCookiesName,
CookiesType.SocketIO => SocketIOCookiesName,
_ => string.Empty,
};
}
public string GetRequestVar(CookiesType type)
{
if (_httpContextAccessor?.HttpContext == null)
{
return "";
}
var cookie = _httpContextAccessor.HttpContext.Request.Query[GetCookiesName(type)].FirstOrDefault() ?? _httpContextAccessor.HttpContext.Request.Form[GetCookiesName(type)].FirstOrDefault();
return string.IsNullOrEmpty(cookie) ? GetCookies(type) : cookie;
}
public void SetCookies(CookiesType type, string value, bool session = false)
{
if (_httpContextAccessor?.HttpContext == null)
@ -110,45 +89,15 @@ public class CookiesManager
{
options.HttpOnly = true;
if (_httpContextAccessor.HttpContext.Request.GetUrlRewriter().Scheme == "https")
var urlRewriter = _httpContextAccessor.HttpContext.Request.GetUrlRewriter();
if (urlRewriter.Scheme == "https")
{
options.Secure = true;
if (_coreBaseSettings.Personal)
{
options.SameSite = SameSiteMode.None;
}
}
}
_httpContextAccessor.HttpContext.Response.Cookies.Append(GetCookiesName(type), value, options);
}
public void SetCookies(CookiesType type, string value, string domain, bool session = false)
{
if (_httpContextAccessor?.HttpContext == null)
{
return;
}
var options = new CookieOptions
{
Expires = GetExpiresDate(session),
Domain = domain
};
if (type == CookiesType.AuthKey)
{
options.HttpOnly = true;
if (_httpContextAccessor.HttpContext.Request.GetUrlRewriter().Scheme == "https")
if (FromCors())
{
options.Secure = true;
if (_coreBaseSettings.Personal)
{
options.SameSite = SameSiteMode.None;
}
options.Domain = $".{_coreBaseSettings.Basedomain}";
}
}
@ -322,4 +271,62 @@ public class CookiesManager
return _messageService.SendLoginMessage(data, action);
}
public string GetAscCookiesName()
{
return GetCookiesName(CookiesType.AuthKey);
}
private string GetCookiesName(CookiesType type)
{
var result = type switch
{
CookiesType.AuthKey => AuthCookiesName,
CookiesType.SocketIO => SocketIOCookiesName,
_ => string.Empty,
};
if (FromCors())
{
var origin = _httpContextAccessor.HttpContext.Request.Headers[HeaderNames.Origin].FirstOrDefault();
if (!string.IsNullOrEmpty(origin))
{
var originUri = new Uri(origin);
var host = originUri.Host;
var alias = host.Substring(0, host.Length - _coreBaseSettings.Basedomain.Length - 1);
result = $"{result}_{alias}";
}
}
return result;
}
private bool FromCors()
{
var urlRewriter = _httpContextAccessor.HttpContext.Request.GetUrlRewriter();
var origin = _httpContextAccessor.HttpContext.Request.Headers[HeaderNames.Origin].FirstOrDefault();
var baseDomain = _coreBaseSettings.Basedomain;
try
{
if (!string.IsNullOrEmpty(origin))
{
var originUri = new Uri(origin);
if (!string.IsNullOrEmpty(baseDomain) &&
urlRewriter.Host != originUri.Host &&
originUri.Host.EndsWith(baseDomain))
{
return true;
}
}
}
catch (Exception)
{
}
return false;
}
}

View File

@ -41,12 +41,6 @@ public class Startup : BaseStartup
});
app.UseRouting();
app.UseCors(builder =>
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
app.UseAuthentication();
@ -71,9 +65,7 @@ public class Startup : BaseStartup
}
public override void ConfigureServices(IServiceCollection services)
{
services.AddCors();
{
base.ConfigureServices(services);
services.AddMemoryCache();