Error_PermissionDenied in MutateCustomerUserAccessInvitation
Savvelev opened this issue · comments
Describe the bug:
Faced the problem of canceling invitations to the manager account.
The invitation uses the CustomerClientLinkService.MutateCustomerClientLink service.
Using CustomerClientLinkOperation with ClientCustomer and its identifier and Status ManagerLinkStatusEnum.Types.ManagerLinkStatus.Pending requests go, clients receive letters and become in the manager account hierarchy. All functionality works. LoginCustomerId = CustomerId of the manager. Everything is as described in the documentation.
The problem appeared when I ran into a limit on 20 Pending
requests and you need to withdraw irrelevant ones.
CustomerClientLinkOperation doesn't make it possible to do this, as I understand it.
In the documentation, I found CustomerUserAccessInvitationOperation and the remove operation.
Faced the problem described in the title : USER_PERMISSION_DENIED
The request contains LoginCustomerId = CustomerId of the manager. The previous logic only confirms that everything should work, like other methods that, after gaining access, interact with subordinate accounts - change, update. And such requests should have LoginCustomerId. Through the web interface, the recall of the invite works.
What to do in such a situation?
Steps to Reproduce:
Here is my client for which I am creating a Google.Ads.GoogleAds.Services.V12.CustomerUserAccessInvitationService service. (Version 13 gives the same error)
_client = new GoogleAdsClient(new GoogleAdsConfig
{
OAuth2Mode = Google.Ads.Gax.Config.OAuth2Flow.APPLICATION,
DeveloperToken = "***",
OAuth2ClientId = "***.apps.googleusercontent.com",
OAuth2ClientSecret = "***",
OAuth2RefreshToken = "***",
LoginCustomerId = "###" // manager account id
});
_service = _client.GetService(Google.Ads.GoogleAds.Services.V12.GoogleAdsService);
A small piece of code that calls a function
var customerClientLinkService =
_user.GetService(Google.Ads.GoogleAds.Services.V12.CustomerUserAccessInvitationService);
var customerId = #########;;
var invitationId = #########;
var request = new MutateCustomerUserAccessInvitationRequest
{
CustomerId = customerId,
Operation = new CustomerUserAccessInvitationOperation
{
Remove = $"customers/{customerId}/customerUserAccessInvitations/{invitationId}"
}
};
try
{
var response =
customerClientLinkService.MutateCustomerUserAccessInvitation(request);
var customerClientLinkResourceName = response.Result.ResourceName;
}
catch (GoogleAdsException ex)
{
if (ex.Failure.Errors.Count > 0)
throw new Exception(string.Join("; ", ex.Failure.Errors.Select(er => er.Message)), ex);
throw new Exception($"ex.Message: {ex.Message}", ex);
}
customerId = #########;;
invitationId = #########;
I'm getting from another service which returns all links to me.
const string defaultCustomerClientLinkQuery = @"
SELECT
customer_client_link.client_customer,
customer_client_link.hidden,
customer_client_link.manager_link_id,
customer_client_link.resource_name,
customer_client_link.status,
customer.id
FROM customer_client_link";
var googleAdsService = _user.GetService(Google.Ads.GoogleAds.Services.V12.GoogleAdsService);
try
{
googleAdsService.SearchStream(WithoutHyphens(managerCustomerId), defaultCustomerClientLinkQuery,
delegate(SearchGoogleAdsStreamResponse response)
{
result = (from row in response.Results
group row.CustomerClientLink by IdToLong(
row.CustomerClientLink.ClientCustomer.Split('/')[1]))
.ToDictionary(x => x.Key,
x =>
x.FirstOrDefault(y =>
y.Status == ManagerLinkStatusEnum.Types.ManagerLinkStatus.Active)?.Status
?? x.Last().Status);
});
}
As a result, the following error:
Google.Ads.GoogleAds.V12.Errors.GoogleAdsException
HResult=0x80131500
Message=Status(StatusCode="PermissionDenied", Detail="The caller does not have permission", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1680774582.737000000","description":"Error received from peer ipv4:173.194.222.95:443","file":"..\..\..\src\core\lib\surface\call.cc","file_line":953,"grpc_message":"The caller does not have permission","grpc_status":7}")
Source=Google.Ads.Gax
StackTrace:
at Google.Ads.Gax.Interceptors.UnaryRpcInterceptor.<Intercept>d__1`2.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Api.Gax.Grpc.ApiCall.GrpcCallAdapter`2.<>c__DisplayClass4_0.<<CallAsync>g__WaitAndCallHandlers|0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Google.Api.Gax.TaskExtensions.WaitWithUnwrappedExceptions(Task task)
at Google.Api.Gax.Grpc.ApiCall.GrpcCallAdapter`2.CallSync(TRequest request, CallSettings callSettings)
at Google.Api.Gax.Grpc.ApiCallRetryExtensions.<>c__DisplayClass1_0`2.<WithRetry>b__0(TRequest request, CallSettings callSettings)
at Google.Api.Gax.Grpc.ApiCall`2.<>c__DisplayClass12_0.<WithCallSettingsOverlay>b__1(TRequest req, CallSettings cs)
at Google.Api.Gax.Grpc.ApiCall`2.Sync(TRequest request, CallSettings perCallCallSettings)
at Google.Ads.GoogleAds.V12.Services.CustomerUserAccessInvitationServiceClientImpl.MutateCustomerUserAccessInvitation(MutateCustomerUserAccessInvitationRequest request, CallSettings callSettings)
at ****.DAL.ExternalServices.GoogleAds.Services.GoogleAdsApiService.CancelInvitation(Int64 clientId) in C:\Repos\****\****\****.DAL\ExternalServices\GoogleAds\Services\GoogleAdsManagerAccountApiService.cs:line 130
This exception was originally thrown at this call stack:
[External Code]
****.DAL.ExternalServices.GoogleAds.Services.GoogleAdsApiService.CancelInvitation(long) in GoogleAdsManagerAccountApiService.cs
Client library version and API version:
Google.Ads.GoogleAds.Core version: 2.1/0
Google.Ads.GoogleAds version: 14.2.0
Google.Ads.Gax 4.0.0
.NET version: Framework 4.8
Operating system ( Windows10)
Request/Response Logs:
Anything else we should know about your project / environment
Sorry for this answer, I just now noticed that the replay is like this. Already deleted. Github does not show me the email address where you should write, replacing everything with a template with *. The mail agent showed me your name for a reply. I answered there.
Github doesn't show me the email address to write to, replacing everything with a wildcard with *. What is your email address to resolve the issue? I need your help. My problem is still not resolved.
Regards, Mikhail
Hi, This issue is specific to Google Ads API, so could you share this exact information with @.*** and add a note that this was redirected from this issue tracker?
…
On Thu, Apr 6, 2023, 8:13 AM Mikhail @.> wrote: Describe the bug: Faced the problem of canceling invitations to the manager account. The invitation uses the CustomerClientLinkService.MutateCustomerClientLink service. Using CustomerClientLinkOperation with ClientCustomer and its identifier and Status ManagerLinkStatusEnum.Types.ManagerLinkStatus.Pending requests go, clients receive letters and become in the manager account hierarchy. All functionality works. LoginCustomerId = CustomerId of the manager. Everything is as described in the documentation. The problem appeared when I ran into a limit on 20 Pending requests and you need to withdraw irrelevant ones. CustomerClientLinkOperation doesn't make it possible to do this, as I understand it. In the documentation, I found CustomerUserAccessInvitationOperation and the remove operation. Faced the problem described in the title : USER_PERMISSION_DENIED The request contains LoginCustomerId = CustomerId of the manager. The previous logic only confirms that everything should work, like other methods that, after gaining access, interact with subordinate accounts - change, update. And such requests should have LoginCustomerId. Through the web interface, the recall of the invite works. What to do in such a situation? Steps to Reproduce: Here is my client for which I am creating a Google.Ads.GoogleAds.Services.V12.CustomerUserAccessInvitationService service. (Version 13 gives the same error) _client = new GoogleAdsClient(new GoogleAdsConfig { OAuth2Mode = Google.Ads.Gax.Config.OAuth2Flow.APPLICATION, DeveloperToken = "", OAuth2ClientId = ".apps.googleusercontent.com", OAuth2ClientSecret = "", OAuth2RefreshToken = "", LoginCustomerId = "###" // manager account id }); _service = _client.GetService(Google.Ads.GoogleAds.Services.V12.GoogleAdsService); A small piece of code that calls a function var customerClientLinkService = _user.GetService(Google.Ads.GoogleAds.Services.V12.CustomerUserAccessInvitationService); var customerId = #########;; var invitationId = #########; var request = new MutateCustomerUserAccessInvitationRequest { CustomerId = customerId, Operation = new CustomerUserAccessInvitationOperation { Remove = $"customers/{customerId}/customerUserAccessInvitations/{invitationId}" } }; try { var response = customerClientLinkService.MutateCustomerUserAccessInvitation(request); var customerClientLinkResourceName = response.Result.ResourceName; } catch (GoogleAdsException ex) { if (ex.Failure.Errors.Count > 0) throw new Exception(string.Join("; ", ex.Failure.Errors.Select(er => er.Message)), ex); throw new Exception($"ex.Message: {ex.Message}", ex); } customerId = #########;; invitationId = #########; I'm getting from another service which returns all links to me. const string defaultCustomerClientLinkQuery = @" SELECT customer_client_link.client_customer, customer_client_link.hidden, customer_client_link.manager_link_id, customer_client_link.resource_name, customer_client_link.status, customer.id FROM customer_client_link"; var googleAdsService = _user.GetService(Google.Ads.GoogleAds.Services.V12.GoogleAdsService); try { googleAdsService.SearchStream(WithoutHyphens(managerCustomerId), defaultCustomerClientLinkQuery, delegate(SearchGoogleAdsStreamResponse response) { result = (from row in response.Results group row.CustomerClientLink by IdToLong( row.CustomerClientLink.ClientCustomer.Split('/')[1])) .ToDictionary(x => x.Key, x => x.FirstOrDefault(y => y.Status == ManagerLinkStatusEnum.Types.ManagerLinkStatus.Active)?.Status ?? x.Last().Status); }); } As a result, the following error: Google.Ads.GoogleAds.V12.Errors.GoogleAdsException HResult=0x80131500 Message=Status(StatusCode="PermissionDenied", Detail="The caller does not have permission", DebugException="Grpc.Core.Internal.CoreErrorDetailException: @.","description":"Error received from peer ipv4:173.194.222.95:443","file":"......\src\core\lib\surface\call.cc","file_line":953,"grpc_message":"The caller does not have permission","grpc_status":7}") Source=Google.Ads.Gax StackTrace: at Google.Ads.Gax.Interceptors.UnaryRpcInterceptor.d__12.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Google.Api.Gax.Grpc.ApiCall.GrpcCallAdapter
2.<>c__DisplayClass4_0.<g__WaitAndCallHandlers|0>d.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Google.Api.Gax.TaskExtensions.WaitWithUnwrappedExceptions(Task task) at Google.Api.Gax.Grpc.ApiCall.GrpcCallAdapter2.CallSync(TRequest request, CallSettings callSettings) at Google.Api.Gax.Grpc.ApiCallRetryExtensions.<>c__DisplayClass1_0
2.b__0(TRequest request, CallSettings callSettings) at Google.Api.Gax.Grpc.ApiCall2.<>c__DisplayClass12_0.<WithCallSettingsOverlay>b__1(TRequest req, CallSettings cs) at Google.Api.Gax.Grpc.ApiCall
2.Sync(TRequest request, CallSettings perCallCallSettings) at Google.Ads.GoogleAds.V12.Services.CustomerUserAccessInvitationServiceClientImpl.MutateCustomerUserAccessInvitation(MutateCustomerUserAccessInvitationRequest request, CallSettings callSettings) at .DAL.ExternalServices.GoogleAds.Services.GoogleAdsApiService.CancelInvitation(Int64 clientId) in C:\Repos****.DAL\ExternalServices\GoogleAds\Services\GoogleAdsManagerAccountApiService.cs:line 130 This exception was originally thrown at this call stack: [External Code] *.DAL.ExternalServices.GoogleAds.Services.GoogleAdsApiService.CancelInvitation(long) in GoogleAdsManagerAccountApiService.cs Client library version and API version: Google.Ads.GoogleAds.Core version: 2.1/0 Google.Ads.GoogleAds version: 14.2.0 Google.Ads.Gax 4.0.0 .NET version: Framework 4.8 Operating system ( Windows10) Request/Response Logs: Anything else we should know about your project / environment — Reply to this email directly, view it on GitHub <#510>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABCOJCAOOHGZV2QXP7GBPLDW72XO5ANCNFSM6AAAAAAWVKL75Q . You are receiving this because you are subscribed to this thread.Message ID: @.>
@Savvelev if the issue still persists, pls send it anash@google.com. I'll forward it to the right aliases.