mirror of
https://github.com/bitwarden/server.git
synced 2024-11-25 12:45:18 +01:00
hibp api v3
This commit is contained in:
parent
2c80e337ae
commit
b21e89f264
@ -8,6 +8,7 @@ using Bit.Core.Services;
|
|||||||
using Bit.Core;
|
using Bit.Core;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Bit.Api.Controllers
|
namespace Bit.Api.Controllers
|
||||||
{
|
{
|
||||||
@ -15,17 +16,18 @@ namespace Bit.Api.Controllers
|
|||||||
[Authorize("Application")]
|
[Authorize("Application")]
|
||||||
public class HibpController : Controller
|
public class HibpController : Controller
|
||||||
{
|
{
|
||||||
private const string HibpBreachApi = "https://haveibeenpwned.com/api/v2/breachedaccount/{0}";
|
private const string HibpBreachApi = "https://haveibeenpwned.com/api/v3/breachedaccount/{0}" +
|
||||||
|
"?truncateResponse=false&includeUnverified=false";
|
||||||
private static HttpClient _httpClient;
|
private static HttpClient _httpClient;
|
||||||
|
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly CurrentContext _currentContext;
|
private readonly CurrentContext _currentContext;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
private readonly string _userAgent;
|
||||||
|
|
||||||
static HibpController()
|
static HibpController()
|
||||||
{
|
{
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "Bitwarden");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HibpController(
|
public HibpController(
|
||||||
@ -36,19 +38,24 @@ namespace Bit.Api.Controllers
|
|||||||
_userService = userService;
|
_userService = userService;
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
|
_userAgent = _globalSettings.SelfHosted ? "Bitwarden Self-Hosted" : "Bitwarden";
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("breach")]
|
[HttpGet("breach")]
|
||||||
public async Task<IActionResult> Get(string username)
|
public async Task<IActionResult> Get(string username)
|
||||||
{
|
{
|
||||||
var encodedUsername = WebUtility.UrlEncode(username);
|
return await SendAsync(WebUtility.UrlEncode(username), true);
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, string.Format(HibpBreachApi, encodedUsername));
|
}
|
||||||
if(!string.IsNullOrWhiteSpace(_globalSettings.HibpBreachApiKey))
|
|
||||||
|
private async Task<IActionResult> SendAsync(string username, bool retry)
|
||||||
|
{
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, string.Format(HibpBreachApi, username));
|
||||||
|
if(!string.IsNullOrWhiteSpace(_globalSettings.HibpApiKey))
|
||||||
{
|
{
|
||||||
request.Headers.Add("Authorization", $"Basic {_globalSettings.HibpBreachApiKey}");
|
request.Headers.Add("hibp-api-key", _globalSettings.HibpApiKey);
|
||||||
}
|
}
|
||||||
request.Headers.Add("Client-Id", GetClientId());
|
request.Headers.Add("hibp-client-id", GetClientId());
|
||||||
request.Headers.Add("Client-Ip", _currentContext.IpAddress);
|
request.Headers.Add("User-Agent", _userAgent);
|
||||||
var response = await _httpClient.SendAsync(request);
|
var response = await _httpClient.SendAsync(request);
|
||||||
if(response.IsSuccessStatusCode)
|
if(response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
@ -59,6 +66,20 @@ namespace Bit.Api.Controllers
|
|||||||
{
|
{
|
||||||
return new NotFoundResult();
|
return new NotFoundResult();
|
||||||
}
|
}
|
||||||
|
else if(response.StatusCode == HttpStatusCode.TooManyRequests && retry)
|
||||||
|
{
|
||||||
|
var delay = 2000;
|
||||||
|
if(response.Headers.Contains("retry-after"))
|
||||||
|
{
|
||||||
|
var vals = response.Headers.GetValues("retry-after");
|
||||||
|
if(vals.Any() && int.TryParse(vals.FirstOrDefault(), out var secDelay))
|
||||||
|
{
|
||||||
|
delay = (secDelay * 1000) + 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Task.Delay(delay);
|
||||||
|
return await SendAsync(username, false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new BadRequestException("Request failed. Status code: " + response.StatusCode);
|
throw new BadRequestException("Request failed. Status code: " + response.StatusCode);
|
||||||
|
@ -14,7 +14,7 @@ namespace Bit.Core
|
|||||||
public string LicenseCertificatePassword { get; set; }
|
public string LicenseCertificatePassword { get; set; }
|
||||||
public virtual string PushRelayBaseUri { get; set; }
|
public virtual string PushRelayBaseUri { get; set; }
|
||||||
public virtual string InternalIdentityKey { get; set; }
|
public virtual string InternalIdentityKey { get; set; }
|
||||||
public virtual string HibpBreachApiKey { get; set; }
|
public virtual string HibpApiKey { get; set; }
|
||||||
public virtual bool DisableUserRegistration { get; set; }
|
public virtual bool DisableUserRegistration { get; set; }
|
||||||
public virtual bool DisableEmailNewDevice { get; set; }
|
public virtual bool DisableEmailNewDevice { get; set; }
|
||||||
public virtual int OrganizationInviteExpirationHours { get; set; } = 120; // 5 days
|
public virtual int OrganizationInviteExpirationHours { get; set; } = 120; // 5 days
|
||||||
|
Loading…
Reference in New Issue
Block a user