Skip to content

Commit e5de2d4

Browse files
authored
feat(Clusters): authorize with meta (#2988)
1 parent 1cff57d commit e5de2d4

File tree

8 files changed

+91
-16
lines changed

8 files changed

+91
-16
lines changed

src/containers/App/Content.tsx

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@ import React from 'react';
22

33
import {connect} from 'react-redux';
44
import type {RedirectProps} from 'react-router-dom';
5-
import {Redirect, Route, Switch} from 'react-router-dom';
5+
import {Redirect, Route, Switch, useLocation} from 'react-router-dom';
66

77
import {AccessDenied} from '../../components/Errors/403';
88
import {PageError} from '../../components/Errors/PageError/PageError';
99
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
1010
import {useSlots} from '../../components/slots';
1111
import type {SlotMap} from '../../components/slots/SlotMap';
1212
import type {SlotComponent} from '../../components/slots/types';
13-
import routes from '../../routes';
13+
import routes, {checkIsClustersPage} from '../../routes';
1414
import type {RootState} from '../../store';
1515
import {authenticationApi} from '../../store/reducers/authentication/authentication';
1616
import {
1717
useCapabilitiesQuery,
1818
useClusterWithoutAuthInUI,
1919
useMetaCapabilitiesLoaded,
2020
useMetaCapabilitiesQuery,
21+
useMetaLoginAvailable,
2122
} from '../../store/reducers/capabilities/hooks';
2223
import {nodesListApi} from '../../store/reducers/nodesList';
2324
import {uiFactory} from '../../uiFactory/uiFactory';
@@ -160,7 +161,7 @@ export function Content(props: ContentProps) {
160161
exact: true,
161162
component: Clusters,
162163
slot: ClustersSlot,
163-
wrapper: GetMetaCapabilities,
164+
wrapper: ClustersDataWrapper,
164165
})}
165166
{/* Single cluster routes */}
166167
{routesSlots.map((route) => {
@@ -191,9 +192,34 @@ function DataWrapper({children}: {children: React.ReactNode}) {
191192
);
192193
}
193194

194-
function GetUser({children}: {children: React.ReactNode}) {
195+
function ClustersDataWrapper({children}: {children: React.ReactNode}) {
196+
return (
197+
<GetMetaCapabilities>
198+
<GetMetaUser>{children}</GetMetaUser>
199+
</GetMetaCapabilities>
200+
);
201+
}
202+
203+
function GetMetaUser({children}: {children: React.ReactNode}) {
204+
const location = useLocation();
205+
206+
const isClustersPage = checkIsClustersPage(location.pathname);
207+
208+
const isMetaLoginAvailable = useMetaLoginAvailable();
209+
210+
if (isClustersPage && isMetaLoginAvailable) {
211+
return <GetUser useMeta>{children}</GetUser>;
212+
}
213+
return children;
214+
}
215+
216+
function GetUser({children, useMeta}: {children: React.ReactNode; useMeta?: boolean}) {
195217
const database = useDatabaseFromQuery();
196-
const {isLoading, error} = authenticationApi.useWhoamiQuery({database});
218+
219+
const {isLoading, error} = authenticationApi.useWhoamiQuery({
220+
database,
221+
useMeta,
222+
});
197223
const {appTitle} = useAppTitle();
198224

199225
const errorProps = error ? {...uiFactory.clusterOrDatabaseAccessError} : undefined;
@@ -262,8 +288,15 @@ function ContentWrapper(props: ContentWrapperProps) {
262288
const {singleClusterMode, isAuthenticated} = props;
263289
const authUnavailable = useClusterWithoutAuthInUI();
264290

291+
const location = useLocation();
292+
const isClustersPage = checkIsClustersPage(location.pathname);
293+
294+
const isMetaLoginAvailable = useMetaLoginAvailable();
295+
296+
const isClustersAuthUnavailable = isClustersPage && !isMetaLoginAvailable;
297+
265298
const renderNotAuthenticated = () => {
266-
if (authUnavailable) {
299+
if (authUnavailable || isClustersAuthUnavailable) {
267300
return <AccessDenied />;
268301
}
269302
return <Authentication />;

src/containers/Authentication/Authentication.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import {Eye, EyeSlash, Xmark} from '@gravity-ui/icons';
44
import {Button, Link as ExternalLink, Icon, TextInput} from '@gravity-ui/uikit';
55
import {useHistory, useLocation} from 'react-router-dom';
66

7-
import {parseQuery} from '../../routes';
7+
import {checkIsClustersPage, parseQuery} from '../../routes';
88
import {authenticationApi} from '../../store/reducers/authentication/authentication';
9-
import {useLoginWithDatabase} from '../../store/reducers/capabilities/hooks';
9+
import {useLoginWithDatabase, useMetaLoginAvailable} from '../../store/reducers/capabilities/hooks';
1010
import {cn} from '../../utils/cn';
1111

1212
import {isDatabaseError, isPasswordError, isUserError} from './utils';
@@ -27,7 +27,10 @@ function Authentication({closable = false}: AuthenticationProps) {
2727

2828
const needDatabase = useLoginWithDatabase();
2929

30-
const [authenticate, {isLoading}] = authenticationApi.useAuthenticateMutation(undefined);
30+
const isClustersPage = checkIsClustersPage(location.pathname);
31+
const isMetaLoginAvailable = useMetaLoginAvailable();
32+
33+
const [authenticate, {isLoading}] = authenticationApi.useAuthenticateMutation();
3134

3235
const {returnUrl, database: databaseFromQuery} = parseQuery(location);
3336

@@ -53,8 +56,10 @@ function Authentication({closable = false}: AuthenticationProps) {
5356
setPasswordError('');
5457
};
5558

59+
const useMeta = isClustersPage && isMetaLoginAvailable;
60+
5661
const onLoginClick = () => {
57-
authenticate({user: login, password, database})
62+
authenticate({user: login, password, database, useMeta})
5863
.unwrap()
5964
.then(() => {
6065
if (returnUrl) {

src/containers/Header/Header.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {useHistory, useLocation} from 'react-router-dom';
1515

1616
import {getConnectToDBDialog} from '../../components/ConnectToDB/ConnectToDBDialog';
1717
import {InternalLink} from '../../components/InternalLink';
18+
import {checkIsClustersPage, checkIsTenantPage} from '../../routes';
1819
import {
1920
useAddClusterFeatureAvailable,
2021
useDatabasesAvailable,
@@ -64,8 +65,8 @@ function Header() {
6465
const location = useLocation();
6566
const history = useHistory();
6667

67-
const isDatabasePage = location.pathname === '/tenant';
68-
const isClustersPage = location.pathname === '/clusters';
68+
const isDatabasePage = checkIsTenantPage(location.pathname);
69+
const isClustersPage = checkIsClustersPage(location.pathname);
6970

7071
const {isLoading: isClustersLoading, error: clustersError} =
7172
clustersApi.useGetClustersListQuery(undefined, {

src/routes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,11 @@ type TabletPageQuery = QueryParamsTypeFromQueryObject<typeof tabletPageQueryPara
146146
export function getTabletPagePath(tabletId: string | number, query: TabletPageQuery = {}) {
147147
return createHref(routes.tablet, {id: tabletId}, {...query});
148148
}
149+
150+
export function checkIsClustersPage(pathname: string) {
151+
return pathname.endsWith(routes.clusters);
152+
}
153+
154+
export function checkIsTenantPage(pathname: string) {
155+
return pathname.endsWith(routes.tenant);
156+
}

src/services/api/meta.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
MetaClusters,
99
MetaTenants,
1010
} from '../../types/api/meta';
11+
import type {TUserToken} from '../../types/api/whoami';
1112
import {parseMetaTenants} from '../parsers/parseMetaTenants';
1213

1314
import type {AxiosOptions, BaseAPIParams} from './base';
@@ -28,6 +29,14 @@ export class MetaAPI extends BaseYdbAPI {
2829
return `${META_BACKEND ?? ''}${path}`;
2930
}
3031

32+
metaAuthenticate(params: {user: string; password: string}) {
33+
return this.post(this.getPath('/meta/login'), params, {});
34+
}
35+
36+
metaWhoami() {
37+
return this.post<TUserToken>(this.getPath('/meta/whoami'), {}, {});
38+
}
39+
3140
getMetaCapabilities() {
3241
return this.get<MetaCapabilitiesResponse>(
3342
this.getPath('/capabilities'),

src/store/reducers/authentication/authentication.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,17 @@ export const {selectIsUserAllowedToMakeChanges, selectIsViewerUser, selectUser}
5252
export const authenticationApi = api.injectEndpoints({
5353
endpoints: (build) => ({
5454
whoami: build.query({
55-
queryFn: async ({database}: {database?: string}, {dispatch}) => {
55+
queryFn: async (
56+
{database, useMeta}: {database?: string; useMeta?: boolean},
57+
{dispatch},
58+
) => {
5659
try {
57-
const data = await window.api.viewer.whoami({database});
60+
let data: TUserToken;
61+
if (useMeta && window.api.meta) {
62+
data = await window.api.meta.metaWhoami();
63+
} else {
64+
data = await window.api.viewer.whoami({database});
65+
}
5866
dispatch(setUser(data));
5967
return {data};
6068
} catch (error) {
@@ -68,11 +76,17 @@ export const authenticationApi = api.injectEndpoints({
6876
}),
6977
authenticate: build.mutation({
7078
queryFn: async (
71-
params: {user: string; password: string; database?: string},
79+
params: {user: string; password: string; database?: string; useMeta?: boolean},
7280
{dispatch},
7381
) => {
7482
try {
75-
const data = await window.api.auth.authenticate(params);
83+
const {useMeta, ...rest} = params;
84+
let data;
85+
if (useMeta) {
86+
data = await window.api.meta?.metaAuthenticate(rest);
87+
} else {
88+
data = await window.api.auth.authenticate(rest);
89+
}
7690
dispatch(setIsAuthenticated(true));
7791
return {data};
7892
} catch (error) {

src/store/reducers/capabilities/hooks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,7 @@ export const useClusterEventsAvailable = () => {
176176
export const useDatabasesAvailable = () => {
177177
return useGetMetaFeatureVersion('/meta/databases') >= 1;
178178
};
179+
180+
export const useMetaLoginAvailable = () => {
181+
return useGetMetaFeatureVersion('/meta/login') >= 1;
182+
};

src/types/api/capabilities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ export type MetaCapability =
5252
| '/meta/update_cluster'
5353
| '/meta/delete_cluster'
5454
| '/meta/events'
55+
| '/meta/login'
5556
| '/meta/databases';

0 commit comments

Comments
 (0)