mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(authentication): implementation
CB-63
This commit is contained in:
@@ -15,7 +15,7 @@ type AuthCredentialInfo {
|
||||
admin: Boolean
|
||||
# This field must be shown in login form
|
||||
user: Boolean
|
||||
possibleValues: [String]!
|
||||
possibleValues: [String]
|
||||
encryption: AuthCredentialEncryption
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observable } from 'mobx';
|
||||
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import { NotificationService } from '@dbeaver/core/eventsLog';
|
||||
import { GraphQLService, UserAuthInfo } from '@dbeaver/core/sdk';
|
||||
|
||||
@injectable()
|
||||
export class AuthInfoService {
|
||||
@observable private user: UserAuthInfo | null = null;
|
||||
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
private notificationService: NotificationService,
|
||||
) { }
|
||||
|
||||
get userInfo() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
async login(provider: string, credentials: object): Promise<UserAuthInfo> {
|
||||
if (this.user) {
|
||||
throw new Error('User already logged in');
|
||||
}
|
||||
|
||||
const { user } = await this.graphQLService.gql.authLogin({ provider, credentials });
|
||||
this.user = user;
|
||||
|
||||
return this.user;
|
||||
}
|
||||
|
||||
async logout() {
|
||||
if (this.user) {
|
||||
await this.graphQLService.gql.authLogout();
|
||||
this.user = null;
|
||||
}
|
||||
}
|
||||
|
||||
async updateAuthInfo(): Promise<UserAuthInfo | null> {
|
||||
try {
|
||||
const { user } = await this.graphQLService.gql.getSessionUser();
|
||||
this.user = user || null;
|
||||
} catch (exception) {
|
||||
this.notificationService.logException(exception, 'Can\'t load session user');
|
||||
}
|
||||
|
||||
return this.user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import {
|
||||
GraphQLService, CachedResource, AuthProviderInfo
|
||||
} from '@dbeaver/core/sdk';
|
||||
|
||||
export type AuthProvider = Omit<AuthProviderInfo, 'configurationParameters'>
|
||||
|
||||
@injectable()
|
||||
export class AuthProviderService {
|
||||
readonly providers = new CachedResource([], this.refreshAsync.bind(this), data => !!data.length)
|
||||
|
||||
constructor(
|
||||
private graphQLService: GraphQLService,
|
||||
) { }
|
||||
|
||||
private async refreshAsync(data: AuthProvider[]): Promise<AuthProvider[]> {
|
||||
const { providers } = await this.graphQLService.gql.getAuthProviders();
|
||||
|
||||
return providers;
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,34 @@
|
||||
*/
|
||||
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import { PermissionsService } from '@dbeaver/core/root';
|
||||
import { ServerService } from '@dbeaver/core/root';
|
||||
|
||||
import { AuthInfoService } from './AuthInfoService';
|
||||
import { AuthDialogService } from './Dialog/AuthDialogService';
|
||||
|
||||
@injectable()
|
||||
export class AuthenticationService {
|
||||
constructor(
|
||||
private permissionsService: PermissionsService,
|
||||
private serverService: ServerService,
|
||||
private authDialogService: AuthDialogService,
|
||||
private authInfoService: AuthInfoService,
|
||||
) { }
|
||||
|
||||
register() {
|
||||
async auth() {
|
||||
if (this.isForceAuthentication()) {
|
||||
await this.authDialogService.showLoginForm();
|
||||
}
|
||||
}
|
||||
|
||||
async isForceAuthentication() {
|
||||
const config = await this.serverService.config.load();
|
||||
if (!config) {
|
||||
throw new Error('Can\'t configure Authentication');
|
||||
}
|
||||
const userInfo = await this.authInfoService.updateAuthInfo();
|
||||
|
||||
return !config.anonymousAccessEnabled
|
||||
&& config.authenticationEnabled
|
||||
&& !userInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { AuthenticationService } from './AuthenticationService';
|
||||
export class Bootstrap {
|
||||
constructor(private authenticationService: AuthenticationService) { }
|
||||
|
||||
bootstrap() {
|
||||
this.authenticationService.register();
|
||||
async bootstrap() {
|
||||
return this.authenticationService.auth();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import { useTabState, Tab as BaseTab, TabList } from 'reakit/Tab';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { SubmittingForm, ErrorMessage } from '@dbeaver/core/blocks';
|
||||
import { useController } from '@dbeaver/core/di';
|
||||
import { DialogComponent, CommonDialogWrapper } from '@dbeaver/core/dialogs';
|
||||
import { useTranslate } from '@dbeaver/core/localization';
|
||||
import { composes, useStyles } from '@dbeaver/core/theming';
|
||||
|
||||
import { AuthDialogController } from './AuthDialogController';
|
||||
import { AuthDialogFooter } from './AuthDialogFooter';
|
||||
import { AuthProviderForm } from './AuthProviderForm/AuthProviderForm';
|
||||
|
||||
const styles = composes(
|
||||
css`
|
||||
BaseTab {
|
||||
composes: theme-ripple theme-background-secondary theme-text-on-secondary from global;
|
||||
}
|
||||
ErrorMessage {
|
||||
composes: theme-background-secondary from global;
|
||||
}
|
||||
`,
|
||||
css`
|
||||
custom-connection {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
CommonDialogWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 330px;
|
||||
min-height: 330px;
|
||||
}
|
||||
SubmittingForm {
|
||||
overflow: auto;
|
||||
}
|
||||
SubmittingForm, AuthProviderForm {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
BaseTab {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
TabList {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
padding-left: 24px;
|
||||
}
|
||||
BaseTab {
|
||||
composes: theme-typography--body2 from global;
|
||||
text-transform: uppercase;
|
||||
padding: 12px 16px;
|
||||
border-top: solid 2px transparent;
|
||||
height: 48px;
|
||||
|
||||
&:global([aria-selected='true']) {
|
||||
border-top-color: #fd1d48;
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:global([aria-selected='true'])) {
|
||||
cursor: pointer;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
AuthProviderForm {
|
||||
flex-direction: column;
|
||||
padding: 18px 24px;
|
||||
}
|
||||
ErrorMessage {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
padding: 8px 24px;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
export const AuthDialog: DialogComponent<null, null> = observer(
|
||||
function AuthDialog(props) {
|
||||
const controller = useController(AuthDialogController, props.rejectDialog);
|
||||
const translate = useTranslate();
|
||||
const tab = useTabState({
|
||||
selectedId: controller.provider?.id,
|
||||
});
|
||||
tab.selectedId = controller.provider?.id || null;
|
||||
|
||||
return styled(useStyles(styles))(
|
||||
<CommonDialogWrapper
|
||||
title={translate('sas')}
|
||||
noBodyPadding
|
||||
header={(
|
||||
<TabList {...tab} aria-label="My tabs">
|
||||
{controller.providers.map(provider => (
|
||||
<BaseTab {...tab} key={provider.id} type='button' stopId={provider.id}>{provider.label}</BaseTab>
|
||||
))}
|
||||
</TabList>
|
||||
)}
|
||||
footer={(
|
||||
<AuthDialogFooter
|
||||
isAuthenticating={controller.isAuthenticating}
|
||||
onLogin={controller.login}
|
||||
/>
|
||||
)}
|
||||
onReject={props.rejectDialog}
|
||||
>
|
||||
<SubmittingForm onSubmit={controller.login}>
|
||||
{controller.provider && (
|
||||
<AuthProviderForm
|
||||
provider={controller.provider}
|
||||
credentials={controller.credentials}
|
||||
authenticate={controller.isAuthenticating}
|
||||
/>
|
||||
)}
|
||||
</SubmittingForm>
|
||||
{controller.error.responseMessage && (
|
||||
<ErrorMessage
|
||||
text={controller.error.responseMessage}
|
||||
hasDetails={controller.error.hasDetails}
|
||||
onShowDetails={controller.showDetails}
|
||||
/>
|
||||
)}
|
||||
</CommonDialogWrapper>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observable, computed } from 'mobx';
|
||||
|
||||
import { injectable, IInitializableController, IDestructibleController } from '@dbeaver/core/di';
|
||||
import { CommonDialogService } from '@dbeaver/core/dialogs';
|
||||
import { NotificationService } from '@dbeaver/core/eventsLog';
|
||||
import { GQLErrorCatcher } from '@dbeaver/core/sdk';
|
||||
import { ErrorDetailsDialog } from '@dbeaver/core/src/app';
|
||||
|
||||
import { AuthInfoService } from '../AuthInfoService';
|
||||
import { AuthProviderService, AuthProvider } from '../AuthProviderService';
|
||||
|
||||
@injectable()
|
||||
export class AuthDialogController implements IInitializableController, IDestructibleController {
|
||||
@observable provider: AuthProvider | null = null
|
||||
@observable isAuthenticating = false;
|
||||
@observable credentials = {};
|
||||
|
||||
get isLoading() {
|
||||
return this.authProviderService.providers.isLoading();
|
||||
}
|
||||
|
||||
@computed get providers(): AuthProvider[] {
|
||||
return this.authProviderService
|
||||
.providers
|
||||
.data
|
||||
.concat()
|
||||
.sort(this.compareProviders);
|
||||
}
|
||||
|
||||
readonly error = new GQLErrorCatcher();
|
||||
private isDistructed = false;
|
||||
private close!: () => void;
|
||||
|
||||
constructor(
|
||||
private notificationService: NotificationService,
|
||||
private authProviderService: AuthProviderService,
|
||||
private authInfoService: AuthInfoService,
|
||||
private commonDialogService: CommonDialogService,
|
||||
) { }
|
||||
|
||||
init(onClose: () => void) {
|
||||
this.close = onClose;
|
||||
this.loadProviders();
|
||||
}
|
||||
|
||||
destruct(): void {
|
||||
this.isDistructed = true;
|
||||
}
|
||||
|
||||
login = async () => {
|
||||
if (!this.provider || this.isAuthenticating) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isAuthenticating = true;
|
||||
try {
|
||||
await this.authInfoService.login(this.provider.id, this.credentials);
|
||||
this.close();
|
||||
} catch (exception) {
|
||||
if (!this.error.catch(exception) || this.isDistructed) {
|
||||
this.notificationService.logException(exception, 'Login failed');
|
||||
}
|
||||
} finally {
|
||||
this.isAuthenticating = false;
|
||||
}
|
||||
}
|
||||
|
||||
selectProvider = (providerId: string) => {
|
||||
this.provider = this.authProviderService
|
||||
.providers.data.find(provider => provider.id === providerId) || null;
|
||||
this.credentials = {};
|
||||
}
|
||||
|
||||
showDetails = () => {
|
||||
if (this.error.exception) {
|
||||
this.commonDialogService.open(ErrorDetailsDialog, this.error.exception);
|
||||
}
|
||||
}
|
||||
|
||||
private async loadProviders() {
|
||||
try {
|
||||
await this.authProviderService.providers.load();
|
||||
if (this.providers.length > 0) {
|
||||
this.provider = this.providers[0];
|
||||
}
|
||||
} catch (exception) {
|
||||
this.notificationService.logException(exception, 'Can\'t load auth providers');
|
||||
}
|
||||
}
|
||||
|
||||
private compareProviders = (providerA: AuthProvider, providerB: AuthProvider): number => {
|
||||
if (providerA.isDefault === providerB.isDefault)
|
||||
{
|
||||
return providerA.label.localeCompare(providerB.label);
|
||||
}
|
||||
|
||||
return +!!providerA.isDefault - +!!providerB.isDefault;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { Button } from '@dbeaver/core/blocks';
|
||||
import { useTranslate } from '@dbeaver/core/localization';
|
||||
|
||||
const styles = css`
|
||||
controls {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
fill {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
Button:not(:first-child) {
|
||||
margin-left: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
export type Props = {
|
||||
isAuthenticating: boolean;
|
||||
onLogin(): void;
|
||||
}
|
||||
|
||||
export const AuthDialogFooter = observer(
|
||||
function AuthDialogFooter({
|
||||
isAuthenticating,
|
||||
onLogin,
|
||||
}: Props) {
|
||||
const translate = useTranslate();
|
||||
|
||||
return styled(styles)(
|
||||
<controls as="div">
|
||||
<fill as="div"/>
|
||||
<Button
|
||||
type="button"
|
||||
mod={['unelevated']}
|
||||
onClick={onLogin}
|
||||
disabled={isAuthenticating}
|
||||
>
|
||||
{translate('Login')}
|
||||
</Button>
|
||||
</controls>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@dbeaver/core/di';
|
||||
import { CommonDialogService } from '@dbeaver/core/dialogs';
|
||||
|
||||
import { AuthDialog } from './AuthDialog';
|
||||
|
||||
@injectable()
|
||||
export class AuthDialogService {
|
||||
constructor(
|
||||
private commonDialogService: CommonDialogService,
|
||||
) { }
|
||||
|
||||
async showLoginForm() {
|
||||
await this.commonDialogService.open(AuthDialog, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import { useCallback } from 'react';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { InputField } from '@dbeaver/core/blocks';
|
||||
import { useStyles } from '@dbeaver/core/theming';
|
||||
|
||||
import { AuthProvider } from '../../AuthProviderService';
|
||||
import { formStyles } from './formStyles';
|
||||
|
||||
type Props = {
|
||||
provider: AuthProvider;
|
||||
credentials: any;
|
||||
authenticate: boolean;
|
||||
}
|
||||
|
||||
export const AuthProviderForm = observer(function AuthProviderForm({
|
||||
provider,
|
||||
credentials,
|
||||
authenticate,
|
||||
}: Props) {
|
||||
// const translate = useTranslate();
|
||||
const handleChange = useCallback((key: string, value: string) => {
|
||||
credentials[key] = value;
|
||||
}, [credentials]);
|
||||
|
||||
return styled(useStyles(formStyles))(
|
||||
<>
|
||||
{provider.credentialParameters.map(parameter => parameter.user && (
|
||||
<group as="div" key={parameter.id}>
|
||||
<InputField
|
||||
type={parameter.encryption === 'none' ? 'text' : 'password'}
|
||||
name={parameter.id}
|
||||
value={credentials[parameter.id]}
|
||||
onChange={value => handleChange(parameter.id, value)}
|
||||
disabled={authenticate}
|
||||
mod='surface'
|
||||
>
|
||||
{parameter.displayName}
|
||||
</InputField>
|
||||
</group>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* cloudbeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { css } from 'reshadow';
|
||||
|
||||
export const formStyles = css`
|
||||
sub-label {
|
||||
composes: theme-typography--caption from global;
|
||||
line-height: 14px;
|
||||
}
|
||||
group {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
margin: 0 12px;
|
||||
}
|
||||
InputField[|short] {
|
||||
min-width: unset;
|
||||
max-width: 250px;
|
||||
}
|
||||
hr {
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
`;
|
||||
@@ -3,3 +3,6 @@ import { manifest } from './manifest';
|
||||
export default manifest;
|
||||
|
||||
export * from './AuthenticationService';
|
||||
export * from './AuthInfoService';
|
||||
export * from './AuthProviderService';
|
||||
export * from './Dialog/AuthDialogService';
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
import { IServiceInjector, PluginManifest } from '@dbeaver/core/di';
|
||||
|
||||
import { AuthenticationService } from './AuthenticationService';
|
||||
import { AuthInfoService } from './AuthInfoService';
|
||||
import { AuthProviderService } from './AuthProviderService';
|
||||
import { Bootstrap } from './Bootstrap';
|
||||
import { AuthDialogService } from './Dialog/AuthDialogService';
|
||||
|
||||
export const manifest: PluginManifest = {
|
||||
info: {
|
||||
@@ -18,6 +21,9 @@ export const manifest: PluginManifest = {
|
||||
|
||||
providers: [
|
||||
AuthenticationService,
|
||||
AuthInfoService,
|
||||
AuthProviderService,
|
||||
AuthDialogService,
|
||||
],
|
||||
|
||||
async initialize(services: IServiceInjector) {
|
||||
|
||||
@@ -5,6 +5,7 @@ schema:
|
||||
- ../../../server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls
|
||||
- ../../../server/bundles/io.cloudbeaver.service.metadata/schema/service.metadata.graphqls
|
||||
- ../../../server/bundles/io.cloudbeaver.service.data.transfer/schema/service.data.transfer.graphqls
|
||||
- ../../../server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls
|
||||
documents:
|
||||
- ./src/**/*.gql
|
||||
generates:
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
query authLogin(
|
||||
$provider: ID!
|
||||
$credentials: Object!
|
||||
) {
|
||||
user: authLogin(provider: $provider, credentials: $credentials) {
|
||||
userId
|
||||
displayName
|
||||
authProvider
|
||||
loginTime
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
query authLogout {
|
||||
authLogout
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
query getAuthProviders {
|
||||
providers: authProviders {
|
||||
id
|
||||
label
|
||||
icon
|
||||
description
|
||||
isDefault
|
||||
|
||||
#configurationParameters {
|
||||
# id
|
||||
# displayName
|
||||
# description
|
||||
# category
|
||||
# dataType
|
||||
# value
|
||||
# validValues
|
||||
# defaultValue
|
||||
# features
|
||||
#}
|
||||
|
||||
credentialParameters {
|
||||
id
|
||||
displayName
|
||||
description
|
||||
editable
|
||||
identifying
|
||||
admin
|
||||
user
|
||||
possibleValues
|
||||
encryption
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
query getSessionUser {
|
||||
user: sessionUser {
|
||||
userId
|
||||
displayName
|
||||
authProvider
|
||||
loginTime
|
||||
message
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ query serverConfig {
|
||||
supportsCustomConnections
|
||||
supportsConnectionBrowser
|
||||
supportsWorkspaces
|
||||
anonymousAccessEnabled
|
||||
authenticationEnabled
|
||||
supportedLanguages {
|
||||
isoCode
|
||||
displayName
|
||||
|
||||
@@ -31,6 +31,36 @@ export type AsyncTaskInfo = {
|
||||
taskResult?: Maybe<Scalars["Object"]>;
|
||||
};
|
||||
|
||||
export enum AuthCredentialEncryption {
|
||||
None = "none",
|
||||
Plain = "plain",
|
||||
Hash = "hash",
|
||||
}
|
||||
|
||||
export type AuthCredentialInfo = {
|
||||
id: Scalars["ID"];
|
||||
displayName: Scalars["String"];
|
||||
description?: Maybe<Scalars["String"]>;
|
||||
editable?: Maybe<Scalars["Boolean"]>;
|
||||
identifying?: Maybe<Scalars["Boolean"]>;
|
||||
/** This field must be shown in admin panel */
|
||||
admin?: Maybe<Scalars["Boolean"]>;
|
||||
/** This field must be shown in login form */
|
||||
user?: Maybe<Scalars["Boolean"]>;
|
||||
possibleValues?: Maybe<Array<Maybe<Scalars["String"]>>>;
|
||||
encryption?: Maybe<AuthCredentialEncryption>;
|
||||
};
|
||||
|
||||
export type AuthProviderInfo = {
|
||||
id: Scalars["ID"];
|
||||
label: Scalars["String"];
|
||||
icon?: Maybe<Scalars["ID"]>;
|
||||
description?: Maybe<Scalars["String"]>;
|
||||
isDefault?: Maybe<Scalars["Boolean"]>;
|
||||
configurationParameters: Array<Maybe<ObjectPropertyInfo>>;
|
||||
credentialParameters: Array<Maybe<AuthCredentialInfo>>;
|
||||
};
|
||||
|
||||
/** Configuration of particular connection. Used for new connection create. Includes auth info */
|
||||
export type ConnectionConfig = {
|
||||
name?: Maybe<Scalars["String"]>;
|
||||
@@ -387,6 +417,10 @@ export type Query = {
|
||||
sqlDialectInfo?: Maybe<SqlDialectInfo>;
|
||||
sqlListContexts?: Maybe<Array<Maybe<SqlContextInfo>>>;
|
||||
sqlCompletionProposals?: Maybe<Array<Maybe<SqlCompletionProposal>>>;
|
||||
authLogin?: Maybe<UserAuthInfo>;
|
||||
authLogout?: Maybe<Scalars["Boolean"]>;
|
||||
sessionUser?: Maybe<UserAuthInfo>;
|
||||
authProviders: Array<Maybe<AuthProviderInfo>>;
|
||||
/** Available transfer processors */
|
||||
dataTransferAvailableStreamProcessors?: Maybe<
|
||||
Array<Maybe<DataTransferProcessorInfo>>
|
||||
@@ -447,6 +481,11 @@ export type QuerySqlCompletionProposalsArgs = {
|
||||
maxResults?: Maybe<Scalars["Int"]>;
|
||||
};
|
||||
|
||||
export type QueryAuthLoginArgs = {
|
||||
provider: Scalars["ID"];
|
||||
credentials: Scalars["Object"];
|
||||
};
|
||||
|
||||
export type QueryDataTransferExportDataFromContainerArgs = {
|
||||
connectionId: Scalars["ID"];
|
||||
containerNodePath: Scalars["ID"];
|
||||
@@ -594,6 +633,18 @@ export type SqlResultSet = {
|
||||
hasMoreData?: Maybe<Scalars["Boolean"]>;
|
||||
};
|
||||
|
||||
export type UserAuthInfo = {
|
||||
/** User unique identifier */
|
||||
userId: Scalars["String"];
|
||||
/** Human readable display name. May be null */
|
||||
displayName?: Maybe<Scalars["String"]>;
|
||||
/** Auth provider ID */
|
||||
authProvider: Scalars["String"];
|
||||
loginTime: Scalars["DateTime"];
|
||||
/** Optional login message */
|
||||
message?: Maybe<Scalars["String"]>;
|
||||
};
|
||||
|
||||
export type WebServiceConfig = {
|
||||
id: Scalars["String"];
|
||||
name: Scalars["String"];
|
||||
@@ -855,6 +906,65 @@ export type ChangeSessionLanguageMutation = Pick<
|
||||
"changeSessionLanguage"
|
||||
>;
|
||||
|
||||
export type AuthLoginQueryVariables = {
|
||||
provider: Scalars["ID"];
|
||||
credentials: Scalars["Object"];
|
||||
};
|
||||
|
||||
export type AuthLoginQuery = {
|
||||
user: Maybe<
|
||||
Pick<
|
||||
UserAuthInfo,
|
||||
"userId" | "displayName" | "authProvider" | "loginTime" | "message"
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
export type AuthLogoutQueryVariables = {};
|
||||
|
||||
export type AuthLogoutQuery = Pick<Query, "authLogout">;
|
||||
|
||||
export type GetAuthProvidersQueryVariables = {};
|
||||
|
||||
export type GetAuthProvidersQuery = {
|
||||
providers: Array<
|
||||
Maybe<
|
||||
Pick<
|
||||
AuthProviderInfo,
|
||||
"id" | "label" | "icon" | "description" | "isDefault"
|
||||
> & {
|
||||
credentialParameters: Array<
|
||||
Maybe<
|
||||
Pick<
|
||||
AuthCredentialInfo,
|
||||
| "id"
|
||||
| "displayName"
|
||||
| "description"
|
||||
| "editable"
|
||||
| "identifying"
|
||||
| "admin"
|
||||
| "user"
|
||||
| "possibleValues"
|
||||
| "encryption"
|
||||
>
|
||||
>
|
||||
>;
|
||||
}
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
export type GetSessionUserQueryVariables = {};
|
||||
|
||||
export type GetSessionUserQuery = {
|
||||
user: Maybe<
|
||||
Pick<
|
||||
UserAuthInfo,
|
||||
"userId" | "displayName" | "authProvider" | "loginTime" | "message"
|
||||
>
|
||||
>;
|
||||
};
|
||||
|
||||
export type AsyncExportTaskStatusMutationVariables = {
|
||||
taskId: Scalars["String"];
|
||||
};
|
||||
@@ -1278,6 +1388,8 @@ export type ServerConfigQuery = {
|
||||
| "supportsCustomConnections"
|
||||
| "supportsConnectionBrowser"
|
||||
| "supportsWorkspaces"
|
||||
| "anonymousAccessEnabled"
|
||||
| "authenticationEnabled"
|
||||
> & {
|
||||
supportedLanguages: Array<
|
||||
Maybe<Pick<ServerLanguage, "isoCode" | "displayName" | "nativeName">>
|
||||
@@ -1513,6 +1625,55 @@ export const ChangeSessionLanguageDocument = gql`
|
||||
changeSessionLanguage(locale: $locale)
|
||||
}
|
||||
`;
|
||||
export const AuthLoginDocument = gql`
|
||||
query authLogin($provider: ID!, $credentials: Object!) {
|
||||
user: authLogin(provider: $provider, credentials: $credentials) {
|
||||
userId
|
||||
displayName
|
||||
authProvider
|
||||
loginTime
|
||||
message
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AuthLogoutDocument = gql`
|
||||
query authLogout {
|
||||
authLogout
|
||||
}
|
||||
`;
|
||||
export const GetAuthProvidersDocument = gql`
|
||||
query getAuthProviders {
|
||||
providers: authProviders {
|
||||
id
|
||||
label
|
||||
icon
|
||||
description
|
||||
isDefault
|
||||
credentialParameters {
|
||||
id
|
||||
displayName
|
||||
description
|
||||
editable
|
||||
identifying
|
||||
admin
|
||||
user
|
||||
possibleValues
|
||||
encryption
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const GetSessionUserDocument = gql`
|
||||
query getSessionUser {
|
||||
user: sessionUser {
|
||||
userId
|
||||
displayName
|
||||
authProvider
|
||||
loginTime
|
||||
message
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AsyncExportTaskStatusDocument = gql`
|
||||
mutation asyncExportTaskStatus($taskId: String!) {
|
||||
taskInfo: asyncTaskStatus(id: $taskId) {
|
||||
@@ -1926,6 +2087,8 @@ export const ServerConfigDocument = gql`
|
||||
supportsCustomConnections
|
||||
supportsConnectionBrowser
|
||||
supportsWorkspaces
|
||||
anonymousAccessEnabled
|
||||
authenticationEnabled
|
||||
supportedLanguages {
|
||||
isoCode
|
||||
displayName
|
||||
@@ -2089,6 +2252,34 @@ export function getSdk(client: GraphQLClient) {
|
||||
variables,
|
||||
);
|
||||
},
|
||||
authLogin(variables: AuthLoginQueryVariables): Promise<AuthLoginQuery> {
|
||||
return client.request<AuthLoginQuery>(
|
||||
print(AuthLoginDocument),
|
||||
variables,
|
||||
);
|
||||
},
|
||||
authLogout(variables?: AuthLogoutQueryVariables): Promise<AuthLogoutQuery> {
|
||||
return client.request<AuthLogoutQuery>(
|
||||
print(AuthLogoutDocument),
|
||||
variables,
|
||||
);
|
||||
},
|
||||
getAuthProviders(
|
||||
variables?: GetAuthProvidersQueryVariables,
|
||||
): Promise<GetAuthProvidersQuery> {
|
||||
return client.request<GetAuthProvidersQuery>(
|
||||
print(GetAuthProvidersDocument),
|
||||
variables,
|
||||
);
|
||||
},
|
||||
getSessionUser(
|
||||
variables?: GetSessionUserQueryVariables,
|
||||
): Promise<GetSessionUserQuery> {
|
||||
return client.request<GetSessionUserQuery>(
|
||||
print(GetSessionUserDocument),
|
||||
variables,
|
||||
);
|
||||
},
|
||||
asyncExportTaskStatus(
|
||||
variables: AsyncExportTaskStatusMutationVariables,
|
||||
): Promise<AsyncExportTaskStatusMutation> {
|
||||
|
||||
Reference in New Issue
Block a user