Skip to content

Commit 2469ead

Browse files
committed
feat(Clusters): authorize with meta
1 parent 2fb30ad commit 2469ead

File tree

7 files changed

+41
-8
lines changed

7 files changed

+41
-8
lines changed

src/containers/App/Content.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ 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';
@@ -18,6 +18,7 @@ import {
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';
@@ -262,8 +263,15 @@ function ContentWrapper(props: ContentWrapperProps) {
262263
const {singleClusterMode, isAuthenticated} = props;
263264
const authUnavailable = useClusterWithoutAuthInUI();
264265

266+
const location = useLocation();
267+
const isClustersPage = location.pathname === '/clusters';
268+
269+
const isMetaLoginAvailable = useMetaLoginAvailable();
270+
271+
const isClustersAuthUnavailable = isClustersPage && !isMetaLoginAvailable;
272+
265273
const renderNotAuthenticated = () => {
266-
if (authUnavailable) {
274+
if (authUnavailable || isClustersAuthUnavailable) {
267275
return <AccessDenied />;
268276
}
269277
return <Authentication />;

src/containers/Authentication/Authentication.tsx

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

77
import {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 = location.pathname === '/clusters';
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/services/api/meta.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export class MetaAPI extends BaseYdbAPI {
2828
return `${META_BACKEND ?? ''}${path}`;
2929
}
3030

31+
metaAuthenticate(params: {user: string; password: string}) {
32+
return this.post(this.getPath('/meta/login'), params, {});
33+
}
34+
3135
getMetaCapabilities() {
3236
return this.get<MetaCapabilitiesResponse>(
3337
this.getPath('/capabilities'),

src/store/reducers/authentication/authentication.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,17 @@ export const authenticationApi = api.injectEndpoints({
6868
}),
6969
authenticate: build.mutation({
7070
queryFn: async (
71-
params: {user: string; password: string; database?: string},
71+
params: {user: string; password: string; database?: string; useMeta?: boolean},
7272
{dispatch},
7373
) => {
7474
try {
75-
const data = await window.api.auth.authenticate(params);
75+
const {useMeta, ...rest} = params;
76+
let data;
77+
if (useMeta) {
78+
data = await window.api.meta?.metaAuthenticate(rest);
79+
} else {
80+
data = await window.api.auth.authenticate(rest);
81+
}
7682
dispatch(setIsAuthenticated(true));
7783
return {data};
7884
} 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/store/reducers/clusters/clusters.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {createSlice} from '@reduxjs/toolkit';
22
import type {PayloadAction} from '@reduxjs/toolkit';
33

4+
import {isAxiosResponse} from '../../../utils/response';
45
import {api} from '../api';
6+
import {setIsAuthenticated} from '../authentication/authentication';
57

68
import type {ClustersFilters} from './types';
79
import {prepareClustersData} from './utils';
@@ -30,7 +32,7 @@ export const {changeClustersFilters} = slice.actions;
3032
export const clustersApi = api.injectEndpoints({
3133
endpoints: (builder) => ({
3234
getClustersList: builder.query({
33-
queryFn: async (_, {signal}) => {
35+
queryFn: async (_, {signal, dispatch}) => {
3436
try {
3537
if (window.api.meta) {
3638
const data = await window.api.meta.getClustersList(undefined, {signal});
@@ -39,6 +41,9 @@ export const clustersApi = api.injectEndpoints({
3941
throw new Error('Method is not implemented.');
4042
}
4143
} catch (error) {
44+
if (isAxiosResponse(error) && error.status === 401) {
45+
dispatch(setIsAuthenticated(false));
46+
}
4247
return {error};
4348
}
4449
},

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)