google-api-python-client icon indicating copy to clipboard operation
google-api-python-client copied to clipboard

OU with + in name causes Directory API to return information about a different OU

Open taers232c opened this issue 3 years ago • 6 comments

I am the author of Advanced GAM and have run into the following issue regarding OU names. I have two test OUs: /Test/Test+Plus /Test/Test Plus

When trying to retrieve information about /Test/Test+Plus, the URL quoting causes results to be returned for /Test/Test Plus If /Test/Test Plus doesn't exist, you get a 404 Not Found error.

Thanks,

Ross

$ gam config debug_level 1 info ous "'/Test/Test+Plus','/Test/Test Plus'" nousers
connect: (admin.googleapis.com, 443)
send: b'GET /$discovery/rest?version=directory_v1 HTTP/1.1\r\nHost: admin.googleapis.com\r\ncontent-length: 0\r\nuser-agent: GAMADV-XTD3 6.22.18 - https://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <[email protected]> / Python 3.10.4 final / macOS-10.13.6-x86_64-i386-64bit x86_64 /\r\nauthorization: Bearer xxx\r\naccept-encoding: gzip, deflate\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
...

 /Test/Test+Plus returns information about /Test/Test Plus
because the + is not quoted as %2B and the + is interpreted as a space at the server 
 
send: b'GET /admin/directory/v1/customer/my_customer/orgunits/Test/Test+Plus?prettyPrint=true&alt=json HTTP/1.1\r\nHost: admin.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: GAMADV-XTD3 6.22.18 - https://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <[email protected]> / Python 3.10.4 final / macOS-10.13.6-x86_64-i386-64bit x86_64 / (gzip)\r\nx-goog-api-client: gdcl/2.49.0 gl-python/3.10.4\r\ncontent-length: 0\r\nauthorization: Bearer xxx\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: ETag: "SsISqFfgRYY11XaGpPyQF5FTf1EAwqUmKLMPaD85FHw/KI28M3UI1BxB0wdXnhkjO_hi7js"
...
Organizational Unit: /Test/Test Plus (1/2)
  orgUnitId: id:03ph8a2z41o9s36
  name: Test Plus
  description:
  parentOrgUnitPath: /Test
  parentOrgUnitId: id:040i61yy3fw7czd

 /Test/Test Plus returns the correct information, the space is quoted as %20

send: b'GET /admin/directory/v1/customer/my_customer/orgunits/Test/Test%20Plus?prettyPrint=true&alt=json HTTP/1.1\r\nHost: admin.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: GAMADV-XTD3 6.22.18 - https://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <[email protected]> / Python 3.10.4 final / macOS-10.13.6-x86_64-i386-64bit x86_64 / (gzip)\r\nx-goog-api-client: gdcl/2.49.0 gl-python/3.10.4\r\ncontent-length: 0\r\nauthorization: Bearer xxx\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: ETag: "SsISqFfgRYY11XaGpPyQF5FTf1EAwqUmKLMPaD85FHw/KI28M3UI1BxB0wdXnhkjO_hi7js"
...
Organizational Unit: /Test/Test Plus (2/2)
  orgUnitId: id:03ph8a2z41o9s36
  name: Test Plus
  description:
  parentOrgUnitPath: /Test
  parentOrgUnitId: id:040i61yy3fw7czd

taers232c avatar May 28 '22 16:05 taers232c

Hi @taers232c Please provide more details on how this specific repository is used to make those failing calls. Looking at the logs it seems like they are all showing how gam is used not how the client form this repository is used to make an actual call underneath. Basically the bug is formulated as a bug in gam, not as a bug in google-api-python-client.

vam-google avatar Jun 03 '22 19:06 vam-google

def callGAPI(service, function,
             throwReasons=None, retryReasons=None, retries=10,
             **kwargs):

  method = getattr(service, function)
  svcparms = dict(list(kwargs.items())
  return method(**svcparms).execute()

cd = googleapiclient.discovery.build(API.DIRECTORY, version, http=httpObj, cache_discovery=False,
                                     discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False)
# First call Test/Test+Plus                                                                                                                                                                                                                            
callGAPI(cd.orgunits(), 'get',
         throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
         customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath='Test/Test+Plus')

send: b'GET /admin/directory/v1/customer/my_customer/orgunits/Test/Test+Plus?prettyPrint=true&alt=json HTTP/1.1\r\nHost: admin.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: GAMADV-XTD3 6.22.18 - https\
://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <[email protected]> / Python 3.10.4 final / macOS-10.13.6-x86_64-i386-64bit x86_64 / (gzip)\r\nx-goog-api-client: gdcl/2.49.0 gl-python/3.10.4\r\ncontent-length: 0\r\nauthorization: Bearer x\
xx\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: ETag: "SsISqFfgRYY11XaGpPyQF5FTf1EAwqUmKLMPaD85FHw/KI28M3UI1BxB0wdXnhkjO_hi7js"

# Second call Test/Test PLus                                                                                                                                                                                                                           
callGAPI(cd.orgunits(), 'get',
         throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
         customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath='Test/Test Plus')

send: b'GET /admin/directory/v1/customer/my_customer/orgunits/Test/Test%20Plus?prettyPrint=true&alt=json HTTP/1.1\r\nHost: admin.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: GAMADV-XTD3 6.22.18 - htt\
ps://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <[email protected]> / Python 3.10.4 final / macOS-10.13.6-x86_64-i386-64bit x86_64 / (gzip)\r\nx-goog-api-client: gdcl/2.49.0 gl-python/3.10.4\r\ncontent-length: 0\r\nauthorization: Bearer\
 xxx\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: ETag: "SsISqFfgRYY11XaGpPyQF5FTf1EAwqUmKLMPaD85FHw/KI28M3UI1BxB0wdXnhkjO_hi7js"

Note that the two ETags	are identical. Since the plus is not encoded as	%2b by the googleapiclient,
the Google server interprets the + as a	space and returns infomation for Test/Test Plus	instead	of Test/Test+Plus

taers232c avatar Jun 03 '22 20:06 taers232c

Do you need any additional information?

taers232c avatar Jun 08 '22 22:06 taers232c

Is this issue going to be addressed?

taers232c avatar Jun 24 '22 16:06 taers232c

I think this issue is caused because uritemplate is not encoding +

https://github.com/python-hyper/uritemplate/blob/main/uritemplate/variable.py#L419

DKbyo avatar Mar 08 '24 22:03 DKbyo

Here's the OU retrieved by ID

$ gam info ou id:03ph8a2z1fdhw7r

Organizational Unit: /Test/Test+Plus

orgUnitId: id:03ph8a2z1fdhw7r

name: Test+Plus

description:

parentOrgUnitPath: /Test

parentOrgUnitId: id:040i61yy3fw7czd

Users:

Total Users in Organizational Unit: 0

Try to retrieve the OU by name

$ gam config debug_level 1 info ou "/Test+Plus"

connect: (admin.googleapis.com, 443)

send: b'GET /$discovery/rest?version=directory_v1 HTTP/1.1\r\nHost: admin.googleapis.com\r\ncontent-length: 0\r\nuser-agent: GAMADV-XTD3 6.71.12 - https://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs <ross.scrogg\

@.***> / Python 3.12.2 final / macOS-14.3.1-arm64-arm-64bit arm64 /\r\nx-goog-api-client: cred-type/u\r\nauthorization: Bearer ya29.xxx\r\naccept-encoding: gzip, deflate\r\n\r\n'

reply: 'HTTP/1.1 200 OK\r\n'

header: Content-Type: application/json; charset=UTF-8

header: Vary: Origin

header: Vary: X-Origin

header: Vary: Referer

header: Date: Sat, 09 Mar 2024 19:59:48 GMT

header: Server: ESF

header: Content-Length: 368422

header: X-XSS-Protection: 0

header: X-Frame-Options: SAMEORIGIN

header: X-Content-Type-Options: nosniff

header: Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

send: b'GET /admin/directory/v1/customer/C03kt1xxx/orgunits/Test+Plus?prettyPrint=true&alt=json HTTP/1.1\r\nHost: admin.googleapis.com\r\naccept: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: GAM\

ADV-XTD3 6.71.12 - https://github.com/taers232c/GAMADV-XTD3 / Ross Scroggs < @.***> / Python 3.12.2 final / macOS-14.3.1-arm64-arm-64bit arm64 / (gzip)\r\nx-goog-api-client: gdcl/2.117.0 gl-python/3.\

12.2 cred-type/u\r\ncontent-length: 0\r\nauthorization: Bearer ya29.xxx\r\n\r\n'

reply: 'HTTP/1.1 404 Not Found\r\n'

header: Vary: Origin

header: Vary: X-Origin

header: Vary: Referer

header: Content-Type: application/json; charset=UTF-8

header: Content-Encoding: gzip

header: Date: Sat, 09 Mar 2024 19:59:49 GMT

header: Server: ESF

header: Cache-Control: private

header: X-XSS-Protection: 0

header: X-Frame-Options: SAMEORIGIN

header: X-Content-Type-Options: nosniff

header: Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

header: Transfer-Encoding: chunked

ERROR: JSON: {'error': {'code': 404, 'message': 'Org unit not found', 'errors': [{'message': 'Org unit not found', 'domain': 'global', 'reason': 'notFound'}]}}

Organizational Unit: Test+Plus, Show Info Failed: Does not exist

It fails because the +is not encoded' it should be:

send: b'GET /admin/directory/v1/customer/C03kt1xxx/orgunits/Test%2bPlus?prettyPrint=true&alt=json

Ross

On Fri, Jun 3, 2022 at 12:26 PM Vadym Matsishevskyi < @.***> wrote:

Hi @taers232c https://github.com/taers232c Please provide more details on how this specific repository is used to make those failing calls. Looking at the logs it seems like they are all showing how gam is used not how the client form this repository is used to make an actual call underneath. Basically the bug is formulated as a bug in gam, not as a bug in google-api-python-client.

— Reply to this email directly, view it on GitHub https://github.com/googleapis/google-api-python-client/issues/1812#issuecomment-1146291223, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACCTYL7C25ZFK7V3VDFKKB3VNJL7NANCNFSM5XG2TNYA . You are receiving this because you were mentioned.Message ID: @.***>

-- Ross Scroggs @.***

taers232c avatar Mar 09 '24 20:03 taers232c