Rails omniauth Google - how to update profile data - ruby-on-rails

I'm using omniauth to authenticate a user via Google. When the user logs in via Google, I check if an account already exists with the same email (if it does, I reject sign in).
When I create the new User model, I give it the name, email, and the URL of the user's 'image'. I am not sure how to dynamically update the information in my database when the user changes their settings on Google, including the image_url when they change their profile image.
A good example of this scenario is this Stack Overflow; I signed up to SO with Google. Having changed my profile image (recently), I was surprised to find that my old Google image remains attached to my SO profile. Maybe it takes time for Google to change the old URL to represent the new image. I have noticed that some parts of Google use my new image, and other parts continue to use my old. Of course, this question doesn't have much to do with Google's profile image mechanism, I just think this is a perfect example.
My questions are:
Should I want to do this, or should I instead provide the user the ability to change their details through my site, completely ignoring what happens to their Google profile?
If I should do this, what is the best way? Checking on every login isn't ideal as the user might not log out for days or even weeks.
Should I be storing the Google auth token? Currently, I'm not as I don't need to make any Google API calls -- I only use OAuth for the 'uid' to ensure it's the same account logging in (the email isn't used at all).
I don't think the answer will be "don't store user info, query Google instead", so I'm not really sure what best practice is in this scenario. A brief walkthrough on proper procedure would be very helpful.

Normally, oauth applications will use the endpoint /me.json as part of the login process: After the user is signed in, the app uses that fresh token to query their profile info right away and update data. In your case, I understand you ignore when email already exists. You should probably add a new step there, to update your local record if it already exists instead of purely ignoring it.
In other words, your app wont be automatically notified if users change their profile pictures. But you can always use their log in action to fetch the latest image (or use their token in a background job that runs every n periods of time using something like cron + whenever, assuming the oauth scope authorizes offline access)

Related

Gigya removeLoginEmails removes last login id

Is there a way to stop accounts.setAccountInfo from deleting an email if it is the last standing login ID?
Currently if I have 2 verified emails both loginIds and issue 2 requests removing one email at a time (I know I can pass a comma separated list) I end up with an account that can't login anymore as no login Id is left.
Both return 200 ok and no error code.
I've looked for an etag implementation so I can at least force some sort of an optimistic lock but couldn't find support for it.
Any ideas?
This is by design, as in the case a user's email(s) were compromised, there needs to be a way to disable login of the account until the user can have their information updated via a customer service representative. There is no out-of-the-box way for an end-user to use this particular parameter, so, unless a currently logged in user is manually calling the method from the JS console, there is no way for this scenario to accidentally happen.
From the server-side, if you are worried about a specific application from calling this method and require restricting a specific app from accessing this particular API you can assign the application key to a permissions group with restricted permissions. ref:https://developers.gigya.com/display/GD/Console+Administration#ConsoleAdministration-PermissionGroups
If you think this behavior should change, please open a ticket from your Gigya/CDC account dashboard for investigation.

iOS Firebase Database Security. Create New App User: Checking for Existence of Username

I have an iOS app where all user and data functionality is handled through firebase. For all required firebase functions, we have set the rights on firebase set such that they are secure (i.e., everyone can only read/write the parts of the database that are relevant to them).
Now, in the “create new user” screen of my app, obviously no user is signed in yet, but I would like to check for availability of the desired email address and username.
How can I conduct the check without making a list of all email addresses and usernames openly accessible in the database (i.e., setting the rights such that everyone can read them).
Keeping an openly accessible list of usernames in the database in my view is a security risk. On the other hand of course no user is signed in when on the “create user” screen, so I don’t know how to restrict the access.
Thanks.
There are many ways around this. Here are a couple suggestions:
Sign the user in anonymously before choosing a username. This would then give them the access you're looking for without making the data public. Then, when the user creates an account, the anonymous account can be converted, as shown in the documentation.
Use an HTTP-triggered Cloud Function, passing the username the user wants to try as a query. Inside the function, check the database for the existence of the username, and then respond to the HTTP call accordingly.
I'd probably do the former because it'll return a quicker response. Cloud Functions can take time to spin up if they haven't run for a while.

Parse and Additional Facebook Permissions (iOS)

There are two Parse methods for reauthorizing a Facebook User (to gain additional permissions) in Parse (for iOS):
reauthorizeUser:withPublishPermissions:audience:block:
reauthorizeUser:withPublishPermissions:audience:target:selector:
Unfortunately, both of these methods are for publishPermissions. I am confused, because it seems that there is no way to add additional read permissions (i.e. Extended Profile Permissions) after the initial login.
Facebook advises that, when doing a general login (i.e. on app opening), you only ask for basic permissions, and then ask for extended permissions as needed, so as not to scare off the user.
So with Parse and Facebook for iOS, does this now mean that we need to ask for every single read permission that we may possibly need at initial login?
Overall it seems that the Parse documentation and framework seems to be lacking a lot of the Facebook instructions for login in various scenarios. We are directed to view the Facebook SDK, but everything there seems to apply to FBSession, and it is not clear which methods are replaced by Parse and which are needed in addition to Parse.
I, for example, have an app where the user can login to Parse via FB on app launch, but does not have to. If they do login, they are asked for only the basic permissions, as advised by FB. Then, should the user try to perform certain actions, they are asked for the permissions for that particular action. I have additional read permissions that need to be granted for the extended profile, as well as publish_actions.
Can anyone give me some direction in this case, or point me too a really thorough, up-to-date, example? The Parse FB Scrumptious example code looked promising to me at first, but it is severely outdated.
Thanks!
Apparently there are more than one way to do it. The easiest one I found using Parse for Android was like this:
Collection<String> publishPermissions = Arrays.asList("publish_actions");
ParseFacebookUtils.linkWithPublishPermissionsInBackground(user, myActivityOrFragment, publishPermissions, new SaveCallback() {...});
Which means that after logging in, you should call linkWithPublishPermissionsInBackground with your user reference and the new permission list. It will open a new Facebook window asking for that permission and link the result to your user.
This code I tested and it works. But seems that Parse is not that smart, some things it does automatically and some it does not. So after that you need to call something like:
ParseFacebookUtilities.linkInBackground(ParseUser, AccessToken)
To actually save it to the user on the server, otherwise, it would work only while the App is running.

MyOpenId not sharing email address

I'm trying to use MyOpenID for my sign-in, but it doesn't seem to be sharing the email address.
If I use Google or others I do seem to get the email address, though. I thought that this was a standard field to return.
I even see some documentation here that seems to suggest they would share email:
https://rpxnow.com/docs/providers
(I'm using Ruby on Rails and Janrain for this project)
One interesting thing is that if I setup an identity page on MyOpenId, then the email IS shared with my application. I thought that there was supposed to be a way when logging in with MyOpenID to specify what data is shared during "SimpleRegistration"?
The problem was that I was testing with my own MyOpenId account and the very first time I logged in to my development server I had not paid enough attention.
When logging in the first time it said something along the lines of "blah site is asking you to share information with it. Click here to use an existing persona or to create a new one. I didn't select one and it defaulted to "don't ask again".
I was able to fix this by going in to MyOpenId and revoking permission for my site. Then the next time I logged in it asked me again and it worked.

Twitterizer: what is the workflow in order to publish messages on user's profile?

as I started to work with Twitterizer in order to publish on someone's wall I am in confusing time.
There is a page, my case, DefaultTwitter.aspx where is link to authenticate on twitter with token provided. Goes on Twitter and comes back to CallbackTwitter.aspx with outh_token and secret. And so the user is identified. On twitterizer example says:
Step 5 - Store the results
You should now store the access token and the user details. Keep in mind that the
only way an access token will become invalid is if the user revokes access by logging
into Twitter. Otherwise, those values will grant you access to that user's data
forever.
My questions are: - should I store any data in SQL datatable and what exactly(however I hope that is not the case to do so)
somebody said that I should save in a cookie(I thought in session); however then if another user comes then how should I create a button to logout or something like that?
-how will user revoke application access if he would like so?
A live example will be much appreciated as I could not found any on internet how exactly twitter api works.
When your application finishes getting authorization to access the user's data, the result is the access token (represented by 2 values, a key and a secret). Those values are, in effect, the username/password you can use in requests to the API on behalf of that user.* Save those values in your SQL database. You'll also be given the user id and screen name. It's probably a good idea to keep those handy, too.
The user can revoke access to an application by going to http://twitter.com/settings/applications, finding the application and clicking the revoke access button next to it. Your application cannot revoke access for the user.
You asked for an example, but you're citing the example application. Just look at the source code in that sample.
* - That's a simplification for explanation sake. Please don't crucify me, OAuth experts.

Resources