mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 08:32:50 -05:00
Protect user registration with captcha (#1480)
* Protect user registration with captcha * PR feedback
This commit is contained in:
@ -1,13 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public interface ICaptchaValidationService
|
||||
{
|
||||
bool ServiceEnabled { get; }
|
||||
string SiteKey { get; }
|
||||
bool RequireCaptcha { get; }
|
||||
string SiteKeyResponseKeyName { get; }
|
||||
bool RequireCaptchaValidation(ICurrentContext currentContext);
|
||||
Task<bool> ValidateCaptchaResponseAsync(string captchResponse, string clientIpAddress);
|
||||
string GenerateCaptchaBypassToken(User user);
|
||||
bool ValidateCaptchaBypassToken(string encryptedToken, User user);
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
@ -33,9 +34,8 @@ namespace Bit.Core.Services
|
||||
_dataProtector = dataProtectorProvider.CreateProtector("CaptchaServiceDataProtector");
|
||||
}
|
||||
|
||||
public bool ServiceEnabled => true;
|
||||
public string SiteKeyResponseKeyName => "HCaptcha_SiteKey";
|
||||
public string SiteKey => _globalSettings.Captcha.HCaptchaSiteKey;
|
||||
public bool RequireCaptcha => _globalSettings.Captcha.RequireCaptcha;
|
||||
|
||||
public string GenerateCaptchaBypassToken(User user) =>
|
||||
$"{TokenClearTextPrefix}{_dataProtector.Protect(CaptchaBypassTokenContent(user))}";
|
||||
@ -44,9 +44,9 @@ namespace Bit.Core.Services
|
||||
CoreHelpers.TokenIsValid(TokenName, _dataProtector, encryptedToken[TokenClearTextPrefix.Length..],
|
||||
user.Email, user.Id, TokenLifetimeInHours);
|
||||
|
||||
public async Task<bool> ValidateCaptchaResponseAsync(string captchResponse, string clientIpAddress)
|
||||
public async Task<bool> ValidateCaptchaResponseAsync(string captchaResponse, string clientIpAddress)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(captchResponse))
|
||||
if (string.IsNullOrWhiteSpace(captchaResponse))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -59,7 +59,7 @@ namespace Bit.Core.Services
|
||||
RequestUri = new Uri("https://hcaptcha.com/siteverify"),
|
||||
Content = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||
{
|
||||
{ "response", captchResponse.TrimStart("hcaptcha|".ToCharArray()) },
|
||||
{ "response", captchaResponse.TrimStart("hcaptcha|".ToCharArray()) },
|
||||
{ "secret", _globalSettings.Captcha.HCaptchaSecretKey },
|
||||
{ "sitekey", SiteKey },
|
||||
{ "remoteip", clientIpAddress }
|
||||
@ -87,6 +87,9 @@ namespace Bit.Core.Services
|
||||
return (bool)jsonResponse.success;
|
||||
}
|
||||
|
||||
public bool RequireCaptchaValidation(ICurrentContext currentContext) =>
|
||||
currentContext.IsBot || _globalSettings.Captcha.ForceCaptchaRequired;
|
||||
|
||||
private static string CaptchaBypassTokenContent(User user) =>
|
||||
string.Join(' ', new object[] {
|
||||
TokenName,
|
||||
|
@ -1,13 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class NoopCaptchaValidationService : ICaptchaValidationService
|
||||
{
|
||||
public bool ServiceEnabled => false;
|
||||
public string SiteKeyResponseKeyName => null;
|
||||
public string SiteKey => null;
|
||||
public bool RequireCaptcha => false;
|
||||
public bool RequireCaptchaValidation(ICurrentContext currentContext) => false;
|
||||
|
||||
public string GenerateCaptchaBypassToken(User user) => "";
|
||||
public bool ValidateCaptchaBypassToken(string encryptedToken, User user) => false;
|
||||
|
Reference in New Issue
Block a user