Facebook Authentication with MongoMapper - facebook

I am trying to integrate Facebook authentication into a Rails application with mongomapper and I am getting an error on the following method. I think the error is in the first_or_initialize section because it is ActiveRecord query instead of mongomapper.
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
EDIT:
Any suggestions?

I'm in the same boat. I was able to create the user by changing the first_or_initialize line to this:
first_or_create(auth.slice(:provider, :uid)).tap do |user|

Related

Jira Tempo users are pseudonymised

I am trying to obtain the worklogs using the Jira Tempo REST API.
The server I am working with is an on-premises one.
The data extraction is straightforward with one exception: some users are renamed from john.doe to JIRAUSER12345.
I could not find any rule for this and I also couldn't find any way to map the JIRAUSER12345 to the actual username.
Is there any way of getting the real user name? Is it possible that I am missing some access rights (probably at team level) that forbid me seeing the real user names?
Reading this article gives the reason for the anonymization:
https://tempo-io.atlassian.net/wiki/spaces/KB/pages/1196327022/Why+do+I+see+JIRAUSERxxxx+as+worklog+author
In order to get the correct user id I did something like:
usersCache = {}
def getUserbyKey(key):
if not key in usersCache:
query = {
'key': key
}
response = requests.get(f"{JIRA_BASE_URL}/rest/api/latest/user",auth=authorization, headers=headers, params=query)
j = response.json()
usersCache[key]=j["displayName"]
j = usersCache.get(key)
return j
...
for wl in worklogs:
user = getUserbyKey(wl["worker"])
key = wl["issue"]["key"]
timeSpent = wl["timeSpent"]

Graphene JWT authentication

I'm using graphene-jwt to authenticate user but my user has to multiple object return
here
def mutate(cls, root, info, **kwargs):
result = super().mutate(root, info, **kwargs)
...
How can I add additional query to 'filter' more like User.object.filter(user_type=3)? cause currently my code is like this
except (MultipleObjectsReturned, JSONWebTokenError) as e:
users = models.User.objects.get(email=kwargs.get("email"), user_type_id=3)
result = cls(
user=users,
errors=[Error()],
account_errors=[],
token=get_token(users))
user = result.user
I do get token even my password is wrong, it should be failed when the password is wrong.
Thanks

'Cursor' object has no attribute - In pymongo

Im trying to make a web app in Flask with Pymongo and a MongoDB
Im getting that it cant find the attribute password in my db under users
elif request.method == 'POST':
login_user = request.form['username']
db_user = mongo.db.users.find({"username": "MattatMatt"})
pw = db_user.password
I know im being an idiot, please help.
This is the database:
username:"MattatMatt"
password:"..."
If you need anything else please ask.
Thank you!!!
find() returns a cursor. You likely want find_one() which returns a single record as a dict. As it's a dict and not an object, you will need to get the password using db_user['password'], e.g.
elif request.method == 'POST':
login_user = request.form['username']
db_user = mongo.db.users.find_one({"username": "MattatMatt"})
pw = db_user['password']

I want to update the user image, if it's been changed on Facebook / Twitter in my Rails app

I'm using omniauth for user to signin using his Facebook and Twitter account. Everything is working fine till here, getting whatever I need and saving in my db. Now what I want is to update update user info for example: image (more specific) or name or any other thing, how should I do that, so that it's updated information appears in my app as well.
I am posting my user model code where I'm saving the user
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
user = User.where(:provider => auth.provider, :uid => auth.uid).first
if user
return user
else
registered_user = User.where(:email => auth.info.email).first
if registered_user
return registered_user
else
user = User.create(name:auth.extra.raw_info.name,provider:auth.provider,uid:auth.uid,email:auth.info.email,password:Devise.friendly_token[0,20],image:auth.info.image)
end
end
end
You can refactor your code like this:
def self.find_for_facebook_oauth(auth)
user = User.where("(uid = ? AND provider = 'facebook') OR lower(email) = ?", auth.uid, auth.info.email).first || User.new
#Here you simply update the attributes you want
user.name = auth.extra.raw_info.name
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0..20]
user.image = auth.info.image
user.save
user
end
I highly recommend you include a oauth_token and oauth_expires_at fields for further extension and usage of the Facebook Graph.
Hope this helps!

Rails 3.2 Email Address "If Blank"

So I had a problem where Omni-Auth Facebook wasn't returning an email address for SOME (20-30%) user accounts, therefore the accounts wouldn't be registered because of an "email can't be blank error."
So I decided to solve this by automatically generating an email address based on the user's facebook ID if omniauth couldn't get the email address...
Now... of course... the problem with my solution (as you'll see below) is that it started saving the auto-generated email address REGARDLESS of whether or not omniauth was returning an email address. (For example my email always worked fine, but it was replaced with 123213#facebook.com)
Basically what I want is this: if a user has already supplied an email address then it just stays with the original. If they haven't, and the email address can't be gotten from omniauth, then it generates a new one.
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = "#{auth.provider}-#{auth.uid}#liquid-radio.com"
user.password = user.password_confirmation = SecureRandom.urlsafe_base64(n=6)
if auth.provider == "facebook"
user.name = auth.info.name
user.email = auth.info.email = "#{auth.uid}#facebook.com"
else
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
end
user.save
end
end
You'll probably want to move this line:
user.email = "#{auth.provider}-#{auth.uid}#liquid-radio.com"
down into the "else" case, since it only (presumably) applies to non-Facebook users.
Aside from that, try changing this:
user.email = auth.info.email = "#{auth.uid}#facebook.com"
to this:
user.email ||= auth.info.email || "#{auth.uid}#facebook.com"
A breakdown of what this does:
if the user already has an email, it doesn't change it
if there's a value in auth.info.email and the user doesn't have an email yet, set it
if there isn't a value in auth.info.email, punt and use the generated version
You could write this out long-form in Ruby as:
if user.email
# do nothing
elsif auth.info.email
user.email = auth.info.email
else
user.email = "#{auth.uid}#facebook.com"
end
Note: the solution above will not work if the liquid-radio.com line is still above the if auth.provider part - the user will ALWAYS have a value in the email field in that case.
Another note: this code will not update a user's email from their Facebook auth if it changes. This may or may not be what you want.