1
0
mirror of https://github.com/bitwarden/server synced 2026-01-03 09:03:44 +00:00

PM-21024 ChangePasswordUri controller + service (#5845)

* add ChangePasswordUri controller and service to Icons

* add individual settings for change password uri

* add logging to change password uri controller

* use custom http client that follows redirects

* add ChangePasswordUriService tests

* remove unneeded null check

* fix copy pasta - changePasswordUriSettings

* add `HelpUsersUpdatePasswords` policy

* Remove policy for change password uri - this was removed from scope

* fix nullable warnings
This commit is contained in:
Nick Krantz
2025-08-26 07:35:23 -05:00
committed by GitHub
parent a4c4d0157b
commit 004e6285a1
9 changed files with 343 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
using Bit.Icons.Models;
using Bit.Icons.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
namespace Bit.Icons.Controllers;
[Route("change-password-uri")]
public class ChangePasswordUriController : Controller
{
private readonly IMemoryCache _memoryCache;
private readonly IDomainMappingService _domainMappingService;
private readonly IChangePasswordUriService _changePasswordService;
private readonly ChangePasswordUriSettings _changePasswordSettings;
private readonly ILogger<ChangePasswordUriController> _logger;
public ChangePasswordUriController(
IMemoryCache memoryCache,
IDomainMappingService domainMappingService,
IChangePasswordUriService changePasswordService,
ChangePasswordUriSettings changePasswordUriSettings,
ILogger<ChangePasswordUriController> logger)
{
_memoryCache = memoryCache;
_domainMappingService = domainMappingService;
_changePasswordService = changePasswordService;
_changePasswordSettings = changePasswordUriSettings;
_logger = logger;
}
[HttpGet("config")]
public IActionResult GetConfig()
{
return new JsonResult(new
{
_changePasswordSettings.CacheEnabled,
_changePasswordSettings.CacheHours,
_changePasswordSettings.CacheSizeLimit
});
}
[HttpGet]
public async Task<IActionResult> Get([FromQuery] string uri)
{
if (string.IsNullOrWhiteSpace(uri))
{
return new BadRequestResult();
}
var uriHasProtocol = uri.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
uri.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
var url = uriHasProtocol ? uri : $"https://{uri}";
if (!Uri.TryCreate(url, UriKind.Absolute, out var validUri))
{
return new BadRequestResult();
}
var domain = validUri.Host;
var mappedDomain = _domainMappingService.MapDomain(domain);
if (!_changePasswordSettings.CacheEnabled || !_memoryCache.TryGetValue(mappedDomain, out string? changePasswordUri))
{
var result = await _changePasswordService.GetChangePasswordUri(domain);
if (result == null)
{
_logger.LogWarning("Null result returned for {0}.", domain);
changePasswordUri = null;
}
else
{
changePasswordUri = result;
}
if (_changePasswordSettings.CacheEnabled)
{
_logger.LogInformation("Cache uri for {0}.", domain);
_memoryCache.Set(mappedDomain, changePasswordUri, new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = new TimeSpan(_changePasswordSettings.CacheHours, 0, 0),
Size = changePasswordUri?.Length ?? 0,
Priority = changePasswordUri == null ? CacheItemPriority.High : CacheItemPriority.Normal
});
}
}
return Ok(new ChangePasswordUriResponse(changePasswordUri));
}
}