Skip to content

AB#38712 Check user resource ownership - #14

Merged
omersayshi merged 50 commits into
interns/feature/ge-app-mode-proxy-endpointfrom
interns/omersayshi/38712-check-ownership
Aug 4, 2021
Merged

AB#38712 Check user resource ownership #14
omersayshi merged 50 commits into
interns/feature/ge-app-mode-proxy-endpointfrom
interns/omersayshi/38712-check-ownership

Conversation

@omersayshi

@omersayshi omersayshi commented Jul 28, 2021

Copy link
Copy Markdown

Overview

Using the user's passed in Graph delegated token, I retrieved the tenantId and user id from the token. The purpose of this PR is to use the token and the user id to make a graph call to check if the resource (teams or chat) that the client is trying to make a request on is owned by the user.

Testing Instructions

NOTE: Alot of overhead is required to test this PR. to make it easier, ping me on Teams for a ClientId and ClientSecret to avoid registering an app and installing a Teams app on a test tenant with the same ClientId.

  • Open the file appsettings.json
  • In ClientId, paste the clientId of your app registration
  • In ClientSecret, paste the client secret of your app registration
  • Head over to Graph Explorer
  • Go to Access token and copy the access token
  • Run the branch locally and open Postman
  • Add your access token that was copied from GE into the Authorization tab as a 'Bearer Token'
  • Make a call to the API using the endpoint /graphproxy/{ADD YOUR GRAPH QUERY HERE}. Example: /v1.0/teams/{team-id}/channels
  • Make sure its a Graph call on a Teams resource (Team or Chat) that you are a owner of and have the GE Teams app (with the same client Id as the you pasted in appsettings.json) installed on (in order for the Graph request to work)

Expected behavior

  • If you have the teams app installed on the resource you are trying to call AND you are the owner of that resource, you will receive a 200 OK with the response
  • If you have the teams app installed on the resource you are trying to call AND you are the NOT owner of that resource, you will receive a 403 forbidden with an empty response
  • If you dont have the teams app installed on the resource you are trying to call, you will receive a 403 forbidden with an error message from Graph.

MaggieKimani1 and others added 30 commits June 9, 2021 14:54
* Add telemetry diagnostic tracing for samples

* Add trace info for permissions

* Update telemetry trace capture points

* Install Application insights for trace telemetry tracking

* Adds trace messages to log diagnostic events at service level

* Track exceptions including stack traces  at controller level

* Add Telemetry lib. to OpenAPIService

* Add OpenApiService as Singleton

* Use static property to set TelemetryClient

* Use parameter to set telemetry client in OpenApiService

* Adds the ChangesService class as a singleton on startup and refactor code

* Modify the ChangesService from a static class to a singleton and add trace telemetry for tracking purposes

* Update value of the trace properties dictionary

* Initialize a telemetry client and use it to track exceptions

* Use a static property to set the telemetry client and use it to track trace telemetry

* Install ApplicationInsights

* Revert "Adds the ChangesService class as a singleton on startup and refactor code"

This reverts commit 36bb74a.

* Revert "Modify the ChangesService from a static class to a singleton and add trace telemetry for tracking purposes"

This reverts commit 71eeb6b.

* Reverts changes for ChangesService class and adds trace telemetry

* Edit value for the trace properties dictionary

* Remove unnecessary line

* Remove whitespaces

* Add null check

* Track exceptions thrown for better inspection

* Update OpenApiService and controller trace information and properties

* Message update

* Rename the trace properties dictionaries

* Further trace telemetry message and property updates

* Add log messages to track trace events and exceptions

* Install Application Insights

* Edit the trace message

* Add count properties and prevent them from being sanitized

* Minor edit

* Create UtilityConstants class that will have constants

* Add UtilityService project dependencies

* Use UtilityService constants

* Add TelemetryClientUtility class and update its implementations

Also, some class renames and code simplifications. Remove unnecessary code as well.

* Code formatting

* Transfer TelemetryClientUtility to a dedicated library; delete unnecessary packages and code

* Remove unnecessary code and imports; code simplification

* Auto stash before merge of "feature/mk/instrument-changes-service" and "origin/feature/is/code-instrumentation"

* Add a reference to the TelemetryClientWrapper

* Add a reference for the TelemetryClientWrapper

* Use a singleton instance of telemetry client to track telemetry across multiple services and controllers

* Add a Changes property key for storing count data to avoid unnecessary numerical sanitization

* Clean up file

* Add a trace message to trigger an alert when our permission data source is empty

* Fix indentation

* Remove  whitespace

* Create a joining service.

* Refactor startup file

* Inject IServiceProvider and use it to get an IPermissionsStore instance

* Use the TelemetryClient available from our DI container to track telemetry

* Remove optional param

* Add/remove packages

* Mock an IServiceProvider object and use it to call a mocked instance of IPermissionsStore

* Simplify null check

* Remove files

* Create interfaces and initialize the services as singletons

* Implement the interface

* Add OpenApi telemetry property key as a constant

* Replace string with changes telemetry property key constant

* Add project reference

* Code cleanup

* Add property to prevent graph uri Version from sanitization

* Add abstract methods to interfaces and refactor code

* Code cleanup

* Rename dictionary value to PermissionsStore and delete the dictionary afterwards

* Rename dictionary value

* Use nameof() operator to get the  class names

* Use defensive programming

Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: George <gendungu@microsoft.com>
…tionals

Fix: Use null-conditionals when capturing count of IEnumerable types in TrackTrace telemetry
The new metadata with annotations has some annotation discrepancies that needs to be looked into before being accepted into prod.
* Add telemetry diagnostic tracing for samples

* Add trace info for permissions

* Update telemetry trace capture points

* Install Application insights for trace telemetry tracking

* Adds trace messages to log diagnostic events at service level

* Track exceptions including stack traces  at controller level

* Add Telemetry lib. to OpenAPIService

* Add OpenApiService as Singleton

* Use static property to set TelemetryClient

* Use parameter to set telemetry client in OpenApiService

* Adds the ChangesService class as a singleton on startup and refactor code

* Modify the ChangesService from a static class to a singleton and add trace telemetry for tracking purposes

* Update value of the trace properties dictionary

* Initialize a telemetry client and use it to track exceptions

* Use a static property to set the telemetry client and use it to track trace telemetry

* Install ApplicationInsights

* Revert "Adds the ChangesService class as a singleton on startup and refactor code"

This reverts commit 36bb74a.

* Revert "Modify the ChangesService from a static class to a singleton and add trace telemetry for tracking purposes"

This reverts commit 71eeb6b.

* Reverts changes for ChangesService class and adds trace telemetry

* Edit value for the trace properties dictionary

* Remove unnecessary line

* Remove whitespaces

* Add null check

* Track exceptions thrown for better inspection

* Update OpenApiService and controller trace information and properties

* Message update

* Rename the trace properties dictionaries

* Further trace telemetry message and property updates

* Add log messages to track trace events and exceptions

* Install Application Insights

* Edit the trace message

* Add count properties and prevent them from being sanitized

* Minor edit

* Create UtilityConstants class that will have constants

* Add UtilityService project dependencies

* Use UtilityService constants

* Add TelemetryClientUtility class and update its implementations

Also, some class renames and code simplifications. Remove unnecessary code as well.

* Code formatting

* Transfer TelemetryClientUtility to a dedicated library; delete unnecessary packages and code

* Remove unnecessary code and imports; code simplification

* Auto stash before merge of "feature/mk/instrument-changes-service" and "origin/feature/is/code-instrumentation"

* Add a reference to the TelemetryClientWrapper

* Add a reference for the TelemetryClientWrapper

* Use a singleton instance of telemetry client to track telemetry across multiple services and controllers

* Add a Changes property key for storing count data to avoid unnecessary numerical sanitization

* Clean up file

* Add a trace message to trigger an alert when our permission data source is empty

* Fix indentation

* Remove  whitespace

* Create a joining service.

* Refactor startup file

* Inject IServiceProvider and use it to get an IPermissionsStore instance

* Use the TelemetryClient available from our DI container to track telemetry

* Remove optional param

* Add/remove packages

* Mock an IServiceProvider object and use it to call a mocked instance of IPermissionsStore

* Simplify null check

* Remove files

* Create interfaces and initialize the services as singletons

* Implement the interface

* Add OpenApi telemetry property key as a constant

* Replace string with changes telemetry property key constant

* Add project reference

* Code cleanup

* Add property to prevent graph uri Version from sanitization

* Add abstract methods to interfaces and refactor code

* Code cleanup

* Rename dictionary value to PermissionsStore and delete the dictionary afterwards

* Rename dictionary value

* Use nameof() operator to get the  class names

* Use defensive programming

Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: George <gendungu@microsoft.com>

Co-authored-by: Maggie Kimani <maggiekim42@gmail.com>
Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
Co-authored-by: George <gendungu@microsoft.com>
* Add test for validating setting explode property

* Visit Parameters to set Explode property to false

* Add parameters to test

* Move parameter visitor to separate class to update entire OpenApi doc.

* Nit fix on comment

* Use instance variable to make calls to the service

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService.Test/OpenAPIDocumentCreatorMock.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService.Test/OpenAPIDocumentCreatorMock.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Auto stash before merge of "fix/is/set-explode-false" and "microsoft-graph-devx-api/fix/is/set-explode-false"

* Refactor class; import LINQ library

* Update OpenAPIService/OperationSearch.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Add default locale for requests with unspecified Accept-Language

Unrelated to the overall work item but is important for servicing /sample requests which don't provide an Accept-Language value in the header.

Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
* Update how permissions values are fetched

* Update path to the new permissions files container

* Update test files structure

* Update file path

* Make linq query more readable

* Refactor code

Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Irvine Sunday <40403681+irvinesunday@users.noreply.github.com>
* add issue creation templates

* add pull request template
…re-pipeline

Set up CI with Azure Pipelines
Bumps [Microsoft.AspNetCore.Authorization](https://github.com/dotnet/aspnetcore) from 5.0.7 to 5.0.8.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Commits](dotnet/aspnetcore@v5.0.7...v5.0.8)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Authorization
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…t.AspNetCore.Authorization-5.0.8

Bump Microsoft.AspNetCore.Authorization from 5.0.7 to 5.0.8
Bumps [Microsoft.AspNetCore.Mvc.NewtonsoftJson](https://github.com/dotnet/aspnetcore) from 5.0.7 to 5.0.8.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Commits](dotnet/aspnetcore@v5.0.7...v5.0.8)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Mvc.NewtonsoftJson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…t.AspNetCore.Mvc.NewtonsoftJson-5.0.8

Bump Microsoft.AspNetCore.Mvc.NewtonsoftJson from 5.0.7 to 5.0.8
Bumps [Microsoft.AspNetCore.Authentication.JwtBearer](https://github.com/dotnet/aspnetcore) from 5.0.7 to 5.0.8.
- [Release notes](https://github.com/dotnet/aspnetcore/releases)
- [Commits](dotnet/aspnetcore@v5.0.7...v5.0.8)

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Authentication.JwtBearer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…t.AspNetCore.Authentication.JwtBearer-5.0.8

Bump Microsoft.AspNetCore.Authentication.JwtBearer from 5.0.7 to 5.0.8
* Refactor permissions fetching and update fetch-all permissions algo.

* Add null checks; reorder params

* Spacing

* Variable renaming; add XML comment

* Update permission tests

Capture multiple scopes for a given endpoint/method to test whether distinct scopes gets returned

* Add null checks; get distinct scopes; code refactoring

* Update telemetry message

* Update GraphExplorerPermissionsService/Services/PermissionsStore.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* PR review suggestions fixes

* Update GraphExplorerPermissionsService/Services/PermissionsStore.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* Update GraphExplorerPermissionsService/Services/PermissionsStore.cs

Co-authored-by: Vincent Biret <vibiret@microsoft.com>

* PR review suggestion fixes

* Further PR review suggestion fixes - LINQ Select

Co-authored-by: Irvine Sunday <irochand@microsoft.com>
Co-authored-by: Vincent Biret <vibiret@microsoft.com>
Bumps [Microsoft.Extensions.DependencyInjection](https://github.com/dotnet/runtime) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](dotnet/runtime@v5.0.1...v5.0.2)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.DependencyInjection
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…t.Extensions.DependencyInjection-5.0.2

Bump Microsoft.Extensions.DependencyInjection from 5.0.1 to 5.0.2
Comment thread GraphExplorerAppModeService/Services/GraphService.cs Outdated
Comment thread GraphExplorerAppModeService/Services/GraphService.cs
Comment thread GraphExplorerAppModeService/Services/GraphService.cs

@gracet9182 gracet9182 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I tested:
-I ran a query with a teams channel that I created which didn't have any tabs added and it gave me a 403 error. This is as expected since it didn't have permissions.

-Then, I ran a GET query in that same teams channel with my app added. It gave me a response; awesome, it checks for owner

-Then, I changed myself from an owner to a member and got a 403 error; yay! That's what we want ╰(°▽°)╯

-Then, I created a chat with 2 people without adding the app and ran a query. It gave a 403 error as expected.

-Then, I added the app to the chat with 2 people and ran the query but still gave me a 403 error. I attached a screenshot below. I ran the query in GE with delegated permissions just to make sure the query was valid after. From the error message I thought it was an issue on my side but when I ran the same query on my deployed endpoint that doesn't check for ownership, the api call went through. I also think the error message might be misleading. I noticed in the first scenario that I tested, there was no error message but just a 403. You could do the same with this one or maybe craft a better error message but not sure how feasible it is with the amount of time we have left.

-I tried the same thing again but it was a chat with a single person. It gave a 403 error. Are they considered owners if it's a OneOnOne chat?

It would be really great to see expected behavior so we know what has been considered

Screenshot 2021-07-29 162214

@omersayshi

omersayshi commented Jul 30, 2021

Copy link
Copy Markdown
Author

@gracet9182 That is also expected behaviour, From the screenshot the call was done using Graph v1.0 and currently RSC permissions for chats (correct me if I am wrong) are mostly in beta. So this 403 error you are receiving is directly from Graph.
Also my apologies for not including expected behaviour in the PR details, will add them.

@gracet9182

gracet9182 commented Jul 30, 2021

Copy link
Copy Markdown
Member

Talked to Omer about a token error. The solution was to input a random guid into appsettings for tenantId - might be something that can be fixed as a bug later but this seems to work! ╰(°▽°)╯amazing work

Comment thread GraphWebApi/Controllers/GraphExplorerAppModeController.cs Outdated
3. Scroll down to '....'
4. See error

**Expected behavior**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can also add a section called actual behavior to understand the bug more easily and clearly

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are from an upstream merge and not mine, so I cant change it.

Comment thread GraphExplorerAppModeService/Interfaces/IGraphService.cs
Comment thread GraphExplorerAppModeService/Interfaces/IGraphService.cs
Comment thread GraphExplorerAppModeService/Services/GraphService.cs
Comment thread GraphExplorerAppModeService/Services/GraphService.cs
/// <param name="scopes">The target list of scopes.</param>
/// <param name="scopeType">The type of scope from which to retrieve the scopes information for.</param>
/// <returns>A list of <see cref="ScopeInformation"/>.</returns>
private static List<ScopeInformation> GetScopesInformation(IDictionary<string, IDictionary<string, ScopeInformation>> scopesInformationDictionary,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the inputs will not be modified, make them as read only such as IReadOnlyDictionary and IReadOnlyList

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are from an upstream merge and not mine, so I cant change it.

@omersayshi
omersayshi merged commit 9a47865 into interns/feature/ge-app-mode-proxy-endpoint Aug 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.