Google Classroom, Ruby, Rails: #NotGoogleAppsUser with test account - ruby-on-rails

I've got a test account for Classroom from Google (that is, all services apart from Classroom are disabled for it). Following the example as in https://developers.google.com/classroom/quickstart/ruby (with slight modifications), I'm able to log in and fetch details e.g. about the student's courses.
However what I want to do is utilize it in a Rails app. I'm using omniauth-google-oauth2 and google-api-ruby-client (the new 0.9.x branch). After having fetched the token for that test account from Google (I've triple checked that it is this account and not any other profile I use) I'm trying to access data from Google::Apis::ClassroomV1::ClassroomService, but it keeps telling me:
Sending HTTP get https://classroom.googleapis.com/v1/courses?pageSize=10
403
#<Hurley::Response GET https://classroom.googleapis.com/v1/courses?pageSize=10 == 403 (319 bytes) 748ms>
Caught error forbidden: #NotGoogleAppsUser The user is not a Google Apps user.
Error - #<Google::Apis::ClientError: forbidden: #NotGoogleAppsUser The user is not a Google Apps user.>
Google::Apis::ClientError: forbidden: #NotGoogleAppsUser The user is not a Google Apps user.
The code I use is:
require 'google/apis/classroom_v1'
module GoogleIntegration::Client
Classroom = Google::Apis::ClassroomV1
def self.create(token)
service = Classroom::ClassroomService.new
scopes = ['https://www.googleapis.com/auth/classroom.courses.readonly', 'profile', 'email']
service.authorization = Google::Auth.get_application_default(scopes)
service.authorization.access_token = token
service.client_options.application_name = 'Membean Classroom Sample'
service
end
and in the controller:
service = GoogleIntegration::Client.create(request.env['omniauth.auth'].credentials.token)
response = service.list_courses(page_size: 10)

According to Classroom API Access Errors:
NotGoogleAppsUser indicates that the requesting user does not belong
to a Google Apps domain.
Possible Action: Prompt the user to re-authenticate using a "Google
Apps for Education" account. Provide a link to using multiple
accounts so the
user can select the correct account.

Related

Microsoft Graph API: How to access guest calendar events using API?

I am working on the integration of the outlook calendar with our app. I am trying to get the calendar events of the guest user. So far I have done the following steps.
Registered an app in the Azure Active Directory admin centre and added the following API permissions.
API permissions
Then I used the following API call to get the access token.
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
I used this token to get the user list which is working fine.
https://graph.microsoft.com/v1.0/users
Then I am using user_id from this result to call the following APIs
https://graph.microsoft.com/v1.0/users/{user_id}/calendars
https://graph.microsoft.com/v1.0/users/{user_id}/calendars/events
https://graph.microsoft.com/v1.0/users/{user_id}/events
I am getting a successful result for Member users but getting the following error for guest users
>AuthOMMissingRequiredPermissions
>The AadGuestPft token doesn't contain the permissions required by the target API.
Any Idea what am I missing?
To get guest users(external) you can use https://graph.microsoft.com/v1.0/users?$filter=userType eq 'Guest' Graph API endpoint. This will give you all external users details in response. Event API will only work for the user within tenant, for external users who does not have license it will not work.
Hope this helps.

Using Microsoft graph to read all users calendars

I gave my application the following scopes:
SCOPES = [ "Calendars.Read", "User.Read.All" ]
I got an access token. With this token I am able to get the users and I get two users back which is correct.
When I then ask for the calendar of myself (admin):
https://graph.microsoft.com/v1.0/users/stijn#temponia.onmicrosoft.com/calendarview?startDateTime=#{start_date.to_s}&endDateTime=#{end_date.to_s}
This also works perfectly. However when I do this for the other user:
https://graph.microsoft.com/v1.0/users/frank#temponia.onmicrosoft.com/calendarview?startDateTime=#{start_date.to_s}&endDateTime=#{end_date.to_s}
I get this error message:
Access is denied. Check credentials and try again.
According to the documentation: https://graph.microsoft.io/en-us/docs/authorization/permission_scopes
Calendars.Read: Read calendars in all mailboxes: Allows the app to read events of all calendars without a signed-in user.
The scope I got back together with the access token was this: "calendars.read user.read.all" so it got accepted.
What am I missing here?
We are working to support the scenario you are requesting (Accessing other users' calendars) but the feature hasn't shipped yet. Stay tuned ...
UPDATE: Please take a look at using client credential flow. The blog post https://blogs.msdn.microsoft.com/exchangedev/2015/01/21/building-daemon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow/ explains how to do this for Outlook API endpoint. But you should be able to follow the instructions for Microsoft Graph as well.
The app will require an admin to consent, and then can access calendar of any user in the organization, as long as their mailbox is in Office 365.

How to change the google API "service account" name/email address

I am using the Google API to create a spreadsheet on google drive.
My app has a link that says 'Download To Google Doc'
The app sends a file to google docs and shares it with the user.
The user can then see it in google docs.
This all works good.
The problem is the identity of the service account sharing the doc.
It is a generated id. I want it to be branded to my app.
Is this possible?
-
You can't change the service account email address, nor can you supply a real world user name to it. The service account email address is created by Google in the Google Developer console.
The only way to change the email address would be to delete it and create a new one but again you would be stuck with the one Google Created. I suspect that the client id and email address are a pair used for identification of your application. Similar to client id and client secret, but I cant verify that.
I do see your point it would be nice if we could.
Google Service Accounts do allow you to impersonate an existing user account (for some services). I haven't tested it on Google Drive, but I have used it with the Webmaster tools API. The instructions can be found here: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
To sum them up, when creating the service account credentials you can specify the "sub" parameter with "The email address of the user for which the application is requesting delegated access." The account you're requesting access for must exist and have permission to access to the services you're requesting.
In the link above Google provides examples for Java, Python and HTTP/REST, here's the Python example:
credentials = SignedJwtAssertionCredentials(client_email, private_key,
'https://www.googleapis.com/auth/sqlservice.admin',
sub='user#example.org')
I'm using the Ruby google-api-client gem (0.9.pre3) and the ServiceAccountCredentials constructor does not pass the 'sub' parameter to its parent class so it has to be specified in another step:
client = Google::Auth::ServiceAccountCredentials.new(json_key_io: json_key_io, scope: scope)
client.update!(sub: 'user#example.org')
client.fetch_access_token!
service = Google::Apis::WebmastersV3::WebmastersService.new
service.authorization = client
Using this code I can authenticate using my service account and I have access to the sites

Looking for timeline of a twitter user using twitter4j 3.03

I am trying to retrieve the timeline of a twitter user using twitter4j. I was able to do this using version 2.6 but now I upgraded to 3.03 and started getting authenticaton error from twitter.
401:Authentication credentials (https://dev.twitter.com/pages/auth)
were missing or incorrect. Ensure that you have set valid consumer
key/secret, access token/secret, and the system clock is in sync.
message - Could not authenticate you code - 32
This is how I retrieve a twitter object
TwitterFactory twitterFactory = new TwitterFactory(
new ConfigurationBuilder().setDebugEnabled(true).
setOAuthConsumerKey(oAuthConsumerKey).
setOAuthConsumerSecret(oAuthConsumerSecret).
setJSONStoreEnabled(true).
build());
twitter = twitterFactory.getInstance();
twitter.setOAuthAccessToken(new AccessToken(accessToken, accessTokenSecret));
When I retrieve a twitter object like this and try to get a different user than the authenticated user I got an authentication error. Here is the code for retrieving the user:
user = twitter.showUser(userName);
Before the upgrade I was able to retrieve any user who has a public profile, but now I can't retrieve any user other than the authenticated user itself. Am I doing smtg wrong here, Do I need to get permission from the user to lookup for his timeline, which I don't believe because when I use oauth tool of twitter I am able to retrieve the user without getting any permission from the user.
I am using twitter4j version 3.03.
Apparently old api was accepting userNames starting with "#" whereas the new version just throws this strange error. After removing the "#" from the searched user name everything worked without any problem.

Why is the access token that I pass to appEngine from iOS invalid?

I am working on an iPhone game that maintains a leaderboard and some social interaction through a backend that I built in Google App Engine. The user can log in through facebook in the iPhone app. The app sends some user details including the access token to my Google App Engine app through an HTTP post.
The handler that receives the request tries to use the access token to retrieve the users friends. I am using the pythonforfacebook SDK (which I have had success with previously) which is on Github here:
https://github.com/pythonforfacebook/facebook-sdk
The relevant python code in my GAE app is as follows:
def post(self):
at = self.request.get('at')
user = User.get_by_key_name(uid)
if not user: #create previously unknown user
logging.info('Entered unknown user code')
logging.info(at)
logging.info(type(at))
graph = facebook.GraphAPI(at)
facebook_user = graph.get_object("me")
friends = graph.get_connections(facebook_user["id"], "friends")
The logging commands print what looks like a good access token and states that the type is 'Unicode'. When I copy the access token that logging.info prints to the GAE logs and paste it into the facebook access token debugger, I get the following output:
App ID: deleted for privacy but looks right
Metadata: {"sso":"iphone-safari"}
User ID: deleted for privacy but looks right
Issued: 1345405177 (10 minutes ago)
Expires: Never
Valid: True
Origin: Mobile Web Faceweb
Scopes: offline_access read_stream
I just updated my code to use the most recent posted version of pythonforfacebook but that didn't make any difference. Any ideas would be much appreciated.
Thanks,
Dessie
To get friends of the user you can do it pretty easily without the pythonforfacebook SDK.
https://graph.facebook.com/<username or ID>/friends?access_token=<your token>
That link will give you the friends of the user in JSON format. So if you import urllib2 and json you could do:
response = urllib2.urlopen(<url above>)
friendsString = response.read()
friends = json.loads(friendsString )
Then friends will be a dict containing of all the friends.

Resources