Merge branch 'master' into feature/files

This commit is contained in:
Alexey Safronov 2020-09-30 18:28:27 +03:00
commit 140d57d5d4
8 changed files with 76 additions and 40 deletions

View File

@ -39,13 +39,13 @@ namespace ASC.Security.Cryptography
public PasswordHasher(IConfiguration configuration, MachinePseudoKeys machinePseudoKeys)
{
if (!int.TryParse(configuration["core:password:size"], out var size)) size = 256;
PasswordHashSize = size;
Size = size;
if (!int.TryParse(configuration["core.password.iterations"], out var iterations)) iterations = 100000;
PasswordHashIterations = iterations;
Iterations = iterations;
PasswordHashSalt = (configuration["core:password:salt"] ?? "").Trim();
if (string.IsNullOrEmpty(PasswordHashSalt))
Salt = (configuration["core:password:salt"] ?? "").Trim();
if (string.IsNullOrEmpty(Salt))
{
var salt = Hasher.Hash("{9450BEF7-7D9F-4E4F-A18A-971D8681722D}", HashAlg.SHA256);
@ -53,25 +53,25 @@ namespace ASC.Security.Cryptography
Encoding.UTF8.GetString(machinePseudoKeys.GetMachineConstant()),
salt,
KeyDerivationPrf.HMACSHA256,
PasswordHashIterations,
PasswordHashSize / 8);
PasswordHashSalt = BitConverter.ToString(PasswordHashSaltBytes).Replace("-", string.Empty).ToLower();
Iterations,
Size / 8);
Salt = BitConverter.ToString(PasswordHashSaltBytes).Replace("-", string.Empty).ToLower();
}
}
public int PasswordHashSize
public int Size
{
get;
private set;
}
public int PasswordHashIterations
public int Iterations
{
get;
private set;
}
public string PasswordHashSalt
public string Salt
{
get;
private set;
@ -81,14 +81,14 @@ namespace ASC.Security.Cryptography
{
if (string.IsNullOrWhiteSpace(password)) password = Guid.NewGuid().ToString();
var salt = new UTF8Encoding(false).GetBytes(PasswordHashSalt);
var salt = new UTF8Encoding(false).GetBytes(Salt);
var hashBytes = KeyDerivation.Pbkdf2(
password,
salt,
KeyDerivationPrf.HMACSHA256,
PasswordHashIterations,
PasswordHashSize / 8);
Iterations,
Size / 8);
var hash = BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLower();

View File

@ -67,7 +67,6 @@ namespace ASC.Core.Data
public class EFUserService : IUserService
{
public Expression<Func<User, UserInfo>> FromUserToUserInfo { get; set; }
public Expression<Func<DbUserSecurity, UserInfo>> FromDbUserSecurityToUserInfo { get; set; }
public Func<UserInfo, User> FromUserInfoToUser { get; set; }
public Expression<Func<DbGroup, Group>> FromDbGroupToGroup { get; set; }
public Func<Group, DbGroup> FromGroupToDbGroup { get; set; }
@ -111,9 +110,6 @@ namespace ASC.Core.Data
Contacts = user.Contacts
};
var fromUserToUserInfo = FromUserToUserInfo.Compile();
FromDbUserSecurityToUserInfo = r => fromUserToUserInfo(r.User);
FromUserInfoToUser = user => new User
{
ActivationStatus = user.ActivationStatus,
@ -246,7 +242,7 @@ namespace ASC.Core.Data
q = q.Where(r => r.User.Tenant == tenant);
}
return q.Select(FromDbUserSecurityToUserInfo).FirstOrDefault();
return q.Select(r => r.User).Select(FromUserToUserInfo).FirstOrDefault();
}
else
{
@ -576,7 +572,8 @@ namespace ASC.Core.Data
Tenant = tenant,
UserId = id,
PwdHash = h1,
PwdHashSha512 = null //todo: remove
PwdHashSha512 = null,//todo: remove
LastModified = DateTime.UtcNow
};
UserDbContext.AddOrUpdate(r => r.UserSecurity, us);

View File

@ -17,12 +17,18 @@ map $uri $basename {
~/(?<captured_basename>[^/]*)$ $captured_basename;
}
map $request_uri $header_x_frame_options {
~*^/(favicon\.ico|products\/files\/share|products\/files\/saveas|products\/files\/filechoice|products\/files\/doceditor|thirdparty\/plugin) "";
default "SAMEORIGIN";
}
include /etc/nginx/includes/onlyoffice-*.conf;
server {
listen 8092;
add_header Access-Control-Allow-Origin *;
add_header X-Frame-Options $header_x_frame_options;
large_client_header_buffers 4 16k;

View File

@ -464,19 +464,22 @@ namespace ASC.Employee.Core.Controllers
var user = new UserInfo();
memberModel.Password = (memberModel.Password ?? "").Trim();
if (string.IsNullOrEmpty(memberModel.Password))
memberModel.PasswordHash = (memberModel.PasswordHash ?? "").Trim();
if (string.IsNullOrEmpty(memberModel.PasswordHash))
{
memberModel.Password = UserManagerWrapper.GeneratePassword();
}
else
{
UserManagerWrapper.CheckPasswordPolicy(memberModel.Password);
}
memberModel.Password = (memberModel.Password ?? "").Trim();
var passwordHash = PasswordHasher.GetClientPassword(memberModel.Password);
if (string.IsNullOrEmpty(memberModel.Password))
{
memberModel.Password = UserManagerWrapper.GeneratePassword();
}
else
{
UserManagerWrapper.CheckPasswordPolicy(memberModel.Password);
}
memberModel.PasswordHash = PasswordHasher.GetClientPassword(memberModel.Password);
}
//Validate email
var address = new MailAddress(memberModel.Email);
@ -496,7 +499,7 @@ namespace ASC.Employee.Core.Controllers
UpdateContacts(memberModel.Contacts, user);
user = UserManagerWrapper.AddUser(user, passwordHash, false, false, memberModel.IsVisitor);
user = UserManagerWrapper.AddUser(user, memberModel.PasswordHash, false, false, memberModel.IsVisitor);
user.ActivationStatus = EmployeeActivationStatus.Activated;
@ -982,11 +985,20 @@ namespace ASC.Employee.Core.Controllers
}
}
if (!string.IsNullOrEmpty(memberModel.Password))
memberModel.PasswordHash = (memberModel.PasswordHash ?? "").Trim();
if (string.IsNullOrEmpty(memberModel.PasswordHash))
{
var passwordHash = PasswordHasher.GetClientPassword(memberModel.Password);
SecurityContext.SetUserPasswordHash(userid, passwordHash);
memberModel.Password = (memberModel.Password ?? "").Trim();
if (!string.IsNullOrEmpty(memberModel.Password))
{
memberModel.PasswordHash = PasswordHasher.GetClientPassword(memberModel.Password);
}
}
if (!string.IsNullOrEmpty(memberModel.PasswordHash))
{
SecurityContext.SetUserPasswordHash(userid, memberModel.PasswordHash);
MessageService.Send(MessageAction.UserUpdatedPassword);
CookiesManager.ResetUserCookie(userid);

View File

@ -57,7 +57,7 @@ namespace ASC.Web.Api.Controllers
public AuthenticationTokenData AuthenticateMe([FromBody] AuthModel auth)
{
var tenant = TenantManager.GetCurrentTenant();
var user = GetUser(tenant.TenantId, auth.UserName, auth.Password);
var user = GetUser(tenant.TenantId, auth);
try
{
@ -91,13 +91,24 @@ namespace ASC.Web.Api.Controllers
return model.Validate();
}
private UserInfo GetUser(int tenantId, string userName, string password)
private UserInfo GetUser(int tenantId, AuthModel memberModel)
{
var passwordHash = PasswordHasher.GetClientPassword(password);
memberModel.PasswordHash = (memberModel.PasswordHash ?? "").Trim();
if (string.IsNullOrEmpty(memberModel.PasswordHash))
{
memberModel.Password = (memberModel.Password ?? "").Trim();
if (!string.IsNullOrEmpty(memberModel.Password))
{
memberModel.PasswordHash = PasswordHasher.GetClientPassword(memberModel.Password);
}
}
var user = UserManager.GetUsersByPasswordHash(
tenantId,
userName,
passwordHash);
memberModel.UserName,
memberModel.PasswordHash);
if (user == null || !UserManager.UserExists(user))
{

View File

@ -163,6 +163,7 @@ namespace ASC.Api.Settings
private BackupServiceNotifier BackupServiceNotifier { get; }
private ICacheNotify<DeleteSchedule> CacheDeleteSchedule { get; }
private EncryptionServiceNotifier EncryptionServiceNotifier { get; }
private PasswordHasher PasswordHasher { get; }
private ILog Log { get; set; }
private TelegramHelper TelegramHelper { get; }
@ -225,7 +226,8 @@ namespace ASC.Api.Settings
EncryptionSettingsHelper encryptionSettingsHelper,
BackupServiceNotifier backupServiceNotifier,
ICacheNotify<DeleteSchedule> cacheDeleteSchedule,
EncryptionServiceNotifier encryptionServiceNotifier)
EncryptionServiceNotifier encryptionServiceNotifier,
PasswordHasher passwordHasher)
{
Log = option.Get("ASC.Api");
WebHostEnvironment = webHostEnvironment;
@ -283,6 +285,7 @@ namespace ASC.Api.Settings
BackupServiceNotifier = backupServiceNotifier;
CacheDeleteSchedule = cacheDeleteSchedule;
EncryptionServiceNotifier = encryptionServiceNotifier;
PasswordHasher = passwordHasher;
StorageFactory = storageFactory;
UrlShortener = urlShortener;
TelegramHelper = telegramHelper;
@ -326,6 +329,8 @@ namespace ASC.Api.Settings
settings.EnableAdmMess = studioAdminMessageSettings.Enable || TenantExtra.IsNotPaid();
settings.ThirdpartyEnable = SetupInfo.ThirdPartyAuthEnabled && ProviderManager.IsNotEmpty;
settings.PasswordHash = PasswordHasher;
}
return settings;
@ -2455,7 +2460,8 @@ namespace ASC.Api.Settings
.AddBackupService()
.AddEncryptionServiceNotifierService()
.AddTelegramLoginProviderService()
.AddTelegramHelperSerivce();
.AddTelegramHelperSerivce()
.AddPasswordHasherService();
}
}
}

View File

@ -4,5 +4,6 @@
{
public string UserName { get; set; }
public string Password { get; set; }
public string PasswordHash { get; set; }
}
}

View File

@ -28,6 +28,7 @@ using System;
using System.Collections.Generic;
using ASC.Core.Tenants;
using ASC.Security.Cryptography;
namespace ASC.Api.Settings
{
@ -59,6 +60,8 @@ namespace ASC.Api.Settings
public string WizardToken { get; set; }
public PasswordHasher PasswordHash { get; set; }
public static SettingsWrapper GetSample()
{
return new SettingsWrapper