From 35d10bbe210d1113afba14152f4b5a73e92bcfab Mon Sep 17 00:00:00 2001 From: anglicangeek Date: Mon, 6 Feb 2012 21:45:22 -0800 Subject: [PATCH] added configurable reCAPTCHA API keys, in app settings --- PoliteCaptcha/Const.cs | 2 ++ PoliteCaptcha/ErrorMessage.Designer.cs | 9 +++++++ PoliteCaptcha/ErrorMessage.resx | 3 +++ PoliteCaptcha/PoliteCaptcha.csproj | 1 + PoliteCaptcha/ReCaptchaGenerator.cs | 26 +++++++++++++++++++-- PoliteCaptcha/ReCaptchaValidator.cs | 18 ++++++++++---- Sample/RequestModels/SendFeedbackRequest.cs | 2 +- 7 files changed, 53 insertions(+), 8 deletions(-) diff --git a/PoliteCaptcha/Const.cs b/PoliteCaptcha/Const.cs index a412e22..6d8a319 100644 --- a/PoliteCaptcha/Const.cs +++ b/PoliteCaptcha/Const.cs @@ -11,6 +11,8 @@ public static class Const public const string ReCaptchControlId = "RudeCaptcha"; public const string ReCaptchaLocalhostPrivateKey = "6LehOM0SAAAAAC5LsEpHoyyMqJcz7f_zEfqm66um"; public const string ReCaptchaLocalhostPublicKey = "6LehOM0SAAAAAPgsjOy-6_grqy1JiB_W_jJa_aCw"; + public const string ReCaptchaPrivateKeyAppSettingKey = "reCAPTCHA::PrivateKey"; + public const string ReCaptchaPublicKeyAppSettingKey = "reCAPTCHA::PublicKey"; public const string ReCaptchaResponseField = "recaptcha_response_field"; } } diff --git a/PoliteCaptcha/ErrorMessage.Designer.cs b/PoliteCaptcha/ErrorMessage.Designer.cs index c574ff6..530aad4 100644 --- a/PoliteCaptcha/ErrorMessage.Designer.cs +++ b/PoliteCaptcha/ErrorMessage.Designer.cs @@ -60,6 +60,15 @@ public class ErrorMessage { } } + /// + /// Looks up a localized string similar to The default reCAPTCHA API keys may only be used for local requests. Configure your app's own API keys in app settings.. + /// + public static string DefaultReCaptchApiKeysOnlyAllowedForLocalRequest { + get { + return ResourceManager.GetString("DefaultReCaptchApiKeysOnlyAllowedForLocalRequest", resourceCulture); + } + } + /// /// Looks up a localized string similar to The HTTP context must not be null.. /// diff --git a/PoliteCaptcha/ErrorMessage.resx b/PoliteCaptcha/ErrorMessage.resx index beb17d9..8e77047 100644 --- a/PoliteCaptcha/ErrorMessage.resx +++ b/PoliteCaptcha/ErrorMessage.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + The default reCAPTCHA API keys may only be used for local requests. Configure your app's own API keys in app settings. + The HTTP context must not be null. diff --git a/PoliteCaptcha/PoliteCaptcha.csproj b/PoliteCaptcha/PoliteCaptcha.csproj index 21d63da..de66b84 100644 --- a/PoliteCaptcha/PoliteCaptcha.csproj +++ b/PoliteCaptcha/PoliteCaptcha.csproj @@ -37,6 +37,7 @@ ..\packages\recaptcha.1.0.5.0\lib\.NetFramework 4.0\Recaptcha.dll + diff --git a/PoliteCaptcha/ReCaptchaGenerator.cs b/PoliteCaptcha/ReCaptchaGenerator.cs index a04fdc6..5cae18d 100644 --- a/PoliteCaptcha/ReCaptchaGenerator.cs +++ b/PoliteCaptcha/ReCaptchaGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Configuration; using System.IO; using System.Web; using System.Web.Mvc; @@ -11,11 +12,32 @@ public class ReCaptchaGenerator : ICaptchaGenerator { public IHtmlString Generate(HtmlHelper htmlHelper) { + if (htmlHelper == null) + throw new ArgumentNullException("htmlHelper"); + + var publicApiKey = ConfigurationManager.AppSettings[Const.ReCaptchaPublicKeyAppSettingKey]; + if (publicApiKey == null) + { + if (!htmlHelper.ViewContext.HttpContext.Request.IsLocal) + throw new InvalidOperationException(ErrorMessage.DefaultReCaptchApiKeysOnlyAllowedForLocalRequest); + + publicApiKey = Const.ReCaptchaLocalhostPublicKey; + } + + var privateApiKey = ConfigurationManager.AppSettings[Const.ReCaptchaPrivateKeyAppSettingKey]; + if (privateApiKey == null) + { + if (!htmlHelper.ViewContext.HttpContext.Request.IsLocal) + throw new InvalidOperationException(ErrorMessage.DefaultReCaptchApiKeysOnlyAllowedForLocalRequest); + + privateApiKey = Const.ReCaptchaLocalhostPrivateKey; + } + var recaptchaControl = new RecaptchaControl { ID = Const.ReCaptchControlId, - PublicKey = Const.ReCaptchaLocalhostPublicKey, - PrivateKey = Const.ReCaptchaLocalhostPrivateKey, + PublicKey = publicApiKey, + PrivateKey = privateApiKey, }; var htmlWriter = new HtmlTextWriter(new StringWriter()); diff --git a/PoliteCaptcha/ReCaptchaValidator.cs b/PoliteCaptcha/ReCaptchaValidator.cs index 3644db9..dffd0a5 100644 --- a/PoliteCaptcha/ReCaptchaValidator.cs +++ b/PoliteCaptcha/ReCaptchaValidator.cs @@ -1,4 +1,5 @@ using System; +using System.Configuration; using System.Web; using Recaptcha; @@ -10,10 +11,7 @@ public class ReCaptchaValidator : ICaptchaValidator public ReCaptchaValidator() { - recaptchaValidator = new RecaptchaValidator - { - PrivateKey = Const.ReCaptchaLocalhostPrivateKey, - }; + recaptchaValidator = new RecaptchaValidator(); } public bool Validate(HttpContextBase httpContext) @@ -21,6 +19,15 @@ public bool Validate(HttpContextBase httpContext) if (httpContext == null) throw new ArgumentNullException("httpContext"); + var privateApiKey = ConfigurationManager.AppSettings[Const.ReCaptchaPrivateKeyAppSettingKey]; + if (privateApiKey == null) + { + if (!httpContext.Request.IsLocal) + throw new InvalidOperationException(ErrorMessage.DefaultReCaptchApiKeysOnlyAllowedForLocalRequest); + + privateApiKey = Const.ReCaptchaLocalhostPrivateKey; + } + var challenge = httpContext.Request.Form[Const.ReCaptchaChallengeField]; if (string.IsNullOrWhiteSpace(challenge)) return false; @@ -29,9 +36,10 @@ public bool Validate(HttpContextBase httpContext) if (string.IsNullOrWhiteSpace(response)) return false; + recaptchaValidator.PrivateKey = privateApiKey; + recaptchaValidator.RemoteIP = httpContext.Request.UserHostAddress; recaptchaValidator.Challenge = challenge; recaptchaValidator.Response = response; - recaptchaValidator.RemoteIP = httpContext.Request.UserHostAddress; return recaptchaValidator.Validate().IsValid; } diff --git a/Sample/RequestModels/SendFeedbackRequest.cs b/Sample/RequestModels/SendFeedbackRequest.cs index 7652faf..32fb838 100644 --- a/Sample/RequestModels/SendFeedbackRequest.cs +++ b/Sample/RequestModels/SendFeedbackRequest.cs @@ -8,7 +8,7 @@ public class SendFeedbackRequest [Required, DataType(DataType.EmailAddress)] public string EmailAddress { get; set; } - [Required] + [Required, DataType(DataType.MultilineText)] public string Feedback { get; set; } } } \ No newline at end of file