Error with apps in App Engine and Google Vault api - google-vault-api

I need some help with my App Engine apps. I have two aplications, one of them in php and the other in python (both do the same thing). These applications show a list of matters and exports with google vault api, but after two or three calls to the api these apps stay in a state of loading and i get a 500 error, returned by App Engine, but I have a feeling that it is a Google Vault Api problem. Sometimes these work well, but if I reload the pages I get the same error. Do you know if there is a problem with App Engine and Google Vault Api?
Some times a get the error calling listMatters method:
try{
$client = getClient();
$service = new Google_Service_Vault($client);
$optParams = array(
'pageSize' => 100
);
$results = $service->matters->listMatters($optParams);
$matters = $results->getMatters();
} catch (Exception $e) {
die(var_dump($e->getMessage()));
}
Other times calling listMattersExports method:
try {
$client = getClient();
$service = new Google_Service_Vault($client);
$resultsExports = $service->matters_exports->listMattersExports($matterId,$optParams);
$exports = $resultsExports->getExports();
}catch (Exception $e){
die(var_dump($e->getMessage()));
}
The problem is I get 500 error, but no an Api error.

Related

Google Classroom Pub/Sub registration returning 403 authentication error

I'm developing a php application using Google Classroom, and keep getting a "code": 403, "message": "Request had insufficient authentication scopes." error.
Here's what I've done so far, any help would be tremendous!
I've set up my app oauth permissions to use auth/classroom.push-notifications
I've set 'classroom-notifications#system.gserviceaccount.com' to have the Pub/Sub Publisher role
I've set up a Pub/Sub topic
Here's the code I'm using:
$google_course_id = '123456';
$topic_name = 'projects/my-app-name/topics/TopicName';
$feed_type = 'COURSE_WORK_CHANGES';
$user = User::find(2); // User who has authorized via OAuth and accepted all permissions
$client = new Google_Client();
$client->setAccessToken($user->get_google_social_token());
$classroom = new Google_Service_Classroom($client);
$pub_sub = new Google_Service_Classroom_CloudPubsubTopic();
$pub_sub->setTopicName($topic_name);
$work_changes_info = new Google_Service_Classroom_CourseWorkChangesInfo();
$work_changes_info->setCourseId($google_course_id);
$feed = new Google_Service_Classroom_Feed();
$feed->setCourseWorkChangesInfo($work_changes_info);
$feed->setFeedType($feed_type);
$registration = new Google_Service_Classroom_Registration();
$registration->setCloudPubsubTopic($pub_sub);
$registration->setFeed($feed);
$classroom->registrations->create($registration);
Unfortunately, I keep getting the 403 error.
Any help in identifying what I'm missing would be greatly appreciated!
I'm an idiot. While I remembered to add the push-notification scope to my google developer console, I forgot to add them to the Oauth linking code. Adding it to the bottom seems to have fixed the issue!
return Socialite::driver('google')
->scopes(['https://www.googleapis.com/auth/classroom.courses.readonly',
'https://www.googleapis.com/auth/classroom.rosters.readonly',
'https://www.googleapis.com/auth/classroom.coursework.students.readonly',
'https://www.googleapis.com/auth/classroom.guardianlinks.students.readonly',
'https://www.googleapis.com/auth/classroom.profile.emails',
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/classroom.push-notifications',
])
->with(['access_type' => 'offline', 'prompt' => 'consent select_account'])
->redirect();

Accessing authenticated Google Cloud Endpoints API from Google Apps Script

I'm trying to pull some data into a Google sheets spreadsheet from an API that's been built using Google Cloud Endpoints. Here is the API declaration:
#Api(
name = "myendpoint",
namespace =
#ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)
The method I'm trying to access has authentication enabled by means of the user parameter in the API declaration:
#ApiMethod(name = "ping", httpMethod = HttpMethod.GET, path = "ping")
public StringResponse getPing(User user) throws OAuthRequestException {
CheckPermissions(user);//throws an exception if the user is null or doesn't have the correct permissions
return new StringResponse("pong");
}
This works fine when using the generated client libraries or the gapi js library. However AFAIK I can't use those js libraries in Apps Script.
I've got an OAuth2 flow working using the apps-script-oauth2 library from here, and I'm pretty much using the default setup for creating the service
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService(SERVICE_NAME)
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('ruggedAuthCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
.setScope(SCOPES)
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', Session.getActiveUser().getEmail())
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
.setParam('approval_prompt', 'auto')
//.setParam('include_granted_scopes', 'true');
}
These are my methods for accessing the APIs
function getDriveDocs() {
return executeApiMethod('https://www.googleapis.com/drive/v2/','files?maxResults=10');
}
function pingServer(){
return executeApiMethod('https://myapp.appspot.com/_ah/api/myendpoint/v1/','ping');
}
function executeApiMethod(apiUrl, method)
{
//var url = ;
var url = apiUrl + method;
var service = getRuggedService();
return UrlFetchApp.fetch(url, {
'muteHttpExceptions': true,
'method': 'get',
'headers': {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
}
The getDriveDocs() method works perfectly, so I know my auth flow is working correctly. Also, if I call an unauthenticated method in my API I get the correct response. However, when I call the authenticated 'ping' method, the 'user' parameter is always null. Am I missing something in the fetch call? Everything I've read so far seems to suggest that setting
Authorization: 'Bearer ' + service.getAccessToken()
should be enough.
Any help would be much appreciated!
This turned out to be a simple mistake - I had created a new oauth2 credential in the google dev console and had not added the new client id to the API declaration. Here is the working API declaration:
#Api(
name = "myendpoint",
namespace =
#ApiNamespace
(
ownerDomain = "mydomain.com",
ownerName = "mydomain.com",
packagePath = "myapp.model"
),
scopes = {SCOPES},
clientIds = {ANDROID_CLIENT_ID, WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID, GAPPS_CLIENT_ID},
audiences = {WEB CLIENT_ID}
)

Authentication request returned unexpected result 404

Following is a code to get google contacts.
It was working fine but since few days I m getting exception of "Authentication request returned unexpected result: 404".
using Google.GData.Client;
using Google.Contacts;
using Google.GData.Extensions;
private void FetchContactList()
{
List<string> lstContacts = new List<string>();
RequestSettings rsLoginInfo = new RequestSettings("my application", "abc#gmail.com", "XXXXXX");
rsLoginInfo.AutoPaging = true;
ContactsRequest cRequest = new ContactsRequest(rsLoginInfo);
Feed<contact> feedContacts = cRequest.GetContacts();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
// Looping to read email addresses
foreach (EMail emailId in gmailAddresses.Emails)
{
lstContacts.Add(emailId.Address);
}
}
GridView1.DataSource = lstContacts;
GridView1.DataBind();
}
Is google change something from their side?
Please suggest me way to solve the problem.
Update your current api with google api to version 3 and then make changes to the code according. Probably this may be the reason for the error.
https://developers.google.com/analytics/devguides/reporting/core/v3/gdataLibraries
i further suggest you use oauth2.0 for authentication as per the current requirements of your application and if you are using the older version of the api then you must use oauth2.0
Here is the link for oauth2.0 support: https://developers.google.com/google-apps/spreadsheets/authorize
though this is basically for spreadsheets but you can see how it is and working and change it to the requirements of your gmail api

How do I use the Google API Explorer to test my own App Engine Endpoints using OAuth?

I have an Endpoints API deployed on App Engine. I have no problem using the Google API Explorer to make requests to API methods that do NOT require being logged in. The URL I'm using for that is:
https://developers.google.com/apis-explorer/?base=https://[MY_APP_ID].appspot.com/_ah/api
Where I am stuck is calling API methods that require the user to be logged in, such as this one:
#ApiMethod(name = "config.get",
clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID"},
audiences = {"[MY_APP_ID].appspot.com"},
scopes = {"https://www.googleapis.com/auth/userinfo.email"})
public Config getConfig(User user) throws OAuthRequestException {
log.fine("user: " + user);
if (user == null) {
throw new OAuthRequestException("You must be logged in in order to get config.");
}
if (!userService.isUserAdmin()) {
throw new OAuthRequestException("You must be an App Engine admin in order to get config.");
}
...
On the API Explorer there's a switch top right that, when clicked, allows me to specify scopes and authorise. I'm doing that with just the userinfo.email scope checked. It makes no difference. The response I get from my call is:
503 Service Unavailable
- Show headers -
{
"error": {
"errors": [
{
"domain": "global",
"reason": "backendError",
"message": "java.lang.IllegalStateException: The current user is not logged in."
}
],
"code": 503,
"message": "java.lang.IllegalStateException: The current user is not logged in."
}
}
Back when Endpoints was in Trusted Tester phase, I remember there being a manual step in the OAuth2 Playground to get an ID token instead of an access token or some such thing. If that is still required, any mention of that seems to have disappeared from the Endpoints docs now and I see now way to swap out tokens in the API Explorer either.
I see you've got "com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID" in quotes. If that's not a typo in your transcription to Stack Overflow, that's a problem. The value is already a string, so you're just passing in the text com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID (not the actual client ID) as the whitelisted scope. That won't work. Try this instead:
#ApiMethod(name = "config.get",
clientIds = {"[MY_CLIENT_ID].apps.googleusercontent.com", com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID},
audiences = {"[MY_APP_ID].appspot.com"},
scopes = {"https://www.googleapis.com/auth/userinfo.email"})
Edit: isUserAdmin is unsupported within Endpoints, and is likely a secondary cause of error. I'd suggest filing a feature request for supporting this method on the provided User object (we likely won't provide support for the user service itself, so it's separate from OAuth login.)
I don't know when this was introduced, but if you use OAuth2, instead of UserService.isUserAdmin() you can use OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE) where EMAIL_SCOPE is "https://www.googleapis.com/auth/userinfo.email".
This makes it easy to use the old OpenId or OAUth2:
boolean isAdmin = false;
try {
isAdmin = userService.isUserAdmin());
} catch (IllegalStateException e1) {
try {
isAdmin = OAuthServiceFactory.getOAuthService().isUserAdmin(EMAIL_SCOPE);
} catch (Exception e2) {}
}
The original question was asked several years ago, but maybe this will help others.

How to authenticate programmatically to google app engine (with Java)?

I'm trying to authenticate to google app engine programmatically.
I've tried the code sample from the "gae-app-manager" project but it fails:
tmp>java -jar net.sf.gae-app-manager-0.0.1-jar-with-dependencies.jar myaccount#gmail.com mypassword appname
Exception in thread "main" java.lang.Exception: Did not find ACSID cookie
at net.sf.gaeappmanager.google.LogonHelper.loginToGoogleAppEngine(LogonHelper.java:85)
at net.sf.gaeappmanager.google.appengine.Manager.retrieveAppQuotaDetails(Manager.java:34)
at net.sf.gaeappmanager.google.appengine.Main.main(Main.java:55)
Any idea? I'm able to get the token, but there are no cookies.
The code (taken from the gae-app-manager project - http://gae-app-manager.git.sourceforge.net/git/gitweb.cgi?p=gae-app-manager/gae-app-manager;a=blob;f=src/main/java/net/sf/gaeappmanager/google/LogonHelper.java;h=8e09a6d7f864c29b10847ac7fd2eeab2d3e561e6;hb=HEAD):
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accountType", "HOSTED_OR_GOOGLE"));
nvps.add(new BasicNameValuePair("Email", userid));
nvps.add(new BasicNameValuePair("Passwd", password));
nvps.add(new BasicNameValuePair("service", "ah"));
nvps.add(new BasicNameValuePair("source", source));
HttpPost post = new HttpPost(
"https://www.google.com/accounts/ClientLogin");
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = client.execute(post);
if (response.getStatusLine().getStatusCode() != 200) {
throw new Exception("Error obtaining ACSID");
}
String authToken = getAuthToken(response.getEntity().getContent());
post.abort();
HttpGet get = new HttpGet(
"https://appengine.google.com/_ah/login?auth=" + authToken);
response = client.execute(get);
for (Cookie cookie : client.getCookieStore().getCookies()) {
if (cookie.getName().startsWith("ACSID")) {
return cookie.getValue();
}
}
get.abort();
throw new Exception("Did not find ACSID cookie");
Thanks,
Li
Have you considered using the OAuth support instead of trying to log in as a web client would? Every App Engine app can act as an OAuth provider with very little work required on the server side to set it up.
To solve the problem use "SACSID" instead of "ACSID"

Resources