1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-22 21:51:22 +01:00

do not send push notifications to device that intiated the cipher create/update/delete since that device should arleady be handling the action after API response.

This commit is contained in:
Kyle Spearrin 2016-08-06 02:29:15 -04:00
parent 929e264549
commit f07e9e9dd0
4 changed files with 32 additions and 10 deletions

View File

@ -9,5 +9,6 @@ namespace Bit.Core
public class CurrentContext public class CurrentContext
{ {
public virtual User User { get; set; } public virtual User User { get; set; }
public virtual string DeviceIdentifier { get; set; }
} }
} }

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Bit.Core.Domains; using Bit.Core.Domains;
using System.Linq;
namespace Bit.Core.Identity namespace Bit.Core.Identity
{ {
@ -37,6 +38,11 @@ namespace Bit.Core.Identity
// register the current context user // register the current context user
var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>(); var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>();
currentContext.User = user; currentContext.User = user;
var deviceIdentifierClaim = context.Ticket.Principal.Claims.SingleOrDefault(c => c.Type == "DeviceIdentifier");
if(deviceIdentifierClaim != null)
{
currentContext.DeviceIdentifier = deviceIdentifierClaim.Value;
}
} }
public static Task AuthenticationFailedAsync(AuthenticationFailedContext context) public static Task AuthenticationFailedAsync(AuthenticationFailedContext context)

View File

@ -68,7 +68,7 @@ namespace Bit.Core.Identity
if(await UserManager.CheckPasswordAsync(user, password)) if(await UserManager.CheckPasswordAsync(user, password))
{ {
var result = await SignInOrTwoFactorAsync(user); var result = await SignInOrTwoFactorAsync(user, device);
if(result.Succeeded && device != null) if(result.Succeeded && device != null)
{ {
var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id); var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id);
@ -105,7 +105,7 @@ namespace Bit.Core.Identity
if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code)) if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
{ {
var token = await SignInAsync(user, false); var token = await SignInAsync(user, false, device);
var success = JwtBearerSignInResult.Success; var success = JwtBearerSignInResult.Success;
success.Token = token; success.Token = token;
@ -127,7 +127,7 @@ namespace Bit.Core.Identity
return JwtBearerSignInResult.Failed; return JwtBearerSignInResult.Failed;
} }
private async Task<string> SignInAsync(User user, bool twoFactor) private async Task<string> SignInAsync(User user, bool twoFactor, Device device)
{ {
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
@ -150,6 +150,11 @@ namespace Bit.Core.Identity
} }
} }
if(device != null && !string.IsNullOrWhiteSpace(device.Identifier))
{
userPrincipal.Identities.First().AddClaim(new Claim("DeviceIdentifier", device.Identifier));
}
var descriptor = new SecurityTokenDescriptor var descriptor = new SecurityTokenDescriptor
{ {
Issuer = JwtIdentityOptions.Issuer, Issuer = JwtIdentityOptions.Issuer,
@ -164,13 +169,13 @@ namespace Bit.Core.Identity
return handler.WriteToken(securityToken); return handler.WriteToken(securityToken);
} }
private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user) private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user, Device device)
{ {
if(UserManager.SupportsUserTwoFactor && if(UserManager.SupportsUserTwoFactor &&
await UserManager.GetTwoFactorEnabledAsync(user) && await UserManager.GetTwoFactorEnabledAsync(user) &&
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0) (await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0)
{ {
var twoFactorToken = await SignInAsync(user, true); var twoFactorToken = await SignInAsync(user, true, device);
var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired; var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired;
twoFactorResult.Token = twoFactorToken; twoFactorResult.Token = twoFactorToken;
@ -179,7 +184,7 @@ namespace Bit.Core.Identity
return twoFactorResult; return twoFactorResult;
} }
var token = await SignInAsync(user, false); var token = await SignInAsync(user, false, device);
var result = JwtBearerSignInResult.Success; var result = JwtBearerSignInResult.Success;
result.Token = token; result.Token = token;

View File

@ -22,17 +22,20 @@ namespace Bit.Core.Services
{ {
private readonly IDeviceRepository _deviceRepository; private readonly IDeviceRepository _deviceRepository;
private readonly ILogger<IPushService> _logger; private readonly ILogger<IPushService> _logger;
private readonly CurrentContext _currentContext;
private GcmServiceBroker _gcmBroker; private GcmServiceBroker _gcmBroker;
private ApnsServiceBroker _apnsBroker; private ApnsServiceBroker _apnsBroker;
public PushService( public PushService(
IDeviceRepository deviceRepository, IDeviceRepository deviceRepository,
ILogger<IPushService> logger, ILogger<IPushService> logger,
CurrentContext currentContext,
IHostingEnvironment hostingEnvironment, IHostingEnvironment hostingEnvironment,
GlobalSettings globalSettings) GlobalSettings globalSettings)
{ {
_deviceRepository = deviceRepository; _deviceRepository = deviceRepository;
_logger = logger; _logger = logger;
_currentContext = currentContext;
InitGcmBroker(globalSettings); InitGcmBroker(globalSettings);
InitApnsBroker(globalSettings, hostingEnvironment); InitApnsBroker(globalSettings, hostingEnvironment);
@ -74,7 +77,13 @@ namespace Bit.Core.Services
Aps = new PushNotification.AppleData { ContentAvailable = 1 } Aps = new PushNotification.AppleData { ContentAvailable = 1 }
}; };
await PushToAllUserDevicesAsync(cipher.UserId, JObject.FromObject(message)); var excludedTokens = new List<string>();
if(!string.IsNullOrWhiteSpace(_currentContext.DeviceIdentifier))
{
excludedTokens.Add(_currentContext.DeviceIdentifier);
}
await PushToAllUserDevicesAsync(cipher.UserId, JObject.FromObject(message), excludedTokens);
} }
public async Task PushSyncCiphersAsync(Guid userId) public async Task PushSyncCiphersAsync(Guid userId)
@ -87,7 +96,7 @@ namespace Bit.Core.Services
Aps = new PushNotification.AppleData { ContentAvailable = 1 } Aps = new PushNotification.AppleData { ContentAvailable = 1 }
}; };
await PushToAllUserDevicesAsync(userId, JObject.FromObject(message)); await PushToAllUserDevicesAsync(userId, JObject.FromObject(message), null);
} }
private void InitGcmBroker(GlobalSettings globalSettings) private void InitGcmBroker(GlobalSettings globalSettings)
@ -255,9 +264,10 @@ namespace Bit.Core.Services
// timestamp is the time the token was reported as expired // timestamp is the time the token was reported as expired
} }
private async Task PushToAllUserDevicesAsync(Guid userId, JObject message) private async Task PushToAllUserDevicesAsync(Guid userId, JObject message, IEnumerable<string> tokensToSkip)
{ {
var devices = (await _deviceRepository.GetManyByUserIdAsync(userId)).Where(d => !string.IsNullOrWhiteSpace(d.PushToken)); var devices = (await _deviceRepository.GetManyByUserIdAsync(userId))
.Where(d => !string.IsNullOrWhiteSpace(d.PushToken) && (!tokensToSkip?.Contains(d.PushToken) ?? true));
if(devices.Count() == 0) if(devices.Count() == 0)
{ {
return; return;