Skip to content

Commit

Permalink
Add the ability to disable sign-in/sign-up in the UI (#7348)
Browse files Browse the repository at this point in the history
Co-authored-by: Boris Sekachev <boris.sekachev@yandex.ru>
  • Loading branch information
Marishka17 and bsekachev authored Feb 12, 2024
1 parent 4e2b2df commit ad60b82
Show file tree
Hide file tree
Showing 20 changed files with 310 additions and 164 deletions.
2 changes: 2 additions & 0 deletions cvat-core/src/api-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export default function implementAPI(cvat: CVATCore): CVATCore {
return result;
});

implementationMixin(cvat.server.apiSchema, serverProxy.server.apiSchema);

implementationMixin(cvat.assets.create, async (file: File, guideId: number): Promise<SerializedAsset> => {
if (!(file instanceof File)) {
throw new ArgumentError('Assets expect a file');
Expand Down
4 changes: 4 additions & 0 deletions cvat-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ function build(): CVATCore {
const result = await PluginRegistry.apiWrapper(cvat.server.installedApps);
return result;
},
async apiSchema() {
const result = await PluginRegistry.apiWrapper(cvat.server.apiSchema);
return result;
},
},
projects: {
async get(filter = {}) {
Expand Down
1 change: 1 addition & 0 deletions cvat-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export default interface CVATCore {
setAuthData: any;
removeAuthData: any;
installedApps: any;
apiSchema: typeof serverProxy.server.apiSchema;
};
assets: {
create: any;
Expand Down
14 changes: 13 additions & 1 deletion cvat-core/src/server-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
SerializedAbout, SerializedRemoteFile, SerializedUserAgreement,
SerializedRegister, JobsFilter, SerializedJob, SerializedGuide, SerializedAsset,
SerializedQualitySettingsData, SerializedInvitationData, SerializedCloudStorage,
SerializedFramesMetaData, SerializedCollection,
SerializedFramesMetaData, SerializedCollection, SerializedAPISchema,
} from './server-response-types';
import { SerializedQualityReportData } from './quality-report';
import { SerializedAnalyticsReport } from './analytics-report';
Expand Down Expand Up @@ -1899,6 +1899,17 @@ async function installedApps() {
}
}

async function getApiSchema(): Promise<SerializedAPISchema> {
const { backendAPI } = config;

try {
const response = await Axios.get(`${backendAPI}/schema/?scheme=json`);
return response.data;
} catch (errorData) {
throw generateError(errorData);
}
}

async function createCloudStorage(storageDetail) {
const { backendAPI } = config;

Expand Down Expand Up @@ -2410,6 +2421,7 @@ export default Object.freeze({
request: serverRequest,
userAgreements,
installedApps,
apiSchema: getApiSchema,
}),

projects: Object.freeze({
Expand Down
30 changes: 30 additions & 0 deletions cvat-core/src/server-response-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,33 @@ export interface SerializedFramesMetaData {
start_frame: number;
stop_frame: number;
}

export interface SerializedAPISchema {
openapi: string;
info: {
version: string;
description: string;
termsOfService: string;
contact: {
name: string;
url: string;
email: string;
};
license: {
name: string;
url: string;
}
};
paths: {
[path: string]: any;
};
components: {
schemas: {
[component: string]: any;
}
}
externalDocs: {
description: string;
url: string;
};
}
28 changes: 0 additions & 28 deletions cvat-ui/src/actions/auth-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import { ActionUnion, createAction, ThunkAction } from 'utils/redux';
import { RegisterData } from 'components/register-page/register-form';
import { getCore, User } from 'cvat-core-wrapper';
import isReachable from 'utils/url-checker';

const cvat = getCore();

Expand All @@ -33,9 +32,6 @@ export enum AuthActionTypes {
RESET_PASSWORD = 'RESET_PASSWORD_CONFIRM',
RESET_PASSWORD_SUCCESS = 'RESET_PASSWORD_CONFIRM_SUCCESS',
RESET_PASSWORD_FAILED = 'RESET_PASSWORD_CONFIRM_FAILED',
LOAD_AUTH_ACTIONS = 'LOAD_AUTH_ACTIONS',
LOAD_AUTH_ACTIONS_SUCCESS = 'LOAD_AUTH_ACTIONS_SUCCESS',
LOAD_AUTH_ACTIONS_FAILED = 'LOAD_AUTH_ACTIONS_FAILED',
}

export const authActions = {
Expand Down Expand Up @@ -65,14 +61,6 @@ export const authActions = {
resetPassword: () => createAction(AuthActionTypes.RESET_PASSWORD),
resetPasswordSuccess: () => createAction(AuthActionTypes.RESET_PASSWORD_SUCCESS),
resetPasswordFailed: (error: any) => createAction(AuthActionTypes.RESET_PASSWORD_FAILED, { error }),
loadServerAuthActions: () => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS),
loadServerAuthActionsSuccess: (allowChangePassword: boolean, allowResetPassword: boolean) => (
createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_SUCCESS, {
allowChangePassword,
allowResetPassword,
})
),
loadServerAuthActionsFailed: (error: any) => createAction(AuthActionTypes.LOAD_AUTH_ACTIONS_FAILED, { error }),
};

export type AuthActions = ActionUnion<typeof authActions>;
Expand Down Expand Up @@ -188,19 +176,3 @@ export const resetPasswordAsync = (
dispatch(authActions.resetPasswordFailed(error));
}
};

export const loadAuthActionsAsync = (): ThunkAction => async (dispatch) => {
dispatch(authActions.loadServerAuthActions());

try {
const promises: Promise<boolean>[] = [
isReachable(`${cvat.config.backendAPI}/auth/password/change`, 'OPTIONS'),
isReachable(`${cvat.config.backendAPI}/auth/password/reset`, 'OPTIONS'),
];
const [allowChangePassword, allowResetPassword] = await Promise.all(promises);

dispatch(authActions.loadServerAuthActionsSuccess(allowChangePassword, allowResetPassword));
} catch (error) {
dispatch(authActions.loadServerAuthActionsFailed(error));
}
};
37 changes: 37 additions & 0 deletions cvat-ui/src/actions/server-actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) 2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

import { ActionUnion, createAction, ThunkAction } from 'utils/redux';
import { getCore, SerializedAPISchema } from 'cvat-core-wrapper';

const core = getCore();

export enum ServerAPIActionTypes {
GET_SERVER_API_SCHEMA = 'GET_SERVER_API_SCHEMA',
GET_SERVER_API_SCHEMA_SUCCESS = 'GET_SERVER_API_SCHEMA_SUCCESS',
GET_SERVER_API_SCHEMA_FAILED = 'GET_SERVER_API_SCHEMA_FAILED',
}

const serverAPIActions = {
getServerAPISchema: () => createAction(ServerAPIActionTypes.GET_SERVER_API_SCHEMA),
getServerAPISchemaSuccess: (schema: SerializedAPISchema) => (
createAction(ServerAPIActionTypes.GET_SERVER_API_SCHEMA_SUCCESS, { schema })
),
getServerAPISchemaFailed: (error: any) => (
createAction(ServerAPIActionTypes.GET_SERVER_API_SCHEMA_FAILED, { error })
),
};

export type ServerAPIActions = ActionUnion<typeof serverAPIActions>;

export const getServerAPISchemaAsync = (): ThunkAction => async (dispatch): Promise<void> => {
dispatch(serverAPIActions.getServerAPISchema());

try {
const schema = await core.server.apiSchema();
dispatch(serverAPIActions.getServerAPISchemaSuccess(schema));
} catch (error) {
dispatch(serverAPIActions.getServerAPISchemaFailed(error));
}
};
44 changes: 27 additions & 17 deletions cvat-ui/src/components/cvat-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ interface CVATAppProps {
initModels: () => void;
resetErrors: () => void;
resetMessages: () => void;
loadAuthActions: () => void;
loadOrganization: () => void;
initInvitations: () => void;
loadServerAPISchema: () => void;
userInitialized: boolean;
userFetching: boolean;
organizationFetching: boolean;
Expand All @@ -106,14 +106,16 @@ interface CVATAppProps {
aboutFetching: boolean;
userAgreementsFetching: boolean;
userAgreementsInitialized: boolean;
authActionsFetching: boolean;
authActionsInitialized: boolean;
notifications: NotificationsState;
user: any;
isModelPluginActive: boolean;
pluginComponents: PluginsState['components'];
invitationsFetching: boolean;
invitationsInitialized: boolean;
serverAPISchemaFetching: boolean;
serverAPISchemaInitialized: boolean;
isPasswordResetEnabled: boolean;
isRegistrationEnabled: boolean;
}

interface CVATAppState {
Expand Down Expand Up @@ -261,7 +263,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
initPlugins,
initModels,
loadOrganization,
loadAuthActions,
loadServerAPISchema,
userInitialized,
userFetching,
organizationFetching,
Expand All @@ -277,13 +279,13 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
user,
userAgreementsFetching,
userAgreementsInitialized,
authActionsFetching,
authActionsInitialized,
isModelPluginActive,
invitationsInitialized,
invitationsFetching,
initInvitations,
history,
serverAPISchemaFetching,
serverAPISchemaInitialized,
} = this.props;

const { backendIsHealthy } = this.state;
Expand All @@ -305,8 +307,8 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
return;
}

if (!authActionsInitialized && !authActionsFetching) {
loadAuthActions();
if (!serverAPISchemaInitialized && !serverAPISchemaFetching) {
loadServerAPISchema();
}

if (user == null || !user.isVerified || !user.id) {
Expand Down Expand Up @@ -425,17 +427,19 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
modelsInitialized,
organizationInitialized,
userAgreementsInitialized,
authActionsInitialized,
serverAPISchemaInitialized,
pluginComponents,
user,
location,
isModelPluginActive,
isPasswordResetEnabled,
isRegistrationEnabled,
} = this.props;

const { healthIinitialized, backendIsHealthy } = this.state;

const notRegisteredUserInitialized = (userInitialized && (user == null || !user.isVerified));
let readyForRender = userAgreementsInitialized && authActionsInitialized;
let readyForRender = userAgreementsInitialized && serverAPISchemaInitialized;
readyForRender = readyForRender && (notRegisteredUserInitialized ||
(
userInitialized &&
Expand Down Expand Up @@ -549,7 +553,9 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
<GlobalErrorBoundary>
<>
<Switch>
<Route exact path='/auth/register' component={RegisterPageContainer} />
{isRegistrationEnabled && (
<Route exact path='/auth/register' component={RegisterPageContainer} />
)}
<Route exact path='/auth/email-verification-sent' component={EmailVerificationSentPage} />
<Route exact path='/auth/incorrect-email-confirmation' component={IncorrectEmailConfirmationPage} />
<Route exact path='/auth/login' component={LoginPageContainer} />
Expand All @@ -558,12 +564,16 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
path='/auth/login-with-token/:token'
component={LoginWithTokenComponent}
/>
<Route exact path='/auth/password/reset' component={ResetPasswordPageComponent} />
<Route
exact
path='/auth/password/reset/confirm'
component={ResetPasswordPageConfirmComponent}
/>
{isPasswordResetEnabled && (
<Route exact path='/auth/password/reset' component={ResetPasswordPageComponent} />
)}
{isPasswordResetEnabled && (
<Route
exact
path='/auth/password/reset/confirm'
component={ResetPasswordPageConfirmComponent}
/>
)}

<Route exact path='/auth/email-confirmation' component={EmailConfirmationPage} />
{ routesToRender }
Expand Down
6 changes: 5 additions & 1 deletion cvat-ui/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,17 @@ function mapStateToProps(state: CombinedState): StateToProps {
fetching: logoutFetching,
fetching: changePasswordFetching,
showChangePasswordDialog: changePasswordDialogShown,
allowChangePassword: renderChangePasswordItem,
},
plugins: { list },
about,
shortcuts: { normalizedKeyMap, keyMap, visibleShortcutsHelp: shortcutsModalVisible },
settings: { showDialog: settingsModalVisible },
organizations: { fetching: organizationFetching, current: currentOrganization },
serverAPI: {
configuration: {
isPasswordChangeEnabled: renderChangePasswordItem,
},
},
} = state;

return {
Expand Down
Loading

0 comments on commit ad60b82

Please sign in to comment.