diff --git a/src/Api/Controllers/TwoFactorController.cs b/src/Api/Controllers/TwoFactorController.cs index b6d2d0d3a..2690d0c55 100644 --- a/src/Api/Controllers/TwoFactorController.cs +++ b/src/Api/Controllers/TwoFactorController.cs @@ -12,6 +12,7 @@ using System.Linq; using Bit.Core; using Bit.Core.Repositories; using Bit.Core.Utilities; +using Bit.Core.Utilities.Duo; namespace Bit.Api.Controllers { @@ -143,6 +144,16 @@ namespace Bit.Api.Controllers public async Task PutDuo([FromBody]UpdateTwoFactorDuoRequestModel model) { var user = await CheckAsync(model.MasterPasswordHash, true); + try + { + var duoApi = new DuoApi(model.IntegrationKey, model.SecretKey, model.Host); + duoApi.JSONApiCall("GET", "/auth/v2/check"); + } + catch(DuoException) + { + throw new BadRequestException("Duo configuration settings are not valid. Please re-check the Duo Admin panel."); + } + model.ToUser(user); await _userService.UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.Duo); var response = new TwoFactorDuoResponseModel(user); diff --git a/src/Core/Utilities/DuoApi.cs b/src/Core/Utilities/DuoApi.cs index 820692652..aab41e7e7 100644 --- a/src/Core/Utilities/DuoApi.cs +++ b/src/Core/Utilities/DuoApi.cs @@ -79,7 +79,7 @@ namespace Bit.Core.Utilities.Duo return string.Concat("Basic ", Encode64(auth)); } - public string ApiCall(string method, string path, Dictionary parameters) + public string ApiCall(string method, string path, Dictionary parameters = null) { return ApiCall(method, path, parameters, 0, out var statusCode); } @@ -94,6 +94,11 @@ namespace Bit.Core.Utilities.Duo public string ApiCall(string method, string path, Dictionary parameters, int timeout, out HttpStatusCode statusCode) { + if(parameters == null) + { + parameters = new Dictionary(); + } + var canonParams = CanonicalizeParams(parameters); var query = string.Empty; if(!method.Equals("POST") && !method.Equals("PUT")) @@ -151,7 +156,7 @@ namespace Bit.Core.Utilities.Duo } } - public T JSONApiCall(string method, string path, Dictionary parameters) + public T JSONApiCall(string method, string path, Dictionary parameters = null) where T : class { return JSONApiCall(method, path, parameters, 0);