backstage icon indicating copy to clipboard operation
backstage copied to clipboard

🐛 Bug Report: Usage of contains operator for Microsoft Graph query

Open twanbeeren opened this issue 1 year ago • 11 comments

📜 Description

I'm trying to read Users and Groups from Microsoft Entra using the Azure org data integration that is provided by Backstage.

It states that the search and filter can be adjusted to your own liking: https://learn.microsoft.com/en-us/graph/filter-query-parameter?tabs=http https://learn.microsoft.com/en-us/graph/search-query-parameter?tabs=http

However in the documentation only Equals (eq) is used, and I need a contains query. To be specific:

I need to read all groups in Entra that contain "string x"

👍 Expected behavior

My code:

catalog:
  providers:
    microsoftGraphOrg:
      development:
        target: https://graph.microsoft.com/v1.0
        authority: https://login.microsoftonline.com
        clientId: ${AZURE_CLIENT_ID}
        clientSecret: ${AZURE_CLIENT_SECRET}
        tenantId: ${AZURE_TENANT_ID}
        queryMode: advanced
        user:
          loadPhotos: false
        group:
          filter: displayName contains "string x"
        schedule:
          frequency: PT10M
          timeout: PT5M

I also tried the following since it used a lot.

        group:
          filter: contains(displayName,'{string x}')

It should read all groups from entra that contain "string x" (string x is obviously a different value for me)

👎 Actual Behavior with Screenshots

My logging shows me for method 1

error MicrosoftGraphOrgEntityProvider:development refresh failed, Error: Error while reading groups from Microsoft Graph: BadRequest - Invalid filter clause: Syntax error at position 20 in 'displayName contains "string x"'

Where position 20 seems to be the contains operator

My logging shows me for method 2

error MicrosoftGraphOrgEntityProvider:development refresh failed, Error: Error while reading groups from Microsoft Graph: Request_UnsupportedQuery - Operator: 'Contains' is not supported.

👟 Reproduction steps

Setup microsoft graph according to the Azure org data integration name

📃 Provide the context for the Bug.

No response

🖥️ Your Environment

I run in v1.25

I can't run yarn backstage-cli info for this unfortunately

👀 Have you spent some time to check if this bug has been raised before?

  • [X] I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

Are you willing to submit PR?

None

twanbeeren avatar Sep 04 '24 07:09 twanbeeren

I know very little in microsoft graph, did a quick google and found https://stackoverflow.com/questions/35557280/contains-filter-on-microsoft-graph-query-not-working . Could startsWith work for you instead? @pjungermann or @drodil do you have suggestions?

jhaals avatar Sep 05 '24 13:09 jhaals

After some googling I alsoagree that this might be a graph limitation instead of Backstage.

I need to look if starts_with is also an option. I rather not use that, but maybe its possible

twanbeeren avatar Sep 06 '24 06:09 twanbeeren

If there is no way to work around this I'm willing to close this ticket since it's not really a backstage issue

twanbeeren avatar Sep 06 '24 09:09 twanbeeren

@jhaals Just a quick question for you.

I need all users that are part of groups that displayName startwith "string x".

Do I need to use userGroupMember for this or how do I achieve this?

It's not clear to me when looking at the docs.

twanbeeren avatar Sep 06 '24 09:09 twanbeeren

Or I can load up all users but I need to set some RBAC that they can't make use of backstage if the user is not part of an existing group. But that sounds like the worst solution

twanbeeren avatar Sep 06 '24 09:09 twanbeeren

Sorry @twanbeeren but I'm not sure to be honest :) I have never used this provider myself and I don't have access to microsoft graph. This provider is community contributed and I hoped that those that I pinged(based on git blame) was going to spot this issue and jump in. I know there are more microsoft users on Discord that are using this provider and hopefully can help you to construct the filtering

jhaals avatar Sep 10 '24 08:09 jhaals

The syntax is startswith(field, 'prefix') and the same for contains: contains(field, 'infix')

see also https://learn.microsoft.com/en-us/graph/filter-query-parameter?tabs=http#for-single-primitive-types-like-string-int-and-dates with the example

contains ~/identityGovernance/accessReviews/definitions?$filter=contains(scope/microsoft.graph.accessReviewQueryScope/query, './members')

Not all operators are supported on all data types/fields/query arguments.

pjungermann avatar Sep 10 '24 09:09 pjungermann

I"ll try this out next week

twanbeeren avatar Sep 13 '24 15:09 twanbeeren

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Nov 12 '24 15:11 github-actions[bot]

any update on this @twanbeeren?

vinzscam avatar Nov 14 '24 11:11 vinzscam

As it stands startsWith is the only option to use at the moment like mentioned above. I implemented this succesfully:

Here's a look at what I've got now running:

catalog:
  providers:
    microsoftGraphOrg:
      development:
        target: https://graph.microsoft.com/v1.0
        authority: https://login.microsoftonline.com
        clientId: ${AZURE_CLIENT_ID}
        clientSecret: ${AZURE_CLIENT_SECRET}
        tenantId: ${AZURE_TENANT_ID}
        queryMode: advanced
        user:
          expand: manager
          loadPhotos: false
        group:
          filter: startswith(displayName, '*redacted*')
        userGroupMember:
          filter: startswith(displayName, '*redacted*')
        schedule:
          frequency: PT10M
          timeout: PT5M

I've been using custom written transformers for users so thats why I've also changed user.expand: managed

twanbeeren avatar Nov 14 '24 15:11 twanbeeren

Amazing, I'm closing the issue then. Feel free to re-open in case more help is needed.

vinzscam avatar Nov 18 '24 11:11 vinzscam