SQL Email Validation Constraint - sql

I've got a database table which contains an Email field. Somehow an invalid email address has got through application validation, and got into the database field.
How can I add a constraint to this field so that its not possible for an invalid email address to be stored?

It depends a little on what valid means to you. To me, an email address might be valid (that is, it's formed correctly according to RFC 5322), but I might not be able to send to it. Whether you need to test a) the format of the address or b) your ability to send email to it is application-dependent.
If you just want to make sure the user's email address is in the correct format, you're stuck with validation by regular expression. Good luck with that. See RFC 3696, "3. Restrictions on email addresses" for the depressing details.
Off the top of my head, here are some guiding points that I've used in the past to help my clients make decisions about email validation.
The user wants to get email from us; assume the user is motivated to
correct mistakes. (Accept anything with an "#" symbol and a "." in
roughly the right place.)
There are privacy issues; send email to the user's address, and
require the user to click a link to confirm. (You can still accept
anything with an "#" symbol and a "." in roughly the right place.
Requires cooperation between the database and web app development.)
Local policies are involved. Restrict email addresses to this
arbitrary subset of truly valid email addresses. (I've seen this when
one company buys out another company, and requires everybody to be
assigned a new email address before those email accounts are actually
created.)
Depending on which way you go, you'll need a looser or tighter regular expression. In my experience, most of the time most people go with looser validation.

According to this article, SQL Server supports Regular Expressions in CHECK constraints.
Couple this with a solid email validation regular expression and you should be good to go.
You can also use LIKE in the CHECK constraint.
Also you can enable CLR Integration in SQL Server and create a CLR function if you are using SQL Server 2005 or higher and call it in the CHECK constraint. The CLR function would handle the regular expression validation.

Related

dovecot: enabling a secondary password?

We're dealing with an unusual situation involving dovecot that perhaps requires an unusual solution.
We recently required all of our POP/IMAP users to change their passwords, and in almost all cases, they dutifully did so. However, one user has several devices and machines which are repeatedly querying for email, and due to circumstances beyond anyone's control, one of his computers cannot be accessed for at least another few weeks, and therefore, the dovecot password for that user's email access cannot not be changed until that time passes.
Therefore, that computer keeps querying dovecot for email for that user with the old, now invalid password, and those queries fail.
Furthermore, due to various circumstances which are also beyond our control for the time being, we can't have that one user change his password back to the old value on the other machines and devices that he uses.
What we're wondering is whether there is some way that dovecot could be set up to recognize and accept both passwords for this one, specific user. In other words, can we somehow set up a secondary password for this email address so that both the old and the new password will allow this user to access his email?
We are using auth sql by including auth-sql.conf.ext in 10-auth.conf. Perhaps the solution to this problem would to restructure the database we are using for SQL authentication and add one or more columns, and then somehow change the SELECT statement that is used in auth-sql.conf.ext to choose between one of two passwords.
We are willing to attempt this procedure if it's the only option available, but we aren't even sure how it can be done. And in any case, we're hoping that there might be some feature of dovecot that we are unfamilar with which would allow us to set up this one user's dovecot email account to allow two different passwords for authentication without any database changes.
Is there any chance that we could do this?
Thank you in advance.
The link supplied by Allan Wind helped me (thank you!), as well as a couple other things I saw in those dovecot docs which I had overlooked in the past.
It turns out that I can supply a second userdb and passdb block in auth-sql.conf.ext, and they serve as secondary fallbacks if the primary SQL query doesn't return a match. I set up a passwd-file that is usable by both of these which contains the hash of the user's old password, and now, both passwords are working.
For example, the secondary userdb block (which should appear right below the original sql-based userdb block) looks like this:
# Fallback ...
userdb {
driver = passwd-file
args = scheme=md5-crypt username_format=%u /etc/dovecot/extra.userdb
}
The secondary passdb block is identical, except for it being named passdb instead of userdb. It must appear right after the original passdb statement in that same file.
So, all's well that ends well.
Onward!

Auth0 database and social connections, unique email addresses

Maybe I am missing something here, or this is a flaw in Auth0? I'll give an example of my issue:
Let's say I have my Default App (client), hooked up to that I have Username-Password-Authentication (database connection) and google-oauth2 (social connection).
A user comes to my site, signs up via google-oauth2 (social connection) using joe#gmail.com. Once complete, he gets added to my users in Auth0, all great.
A few months later, Joe comes back to my site, and being a busy guy, he forgets he signed up to my site before. This time, he decides to sign up using my custom Email and Password form, that will add the user to the Username-Password-Authentication (database connection). so he signs up there using joe#gmail.com again, and everything goes well, he is now listed in my user's section in my Auth0 dashboard.
This is the problem, I now have two joe#gmail.com accounts, one with google-outh2 and one with Username-Password-Authentication. I really can't have this, I need a unique email address, regardless of the ID Auth0 supplies.
Does anyone know how I can make email address in my user section 100% unique? I'd think a rule would do this, but it appears rules only apply AFTER a user has been registered, so I can't run a rule before adding?
the only way I can see doing this right now is make my own checks and delete via the management API, but that is a really long and messy way to do it I feel.
Any help will be appreciated here!
Thanks!
Auth0's default behavior is to create a new account in the database for every unique entry. Since the user created using Google has a unique id (based on google-oauth2), and the user created using the sign-up form has a unique id - they will technically be considered two separate accounts. In order to resolve this disparity, you can establish a means with which the account data can be merged. In the documentation linked provided above, there are examples of three possible ways of doing this:
Automatic Linking - which involves creating a specific rule to merge users based on matching emails
User-Initiated Linking - which involves providing a UI for users to opt into merging users with matching emails
Suggested Account Linking - which involves setting up a rule that is linked into the UI
One important thing to consider is that the data returned from different social identity providers may not be normalized the way that data is normalized onto the Username-Password-Database. For example, while auth0's default for emails is to lowercase the information, google-oauth2 may return emails as Uppercased - creating the potential for non-matching emails when checks are made using strict equality
The option you are looking for is called account linking.
You can find more info at https://auth0.com/docs/link-accounts

Login routine for password protected website

You are writing the login routine for a password protected website. Give examples of specific user input errors that you might want to catch, and how you might deal with them.
This is an interview question
I answered this as follows
We should add both client side errors and server side errors.
Client side error:
Check if user put nothing in username field. We can show message using javascript that “username not entered”
Server side error:
We can check if username does not exist in database and can throw error message.
We can check if password does not match in database for entered username.
Can anyone suggest. Are these the only error we can catch?
I'd consider syntactically invalid usernames (empty; too short or too long; containing invalid characters like possibly spaces, quote marks or shell/SQL metacharacters; structurally invalid, i.e., starting with dot or number), and syntactically invalid passwords (too short or even empty, too "simple", or equal to username). All these cases you can validate client side with JS, recycling the same code for the "Creating new user, choose user and password" view.
Server side, you might have backend connection error (i.e. not being able to tell whether the user does exist -- not exactly an user error, but we might want to manage it here nonetheless), user not found, password mismatch, and possibly "login disabled" (this is quite common on auto-create-user website: the login exists but must be validated by clicking on a link sent through email. Then again, one might want to place these "not-yet-users" in a storage apart to avoid clogging/churning on the real user database). Of course you might also want to add a special disable state and message ("Your membership fee is overdue"). Other additional "errors" and "warnings" may be added here, e.g. "You're not logging from your usual IP block(s) [, would you mind answering this security question?]" or "password expired, choose another password".
IMO, the main issue (assuming SQL as the database for the users and password) is SQL Injection, that for example adds a specific user as an admin access.
Dealing with it can be done using libraries in the server side to handle all user input — rather then trying to do it on your own.

Users management strategies with LightOpenID

I've discovered recently LightOpenID wich i'm going to use as a login system for all my next websites.
As i'm fetching some infos when users register/login with LighOpenID, I'd like to know if it's technically ok to use user's email as unique id in my USERS table or if it's a bad idea ?
Thanks guys ,
FX
Thinks to consider:
It isn't mandatory to have an e-mail account linked to your OpenID account.
If there is an e-mail address, you are not guaranteed to get it back from the server, even if you ask.
Even if you get the address, you'd still need to validate it (e.g., by sending an e-mail message with a random token).
Users will probably own more than one OpenID identifiers (you are in such situation as soon as you open accounts at some major services like Google or Yahoo). Some of them will share the same e-mail address, some will not, and some will not even have an e-mail address set.
When the user changes his e-mail address behind the scenes, he'll lose his account at your site.
Using the e-mail as key does not really offer any advantage I can think of.
My advice is that, if you want to use OpenID, you should do it right. Read the OpenID URL from $openid->identity() after successful validation and use that to identify the user.
Additionally:
Keep in mind that URLs can be long; don't try to stuff it into a VARCHAR(100) column.
You might want to implement linked identities as Stack Overflow does.
It depends on your service. Normally, every email-adress is only assigned to one person. If multiple accounts per user are not wanted, it's ok.
Some families have a family-email-adress. But I guess they would also use the same account.
Why don't you take the OpenID as the unique ID? OpenIDs are unique and you get the OpenID before you get the Email-Adress, if you use only OpenID for logging in.

May I safely treat email addresses lower case?

In theory emails are case sensitive. But using emails as system login I want them to be all lower case (i.e. john#smith.com and John#smith.com cannot be different users).
Can this be a problem for some users who use case sensitivity in their email address? Does somebody use it out there?
Edit: Because there are many "preserve case on save, ignore on login" answers: This system would break if I really had two different users john#smith and John#smith, wouldn't it?
Example: john#smith and John#smith have the password 123. How do I know which one just authenticated?
Don't throw away data. Store the email address or username exactly as you received it, with the exception of trimming both ends of the string.
When sending email, use the case that was supplied by the user. Just because case-sensitivity is rare is no reason to not handle it - otherwise that user gets no mail, and can possibly not even register.
When authenticating a user, you can optionally do a compare on lower case (or upper case) strings, so that the case is disregarded.
So, by preserving the user input data you have suddenly given yourself options: whether to do case-sensitive compares on authentication, and whether to use case-sensitive email addresses when sending mail. Even if you don't choose to avail yourself of them now, the purpose of preserving data is to allow you (or some other developer) to have those choices down the road.
According to RFC 2821:
The local-part of a mailbox MUST BE treated as case sensitive. Therefore, SMTP implementations MUST take care to preserve the case of mailbox local-parts. Mailbox domains are not case sensitive. In particular, for some hosts the user "smith" is different from the user "Smith". However, exploiting the case sensitivity of mailbox local-parts impedes interoperability and is discouraged.
So, while you can treat emails addresses with case sensitivity, you are discouraged from doing so.
I'd store and display the address the way the user entered it, not only because the RFP says you have to respect case, but because if the user has a preference, we should respect that preference. It's their email address. I'm not a fan of systems reformatting the personal details I provide to them. For example, you'd be surprised how many systems insist on calling me Tj — which is clearly wrong — rather than T.J. (kudos to SO for getting it right).
So if John Smith signs up as John.Smith#example.com, then that's how John Smith wants to see his email address (if he has a preference). I wouldn't let someone else sign up with john.smith#example.com, because the odds are overwhelming that it's the same as the other account's address, but I wouldn't muck about with the user's formatting of their address or other details. At most I might prompt them if they give me a lot of ALL CAPS SHOUTING, asking if they wouldn't prefer something more...gentle.
Some systems are case sensitive.
I'd suggest it be preserved but ignored a la windows filesystems.
i.e. remember john signed up with John#smith.com but let him log in as JOHN#smith.com, john#smith.com or JohN#smith.com.
It's unlikely to cause conflicts and if anyone has a case-sensitive email I'm sure they'll be aware of it.
Yes, that is a problem. I just made a little test on Linux (running exim) and only the mail with correct case reached the mailbox...
I think that most commercial mail providers normalize all email addresses but in general you have to use the correct case!
This link says that "hardly any email service or ISP does enforce case sensitive email addresses".
I don't know of any implementation that distincts between email-addresses having the same letters but in different case.
I've never heard of a message not being transmitted correctly only because the cases were wrong.
If you're using it as a system login, no need. Usually (when talking about logins), admin and Admin are one and the same person ... so is JohnDoe and johndoe ... also , the number of people who use email providers that allow for case sensitivity is way, way too low.