Unsure of how to manage email configurations - django

I am attempting to create Reset Password functionality using Djoser. I am successfully hitting my API's auth/users/reset_password/ endpoint, which is then sending an email as expected. But the problem is occurring in the content of the email. It is sending a redirection link to my api, rather than to my frontend.
Please note, any <> is simply hiding a variable and is not actually displayed like that
Here is an example of what the email looks like:
You're receiving this email because you requested a password reset for your user account at <api>.
Please go to the following page and choose a new password: <api>/reset-password/confirm/<uid>/<token>
Your username, in case you've forgotten: <username>
Thanks for using our site!
The <api> team
The goal with this email is to send the user to the /reset-password/confirm/ url on my frontend, not on my api, which is currently occurring.
Here are my DJOSER settings:
DJOSER = {
'DOMAIN': '<frontend>',
'SITE_NAME': '<site-name>',
'PASSWORD_RESET_CONFIRM_URL': 'reset-password/confirm/{uid}/{token}',
}
The expected behavior is for the DOMAIN setting to alter the link that is being placed in the email, but it is not. I can't seem to find reference to this particular problem within the docs.
Any help here would be greatly appreciated, thanks.

I figured it out:
Due to Djoser extending the package django-templated-mail, the variables DOMAIN and SITE_NAME have to override django-templated-mail setting rather than Djoser's setting. So, you have to pull variables specific to django-templated-mail out of the Djoser variable.
The working setup actually looks like:
DOMAIN = '<frontend>',
SITE_NAME = '<site-name>',
DJOSER = {
'PASSWORD_RESET_CONFIRM_URL': 'reset-password/confirm/{uid}/{token}',
}

Related

How to use Social-Auth-Django-App with Facebook's https://m.me/

I tried using hyperlink and supplied it with my actual Facebook Username and it's working. But the problem is my actual Facebook Username is different from the Username provided by Social-Auth-App-Django. So I tried User ID instead but it's not working either.
By the way what I'm trying to do is an online shopping website and when a user clicks the hyperlink, he/she will be redirected to the seller's Facebook Messenger account to start a conversation.
This is the first line of code that I tried which is working.
Send Message to Seller
And this is the code I used using Social-Auth-App's provided data:
Send Message to Seller
And I also tried this:
Send Message to Seller
Any idea how I can use Facebook's m.me/ using the provided data by Social-Auth-App-Django? Or if you can suggest me other ways other than m.me/ I will greatly appreciate it. Thank you very much!
First Go To Setting.py And Put This Code End Of All Codes:
AUTHENTICATION_BACKENDS = [
'social_core.backends.facebook.FacebookOAuth2',
]
Second Go To FaceBook Developer In This Address :
https://developers.facebook.com
And Make One Account There.
After go To My Apps And Then Click On Create App And Then Put Your Website Name ((Attention...If You Use Your Local Host You Need To Put One Domain Name For Your Local Ip)) And Your Email And Click On Create App ID And In Your Dashboard Looking For Facebook Login And Click On Set Up .
And Then In First Step In Web Window Put Your WebSite Name For Local Host For Example Put mysite.com:8000/ And Click On Save And Other Options Just Cross .
Now In Your Dashboard On The Left Side Click On Setting And Then Basic If You See Your APP ID And Your APP SECRET Put This Two In Your Settings.py After That Last Code .
SOCIAL_AUTH_FACEBOOK_KEY = 'Put Your App Id Code Here'
SOCIAL_AUTH_FACEBOOK_SECRET = 'Put Your App Secret Code Here'
If You Want To Take User's Email Also You Can You This As Well .
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
Now In You Dashboard Go To Settings And After Go To Basic An In Field App Domains Put Your Website Name Also Go To Settings After Advanced And Put Website Name In Domain Manager With CLick On Add a Domain .
Now Again In Dashboar Go In Products+ Part And Click On Facrbook Login After Settings And Check These Option Be Active(Yes) :
• Client OAuth Login
• Web OAuth Login
• Enforce HTTPS
• Embedded Browser OAuth Login
And IN This Form Your Are Now Also Go In This Field Valid OAuth Redirect URIs And Put This URL :
exapmle.com/social-auth/complete/facebook/
And Put Your Button In Your Website Page That Have This Login Auth :
<li>
Sign in with Facebook
</li>

Designing URLs without verbs for operations related to user in a REST API

I'm building REST API.
I have following structure
GET /user/{id} - get
POST /users - Create user
PUT /users/{id} - Update user
DELETE /users/{id} - Delete user
The problem is following. As I got from many tutorials/articles - it is bad practice to use action in URL. But what to do with such actions like:
check email (is unique)
recover user by email
?
Assume user registration. User submits form ( POST /users ) and I need to check if email is unique. Do I need to do it in same api method and return validation errors as response body?
Or do I need to create something like
POST /users/email
And what about user recovering by email? Where do I need to do it? Because recover is verb
POST /users/recover
I'm not sure, that I'm doing it right and I can't find correct explanation for that situation.
Validating the e-mail and registering the user
If you want, you can have an endpoint to check whether an e-mail is already registered or not. It's up to your requirements. So, you can have something as following and then send the e-mail which will be validated in the request payload:
POST /users/email/validation
{
"email": "mail#example.com"
}
The endpoint above can be invoke, for example, when the user completes the e-mail field of your account registration form.
However, do not forget checking if the e-mail is already registered when creating a user:
POST /users
{
"firstName": "John",
"lastName": "Doe",
"email": "mail#example.com",
"password": "123456"
}
If an e-mail is already registered, you could consider returning a 409 Conflict status code and a payload that includes enough information for a user to recognize the source of the conflict.
Recovering the password
I'm unsure if this is your requirement, because of this I posted a comment asking for clarification. I presume you are trying to recover the password of a user, assuming the user has no more access to their account.
If so, you could have an endpoint as following and then send the e-mail of the user in the request payload:
POST /users/password/recovery
{
"email": "mail#example.com"
}
Then your server can send a link with a token to the e-mail specified in the payload. Only send the e-mail if the e-mail specified in the payload is registered in your application, of course.
The link should take the user to a page where they will enter the new password and, when submitting, an endpoint to replace the password of the user will be invoked, sending the token and the new password to the server:
PUT /users/password?token=SomeValueGoesHere
{
"password": "654321"
}

Loopback angular sdk unable to login

I'm trying to use loopback angular SDK to login but instead I'm getting back a 401 unauthorized response.
User.login({ rememberMe: true }, {email: $scope.user.email, password: $scope.user.password})
.$promise
.then(function() {
var next = $location.nextAfterLogin || '/';
$location.nextAfterLogin = null;
$location.path(next);
})
.catch(function(x) {
$scope.authError = 'Wrong Credentials';
});
};
Also i can see the user with the given credentials in the datasource that I've defined for the User model.
So basically, I have a boot script that creates a default user
User.create([{
username: 'admin',
email: 'xxxx#gmail.com',
password: 'admin'
}], on_usersCreated);
And I also have created a custom User model that extends the built-in User model.
Why am I getting a 401 unauthorized response when trying to login? I have even tried to login via the explorer, but with no success.
Update:
I debugged the build-in User model and the login method; and it seems that it cannot find the user with the given email. I can see it though in the mongodb database.
Inspect the ACL records of User model, starting you app in debug mode and viewing console: DEBUG=loopback:security:acl slc run.
I don't see anything wrong with your code. Are you sure the values you're passing into the function are correct? Try logging $scope.user.email and $scope.user.password before calling User.login.
See my new example here: https://github.com/strongloop/loopback-getting-started-intermediate/blob/master/client/js/services/auth.js#L6-L15
The tutorial part is not complete, you can look around the source code to get an idea of what you're doing different.

Catching failed OmniAuth login attempt information in Rails 4 application

Goal: I'm trying to get a Ruby on Rails application to send me emails whenever a user fails to log into OmniAuth. I want the e-mail to include (1) the username entered in the form, and (2) an MD5 hash of the password field.
Obstacle: OmniAuth returns a POST after a successful login, and a GET after an authentication failure. The "success" POST includes the username and a filtered password, but the "fail" GET does not include these two parameters.
So I guess my question is "Can I make OmniAuth return the parameters I want? If not, how can I make Rails remember the form data after it gets POST'ed to OmniAuth?"
I emailed the OmniAuth team and they gave me the solution below (thank you so much!):
You can do custom failure handling by adding an on_failure action.
OmniAuth.config.on_failure = Proc.new { |env| #do stuff }
https://github.com/intridea/omniauth/blob/master/lib/omniauth/failure_endpoint.rb
is the default failure endpoint as an example
So I added the following in config/initializers/omniauth.rb:
OmniAuth.config.on_failure = Proc.new{|env|
myLog = ActiveSupport::TaggedLogging.new(Logger.new("log/omniauth_log.txt"))
myLog.tagged("OmniAuth", "ENV") { myLog.info "Failed login attempt - username: #{env["rack.request.form_hash"]["username"]}, password: #{env["rack.request.form_hash"]["password"]} "}
OmniAuth::FailureEndpoint.new(env).redirect_to_failure}
...and it records the username and password correctly. All that's left to do is encrypt the password.
If you want to display everything that's going on, you can log #{env.inspect} itself. It's a very large hash though (that also contains smaller hashes), so maybe log #{env.inspect} once and pick out the fields relevant to your task.

Sending email not working on heroku

I have this function in forms.py. There is currently no email specifications in my settings.py.
def send_email(FROM_NAME,FROM,TO,SUB,MSG,EXISTING_EMAIL,EXISTING_PASSWORD):
FROMADDR = "%s <%s>" % (FROM_NAME, FROM)
LOGIN = EXISTING_EMAIL
PASSWORD = EXISTING_PASSWORD
TOADDRS = [TO]
SUBJECT = SUB
msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (FROMADDR, ", ".join(TOADDRS), SUBJECT) )
msg += MSG+"\r\n"
server = smtplib.SMTP('smtp.gmail.com', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.login(LOGIN, PASSWORD)
server.sendmail(FROMADDR, TOADDRS, msg)
server.quit()
I call it my views.py like so
send_email('my_name','from_me#gmail.com','to_som1#gmail.com','my subject','mymessage','my_existing_email#gmail.com','password_to_existing_email')
This works locally. I have tested it with yahoomail and gmail. But when I upload to heroku it gives the error "(535, '5.7.1 Please log in with your web browser and then try again. Learn more at\n5.7.1 support.google.com/mail/bin/answer.py?answer=78754 et6sm2577249qab.8')"
Can anyone help?
You want to use this:
FROMADDR = "%s <%s>" % (your_name, your_email)
You shouldn't be building emails with string interpolation, that's a good way to get your site used to send spam via header injections. See my answer here for details on how to construct emails securely.
Generally speaking, when formatting from addresses, you should use the format Display Name <email#example.com>. See RFC 5322 for details.
Have you read the page linked to in the error message?
If you're repeatedly prompted for your username and password, or if
you're getting an 'invalid credentials' or 'web login required' error,
make sure your password is correct. Keep in mind that password are
case-sensitive.
If you’re sure your password is correct, sign in to your account from
the web version of Gmail instead at http://mail.google.com
In most cases signing in from the web should resolve the issue
Here is what worked for me. After getting the error Please log in with your web browser and then try again. Learn more etc. when trying to send email from my web application, I logged in to the email via browser from my local computer.
After I logged in, there was a yellow notification bar on top which asking me if I want to allow external application access my mail. I confirmed this and Google asked me to log in to the account from the application within the next 10 mins. This will white-list the application.