What precisely is the regex pattern that Hibernate validator employes for #Email? - hibernate-validator

Versions:
hibernate-validator: 6.2.0.Final (from mvnrepository.com)
If needs be, you can peruse relevant docs at jboss.org.
I've discovered that out-of-the-box that Hibernate validator (through the #Email annotation) supports validation of E-mail addresses (that is, for strings that should house valid E-mail addresses).
QUESTION: does anyone know the default regexp that the Hibernate Validator 6.2 employs for #Email validation?

From the hibernate-validator source code:
Checks that a given character sequence (e.g. string) is a well-formed email address.
The specification of a valid email can be found in RFC 2822 and one can come up with a regular expression matching all valid email addresses as per specification. However, as this article discusses it is not necessarily practical to implement a 100% compliant email validator. This implementation is a trade-off trying to match most email while ignoring for example emails with double quotes or comments.
private static final int MAX_LOCAL_PART_LENGTH = 64;
private static final String LOCAL_PART_ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uFFFF-]";
private static final String LOCAL_PART_INSIDE_QUOTES_ATOM = "(?:[a-z0-9!#$%&'*.(),<>\\[\\]:; #+/=?^_`{|}~\u0080-\uFFFF-]|\\\\\\\\|\\\\\\\")";
/**
* Regular expression for the local part of an email address (everything before '#')
*/
private static final Pattern LOCAL_PART_PATTERN = Pattern.compile(
"(?:" + LOCAL_PART_ATOM + "+|\"" + LOCAL_PART_INSIDE_QUOTES_ATOM + "+\")" +
"(?:\\." + "(?:" + LOCAL_PART_ATOM + "+|\"" + LOCAL_PART_INSIDE_QUOTES_ATOM + "+\")" + ")*", CASE_INSENSITIVE
);
See also the regex for the domain part.

Related

Setting a static (constant) POST parameter with netflix feign

I'm using a REST api that requires a few fields to be set. My application should always set some of the fields to the same value. Is it possible to make those values "hard coded" in the interface with the feign definition (or somewhere else)?
My feign declaration looks like the example. Let's say I always want to use the same agent from this application. Is that doable?
#RequestLine("POST /files")
#Headers("Content-Type: application/json")
default FileMetadata addFile(#Param("file_name") String fileName,
#Param("agent") String agent,
#Param("md5") String md5,
#Param("file_type") String fileType) {
return new FileMetadata.Builder().build();
}
You have different alternatives, in the case you are using the Spring Annotations you could use defaultValue annotation property to determine the default value
#RequestParam(value = "agent", required = false, defaultValue = "AnyAgent") String agent
But in the case you are using the netflix-feign annotations, and seems it is what you are doing, you would need to add in the path, i.e. in the #RequestLine annotation:
static final String DEFAULT_VALUE_AGENT = "agent";
#RequestLine("POST /files?agent=" + DEFAULT_VALUE_AGENT)
....
But if you are refering to Body POST, you could do it using annotation #Body:
#RequestLine("POST /files")
#Body("%7B\"file_name\": \"{user_name}\", \"agent\": \"" + DEFAULT_VALUE_AGENT +"\"%7D") //... other params..
....
Edit
Based on the Github repository documentation, if you are using Java 8, you could do a default method which calls the other method with a param constant. Just like next
#RequestLine("POST /files")
#Headers("Content-Type: application/json")
FileMetadata addFile(#Param("file_name") String fileName,
#Param("agent") String agent,
#Param("md5") String md5,
#Param("file_type") String fileType);
#RequestLine("POST /files")
#Headers("Content-Type: application/json")
default FileMetadata addFileConstant(#Param("file_name") String fileName,
#Param("md5") String md5,
#Param("file_type") String fileType) {
addFile(fileName, "constant_value", md5, fileType);
}
Personally, I think is more flexible than the other options I proposed before. And the idea works in POST Body as well if they are params.
I had the same situation.
The problem is solved as follows:
added this to the main api on the server that I was knocking on (i.e., on the receiving side, and not on the sending side request).
for example:
#RequestParam(value = "code", required = false, defaultValue = "AAA") String code
Required is required = false (instead of required = true).

asp .net query string encoding and decoding

I type the following url into my web browser and press enter.
http://localhost/website.aspx?paymentID=6++7d6CZRKY%3D&language=English
Now in my code when I do HttpContext.Current.Request.QueryString["paymentID"],
I get 6 7d6CZRKY=
but when I do HttpContext.Current.Request.QueryString.ToString() I see the following:
paymentID=6++7d6CZRKY%3D&language=English
The thing I want to extract the actual payment id that the user typed in the web browser URL. I am not worried as to whether the url is encoded or not. Because I know there is a weird thing going on here %3D and + sign at the same time ! But I do need the actual + sign. Somehow it gets decoded to space when I do HttpContext.Current.Request.QueryString["paymentID"].
I just want to extract the actual payment ID that the user typed. What's the best way to do it?
Thank you.
You'll need to encode the URL first, using URLEncode(). + in URL equals a space so needs to be encoded to %2b.
string paymentId = Server.UrlEncode("6++7d6CZRKY=");
// paymentId = 6%2b%2b7d6CZRKY%3d
And now
string result = Request.QueryString["paymentId"].ToString();
//result = 6++7d6CZRKY=
However
string paymentId = Server.UrlEncode("6 7d6CZRKY=");
//paymentId looks like you want it, but the + is a space -- 6++7d6CZRKY%3d
string result = Request.QueryString["paymentId"].ToString();
//result = 6 7d6CZRKY=
There is some info on this here: Plus sign in query string.
But I suppose you could also use a regular expression to get your parameter out of the query string. Something like this:
string queryString = HttpContext.Current.Request.QueryString.ToString();
string paramPaymentID = Regex.Match(queryString, "paymentID=([^&]+)").Groups[1].Value;
I sent an Arabic text in my query string
and when I resieved this string it was Encoded
after Server.UrlDecode
departmentName = Server.UrlDecode(departmentName);
it back again to arabic
I hope this help you

Character + is converted to %2B in HTTP Post

I'm adding functionality to a GM script we use here at work, but when trying to post (cross site may I add) to another page, my posting value of CMD is different than what it is on the page.
It's supposed to be Access+My+Account+Info but the value that is posted becomes Access%2BMy%2BAccount%2BInfo.
So I guess my question is: What's escaping my value and how do I make it not escape? And if there's no way to unescape it, does anyone have any ideas of a workaround?
Thanks!
%2B is the code for a +. You (or whatever framework you're using) should already be decoding the POST data server-side...
Just a quick remark: If you want to decode a path segment, you can use UriUtils (spring framework):
#Test
public void decodeUriPathSegment() {
String pathSegment = "some_text%2B"; // encoded path segment
String decodedText = UriUtils.decode(pathSegment, "UTF-8");
System.out.println(decodedText);
assertEquals("some_text+", decodedText);
}
Uri path segments are different from HTML escape chars (see list). Here is an example:
#Test
public void decodeHTMLEscape() {
String someString = "some_text+";
String stringJsoup = org.jsoup.parser.Parser.unescapeEntities(someString, false);
String stringApacheCommons = StringEscapeUtils.unescapeHtml4(someString);
String stringSpring = htmlUnescape(someString);
assertEquals("some_text+", stringJsoup);
assertEquals("some_text+", stringApacheCommons);
assertEquals("some_text+", stringSpring);
}
/data/v50.0/query?q=SELECT Id from Case
This worked for me. Give space instead of '+'

ASP.NET : Hide Querystring in URL

I don't know if I'm just being overly hopeful, but is there a way to hide the query string returned in the URL?
The scenario I am in is where I have page1.aspx redirecting a command to an outside server via a post, and it returns it to page2.aspx. The only problem I have with this, is that the querystring of the returned variables are still left in the URL.
I just want to hide the ugly string/information from the common user. So is there a way to edit and reload that in the pageload method or do I just have to save the variables on a middleman page and then hit page 2.
What is the origin of these querystring variables? Can you not submit all data as POST data, so that there is no querystring?
You could possibly also use
Context.RewritePath("/foo.aspx")
Here's a link to a ScottGu blog post about URL rewriting.
http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx
Awhile back I made some http encoding encrypt/decrypt methods for this purpose. Sometimes in asp.net you need to use the query string, but you also need the end user to not know the value. What I do is base 64 encode, encrypt the value, hash the value based on my private key, and stick them together with a -. On the other side I check the left side hash to verify authenticity, and decrypt the right side. One really nice gotcha is that + (which is a valid base64 string value) is equal to space in html encoding, so I take that into account in the decrypt.
The way I use this is add the encrypted value to the query string, and then decrypt it on the other side
private const string KEY = "<random value goes here>";
public static string EncryptAndHash(this string value)
{
MACTripleDES des = new MACTripleDES();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
des.Key = md5.ComputeHash(Encoding.UTF8.GetBytes(KEY));
string encrypted = Convert.ToBase64String(des.ComputeHash(Encoding.UTF8.GetBytes(value))) + '-' + Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
return HttpUtility.UrlEncode(encrypted);
}
/// <summary>
/// Returns null if string has been modified since encryption
/// </summary>
/// <param name="encoded"></param>
/// <returns></returns>
public static string DecryptWithHash(this string encoded)
{
MACTripleDES des = new MACTripleDES();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
des.Key = md5.ComputeHash(Encoding.UTF8.GetBytes(KEY));
string decoded = HttpUtility.UrlDecode(encoded);
// in the act of url encoding and decoding, plus (valid base64 value) gets replaced with space (invalid base64 value). this reverses that.
decoded = decoded.Replace(" ", "+");
string value = Encoding.UTF8.GetString(Convert.FromBase64String(decoded.Split('-')[1]));
string savedHash = Encoding.UTF8.GetString(Convert.FromBase64String(decoded.Split('-')[0]));
string calculatedHash = Encoding.UTF8.GetString(des.ComputeHash(Encoding.UTF8.GetBytes(value)));
if (savedHash != calculatedHash) return null;
return value;
}
I don't like this approach, but it will work.
Once you know you are where you need to be you can Response.Redirect to the same page and they will be gone.
It preserves Query String and Form Variables (optionally). It doesn’t show the real URL where it redirects the request in the users web browser. Server.Transfer happens without the browser knowing anything. The browser requests a page, but the server returns the content of another.
protected void btnServer_Click(object sender, EventArgs e)
{
Server.Transfer("~/About.aspx?UserId=2");
}

How to validate email address inputs?

I have an ASP.NET web form where I can can enter an email address.
I need to validate that field with acceptable email addresses ONLY in the below pattern:
xxx#home.co.uk
xxx#home.com
xxx#homegroup.com
A regular expression to validate this would be:
^[A-Z0-9._%+-]+((#home\.co\.uk)|(#home\.com)|(#homegroup\.com))$
C# sample:
string emailAddress = "jim#home.com";
string pattern = #"^[A-Z0-9._%+-]+((#home\.co\.uk)|(#home\.com)|(#homegroup\.com))$";
if (Regex.IsMatch(emailAddress, pattern, RegexOptions.IgnoreCase))
{
// email address is valid
}
VB sample:
Dim emailAddress As String = "jim#home.com"
Dim pattern As String = "^[A-Z0-9._%+-]+((#home\.co\.uk)|(#home\.com)|(#homegroup\.com))$";
If Regex.IsMatch(emailAddress, pattern, RegexOptions.IgnoreCase) Then
' email address is valid
End If
Here's how I would do the validation using System.Net.Mail.MailAddress:
bool valid = true;
try
{
MailAddress address = new MailAddress(email);
}
catch(FormatException)
{
valid = false;
}
if(!(email.EndsWith("#home.co.uk") ||
email.EndsWith("#home.com") ||
email.EndsWith("#homegroup.com")))
{
valid = false;
}
return valid;
MailAddress first validates that it is a valid email address. Then the rest validates that it ends with the destinations you require. To me, this is simpler for everyone to understand than some clumsy-looking regex. It may not be as performant as a regex would be, but it doesn't sound like you're validating a bunch of them in a loop ... just one at a time on a web page
Depending on what version of ASP.NET your are using you can use one of the Form Validation controls in your toolbox under 'Validation.' This is probably preferable to setting up your own logic after a postback. There are several types that you can drag to your form and associate with controls, and you can customize the error messages and positioning as well.
There are several types that can make it a required field or make sure its within a certain range, but you probably want the Regular Expression validator. You can use one of the expressions already shown or I think Visual Studio might supply a sample email address one.
You could use a regular expression.
See e.g. here:
http://tim.oreilly.com/pub/a/oreilly/windows/news/csharp_0101.html
Here is the official regex from RFC 2822, which will match any proper email address:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
I second the use of a regex, however Patrick's regex won't work (wrong alternation). Try:
[A-Z0-9._%+-]+#home(\.co\.uk|(group)?\.com)
And don't forget to escape backslashes in a string that you use in source code, depending on the language used.
"[A-Z0-9._%+-]+#home(\\.co\\.uk|(group)?\\.com)"
Try this:
Regex matcher = new Regex(#"([a-zA-Z0-9_\-\.]+)\#((home\.co\.uk)|(home\.com)|(homegroup\.com))");
if(matcher.IsMatch(theEmailAddressToCheck))
{
//Allow it
}
else
{
//Don't allow it
}
You'll need to add the Regex namespace to your class too:
using System.Text.RegularExpressions;
Use a <asp:RegularExpressionValidator ../> with the regular expression in the ValidateExpression property.
An extension method to do this would be:
public static bool ValidEmail(this string email)
{
var emailregex = new Regex(#"[A-Za-z0-9._%-]+(#home\.co\.uk$)|(#home\.com$)|(#homegroup\.com$)");
var match = emailregex.Match(email);
return match.Success;
}
Patricks' answer seems pretty well worked out but has a few flaws.
You do want to group parts of the regex but don't want to capture them. Therefore you'll need to use non-capturing parenthesis.
The alternation is partly wrong.
It does not test if this was part of the string or the entire string
It uses Regex.Match instead of Regex.IsMatch.
A better solution in C# would be:
string emailAddress = "someone#home.co.uk";
if (Regex.IsMatch(emailAddress, #"^[A-Z0-9._%+-]+#home(?:\.co\.uk|(?:group)?\.com)$", RegexOptions.IgnoreCase))
{
// email address is valid
}
Of course to be completely sure that all email addresses pass you can use a more thorough expression:
string emailAddress = "someone#home.co.uk";
if (Regex.IsMatch(emailAddress, #"^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#home(?:\.co\.uk|(?:group)?\.com)$", RegexOptions.IgnoreCase))
{
// email address is valid
}

Resources