Email Activation in rails - mysql

I have been looking through examples of email activation on rails and most examples just have a column for activation token and confirmed in their user table. I am not sure but I don't think that this is a good idea as when a user is activated almost both those columns seems like a waste. The way I was thinking of doing activation was having a seperate model called Activation which would have_one :user a ONE-WAY association and I would set the role of the user in my site as "PENDING" or something similar. The activation table would hold an activation token(s) per user. Then a link would be generated with the activation token(s) and the user would be sent an email containing something like www.mysite.com/activate?token='some_really_long_hash'. Upon clicking the link the role of my user would be set to "MEMBER" or something similar. Does this seem like a good idea? I can't conceive any pitfalls of activation this way. Suggestions? Comments?

It sounds like you're at the intro stages of implementing a state machine design pattern on your user model, and no it isn't a bad approach to design. Its just more complicated than what most people need.
I think the State Machine Plugin might be the type of approach you're looking to perform. Obviously this might be more than you're looking for but the approach would be the same.
Also check out these posts:
Why developers should be force-fed state machines
why-developers-never-use-state-machines
Good Luck!

The most straight-forward approach is to generate a random token and save it into a column of the user or member record. It doesn't have to be "really long", 20 random characters will suffice as the probability of guessing that is so slim it will never happen.
Typically the token is used once and once only to validate the user, but if the user clicks on the email a subsequent time it's nice if it still redirects back to their profile.
Usually the user is switched to "validated" or something of the sort, a status flag stored in a separate column. This preserves their initial membership type which might be one of many values. This is why you often see validated_at fields or banned_until fields.

Related

Having hard time with selecting appropriate variable names

I'm mostly developing in JS, but since React and his friends entered my life I feel like I'm writing much more variable names, more than I used to do and I'm having troubles with naming them.
Usually trying to pick something that I can remember and someone else can remember too, also trying to be logical and not annoyingly long.
So for instance in a messaging app, user might represent logged in user, recipient user, or user API.
What I do is usually user refers to any other user in the system.
me refers to the logged-in user. API depends...
What do you do? Is it something that should be camelcase with long variable names?
userLoggedIn, userRecepient, userAPI etc? Is there a commonly used pattern or a source (book, community, etc.) that I can look up to?
My strategy is to first think about what the variable stands for in the most general sense. In your example it's a user. Then I prefix the noun with attributes which makes it sufficiently precise. In your example it would be loggedInUser or currentUser, and recipientUser. I would not recommend the name userLoggedIn in this context because it sounds like a truth value (boolean variable). For boolean variables I start by thinking of an adjective and add nouns in front of it.

How do I prevent my HTML from being exploitable while avoiding GUIDs?

I've recently inherited a ASP.NET MVC 4 code base. One problem I noted was the use of some database ids (ints) in the urls as well in html form submissions. The code in its present state is exploitable through both URL tinkering and creating custom HTML posts with different numbers.
Now while I can easily fix the URL problems by using session state or additional auth checks i'm less sure about the database ids that get embedded into the HTML that the site spits out (i.e. I give them a drop down to fill). When the ids come back in a post how can I be sure I put them there as valid options?
What is considered "best practice" in terms of addressing this problem?
While I appreciate I could just "GUID it up" I'm hesitant to do so because I find them a pain in the ass to work with when debugging databases.
Do I have a choice here? Must I GUID to prevent easy guessing of ids or is there some kind of DRY mechanism I can use to validate the usage of ids as they come back into the site?
UPDATE: A commenter asked about the exploits I'm expecting. Lets say I spit out a HTML form with a drop down list of all the locations one can import "treasure" from. The id of the locations that the user owns are 1,2 and 3, these are provided in the HTML. But the user examines the html, fiddles with it and decides to put together a POST with the id of 4 selected. 4 is not his location, its someone else's.
Validate the ID passed against the IDs the user can modify.
It may seem tedious, but this is really the only way to make sure the user has access to what they're trying to modify. Using GUIDs without validation is security by obscurity: sure guessing them is hard, but you can potentially guess them given enough resources.
You can do this at the top of the controller before you do anything else with the posted data. If there's a violation, just throw an exception and have your global exception handler deal with it; you don't need to handle it in a pretty way since you can safely assume that the user is tampering with data in an unsupported way.
The issue you describe is known as "insecure direct object references," and the OWASP group recommends two policies for dealing with this issue:
using session-based indirect object references, and
validating all accesses to object references.
An example of Suggestion #1 would be that instead of having dropdown options 1, 2, and 3, you assign each option a GUID that is associated with the original ID in a map in the user's session. When you get a POST from that user, you check to see what object the given ID was supposed to be tied to. OWASP's ESAPI has some libraries to help with this in various languages.
But in many cases Suggestion #1 is actually counterproductive. For example, in many cases you want to have URLs that can be copy/pasted from one user to another. Process #2 is generally seen as the most foolproof way to address this issue.
You are describing Broken Access Control with Insecure Ids. Once you've identified the threat and decided which Ids are owned by certain users, ensure checks are in place for this server side.

invitation chains

The site what.cd uses a type of invitation chain whereby if I invite a friend to the service and they break the rules and loose their account I also loose my account as does the person who invited me and so on.
What is the best way to keep track of this kind of invitation inheritance, Just a table cell linking the user to the user who invited them via their ID or something similar?
If you retain the "inviter" information only on the "invited" model, you have essentially created a singly linked list.
http://en.wikipedia.org/wiki/Linked_list
For the described purpose, the features of such a data structure work reasonably well.
If you think you'll ever need to look at all the people that a person has invited, you may want to keep track of both pieces of information for easier lookup. Alternatively, you could build a table of "invites" that is indexed by both inviter and invitee, which would allow pretty flexible querying.

Is it a good idea to let your users change their usernames? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm back and forth on the idea of letting the users on my site change their usernames, which would be displayed through out the site. On one side I want to give the users flexibility. But on the other, I don't want them to use this feature as a way to hide if they do something unwanted on the site. I know SO & Twitter lets you change your display name. Whats keeping someone from behaving bad on the site and then changing their name so they can continue behaving bad?
I need feed back on the pro's and con's.
Thanks!
Update:
To clear things up a bit. I'm not using the user name as the primary internal account ID.
Each user gets a unique number. My question is not really about my system tracking the user its about how other users will be able to track each other.
If userA knows that userB is doing something bad and then userB changes his name to userC. Then userA will no longer know who he is.
What do you mean with "do something bad and then change their name"? If you're implying that users can post content, for instance, with their name attached, and then change their name and the name attached to their posts won't change as well, then I think you need to reconsider your (database) architecture and ensure that a username is a single point of reference and all representations of that username change when someone changes their username.
Edit:
OK, sorry for misunderstanding. But if it's the case that you have a single point of reference, then changing your username is irrelevant to the problem. Let's say my username is Foo and I troll some thread somewhere, then change my name to Bar. As long as people can see what I've posted (eg. a post history page), then it doesn't matter whether I used to be called Foo or not, Bar is associated now with posts made before that were troll material. So perhaps you just need to create transparency, by making something like a post history overview on users' profiles? :)
If the issue of impersonating someone or "cheating" is a factor you could always do ALA eBay and display an icon next to someone who changed their username in the past 30 days.
Depending on the case you can keep an history and display it if required.
If you do that make sure that previous usernames are not recycled for new users.
There are often very good reasons why people would want to legitimately change their username.
For example, assumed someone signed up as pimpleOnGodsAss while at university and then, a few years later, is in the workforce and wants to network with other professionals through the site ... they're going to want to change!
Also, consider the very common case of people changing their names when they marry - if they used their family name as a part of their username, they'll want to change that too. Martha Jones with username marthajones marries John Smith and wants username marthasmith (if available).
Note too that you can't avoid people achieving this - they can always reregister with a new email address, discarding their old history, and getting the new username they want.
I'd suggest that the benefits of the feature outweigh the costs - people will always find a way to game the system, don't penalise good users by locking away features just because some will find a way to abuse them.
I like Steam's "View aliases" function, which lets you see all names that you've seen that user using. As long as the username itself isn't the primary key in the user table, then sure, let them change names. Add an alias table so if someone's being a dick, you can see who they used to be.
You could display both names for a while :
Symbol Guy -> Formerly known as Prince
I wouldn't let the user change their actual username.
However, changing the display name should be safe. You can always track their behavior via their account or username directly. If they're doing something bad, you should flag their account, not necessarily try to track it by their name.
Most sites have this concept (including SO).
If each user has a constant unique id number, they can change the username but are still the same.
Arstechnica.com charges $20 to change your username, and subscribers get one change for free.
It's a feature I'd like to see on more websites.
It's convenient and, as you said it, gives user flexibility. If only changing one's username is enough to hide, there may be another issue.
Keep track of those users another way (user ID, logs, reputation system, ...) and consider showing the original username to your admins/moderators maybe.
I agree with most of the people answering here - let the users change their name, otherwise the site is simply less friendly. As Rahul said, if a user changes their name, make sure that the new name is associated with all their prior activity.
Similarly - If you use email address as your username (as many sites do), let the user change their email address. I can tell from personal experience that not allowing this is a real pain (for users and customer support for whatever site isn't allowing it).
Your database structure shouldn't depend on the username(/email address) being the same, so why enforce that on your users?
If you have the feature, leave it. You would just be encouraging someone to create another account to have the user names goodwitch and badwitch.
If you don't have it, don't add it unless you have nothing better to add.
Personally, i try to make usernames sticky, and a valuable part of the experience of a site.
This is true if other users will see the user names; if there is any social networking involved with the site.
You can always archive really old ones if your site lives for a long time.
As a user, I must say that I absolutely want to be able to change the user name on my account. I wouldn't go as far as asking for multiple aliases, but it is always possible that someone changed his mind, or did not really think much when first setting up the account.
You should not be using the user name as the primary internal account ID.
Yes - ONLY IF users don't interact with another users.
NO - if users can interact: forums and stuff like that. It's kinda confusing to see an user with a different name every day.
I'd allow the change, and perhaps carry both a user (login) name and a display name, and I'd allow a change to both. There are various arguments on both sides, but for me it usually comes down to the fact that either/both of those elements (user & display) typically reflect something about their owner's name, and their owner's name can change.
If your login is an email address, and you change email providers, now what? Or take your name 'Donny V.' I assume you're male, but what if you were female*? And if you got married to Mike Peterson. Wouldn't you now want to be known as "Donny P."? Maybe, maybe not. But many would.
*Yes, I know men can change their last names too.
How about a "formerly known as" display. If a user decides to change the user name, just store the old name in a table and display it additionally. Maybe give the option in all the user profiles to disable this display.
I vote for yes, within reason. Users who have got into trouble (negative total rep, moderation, past warnings, whatever is applicable to your site) should not be allowed.
Other users should be allowed but with a limit (e.g. 3 times a year). There should be a way to keep track of the users past usernames, at the very least for the admins/moderators.
EDIT: However I find systems such as Steam/Wordpress where a user has a display name and login name seperate a little confusing, so I would not reccomend such an approach, however that is just personal feeling.
If userA knows that userB is doing something bad and then userB changes his name to userC. Then userA will no longer know who he is.
If you're main concern is related to abuse, perhaps you should provide a method of reporting abuse, and maintain a log of when usernames change.
You could always control how often users are allowed to change their username to avoid seeing same people in forums who change their name every day; cause someone will do it every day if they are allowed to.
Business questions first
Why are you offering this feature instead of spending the time on another feature? Would another feature offer better benefit (such as a status line?)
What will this accomplish?
Are users asking for this?
Will this feature result increased stickiness or better experience?
Is this a competitive advantage?
Does your site become more confusing?
Technical questions
What is the potential for misuse? Do you have a denormalized database where the username has been copied many places or is there only one place where the username is stored?
Do you have a way to stream a notification to other users "Your friend 'foo' is now 'bar'?"
Like most things in life, it comes down to the context of which you speak of. Personally, I find any service that could or gets abused should have persistent usernames.
Suppose it is ok to let user change their names, but this change should also touch his previous posts - they should be shown with new user name
...
I have reminded about some password has realization that I found in internet resource
password_hash = md5(password + salt + user_name)
if you have the same model then you should reject chaning user name
Regards, Pavel
Combining some of the ideas here:
Every user has a unique internal ID, a number. So you are free to implement this feature any time you want. No need to code it right away, as you can delay this decision.
In case you want to implement it: Let them only change the username every 6 months and indicate every new username by some symbol for 30 days. Show the username history in the profile and be sure to inform the user about this, so he can decide against changing the username.

Is a "Confirm Email" input good practice when user changes email address?

My organization has a form to allow users to update their email address with us.
It's suggested that we have two input boxes for email: the second as an email confirmation.
I always copy/paste my email address when faced with the confirmation.
I'm assuming most of our users are not so savvy.
Regardless, is this considered a good practice?
I can't stand it personally, but I also realize it probably isn't meant for me.
If someone screws up their email, they can't login, and they must call to sort things out.
I've seen plenty of people type their email address wrong and I've also looked through user databases full of invalid email address.
The way I see it you've got two options. Use a second box to confirm the input, or send an authentication/activation email.
Both are annoyances so you get to choose which you think will annoy your users less.
Most would argue that having to find an email and click on a link is more annoying, but it avoids the copy/paste a bad address issue, and it allows you to do things like delete or roll back users if they don't activate after say 48 hours.
I would just use one input box. The "Confirm" input is a remnant form the "Confirm Password" method.
With passwords, this is useful because they are usually typed as little circles. So, you can't just look at it to make sure that you typed it correctly.
With a regular text box, you can visually check your input. So, there is no need for a confirmation input box.
I agree with you in that it is quite an annoyance to me (I also copy and paste my address into the second input).
That being said, for less savvy users, it is probably a good idea. Watching my mother type is affirmation that many users do not look at the screen when they type (when she's using her laptop she resembles Linus from Peanuts when he's playing the piano). If it's important for you to have the user's correct email address then I would say having a confirmation input is a very good idea (one of these days I'll probably type my email address wrong in the first box and paste it wrong into the second box and then feel like a complete idiot).
While the more tech-savvy people tend to copy and paste, not technical people find it just as annoying to have to type something twice. During a lot of user testing I've down, the less tech-savvy - the more annoyed they seem with something like this... They struggle to type as it is, when they see they have to type their email in again it's usually greeted with a strong sign.
I would suggested a few things.
Next to the input box write the style of the information you are looking for so something like (i.e. user#domain.com). The reason this is important is you would be surprised how many of the less tech-savvy don't really understand the different between a website and an email address, so let them know visually the format you want.
Run strong formatting test in real time, and visually show a user that the format is good or bad. A green check box if everything is okay comes to mind.
Lastly, depending on your system architecture I often use a library to actually wrong a domain in the background. I don't necessarily try to run a VRFY on the server - I often use a library to check to make sure the domain they entered has MX records in it's DNS record.
I agree with Justin, while most technical folks will use the copy, paste method, for the less savvy users it is a good practice.
One more thing that I would add is that the second field should have the auto-complete feature disabled. This ensures that there is human input from either method on at least one of the fields.
Typing things twice is frustrating and doesn't prevent copy&paste errors or even some typos.
I would use an authenticate/activate schema with a roll back to the old address if the activation is not met within 48 hours or if the email bounces.
As long as a field is viewable, you do not need a confirm box. As long as you do some form validation to be sure that it is at least in valid format for an email address let the user manage the rest of the issues.
I'd say that this is ok but should only be reserved for forms where the email is essential. If you mistype your email for your flight booking then you have severed the two-way link between yourself and the other party and risk not getting the confirmation number, here on StackOverflow it would only mean your Gravatar would not be loaded ...
I'd consider myself fairly techie but I always fill in both fields /wo cut-paste if I regard it to be important enough.
I tend to have it send a verification code to the email address specified (and only ask for it once), and not change the email address until the user has entered the code I sent them.
This has the advantage that if they try to set it to a dozen different addresses in quick succession, you'll know which ones work by which verification code they put in.
Plus, if I am presented with a "confirm email address" box, I just copy and paste from the previous one, and if I'm guilty of that, I'm sure that other less careful users will do the same.