Mark Dilson
05/22/2025, 8:47 PMStreamReadFeature.INCLUDE_SOURCE_IN_LOCATION
disabled); line: 9, column: 41].","status":400,"title":"Bad Request","traceId":"bbc67d08a4511acd2cee3ae785b15cdf"}
cc: @Marc DusseaultMauricio Cabezas
05/22/2025, 10:15 PMoauthIssuerLocation
being set as a URL should be resolved. Remember, oauthIssuerLocation must always be a URL, as outlined in our documentation.
At this point, we do not believe scheduling a call is necessary. Please await our confirmation once we have disabled our MANAGED_OIDC on your organization.
Thank you.Mark Dilson
05/22/2025, 10:19 PMMark Dilson
05/22/2025, 10:23 PMMarc Dusseault
05/22/2025, 10:24 PM{
"detail": "Can't proceed, OAuth configuration is protected against alteration in the organization.",
"status": 409,
"title": "Conflict",
"traceId": "b010eea56f42de82602a36856b10e4ba"
}
Request:
curl --request PUT \
--header "Authorization: Bearer $GD_TOKEN" \
--header 'Content-Type: application/vnd.gooddata.api+json' \
--data '{
"data": {
"id": "msxwodmudl",
"type": "organization",
"attributes": {
"name": "LQDigital",
"hostname": "lqdigital.cloud.gooddata.com",
"oauthSubjectIdClaim": "sub",
"oauthIssuerLocation":"accounts.google.com",
"oauthClientId": "<excluded>"
}
}
}' $GD_ENDPOINT/api/v1/entities/admin/organizations/msxwodmudl
Mauricio Cabezas
05/22/2025, 10:52 PMMarc Dusseault
05/22/2025, 10:54 PM{
"detail": "Client Id and Secret must be defined all together with the issuer location (external OIDC provider).",
"status": 400,
"title": "Bad Request",
"traceId": "7b0bec9f80806613e52738758272fc2e"
}
Marc Dusseault
05/22/2025, 10:57 PMMarc Dusseault
05/22/2025, 10:57 PMMark Dilson
05/28/2025, 8:19 PM{
"title": "Unauthorized",
"status": 401,
"detail": "401 UNAUTHORIZED \"Authorization failed for given issuer \"accounts.google.com\". URI is not absolute\"",
"traceId": "224bbb2005a949d4f0056be852637b55"
}
Michael Ullock
05/28/2025, 11:27 PM"<https://accounts.google.com>"
instead of:
"<http://accounts.google.com|accounts.google.com>"
Mark Dilson
05/29/2025, 1:26 AMJulius Kos
05/29/2025, 9:58 AMoauthIssuerId
parameter via the API and then you need to insert the value into the below callback URL:
<https://lqdigital.cloud.gooddata.com/login/oauth2/code/><oauthIssuerId>
Let us know if that helped to resolve the issue.Mauricio Cabezas
06/02/2025, 11:32 AMMark Dilson
06/02/2025, 10:09 PM{
"status": 404,
"detail": "404 NOT_FOUND \"User is not registered\"",
"traceId": "5d0fd22d414b13f69bf8709623149521"
}
cc: @Marc DusseaultMark Dilson
06/02/2025, 10:09 PMMark Dilson
06/02/2025, 10:44 PMMoises Morales
06/02/2025, 10:49 PMopenid
scope, which returns an ID token containing the user's unique identifier in the sub
claim.
This involves setting up credentials in the Google Cloud Console, directing the user to the authorization endpoint, and exchanging the authorization code for tokens via Google’s token endpoint. This sub
value in the decoded ID token will serve as the user authentication ID in GoodData. I recommend checking online resources on how to do this.
In the meantime, please set the correct Id I've sent to you via DM.Marc Dusseault
06/05/2025, 4:24 PMMoises Morales
06/05/2025, 7:06 PMMarc Dusseault
06/05/2025, 7:07 PMMarc Dusseault
06/05/2025, 7:07 PMMarc Dusseault
06/05/2025, 7:10 PMMoises Morales
06/05/2025, 7:18 PMMarc Dusseault
06/05/2025, 7:20 PMMarc Dusseault
06/06/2025, 8:53 PMsub
id value.
Is this correct? If yes, do we need to change the redirect uri so it points to a page we control that can perform the check and return the sub
id value for the user?
This is being created to be used with the custom URL mentioned in my previous comments.Moises Morales
06/06/2025, 9:14 PMfrom google.auth.transport.requests import Request
from google.oauth2 import service_account
import requests
import json
# === CONFIGURATION ===
SERVICE_ACCOUNT_FILE = 'FILEPATH' # Replace with the path to the API Key
USER_TO_IMPERSONATE = '<mailto:email@domain.com|email@domain.com>' # Replace with the target user's email
SCOPES = ['openid', 'email', 'profile']
# ======================
# Set up credentials
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE,
scopes=SCOPES,
subject=USER_TO_IMPERSONATE
)
# Refresh token
request = Request()
credentials.refresh(request)
# Use token to get user info (including "sub")
token = credentials.token
response = requests.get(
'<https://openidconnect.googleapis.com/v1/userinfo>',
headers={'Authorization': f'Bearer {token}'}
)
print(json.dumps(response.json(), indent=2))
Please be aware that this only works if you are using Google Workspace.Moises Morales
06/06/2025, 9:14 PMMarc Dusseault
06/06/2025, 9:19 PMsub
value, but we would need to change the redirect uri
value to point to it. Currently I think it points to https://lqdigital.cloud.gooddata.com/login/oauth2/code/lqdigital.cloud.gooddata.com.
The new redirect_uri
is: https://insights.lqdigital.com/auth/callback
Provided my solution works, my plan is to get the sub
id on consent and push it into GoodData using this, replacing <user-sub-claim> with the user's sub
id value:
curl --request POST \
--header "Authorization: Bearer $API_TOKEN" \
--header 'Content-Type: application/vnd.gooddata.api+json' \
--data '{
"data": {
"id": "john.doe",
"type": "user",
"attributes": {
"authenticationId": "<user-sub-claim>"
},
"relationships": {
"userGroups": {
"data": [ {
"id": "adminGroup",
"type": "userGroup"
} ]
}
}
}
}' $HOST_URL/api/v1/entities/users
Marc Dusseault
06/06/2025, 9:22 PMredirect_uri
with the GoodData api?Moises Morales
06/06/2025, 9:24 PMMoises Morales
06/06/2025, 9:29 PM"oauthIssuerId"
parameter in your GoodData organization settings, Google will expect the following redirect URI: https://gooddata_domain/login/oauth2/code/oauthIssuerId. If you omit "oauthIssuerId"
, then the URI will default to https://gooddata_domain/login/oauth2/code/gooddata_domain.Marc Dusseault
06/06/2025, 9:56 PMMoises Morales
06/06/2025, 9:59 PMMarc Dusseault
06/06/2025, 10:46 PMMoises Morales
06/06/2025, 11:01 PMMarc Dusseault
06/06/2025, 11:08 PMMoises Morales
06/06/2025, 11:09 PMMarc Dusseault
06/09/2025, 5:53 PMcurl --request POST \
--header "Authorization: Bearer $API_TOKEN" \
--header 'Content-Type: application/vnd.gooddata.api+json' \
--data '{
"data": {
"id": "john.doe",
"type": "user",
"attributes": {
"authenticationId": "<user-sub-claim>"
},
"relationships": {
"userGroups": {
"data": [ {
"id": "adminGroup",
"type": "userGroup"
} ]
}
}
}
}' $HOST_URL/api/v1/entities/users
Moises Morales
06/09/2025, 6:03 PMMoises Morales
06/09/2025, 6:04 PMMarc Dusseault
06/09/2025, 6:05 PMMoises Morales
06/09/2025, 6:19 PM/api/v1/entities/users/id?include=userGroups
Notice that I am using the parameter ?include=userGroups
this will return the user groups the user belongs to and you will have to include them in the call to avoid removing them. This is particularly important in case you are updating an org admin user, if the user is removed from the admin group, you will lose access to the organization and the API token will not have any privileges anymore (you won't be able to undo the changes).
With this said, the endpoint only supports PUT (since the user already exists), and the headers to use are content-type: application/vnd.gooddata.api+json and accept: application/vnd.gooddata.api+json. Let me know how it goes.Marc Dusseault
06/09/2025, 6:29 PM?include=userGroups
means that all of the user groups currently assigned to a user will remain assigned to the user.
b. If ?include=userGroups
is NOT included, I need to include all of the groups I want assigned to the user.
3. Can you add my id in if I share it with you? I want to see if works.Moises Morales
06/09/2025, 6:39 PMMarc Dusseault
06/09/2025, 9:27 PM"data": {
"attributes": {
"authenticationId": "<new id>"
},
"id": "<my user id>",
"type": "user"
}
How do I regain access to the api and see the workspaces and regain any account privileges that might have been lost following the api update I performed?Marc Dusseault
06/09/2025, 11:52 PMMarc Dusseault
06/10/2025, 12:00 AMMoises Morales
06/10/2025, 1:13 PMMarc Dusseault
06/10/2025, 2:57 PMMoises Morales
06/10/2025, 3:02 PMMarc Dusseault
06/10/2025, 3:04 PMMoises Morales
06/18/2025, 8:42 AM