mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-23 09:51:10 +01:00
gRPC authentication
This commit is contained in:
@@ -1,49 +1,64 @@
|
||||
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
|
||||
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import type { GrpcRequest, HttpRequest } from '../lib/models';
|
||||
import { Input } from './core/Input';
|
||||
import { VStack } from './core/Stacks';
|
||||
|
||||
interface Props {
|
||||
requestId: string;
|
||||
authentication: HttpRequest['authentication'];
|
||||
interface Props<T> {
|
||||
request: T;
|
||||
}
|
||||
|
||||
export function BasicAuth({ requestId, authentication }: Props) {
|
||||
const updateRequest = useUpdateHttpRequest(requestId);
|
||||
export function BasicAuth<T extends HttpRequest | GrpcRequest>({ request }: Props<T>) {
|
||||
const updateHttpRequest = useUpdateHttpRequest(request.id);
|
||||
const updateGrpcRequest = useUpdateGrpcRequest(request.id);
|
||||
|
||||
return (
|
||||
<VStack className="my-2" space={2}>
|
||||
<Input
|
||||
useTemplating
|
||||
autocompleteVariables
|
||||
forceUpdateKey={requestId}
|
||||
forceUpdateKey={request.id}
|
||||
placeholder="username"
|
||||
label="Username"
|
||||
name="username"
|
||||
size="sm"
|
||||
defaultValue={`${authentication.username}`}
|
||||
defaultValue={`${request.authentication.username}`}
|
||||
onChange={(username: string) => {
|
||||
updateRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { password: r.authentication.password, username },
|
||||
}));
|
||||
if (request.model === 'http_request') {
|
||||
updateHttpRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { password: r.authentication.password, username },
|
||||
}));
|
||||
} else {
|
||||
updateGrpcRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { password: r.authentication.password, username },
|
||||
}));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
useTemplating
|
||||
autocompleteVariables
|
||||
forceUpdateKey={requestId}
|
||||
forceUpdateKey={request?.id}
|
||||
placeholder="password"
|
||||
label="Password"
|
||||
name="password"
|
||||
size="sm"
|
||||
type="password"
|
||||
defaultValue={`${authentication.password}`}
|
||||
defaultValue={`${request.authentication.password}`}
|
||||
onChange={(password: string) => {
|
||||
updateRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { username: r.authentication.username, password },
|
||||
}));
|
||||
if (request.model === 'http_request') {
|
||||
updateHttpRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { username: r.authentication.username, password },
|
||||
}));
|
||||
} else {
|
||||
updateGrpcRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { username: r.authentication.username, password },
|
||||
}));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</VStack>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
|
||||
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import type { GrpcRequest, HttpRequest } from '../lib/models';
|
||||
import { Input } from './core/Input';
|
||||
import { VStack } from './core/Stacks';
|
||||
|
||||
interface Props {
|
||||
requestId: string;
|
||||
authentication: HttpRequest['authentication'];
|
||||
interface Props<T> {
|
||||
request: T;
|
||||
}
|
||||
|
||||
export function BearerAuth({ requestId, authentication }: Props) {
|
||||
const updateRequest = useUpdateHttpRequest(requestId);
|
||||
export function BearerAuth<T extends HttpRequest | GrpcRequest>({ request }: Props<T>) {
|
||||
const updateHttpRequest = useUpdateHttpRequest(request?.id ?? null);
|
||||
const updateGrpcRequest = useUpdateGrpcRequest(request?.id ?? null);
|
||||
|
||||
return (
|
||||
<VStack className="my-2" space={2}>
|
||||
@@ -21,12 +22,19 @@ export function BearerAuth({ requestId, authentication }: Props) {
|
||||
label="Token"
|
||||
name="token"
|
||||
size="sm"
|
||||
defaultValue={`${authentication.token}`}
|
||||
defaultValue={`${request.authentication.token}`}
|
||||
onChange={(token: string) => {
|
||||
updateRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { token },
|
||||
}));
|
||||
if (request.model === 'http_request') {
|
||||
updateHttpRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { token },
|
||||
}));
|
||||
} else {
|
||||
updateGrpcRequest.mutate((r) => ({
|
||||
...r,
|
||||
authentication: { token },
|
||||
}));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</VStack>
|
||||
|
||||
@@ -80,10 +80,7 @@ export function GrpcConnectionLayout({ style }: Props) {
|
||||
style={style}
|
||||
activeRequest={activeRequest}
|
||||
methodType={methodType}
|
||||
onUnary={grpc.unary.mutate}
|
||||
onServerStreaming={grpc.serverStreaming.mutate}
|
||||
onClientStreaming={grpc.clientStreaming.mutate}
|
||||
onStreaming={grpc.streaming.mutate}
|
||||
onGo={grpc.go.mutate}
|
||||
onCommit={grpc.commit.mutate}
|
||||
onCancel={grpc.cancel.mutate}
|
||||
onSend={grpc.send.mutate}
|
||||
@@ -93,7 +90,7 @@ export function GrpcConnectionLayout({ style }: Props) {
|
||||
/>
|
||||
)}
|
||||
secondSlot={({ style }) =>
|
||||
!grpc.unary.isLoading && (
|
||||
!grpc.go.isLoading && (
|
||||
<div
|
||||
style={style}
|
||||
className={classNames(
|
||||
@@ -102,9 +99,9 @@ export function GrpcConnectionLayout({ style }: Props) {
|
||||
'shadow shadow-gray-100 dark:shadow-gray-0 relative',
|
||||
)}
|
||||
>
|
||||
{grpc.unary.error ? (
|
||||
{grpc.go.error ? (
|
||||
<Banner color="danger" className="m-2">
|
||||
{grpc.unary.error}
|
||||
{grpc.go.error}
|
||||
</Banner>
|
||||
) : messages.length >= 0 ? (
|
||||
<GrpcConnectionMessagesPane activeRequest={activeRequest} methodType={methodType} />
|
||||
|
||||
@@ -5,9 +5,12 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { createGlobalState } from 'react-use';
|
||||
import type { ReflectResponseService } from '../hooks/useGrpc';
|
||||
import { useGrpcConnections } from '../hooks/useGrpcConnections';
|
||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
|
||||
import type { GrpcRequest } from '../lib/models';
|
||||
import { AUTH_TYPE_BASIC, AUTH_TYPE_BEARER, AUTH_TYPE_NONE } from '../lib/models';
|
||||
import { BasicAuth } from './BasicAuth';
|
||||
import { BearerAuth } from './BearerAuth';
|
||||
import { Button } from './core/Button';
|
||||
import { Icon } from './core/Icon';
|
||||
import { IconButton } from './core/IconButton';
|
||||
@@ -15,6 +18,7 @@ import { RadioDropdown } from './core/RadioDropdown';
|
||||
import { HStack, VStack } from './core/Stacks';
|
||||
import type { TabItem } from './core/Tabs/Tabs';
|
||||
import { TabContent, Tabs } from './core/Tabs/Tabs';
|
||||
import { EmptyStateText } from './EmptyStateText';
|
||||
import { GrpcEditor } from './GrpcEditor';
|
||||
import { UrlBar } from './UrlBar';
|
||||
|
||||
@@ -31,13 +35,10 @@ interface Props {
|
||||
| 'streaming'
|
||||
| 'no-schema'
|
||||
| 'no-method';
|
||||
onUnary: () => void;
|
||||
onCommit: () => void;
|
||||
onCancel: () => void;
|
||||
onSend: (v: { message: string }) => void;
|
||||
onClientStreaming: () => void;
|
||||
onServerStreaming: () => void;
|
||||
onStreaming: () => void;
|
||||
onGo: () => void;
|
||||
services: ReflectResponseService[] | null;
|
||||
}
|
||||
|
||||
@@ -50,19 +51,17 @@ export function GrpcConnectionSetupPane({
|
||||
activeRequest,
|
||||
reflectionError,
|
||||
reflectionLoading,
|
||||
onStreaming,
|
||||
onClientStreaming,
|
||||
onServerStreaming,
|
||||
onGo,
|
||||
onCommit,
|
||||
onCancel,
|
||||
onSend,
|
||||
onUnary,
|
||||
}: Props) {
|
||||
const connections = useGrpcConnections(activeRequest.id ?? null);
|
||||
const updateRequest = useUpdateGrpcRequest(activeRequest?.id ?? null);
|
||||
const activeConnection = connections[0] ?? null;
|
||||
const isStreaming = activeConnection?.elapsed === 0;
|
||||
const [activeTab, setActiveTab] = useActiveTab();
|
||||
const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null);
|
||||
|
||||
const [paneSize, setPaneSize] = useState(99999);
|
||||
const urlContainerEl = useRef<HTMLDivElement>(null);
|
||||
@@ -116,17 +115,9 @@ export function GrpcConnectionSetupPane({
|
||||
body: 'Service or method not selected',
|
||||
});
|
||||
}
|
||||
if (methodType === 'streaming') {
|
||||
onStreaming();
|
||||
} else if (methodType === 'server_streaming') {
|
||||
onServerStreaming();
|
||||
} else if (methodType === 'client_streaming') {
|
||||
onClientStreaming();
|
||||
} else {
|
||||
onUnary();
|
||||
}
|
||||
onGo();
|
||||
},
|
||||
[activeRequest, methodType, onStreaming, onServerStreaming, onClientStreaming, onUnary],
|
||||
[activeRequest, onGo],
|
||||
);
|
||||
|
||||
const tabs: TabItem[] = useMemo(
|
||||
@@ -136,7 +127,7 @@ export function GrpcConnectionSetupPane({
|
||||
value: 'auth',
|
||||
label: 'Auth',
|
||||
options: {
|
||||
value: AUTH_TYPE_NONE, // TODO
|
||||
value: activeRequest.authenticationType,
|
||||
items: [
|
||||
{ label: 'Basic Auth', shortLabel: 'Basic', value: AUTH_TYPE_BASIC },
|
||||
{ label: 'Bearer Token', shortLabel: 'Bearer', value: AUTH_TYPE_BEARER },
|
||||
@@ -144,13 +135,24 @@ export function GrpcConnectionSetupPane({
|
||||
{ label: 'No Authentication', shortLabel: 'Auth', value: AUTH_TYPE_NONE },
|
||||
],
|
||||
onChange: async (authenticationType) => {
|
||||
// TODO
|
||||
let authentication: GrpcRequest['authentication'] = activeRequest.authentication;
|
||||
if (authenticationType === AUTH_TYPE_BASIC) {
|
||||
authentication = {
|
||||
username: authentication.username ?? '',
|
||||
password: authentication.password ?? '',
|
||||
};
|
||||
} else if (authenticationType === AUTH_TYPE_BEARER) {
|
||||
authentication = {
|
||||
token: authentication.token ?? '',
|
||||
};
|
||||
}
|
||||
await updateRequest.mutateAsync({ authenticationType, authentication });
|
||||
},
|
||||
},
|
||||
},
|
||||
{ value: 'metadata', label: 'Metadata' },
|
||||
],
|
||||
[],
|
||||
[activeRequest.authentication, activeRequest.authenticationType, updateRequest],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -166,7 +168,7 @@ export function GrpcConnectionSetupPane({
|
||||
url={activeRequest.url ?? ''}
|
||||
method={null}
|
||||
submitIcon={null}
|
||||
forceUpdateKey={activeRequest?.id ?? ''}
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
placeholder="localhost:50051"
|
||||
onSubmit={handleConnect}
|
||||
onUrlChange={handleChangeUrl}
|
||||
@@ -270,6 +272,15 @@ export function GrpcConnectionSetupPane({
|
||||
request={activeRequest}
|
||||
/>
|
||||
</TabContent>
|
||||
<TabContent value="auth">
|
||||
{activeRequest.authenticationType === AUTH_TYPE_BASIC ? (
|
||||
<BasicAuth key={forceUpdateKey} request={activeRequest} />
|
||||
) : activeRequest.authenticationType === AUTH_TYPE_BEARER ? (
|
||||
<BearerAuth key={forceUpdateKey} request={activeRequest} />
|
||||
) : (
|
||||
<EmptyStateText>No Authentication {activeRequest.authenticationType}</EmptyStateText>
|
||||
)}
|
||||
</TabContent>
|
||||
</Tabs>
|
||||
</VStack>
|
||||
);
|
||||
|
||||
@@ -154,7 +154,7 @@ export const RequestPane = memo(function RequestPane({
|
||||
token: authentication.token ?? '',
|
||||
};
|
||||
}
|
||||
updateRequest.mutate({ authenticationType, authentication });
|
||||
await updateRequest.mutateAsync({ authenticationType, authentication });
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -226,17 +226,9 @@ export const RequestPane = memo(function RequestPane({
|
||||
>
|
||||
<TabContent value="auth">
|
||||
{activeRequest.authenticationType === AUTH_TYPE_BASIC ? (
|
||||
<BasicAuth
|
||||
key={forceUpdateKey}
|
||||
requestId={activeRequest.id}
|
||||
authentication={activeRequest.authentication}
|
||||
/>
|
||||
<BasicAuth key={forceUpdateKey} request={activeRequest} />
|
||||
) : activeRequest.authenticationType === AUTH_TYPE_BEARER ? (
|
||||
<BearerAuth
|
||||
key={forceUpdateKey}
|
||||
requestId={activeRequest.id}
|
||||
authentication={activeRequest.authentication}
|
||||
/>
|
||||
<BearerAuth key={forceUpdateKey} request={activeRequest} />
|
||||
) : (
|
||||
<EmptyStateText>
|
||||
No Authentication {activeRequest.authenticationType}
|
||||
|
||||
@@ -82,7 +82,7 @@ export function Tabs({
|
||||
{tabs.map((t) => {
|
||||
const isActive = t.value === value;
|
||||
const btnClassName = classNames(
|
||||
isActive ? '' : 'text-gray-600 hover:text-gray-800',
|
||||
isActive ? 'text-gray-800' : 'text-gray-600 hover:text-gray-700',
|
||||
'!px-2 ml-[1px]',
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user