custom validation on django-allauth - django-allauth

I'm using dj-allauth on my django app. When people sign up to my django project/app, I want to check that the domain on their email matches mydomain.com. Is this possible? I think I can do it by changing the signup form. I've tried the following which doesn't seem to do anything when I submit the signup form. There aren't any errors. It isn't checking for the domain, it's prompting for the user's nickname and then appending the domain automatically.
forms.py
class VSBSignupForm(SignupForm):
def save(self, request):
# Ensure you call the parent classes save.
# .save() returns a User object.
user = super(VSBSignupForm, self).save(request)
user.email_address = user.username + "#mydomain.com"
user.save()
# You must return the original result.
return user
settings.py
ACCOUNT_FORMS = {'signup': 'myapp.forms.VSBSignupForm'}
I changed the template for the signup.html such that it asks for the nickname and password, but not the email address.
edit I tried putting a print statement in the form save method and it didn't print anything in the shell, which makes me think the form isn't being used.

Related

Rails devise reset password fails if user record contains invalid data

I have an existing application in production where we have added new mandatory fields to the user record. As a result, the forgot password function is failing. I believe the failure occurs in the following method in recoverable.rb
# Update password saving the record and clearing token. Returns true if
# the passwords are valid and the record was saved, false otherwise.
def reset_password(new_password, new_password_confirmation)
if new_password.present?
self.password = new_password
self.password_confirmation = new_password_confirmation
save
else
errors.add(:password, :blank)
false
end
end
The new attributes cannot be generated mechanically. Only the user himself will know the correct values. Does anyone know of a way to get around this problem?
The only idea that I've come up with so far is as follows:
use a rake script to populate the new fields with values that I know would never occur in real life but would be accepted by the model validation rule
when the user logs in, detect if the user record contains invalid data and force them to do an update. In the user edit form, I would use some javascript to change the bogus values to blank.
You could use a custom validation context to make sure the validations on these added fields are only run when a user edits their profile, but skipped when (for example) Devise saves the user record.
In the User model, add an on:-clause to these validations
validates_presence_of :recently_added_mandatory_field, on: :user_updates_profile
And in the appropriate controller action, add this validation context when calling #valid? or #save:
# Existing code uses `#user.valid?` -> change to:
if #user.valid?(:user_updates_profile)
…
# Existing code uses `#user.save` -> change to:
if #user.save(context: :user_updates_profile)
…
See here for a full description of validation contexts: https://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates

Rails - Ask for access code before sign up

I want to have an additional layer of authentication by asking for an access code from users who plan to sign up.
Basically, users have to input an access code prior to getting into the sign up page. I was thinking it could be something like schoology's way for students to sign up (https://app.schoology.com/register.php?type=student)
I am using Devise for authentication
I think you should not do this: Adding another layer to registration avoid users from register to your site.
But anyway, if you just want to put a general password for the whole website you could use Http Basic Authentication
Frontend Only solution:
Make a textfield and check the input via javascript. If it matches your code you hide the input field and show the registration form.
With backend:
First put just the password form on the page and in your rails app you need a action in a controller. There you check if the code matches and et a variable like #code_valid = true. In frontend you only display the registration form when the code is valid
# /controllers/pre_signup_controller.rb
.
.
def validate_code
#code_valid = params[:code] == '12345' ? true : false
if #code_valid
redirect_to ///where ever your registration page is
end
end

Rails: remember user input in devise registration form after error

I'm using Rails 3.2.16 and devise 3.2.2.
I've added a (hidden) field account_level to my devise registration form. This is populated by a query string in the URL depending on what plan the user chooses.
If the user has an error with the registration form, such as the password do not match or a required field isn't filled in, the registration page then reloads with the errors present. However, the account_level field is now blank and the url does not have the query string on it for me to pull the data from it.
How can I have rails "remember" what was in that field after a page reload if a error occurs?
Bonus sanity check question: Is there a better way to pass which plan the user has choose when registering?
----------- Update -----------
I used a combination of the answers from Shamsul and aelor. I ended up grabbing the value of the query string and saving it in a cookie using javascript. If the page then reloads from a validation error, and the query string on the URL is no longer there, I look for the cookie that was set and grab the value from there to populate the hidden field.
I want to keep as much on the front end, which is why I opted for the JS solution. I also felt like cookies are a more tried and tested vs local storage.
use localStorage.
you can save your plan , when the user clicks it.
localStorage.setItem('plan','premium');
then you can check for the the item and fill up the hidden field.
if(localStorage.getItem('plan') != null){
$('#hiddeninput').val(localStorage.getItem('plan'));
}
and you can delete that plan whenever you like by using
localStorage.removeItem('plan');
In registrations_controller.rb of devise
Store account_level field in a cookies as
def new
if params[:account_level]
cookies[:account_level] = params[:account_level]
end
#other code
end
def create
if resource.save
unless cookies[:account_level].nil?
cookies.delete(:account_level)
#do other coding
end
end
end
In this way account_level field will not blank after reloaing the page.

Devise log in with one more condition to check

I´m using devise gem in a rails 4 app and I have in my user table a column called valid that by default is false, when the user registers in the site it should send me a email with the information about them and approve it, and put that valid column in true. So then in the log in action it will check that valid is true and let them login to the site.
My question is how modify that login action that takes care of the valid column in users table.
You should look at adding :confirmable to your User model, it may take care of most of what you are looking to do.
Otherwise, if you want to modify whether someone can login, look at the wiki on how to customize account validation.
From the wiki:
def active_for_authentication?
# Uncomment the below debug statement to view the properties of the returned
# self model values.
# logger.debug self.to_yaml
super && account_active?
end

rails 3 + devise: on after_inactive_sign_up_path_for() how show the not-yet-confirmed user's email address?

In order to have a post-registration page, I added a RegistrationsController and method to provide a custom page to tell the user to check their email for the account confirmation link.
def after_inactive_sign_up_path_for(resource)
"/awaiting_confirmation"
end
Is there any way on that page (which is seen by a user who has created an account, but not confirmed it, and not signed in yet) to show the email address they used to create the account.
I'd like the page to say "we just sent a confirmation link to you at useremail#userdomain.com"
But the view for that page cannot display current_user.email because current_user is nil because they have not signed in.
Is there some other devise variable, or session variable, that would contain the registration info that was just created?
here's how we solved it ... it was easy.
modified the one-line controller method in my custom registration controller (shown in my question) to:
"/awaiting_confirmation?email=#{resource.email}"
then in the receiving method for the route /awaiting_confirmation I simply do
#email = params[:email]
and display the #email variable in my view.
You can do this two ways, the first is to display a flash message to the user after the email is successfully sent. You still have access to the users email in a variable there so something like:
:notice => "Email was sent to #{userobject.email}"
Or you could pass this object into the page that you are sending the user to after a signup and using it there.
Another way you could tackle this would be to authenticate the user with a token and then the user would be effectively signed in and you could then use current_user.
For that you would want to look into single use token authentication and devise.

Resources