🐛 Bug Report: Usage of contains operator for Microsoft Graph query
📜 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?
- [X] I have read the Code of Conduct
Are you willing to submit PR?
None
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?
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
If there is no way to work around this I'm willing to close this ticket since it's not really a backstage issue
@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.
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
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
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.
I"ll try this out next week
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.
any update on this @twanbeeren?
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
Amazing, I'm closing the issue then. Feel free to re-open in case more help is needed.