Can't create bucket with domain using API but allowed in console - php

ERROR
Fatal error: Uncaught exception 'Google\Cloud\Exception\ServiceException' with message
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "The bucket you tried to create is a domain name owned by another user."
}
],
"code": 403,
"message": "The bucket you tried to create is a domain name owned by another user."
}
}
I get this error when I try and create a bucket with a domain using the API. I can, however, create that same bucket in the dashboard visual interface in the console.
Does anyone know why this might happen? The Webmaster verification tools, the domain is listed as verified.
putenv('GOOGLE_APPLICATION_CREDENTIALS=../../service-account.json');
# Your Google Cloud Platform project ID
$projectId = 'PROJECT';
# Instantiates a client
$storage = new StorageClient([
'projectId' => $projectId
]);
# The name for the new bucket
$bucketName = 'somethingsomething123.domain.co';
# Creates the new bucket
$bucket = $storage->createBucket($bucketName);
echo 'Bucket ' . $bucket->name() . ' created.';

I had to go to the following URL and add my service account.
https://www.google.com/webmasters/verification/details?hl=en&domain=[YOUR-DOMAIN.COM]

Related

How to fixed Project Permission Denied problem for update draft grade and assigned grade of student submission from Google Classroom

I want to update the draft grade and assigned grade from Google Classroom using API. The following problem is seen When I test to update the draft grade and assigned grades using Try this API.
Problem:1
{
"error": {
"code": 403,
"message": "#ProjectPermissionDenied The Developer Console project is not permitted to make this request.",
"status": "PERMISSION_DENIED"
}
}
This error may be due to using an insufficient credential type.
Try using OAuth 2.0.
Localhost Code:
$client = getClient();
$service = new Google_Service_Classroom($client);
$courseId = '393351980716';
$courseWorkId = '393445838699';
$id = 'Cg0Iu5q5vHkQ657M2bkL';
$post_body = new Google_Service_Classroom_StudentSubmission(array(
'assignedGrade' => 10,
'draftGrade' => 90
));
$params = array(
'updateMask' => 'assignedGrade,draftGrade'
);
$list = $service->courses_courseWork_studentSubmissions->patch($courseId, $courseWorkId, $id, $post_body,$params);
Then when I run the above code on localhost I see problem-2:
Problem-2
Fatal error: Uncaught Google\Service\Exception: {
"error": {
"code": 403,
"message": "#ProjectPermissionDenied The Developer Console project is not pe
rmitted to make this request.",
"errors": [
{
"message": "#ProjectPermissionDenied The Developer Console project is no
t permitted to make this request.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
How to solve this problem?
According to the Classroom API documentation:
ProjectPermissionDenied indicates that the request attempted to modify a resource associated with a different Developer Console project.
Possible Action: Indicate that your application cannot make the desired request. It can only be made by the Developer Console project of the OAuth client ID that created the resource.
Therefore, if the resource you are trying to modify has been created manually for instance, this means that it is not associated with any developer project, hence the error you are receiving.
You will have to create these resources in the same project in order to be able to execute this request successfully.
Reference
Classroom API Access Errors.
For that API request your API key needs one of the following authorised scopes
Authorization Scopes
Requires one of the following OAuth scopes:
https://www.googleapis.com/auth/classroom.coursework.students
https://www.googleapis.com/auth/classroom.coursework.me

Google Drive API V3, PHP Client, transfer file ownership

I am trying to create a folder and change the owner using Google Drive API PHP Client. Folder gets created properly, and I can set any permission aside from owner, which returns an error. My code:
function createFolder($name, $parents, $mimeType)
{
$client = getClient();
$service = new Google_Service_Drive($client);
$folder = new Google_Service_Drive_DriveFile();
$folder->setName($name);
if ($parents) {$folder->setParents(array($parents));}
$folder->setMimeType($mimeType);
$created_folder = $service->files->create($folder);
$created_folder_id = $created_folder->getId();
$ownerPermission = new Google_Service_Drive_Permission();
$ownerPermission->setEmailAddress("shared#******.com");
$ownerPermission->setType('user');
$ownerPermission->setRole('owner');
$service->permissions->create($created_folder_id, $ownerPermission, array('transferOwnership' => 'true'));
return $created_folder_id;
}
And the return:
Fatal error: Uncaught Google\Service\Exception: {
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "The transferOwnership parameter must be enabled when the permission role is 'owner'.",
"locationType": "parameter",
"location": "transferOwnership"
}
],
"code": 403,
"message": "The transferOwnership parameter must be enabled when the permission role is 'owner'."
}
Am I not setting the transferOwnership parameter correctly?
#DLateef If you want to make the file shareable, you may want to read more about Permission resource in Drive API. For "shared" to be true, each file permission needs to specify a role, type, and email address or domain. As an owner of the file (Docs, Sheets, etc.), you will need to provide the appropriate permission to be set to.
Here is an example, using the Permissions.create
POST https://www.googleapis.com/drive/v3/files/{fileId}/permissions?key={YOUR_API_KEY}
{
"role": "reader",
"type": "user",
"emailAddress": "xxxxxxxx#xxx.com"
}
Response from the Drive Files.get:
GET https://www.googleapis.com/drive/v3/files/{fileId}?fields=appProperties%2CfileExtension%2Ckind%2CmimeType%2Cshared&key={YOUR_API_KEY}
{
"kind": "drive#file",
"mimeType": "application/vnd.google-apps.document",
"shared": true
}
However, if you are unable to switch to the Drive v3, you can still use the Permission.insert from Drive v2 to do the job.
Or else, you can also try ownerPermission->setTransferOwnership(true);
I was able to get this to work by separating the code for creating the folder an transferring ownership. If called as part of the same createFolder function I get the error described above, but transferring ownership in a separate function, after folder is created, works fine.

Google compute engine instance start/status/stop using api

I need to start the google cloud instance and stop if my process is over.
So i tried api calls from https://cloud.google.com/compute/docs/reference/rest/v1/instances/get
Created API Key and oAuth client Id for the same and tried in postman application to test.
Used API Key in header Authorization : Bearer <api_key> and also in URL as key=<api_key>
But both methods are giving error 401 login required.
Then i found API Explorer
https://developers.google.com/apis-explorer/
There also i got same error.
What is the mistake I'm doing.
I need to implement instance start and stop through PHP code as it is background process.
PHP curl response
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
I think the easiest way to actually do this using env variable, as the google api php client library has a neat method.
require_once __DIR__ . '/vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');
$client = new Google_Client();
$client->setApplicationName('RandomNameYouNeedToInsert/0.1');
$client->addScope(array('https://www.googleapis.com/auth/compute'));
$client->useApplicationDefaultCredentials();
$service = new Google_Service_Compute($client);
// TODO: Update placeholder values.
project = 'my-project';
$zone = 'my-zone';
$instance = 'my-instance';
$response = $service->instances->start($project, $zone, $instance);
// TODO: Check if the response satisfies your request.

Google API oauth2 token expires?

I have a problem with google api and oauth2 token.
There is an app which allows to synchronize contacts / calendar with your google account by oauth2 token.
When first time user wants to connect with his google account, he needs to grant access , then app is receiving code/token which is saved and will be used for offline synchronization later.
function getClient($app)
{
$client = new Google_Client();
$client->setAuthConfig("path_to_secret.json");
switch($app)
{
case 'contacts':
$client->addScope(Google_Service_Script::WWW_GOOGLE_COM_M8_FEEDS);
$client->addScope(Google_Service_People::USERINFO_EMAIL);
break;
case 'calendar':
$client->addScope(Google_Service_Calendar::CALENDAR);
break;
default:
throw new Exception('API Callback not defined in setup');
}
$client->setAccessType('offline'); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->setRedirectUri(GOOGLE_APP_URL . $app.'/callback.php');
return $client;
}
(there are different tokens for contacts and calendar)
The synchronization script:
...
try
{
$client = getClient('calendar');
$client->setAccessToken(unserialize($accessToken));
$http = $client->authorize();
$service = new Google_Service_Calendar($client);
...
}
$accessToken is a serialized string like:
a:5:{s:12:"access_token";s:131:"******token_here********";s:10:"token_type";s:6:"Bearer";s:10:"expires_in";i:3598;s:8:"id_token";s:902:"***id_token****";s:7:"created";i:1505178047;}
This is working for first time and couple more times but after some time(hours) there is an error:
Error: {"error": { "errors": [ { "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" }}
What I am doing wrong?
What is interesting that for contacts synchronization works fine all the time (access token has the same attributes as in calendar synchronization )
Ok, propably solved - refresh_token is provided for the first time only, so when I was testing it more times then I didn't get refresh token.
When I revoked access in https://myaccount.google.com/u/0/permissions and connected again then I received also refresh token. I assume now it will work properly

Trouble making authenticated calls to Google API via OAuth

When I try to make a call to the Google Directory API using Server to Server authentication, I get the error message "Not Authorized to access this resource/api".
What I did:
Created an App in the Google Developers Console.
Downloaded the private key and looked up the service account name.
Activated the Admin SDK under APIs.
Downloaded the google-api-php-client.
Wrote the following code:
$serviceAccountName = 'XXXXXXXXXXX#developer.gserviceaccount.com';
$scopes = 'https://www.googleapis.com/auth/admin.directory.group';
$privateKeyFile = dirname(__FILE__).'/../certs/googleapi-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName('API Project');
$client->setScopes($scopes);
$cred = new Google_Auth_AssertionCredentials($serviceAccountName, $scopes, file_get_contents($privateKeyFile));
$client->setAssertionCredentials($cred);
$client->getAuth()->refreshTokenWithAssertion();
$req = new Google_Http_Request("https://www.googleapis.com/admin/directory/v1/groups/group-id#example.com/members?maxResults=1000");
$val = $client->getAuth()->authenticatedRequest($req);
var_dump($client->getAuth()->getAccessToken());
var_dump($val->getResponseBody());
Executing that small script yields a valid access token, valid for an hour and the following error message:
{ "error": { "errors": [ { "domain": "global", "reason": "forbidden", "message": "Not Authorized to access this resource/api" } ], "code": 403, "message": "Not Authorized to access this resource/api" } }
I get the same error when I try to do the same request on the Google OAuth playground with the access key from my PHP script. Do I have to activate access to the group data for that service account somewhere in the Developers Console?
Beyond granting the service account client id access to the given scopes in your Google Apps Control Panel, you need to tell the service account to impersonate a super administrator user within your Google Apps domain:
$auth->sub = $adminEmail;
For some reason, the Admin SDK docs don't contain a PHP sample but there's sample code for instantiating a service account in the Google Drive docs.
I found by trial and error that removing "admin." from the scopes makes it work (in addition to everything said above about following these steps: https://developers.google.com/drive/web/delegation#delegate_domain-wide_authority_to_your_service_account ).
$cs = json_decode(file_get_contents(<MY SECRET PATH> . 'client_secrets.json'), true);
$cs = $cs['web'];
$cred = new Google_Auth_AssertionCredentials(
$cs['client_email'], //why do they call this "service account name" ? Misleading >:(
array(
'https://www.googleapis.com/auth/directory.user',
'https://www.googleapis.com/auth/directory.group',
'https://www.googleapis.com/auth/directory.group.member'
),
$key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
'<MY EMAIL IN THE DOMAIN>' //_my_ email as an user with admin rights
);

Categories