Skip to content

Commit

Permalink
feat(fdc): Add support for Data Connect Impersonation (#2844)
Browse files Browse the repository at this point in the history
* Add support for Data Connect Impersonation

* Add integration tests for impersonation

* fix: export new interfaces and regenerate apidocs

* fix: remove link to DecodedIdToken

* remove test service id

* Export alias type  and update test descriptions

* Revert accidental rebase

* Export alias type `AuthClaims` and update test descriptions

* Change token format link

* Update tests to check each index values

* Equality checks for tests

* More equality checks

---------
  • Loading branch information
jonathanedey authored Feb 27, 2025
1 parent 2379e15 commit 3bf4939
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 42 deletions.
18 changes: 18 additions & 0 deletions etc/firebase-admin.data-connect.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

import { Agent } from 'http';

// Warning: (ae-forgotten-export) The symbol "DecodedIdToken" needs to be exported by the entry point index.d.ts
//
// @public
export type AuthClaims = Partial<DecodedIdToken>;

// @public
export interface ConnectorConfig {
location: string;
Expand Down Expand Up @@ -36,8 +41,21 @@ export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): Dat

// @public
export interface GraphqlOptions<Variables> {
impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated;
operationName?: string;
variables?: Variables;
}

// @public
export interface ImpersonateAuthenticated {
authClaims: AuthClaims;
unauthenticated?: never;
}

// @public
export interface ImpersonateUnauthenticated {
authClaims?: never;
unauthenticated: true;
}

```
1 change: 1 addition & 0 deletions src/data-connect/data-connect-api-client-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export class DataConnectApiClient {
query,
...(options?.variables && { variables: options?.variables }),
...(options?.operationName && { operationName: options?.operationName }),
...(options?.impersonate && { extensions: { impersonate: options?.impersonate } }),
};
return this.getUrl(API_VERSION, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint)
.then(async (url) => {
Expand Down
50 changes: 50 additions & 0 deletions src/data-connect/data-connect-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* limitations under the License.
*/

import { DecodedIdToken } from '../auth/token-verifier';

/**
* Interface representing a Data Connect connector configuration.
*/
Expand Down Expand Up @@ -53,4 +55,52 @@ export interface GraphqlOptions<Variables> {
* The name of the GraphQL operation. Required only if `query` contains multiple operations.
*/
operationName?: string;

/**
* If set, impersonate a request with given Firebase Auth context and evaluate the auth
* policies on the operation. If omitted, bypass any defined auth policies.
*/
impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated;
}

/**
* Type representing the partial claims of a Firebase Auth token used to evaluate the
* Data Connect auth policy.
*/
export type AuthClaims = Partial<DecodedIdToken>;

/**
* Interface representing the impersonation of an authenticated user.
*/
export interface ImpersonateAuthenticated {
/**
* Evaluate the auth policy with a customized JWT auth token. Should follow the Firebase Auth token format.
* https://firebase.google.com/docs/data-connect/cel-reference#auth-token-contents
*
* @example A verified user may have the following `authClaims`:
* ```json
* { "sub": "uid", "email_verified": true }
* ```
*/
authClaims: AuthClaims;

/**
* Both `authClaims` and `unauthenticated` are mutually exclusive fields and should not be both set.
*/
unauthenticated?: never;
}

/**
* Interface representing the impersonation of an unauthenticated user.
*/
export interface ImpersonateUnauthenticated {
/**
* Both `authClaims` and `unauthenticated` are mutually exclusive fields and should not be both set.
*/
authClaims?: never;

/**
* Evaluates the auth policy as an unauthenticated request. Can only be set to true.
*/
unauthenticated: true;
}
3 changes: 3 additions & 0 deletions src/data-connect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export {
GraphqlOptions,
ExecuteGraphqlResponse,
ConnectorConfig,
ImpersonateAuthenticated,
ImpersonateUnauthenticated,
AuthClaims
} from './data-connect-api'
export {
DataConnect,
Expand Down
Loading

0 comments on commit 3bf4939

Please # to comment.