How to obtain user's organization name from Google APIs - google-directory-api

Our app authenticates users with Google using OpenID connect, then attempts to obtain the name of the user's organization using Google's APIs, since it is not available in the Open ID Connect UserInfo object. The code is as follows:
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleCredential credential = getCredentials(jsonFactory, httpTransport, connection.getDomainAdminEmail());
Directory directory = new Directory.Builder(httpTransport, jsonFactory, null).setApplicationName(APP_NAME).setHttpRequestInitializer(setHttpTimeout(credential)).build();
User user = directory.users().get(id).execute();
Object organizations = user.getOrganizations();
Although the user is returned, the value of organizations is null, even though the organization is defined in the Google Apps Admin panel. How does one obtain the company name of an authenticated Google user?

The following call retrieves customer info using Google Directory API:
directory.customers().get("my_customer").execute();
Note: Use of my_customer will retrieve current customer. At minimum, this call requires the following scope:
https://www.googleapis.com/auth/admin.directory.customer.readonly
It seems customer info cannot be obtained using a service credential. It needs to be a Client ID credential. The user logging in has to consent to the above scope.
GoogleCredential credential = getCredentials(jsonFactory, httpTransport, connection.getDomainAdminEmail(),true);
Directory directory = new Directory.Builder(httpTransport, jsonFactory, null)
.setApplicationName(APP_NAME)
.setHttpRequestInitializer(setHttpTimeout(credential))
.build();
Customer customer = directory.customers().get("my_customer").execute();
CustomerPostalAddress postAddress = customer.getPostalAddress();
googleCustomer = new GoogleCustomer.Builder()
.setPhoneNumber(customer.getPhoneNumber())
.setLanguage(customer.getLanguage())
.setCompany(postAddress.getOrganizationName())
.setAddress1(postAddress.getAddressLine1())
.setAddress2(postAddress.getAddressLine2())
.setAddress3(postAddress.getAddressLine3())
.setAddressContactName(postAddress.getContactName())
.setAddressCountryCode(postAddress.getCountryCode())
.setAddressLocality(postAddress.getLocality())
.setAddressPostalCode(postAddress.getPostalCode())
.setAddressRegion(postAddress.getRegion())
.build();

Related

Microsoft Graph works with one program, but not another

I am attempting to create a c# Windows service that periodically captures information from Microsoft Graph. This always fails with a "AADSTS700016: Application not found in the directory of our Microsoft 365 account."
Prior to trying to write this service, I created a test program to do same access. I set up an application in Azure Active Directory with a secret. When I run the exact same code in the this test program with the correct tenant ID, client ID and the secret, the program works fine from whatever computer I run it from.
However, the c# service always fails with the error noted above and detailed below. Can't be an issue with permissions as access IDs and secret are the same. I have even tried creating a separate application in AAD but get the same error.
Common c# statements:
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientID, clientSecret, options); ;
graphClient = new GraphServiceClient(clientSecretCredential, scopes);
if (graphClient == null) throw new Exception("Unable able to obtain a GraphClient for this pass");
var groups = await graphClient.Groups.Request().Select(x => new { x.Id, x.DisplayName }).GetAsync();
Any help appreciated. I am sure it is something simple, but clueless at the moment.
Inner Exception 1:
AuthenticationFailedException: ClientSecretCredential authentication failed: AADSTS700016: Application with identifier 'c62d4eb9-587d-4b7f-a4d8-0640747f0958' was not found in the directory xxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
Trace ID: c8bfac15-c9d6-407e-89e7-36f21fb18300
Correlation ID: 9c8d25ad-c275-43c0-93c1-d295608e9f92
Timestamp: 2022-08-13 15:52:36Z
And just like that, I found the error. Good old global vs local variable name. I hope no one spent too much time on this.

IAM role for multi-tenancy (Identity platform)

I am currently working on multi-tenancy using admin auth as per the documentation: https://cloud.google.com/identity-platform/docs/multi-tenancy
I initialized a Tenant Auth with a registered tenantId:
const tenantManager = admin.auth().tenantManager();
const tenantAuth = tenantManager.authForTenant(tenantId);
let tenantData = await tenantManger.getTenant(tenantId)
When I perform any operations using this tenantAuth or get the tenant data, I get the following error
An internal error has occurred. Raw server response: "{"error":{"code":403,"message":"The caller does not have permission","status":"PERMISSION_DENIED"}}"
I can understand it is an IAM role required for the service account key I used for initializing the admin SDK. Can anyone tell what's the valid role to be added?

Why I have access to an authorized useron a local windows account and not when I am logged in a domain one?

I can authorize a user for a specific Active Directory and get the user's groups when I execute the code as a local wndows account.
However I get acces denied, when I am logged in a specific domain account
What should I add to my api ? Maybe windows user credentials ? And where to add them ?
ADContext = new PrincipalContext(ContextType.Domain, ADSettings.Domain, ADSettings.User, ADSettings.Password);
UserPrincipal user = UserPrincipal.FindByIdentity(ADContext, IdentityType.SamAccountName, user.Username);
var groups = user.GetGroups(); //this one fails.
StackTrace
at System.DirectoryServices.ActiveDirectory.Utils.GetDSHandle(String domainControllerName, String domainName, IntPtr authIdentity, LoadLibrarySafeHandle libHandle)
at System.DirectoryServices.ActiveDirectory.DomainController.GetDSHandle()
at System.DirectoryServices.ActiveDirectory.DomainController.GetDomainControllerInfo()
at System.DirectoryServices.ActiveDirectory.DomainController.get_SiteName()
at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOf(Principal p)
at System.DirectoryServices.AccountManagement.Principal.GetGroupsHelper()
at System.DirectoryServices.AccountManagement.Principal.GetGroups()

Google Analytics API - Integration With Symfony2

I am trying to gain access to Google Analytics API through OAuth2.
What i did:
Open developers console > APIs and Auth > Credentials
Create a new Client ID
Generate p12 key
Copy the key on the server
Open google analytics page > admin > Account > User Management
Add the email from generated Client ID, something like: xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com
Give to this email Read and Analyze permissions
Then when I go back to developers console > permission. The new email is added on Service accounts with Edit permissions
Recheck if Google Analytics is enabled and data is going in.
Now I had installed widop/google-analytics-bundle and configure the bundle:
widop_google_analytics:
client_id: "xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com"
profile_id: "ga:12345678"
private_key_file: "mykey.p12"
http_adapter: "widop_http_adapter.curl"
And the query I try to create is:
$profileId = 'ga:12345678';
$query = new Query($profileId);
$query->setStartDate(new \DateTime('-2months'));
$query->setEndDate(new \DateTime());
$query->setMetrics(array('ga:visits' ,'ga:bounces'));
$query->setDimensions(array('ga:browser', 'ga:city'));
$query->setSorts(array('ga:country', 'ga:browser'));
$query->setFilters(array('ga:browser=~^Firefox'));
$query->setSegment('gaid::10');
$query->setStartIndex(1);
$query->setMaxResults(10000);
$query->setPrettyPrint(false);
$query->setCallback(null);
$clientId = 'xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com';
$privateKeyFile = 'mykey.p12';
$httpAdapter = new CurlHttpAdapter();
$client = new Client($clientId, $privateKeyFile, $httpAdapter);
$token = $client->getAccessToken();
$service = new Service($client);
$response = $service->query($query);
return $response;
As a response I get this error:
User does not have sufficient permissions for this profile.
When I open developers console > overview > 1 hour (tab)
I had notice that requests are going in.
From all that - I assume that authentication and query is OK but the user has no permissions to get any kind of data which is weird because I had granted Read and Analyze permissions to
xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com
What could by the reason for that exception?
I do not know if you already solved this issue.
The solution for me was use the view ID instead of account ID on the analytics account.
The view ID is on the third column in settings, on Google Analytics administration panel.
Sorry for my english.

How to get useID/Email of logged in user in Google Contacts API after OauTh Token

I developed a program which works well and I can import data from gmail but. I want to keep track how is the user given permission to manage contacts. But after a hard search I did not get any Idea about the loged in user. My code is as follows.
============================================
var parameters = new OAuth2Parameters
{
ClientId = ConfigurationManager.AppSettings["ClientID"].ToString(),
ClientSecret = ConfigurationManager.AppSettings["ClientSecret"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectURL"].ToString(),
Scope ="https://www.googleapis.com/auth/userinfo.profile"
};
parameters.AccessCode = Request.QueryString["Code"].ToString();
OAuthUtil.GetAccessToken(parameters);
Session["Token"] = parameters.AccessToken;
==================================
But I dont how to get email of logged in user. Please let me that
Thanks in advance
Request an additionall scope of https://www.googleapis.com/auth/userinfo.email and then you can access the user info as well. There is also a userinfo.profile witch contains other info on the user like name, profile picture, language and so on.
Your code looks like C# but I only have a Python example of using multiple scopes and sharing tokens.
Code: https://code.google.com/p/google-api-oauth-demo/
Article: http://www.hackviking.com/2013/10/python-get-user-info-after-oauth/