Skip to content

Commit

Permalink
service account impersonation
Browse files Browse the repository at this point in the history
  • Loading branch information
maciaszczykm committed Oct 30, 2024
1 parent 8c685c7 commit f8f97ff
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 38 deletions.
25 changes: 9 additions & 16 deletions www/src/components/account/User.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import { Button, Span } from 'honorable'
import { useContext, useMemo, useState } from 'react'

import CurrentUserContext from '../../contexts/CurrentUserContext'
import { Permission, useUpdateUserMutation } from '../../generated/graphql'
import {
Permission,
useImpersonateServiceAccountMutation,
useUpdateUserMutation,
} from '../../generated/graphql'
import {
fetchToken,
setPreviousUserData,
Expand All @@ -23,7 +27,6 @@ import DeleteUserModal from '../utils/user/DeleteUserModal'

import { EditServiceAccount } from './CreateServiceAccount'
import { MoreMenu } from './MoreMenu'
import { IMPERSONATE_SERVICE_ACCOUNT } from './queries'
import { hasRbac } from './utils'

export function UserInfo({
Expand Down Expand Up @@ -185,21 +188,11 @@ export function User({ user, update }: any) {
export function ServiceAccount({ user, update }: any) {
const me = useContext(CurrentUserContext)
const editable = canEdit(me, me.account) || hasRbac(me, Permission.Users)
const [mutation, { error }] = useMutation(IMPERSONATE_SERVICE_ACCOUNT, {
const [mutation, { error }] = useImpersonateServiceAccountMutation({
variables: { id: user.id },
update: (
_cache,
{
data: {
impersonateServiceAccount: { jwt },
},
}
) => {
setPreviousUserData({
me,
jwt: fetchToken(),
})
setToken(jwt)
update: (_cache, { data }) => {
setPreviousUserData({ me, jwt: fetchToken() })
setToken(data?.impersonateServiceAccount?.jwt)
;(window as Window).location = '/'
},
})
Expand Down
8 changes: 0 additions & 8 deletions www/src/components/account/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,6 @@ export const AUDITS_Q = gql`
${AuditFragment}
`

export const IMPERSONATE_SERVICE_ACCOUNT = gql`
mutation Impersonate($id: ID) {
impersonateServiceAccount(id: $id) {
jwt
}
}
`

export const DNS_DOMAINS = gql`
query Domains($cursor: String) {
dnsDomains(after: $cursor, first: 50) {
Expand Down
6 changes: 4 additions & 2 deletions www/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6156,6 +6156,7 @@ export type LoginMutationVariables = Exact<{
export type LoginMutation = { __typename?: 'RootMutationType', login?: { __typename?: 'User', jwt?: string | null } | null };

export type ImpersonateServiceAccountMutationVariables = Exact<{
id?: InputMaybe<Scalars['ID']['input']>;
email?: InputMaybe<Scalars['String']['input']>;
}>;

Expand Down Expand Up @@ -11362,8 +11363,8 @@ export type LoginMutationHookResult = ReturnType<typeof useLoginMutation>;
export type LoginMutationResult = Apollo.MutationResult<LoginMutation>;
export type LoginMutationOptions = Apollo.BaseMutationOptions<LoginMutation, LoginMutationVariables>;
export const ImpersonateServiceAccountDocument = gql`
mutation ImpersonateServiceAccount($email: String) {
impersonateServiceAccount(email: $email) {
mutation ImpersonateServiceAccount($id: ID, $email: String) {
impersonateServiceAccount(id: $id, email: $email) {
jwt
email
}
Expand All @@ -11384,6 +11385,7 @@ export type ImpersonateServiceAccountMutationFn = Apollo.MutationFunction<Impers
* @example
* const [impersonateServiceAccountMutation, { data, loading, error }] = useImpersonateServiceAccountMutation({
* variables: {
* id: // value for 'id'
* email: // value for 'email'
* },
* });
Expand Down
4 changes: 2 additions & 2 deletions www/src/graph/users.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ mutation Login(
}
}

mutation ImpersonateServiceAccount($email: String) {
impersonateServiceAccount(email: $email) {
mutation ImpersonateServiceAccount($id: ID, $email: String) {
impersonateServiceAccount(id: $id, email: $email) {
jwt
email
}
Expand Down
14 changes: 4 additions & 10 deletions www/src/hooks/useImpersonatedServiceAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { useEffect, useMemo, useState } from 'react'
import { ApolloClient, useMutation } from '@apollo/client'
import { ApolloClient } from '@apollo/client'
import memoize from 'lodash/memoize'

import { buildClient, client as defaultClient } from '../helpers/client'
import { IMPERSONATE_SERVICE_ACCOUNT } from '../components/account/queries'
import { fetchToken } from '../helpers/authentication'
import { useImpersonateServiceAccountMutation } from '../generated/graphql'

// Cache tokens with service account ID as keys.
const getImpersonatedToken = memoize((id, mutation) =>
mutation().then(
({
data: {
impersonateServiceAccount: { jwt },
},
}) => jwt
)
mutation().then(({ data }) => data?.impersonateServiceAccount?.jwt)
)

// Cache clients with impersonated service account tokens as keys.
Expand All @@ -26,7 +20,7 @@ export default function useImpersonatedServiceAccount(
) {
const [client, setClient] = useState<ApolloClient<unknown> | undefined>()
const [token, setToken] = useState<any | undefined>()
const [mutation, { error }] = useMutation(IMPERSONATE_SERVICE_ACCOUNT, {
const [mutation, { error }] = useImpersonateServiceAccountMutation({
variables: { id },
})

Expand Down

0 comments on commit f8f97ff

Please sign in to comment.