Retrieve a logged in Google Glass User's email address? - google-mirror-api

We are attempting to be able to provide the ability for a Glass user to request an email to be sent to them from a Timeline Card. On the notify callback Servlet, we are attempting the following to retrieve a user's email address:
String userId = notification.getUserToken();
Credential credential = AuthUtil.getCredential(userId);
Mirror mirrorClient = MirrorClient.getMirror(credential);
Contact contact = MirrorClient.getContact(credential, userId);
We do not get a result back when retrieving an email off of the UserInfo object of a authenticated user. Our application has the following scopes available to the application server:
"https://www.googleapis.com/auth/glass.timeline "
"https://www.googleapis.com/auth/glass.location "
"https://www.googleapis.com/auth/userinfo.profile "
"https://www.googleapis.com/auth/userinfo.email "
"https://www.googleapis.com/auth/contacts"
Are we allowed to retrieve the authenticated user's email address, is there a permission I am missing or is there another means by which to request that data?

The getContact call you are making doesn't have anything to do with the user's email address. You can read up on what Contact is referring to here:
https://developers.google.com/glass/contacts
To get the user's email address, I've successfully used the same auth token used to authorize the Glass mirror API app with the added scope you mention to call this URL:
https://www.googleapis.com/userinfo/email?alt=json
This method seems to stop working after the initial authorization at some point, so be sure to do it when the user first authorizes the app and save off the email.
Although I've also just gotten the email off AppEngine's UserService before as well, which is easier if you happen to be running on AppEngine:
https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/users/UserService

So the question boils down to "Why am I not getting contact info for this userID that I am sending to the Google Mirror service?"
The Mirror service only provides contact information for Contacts that your Glassware has added. See https://developers.google.com/glass/contacts for more about Contacts in Glass and how to add Contacts. Unless you have already added a Mirror Contact with this userId, you won't get anything back.
The Mirror service does not provide direct access to the information from userinfo.info or userinfo.email. You will need to get it out using the OAuth2 libraries first if you want to add them as a Contact for Glass.

Related

How can i get a token expiry when i authenticate to Salesforce using OAuth2?

I have set up a connected app with the following OAuth scopes
Access the identity URL service (id, profile, email, address, phone)
Manage user data via APIs (api)
Manage user data via Web browsers (web)
Perform requests at any time (refresh_token, offline_access)
Access custom permissions (custom_permissions)
I first authenticate using the following
$"{this.ServiceUrl}/authorize?response_type=code&client_id={this.ClientId}&redirect_uri=<HOST_NAME>/SalesForce/MySFCallback";
this presents me with the Salesforce login screen and once i have successfully logged in , I am returned back to my web page and then i try to
get a token as follows:
Using the code value returned from the callback , I call
var client = new RestClient(Uri + "/token");
var request = new RestRequest("", Method.POST);
request.AddParameter("grant_type", "authorization_code", ParameterType.GetOrPost);
request.AddParameter("code", code, ParameterType.GetOrPost);
request.AddParameter("client_id", clientId, ParameterType.GetOrPost);
request.AddParameter("client_secret", clientsecret, ParameterType.GetOrPost);
request.AddParameter("redirect_uri", $"{callbackUri}", ParameterType.GetOrPost);
var response = client.Execute(request);
I get back the JSON response , but there is no expiry for the token.
How can i get an expiry for the token ?
Have you seen https://salesforce.stackexchange.com/q/73512/799 ? Very good answers there.
In a pinch your administrator could try creating a custom number field on User based on user's profile and then expose it to you as a custom attribute (you'd see the extra field in the base64-encoded id_token piece, if you requested this response_type).
But really admin can:
terminate sessions at any time (Setup -> Session Management),
revoke your connected app's access
other things can kick in like you switching IPs (from office vpn to home network or cellular data plan) and company having Setup -> Session Settings -> Lock sessions to IP from which they originated...
So at best this thing would be indicative timeout.
Try to code it defensively based on refresh tokens like in sfdcfox's answer

IdentityServer4: How to set a role for Google user?

I have 3 applications:
An IdentityServer4 API which provides Google authentication and also provides an access token to authorize the resource API.
A simple Resource API which provides some data from DB.
A simple Client in React which have 4 buttons:
Login, for Google auth
Logout
Get data - a simple request with the access token to the Resource API and gets the data from Db
Get user data - returns user profile and token (for debug purpose)
I didn't put any sample code because my problem is not code related, it's knowledge that I'm missing and I ask for guidance.
The workflow is working just fine: the user press the Login button, it is redirected to IdentityServer4 API for Google Auth. From there it is redirected to a Callback Page from the Client and from there to the Index page. I receive the user data and the token, I can request data from the Resource API and it's working.
My problem is: How do I give a Role to the Google Users ?
I don't have users saved in DB. I want three types of Users: SuperAdmin, Admin, Viewer and each of these roles have limited Endpoints which can access.
For limiting their access I saw that I can use Claims-based authorization or Role-based authorization.
So, my question is how ca I give a Google User who wants to login in my app, a specific Claim/Role ? What is the workflow ? I must save it first in DB ? Or there exists a service from Google where I can add an email address and select a Role for that address ?
Thank you very much !
After you get the response from Google in your callback you can handle the user and do what ever you want to do with it. Below are the some typical tasks that you can do in callback that I took from documentation page of identityserver4 link:
Handling the callback and signing in the user
On the callback page your typical tasks are:
inspect the identity returned by the external provider.
make a decision how you want to deal with that user. This might be
different based on the fact if this is a new user or a returning
user.
new users might need additional steps and UI before they are allowed
in.
probably create a new internal user account that is linked to the
external provider.
store the external claims that you want to keep.
delete the temporary cookie
sign-in the user
What I would do is creating an new internal user account that is linked to the external provider and add a role to that user.
If you don't want to save users in db, you can add an extra claim to user in callback method and use that claim in token. and i think this link will help with that.

Getting user email from Twitter using Satellizer

I can't figure out how can I get email address from twitter. I've been using this as example - https://github.com/sahat/satellizer/tree/master/examples/server/node. I've also seen that it's possible to get email from twitter's oauth - https://dev.twitter.com/rest/reference/get/account/verify_credentials. Thanks
The example server doesn't appear to get the email in the twitter case.
And the documentation link explains how to request
Requesting a user’s email address requires your application to be
whitelisted by Twitter. To request access, please use this form.
Once whitelisted, the “Request email addresses from users” checkbox
will be available under your app permissions on apps.twitter.com.
Privacy Policy URL and Terms of Service URL fields will also be
available under settings which are required for email access. If
enabled, users will be informed via the oauth/authorize dialog that
your app can access their email address.
"Given that you have to go through all the hoops to get whitelisted by Twitter in order to access user's email, it is it not part of the example code. If you really need to get user's email, you may have to do that outside Satellizer's auth flow." - sahat (owner of satellizer)

App Engine access anotherusers contacts

In app engine I am using
username= users.get_current_user()
query = gdata.contacts.service.ContactsQuery()
query.max_results = 10000
feed=gd_client.GetContactsFeed(query.ToUri())
to access the contacts of the user who is logged in.
I want to access another users contacts who users my app. This other user has given authsub and I have saved the token.
What do I do to access the other user, changing the username is obviously not enough because I must have to point it to the correct token.
How do I do this?
See http://code.google.com/apis/accounts/docs/OAuth2WebServer.html#offline. You have to get a contacts client authenticated using your stored token, and connect to the service that way. This is less of a GAE and more of a Google Apps API question btw.

Getting an authoritative user id / email in GAE federated login

When performing authentication using the OpenID federated login on GAE, my user object has the following properties:
Nickname: http://wordfaire.com/openid?id=103539105724544727060
email: sudhir.j#wordfaire.com
From the docs,
email()
Returns the email address of
the user. If you use OpenID, you
should not rely on this email address
to be correct. Applications should use
nickname for displayable names.
Obviously, this advice isn't working out very well. So how then can I get an authoritative email handle to associate with a particular OpenID provided by any Google Apps or other domain? I really need the email ID because things like invitations and sharing / access control all function via email ids.
If you need a valid email for OpenID users, ask the user to supply one the first time they log in, and store it yourself along with their user object.
Since anyone can create an OpenID provider, it's not safe to assume that the provider has already gathered a valid address.

Resources