Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosmos DB - Authorization policy #325

Merged
merged 2 commits into from
Jul 21, 2021

Conversation

MindFlavor
Copy link
Contributor

This PR enhances the pipeline by adding the AuthorizationPolicy and migrates the preexisting CosmosDB pipeline operations to the new policy.

AuthorizationPolicy

The AuthorizationPolicy cannot be in Core since every service uses a different authorization mechanism. So this PR proposes to have a specific policy in each module (they can potentially be shared in case of duplication). This PR covers Cosmos DB only. While CosmosDB does not support (yet) the bearer token authentication, it's possibile to authenticate specific users with shared key.

The AuthorizationPolicy will handle the authentication by injecting the required headers to the request passing through the pipeline. Since the resulting authorization token can depend on the preexisting headers the AuthorizationPolicy must be executed right before the TransportPolicy. Also, since the token depends on the current timestamp (to mitigate reply attacks), AuthorizationPolicy must be run at every retry.

Cosmos context

In CosmosDB, the authorization token depends on the resource type. This information must be somehow passed through the pipeline because the AuthorizationPolicy needs it.
The information of which resource to authenticate must be passed by the operation builder prior starting the pipeline. For example, the create_database operation, knowing that it has to work on ResourceType::Databases, must be able to pass ResourceType::Databases to the AuthorizationPolicy. The pipeline has a Context struct that must be instantiated by the SDK user (ie the code that calls create_database). The Context will then traverse the pipeline. As such is a good candidate for the resource type information.

For this reason, this PR proposes an additional type, called PipelineContext that wraps the user-supplied Context and adds the module-dependent field. This is achieved by exposing a generic (constrained to be Send + Sync).

An alternative approach (shown here: https://github.com/MindFlavor/azure-sdk-for-rust/tree/cosmos/auth_policy%2Fdev) is to use Rust's runtime polymorphism in the form of std::any::Any. Basically Context will have a Box<dyn Any> field that can accept anything. It would be responsibility of the operation builder (ie the create_database function) to store the relevant information in the Box<dyn Any> instance. The AuthorizationPolicy will then downcast_ref() the Any instance and get the expected type.
While this approach is easy to do, it lacks any kind of type safety and relies upon conventions (which is very unidiomatic in Rust). Also, it's runtime enforced only (another thing unidiomatic in Rust).

The approach proposed in this PR, instead, is type safe and clearly self-explanatory.

Notable changes

  • Created the PipelineContext<BAG> discussed above (composition of Context and custom field of type BAG).
  • Changed Policy trait to be generic on the BAG above. This allows policies that accept generic PipelineContext<BAG>.
  • Changed the pipeline to be generic on the BAG above.
  • Fixed the preexisting policies to accept the BAG generic (called R for brevity, this is something we might want to correct to avoid confusion).
  • Implemented Policy<CosmosContext> for AuthorizationPolicy.
  • Changed pipeline code in CosmosDB to support the AuthorizationPolicy (and to send the proper PipelineContext<CosmosContext> down the pipeline.
  • Removed useless cosmos_client::prepare_request2.
  • Created a new function in cosmos_client called prepare_request_pipeline. This function will no longer perform authentication since it will delegated to the pipeline policy AuthorizationPolicy.
  • Moved all the authorization code from CosmosClient to AuthorizationPolicy (preexisting non-pipeline code has been rerouted pending removal).
  • Removed uninmplemented from add_as_header2 that caused E2E tests to fail (fix CosmosDB E2E attachment tests fail with not implemented panic #324).
  • Implemented add_as_header2 for all the required types.

@MindFlavor MindFlavor added feature-request This issue requires a new behavior in the product in order be resolved. Client This issue points to a problem in the data-plane of the library. Cosmos The azure_cosmos crate pipeline labels Jul 5, 2021
Copy link
Contributor

@rylev rylev left a comment

Choose a reason for hiding this comment

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

I was skeptical of the proposal, but it's not too bad. I definitely think it's better than having an Any that service specific policies can downcast. I just had a bunch of small notes.

sdk/core/src/errors.rs Outdated Show resolved Hide resolved
sdk/core/src/headers/mod.rs Show resolved Hide resolved
sdk/cosmos/src/authorization_policy.rs Show resolved Hide resolved
sdk/cosmos/src/authorization_policy.rs Outdated Show resolved Hide resolved
sdk/cosmos/src/authorization_policy.rs Outdated Show resolved Hide resolved
sdk/cosmos/src/clients/cosmos_client.rs Outdated Show resolved Hide resolved
resource_link,
&time,
)
};
self.prepare_request_with_signature(uri_path, http_method, &time, &auth)
}

/// Prepares' an `azure_core::Request`.
/// Prepares' an `azure_core::Request`. This function will
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: not sure if we need to make the comment lines so short. Means we quickly have lots of lines of comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have a vim plugin that inserts a cr to keep comments < 80 chars wide (yes, I'm old 🤷‍♂️). I agree it doesn't really matter since Rust's lines can easily go over that limit. What should we use as a limit?

sdk/storage/src/data_lake/properties.rs Outdated Show resolved Hide resolved
sdk/core/src/pipeline_context.rs Outdated Show resolved Hide resolved
sdk/core/src/pipeline.rs Outdated Show resolved Hide resolved
@MindFlavor
Copy link
Contributor Author

Thank you @rylev for taking the time to review this! I'll try to address your suggestions and push another commit.

commit 79556d4
Author: Francesco Cogno <[email protected]>
Date:   Tue Jul 13 10:09:16 2021 +0200

    docs on pipeline

commit 4a95aad
Author: Francesco Cogno <[email protected]>
Date:   Tue Jul 13 09:59:02 2021 +0200

    R -> C generic

commit cac15f7
Author: Francesco Cogno <[email protected]>
Date:   Tue Jul 13 09:52:55 2021 +0200

    better comments

commit f047a82
Author: Francesco Cogno <[email protected]>
Date:   Mon Jul 12 21:11:21 2021 +0200

    docs

commit 876191c
Author: Francesco Cogno <[email protected]>
Date:   Mon Jul 12 18:52:27 2021 +0200

    bag to contents

commit 62b7c76
Author: Francesco Cogno <[email protected]>
Date:   Mon Jul 12 18:43:46 2021 +0200

    data_lake

commit eff9c2a
Author: Francesco Cogno <[email protected]>
Date:   Mon Jul 12 18:23:04 2021 +0200

    from str to TimeNonce

commit 7b63386
Author: Francesco Cogno <[email protected]>
Date:   Wed Jul 7 19:09:24 2021 +0200

    rewritten code

commit 2ad67a2
Author: Francesco Cogno <[email protected]>
Date:   Tue Jul 6 18:46:21 2021 +0200

    removed unwrap

commit 7105dab
Author: Francesco Cogno <[email protected]>
Date:   Tue Jul 6 18:14:57 2021 +0200

    errors to lowercase
Copy link
Contributor

@rylev rylev left a comment

Choose a reason for hiding this comment

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

@MindFlavor looks good. Shall we merge?

@MindFlavor
Copy link
Contributor Author

@MindFlavor looks good. Shall we merge?

Yes, let's keep the ball rolling! 👍

@MindFlavor MindFlavor merged commit 08090ef into Azure:master Jul 21, 2021
@MindFlavor MindFlavor deleted the cosmos/auth_policy/generic/pr branch July 21, 2021 16:16
@heaths heaths added Azure.Core The azure_core crate design-discussion An area of design currently under discussion and open to team and community feedback. labels Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure.Core The azure_core crate Client This issue points to a problem in the data-plane of the library. Cosmos The azure_cosmos crate design-discussion An area of design currently under discussion and open to team and community feedback. feature-request This issue requires a new behavior in the product in order be resolved.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CosmosDB E2E attachment tests fail with not implemented panic
3 participants