Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(revoke-share-code): support revoke shared login code #1728

Merged
merged 2 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3873,6 +3873,39 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
options: localVarRequestOptions,
};
},
/**
*
* @summary Reset encryption key to revoke all authorized codes
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
userRevokeSession: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/user/share/revoke`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}

const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;

// authentication JwtAuth required
await setApiKeyToObject(localVarHeaderParameter, "Authorization", configuration)



setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary Create an impersonation
Expand Down Expand Up @@ -5217,6 +5250,16 @@ export const DefaultApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.userLogin(message, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary Reset encryption key to revoke all authorized codes
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async userRevokeSession(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.userRevokeSession(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary Create an impersonation
Expand Down Expand Up @@ -6274,6 +6317,15 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa
userLogin(message: UserAuthenticateForm, options?: any): AxiosPromise<UserTokenResponse> {
return localVarFp.userLogin(message, options).then((request) => request(axios, basePath));
},
/**
*
* @summary Reset encryption key to revoke all authorized codes
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
userRevokeSession(options?: any): AxiosPromise<void> {
return localVarFp.userRevokeSession(options).then((request) => request(axios, basePath));
},
/**
*
* @summary Create an impersonation
Expand Down Expand Up @@ -8716,6 +8768,17 @@ export class DefaultApi extends BaseAPI {
return DefaultApiFp(this.configuration).userLogin(requestParameters.message, options).then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Reset encryption key to revoke all authorized codes
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof DefaultApi
*/
public userRevokeSession(options?: AxiosRequestConfig) {
return DefaultApiFp(this.configuration).userRevokeSession(options).then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Create an impersonation
Expand Down
16 changes: 16 additions & 0 deletions ui/packages/tidb-dashboard-client/swagger/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -3631,6 +3631,22 @@
}
}
},
"/user/share/revoke": {
"post": {
"security": [
{
"JwtAuth": []
}
],
"summary": "Reset encryption key to revoke all authorized codes",
"operationId": "userRevokeSession",
"responses": {
"200": {
"description": ""
}
}
}
},
"/user/sign_out_info": {
"get": {
"security": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ class DataSource implements IUserProfileDataSource {
userShareSession(request: CodeShareRequest, options?: ReqConfig) {
return client.getInstance().userShareSession({ request }, options)
}

userRevokeSession(options?: ReqConfig) {
return client.getInstance().userRevokeSession(options)
}

metricsGetPromAddress(options?: ReqConfig) {
return client.getInstance().metricsGetPromAddress(options)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ class DataSource implements IUserProfileDataSource {
userShareSession(request: CodeShareRequest, options?: ReqConfig) {
return client.getInstance().userShareSession({ request }, options)
}

userRevokeSession(options?: ReqConfig) {
return client.getInstance().userRevokeSession(options)
}

metricsGetPromAddress(options?: ReqConfig) {
return client.getInstance().metricsGetPromAddress(options)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {
CopyOutlined,
LogoutOutlined,
QuestionCircleOutlined,
RollbackOutlined,
ShareAltOutlined
} from '@ant-design/icons'
import {
Alert,
Button,
Divider,
Form,
message,
Modal,
Select,
Space,
Expand Down Expand Up @@ -40,6 +42,46 @@ const SHARE_SESSION_EXPIRY_HOURS = [
24 * 30
]

function RevokeSessionButton() {
const whoAmI = store.useState((s) => s.whoAmI)
const { t } = useTranslation()
const ctx = useContext(UserProfileContext)

function showRevokeConfirm() {
Modal.confirm({
title: t('user_profile.revoke_modal.title'),
content: t('user_profile.revoke_modal.content'),
okText: t('user_profile.revoke_modal.ok'),
cancelText: t('user_profile.revoke_modal.cancel'),
onOk() {
ctx?.ds.userRevokeSession().then(() => {
message.success(t('user_profile.revoke_modal.success_message'))
})
}
})
}

let button = (
<Button
onClick={showRevokeConfirm}
disabled={!whoAmI || !whoAmI.is_shareable}
>
<RollbackOutlined /> {t('user_profile.session.revoke')}
{Boolean(whoAmI && !whoAmI.is_shareable) && <QuestionCircleOutlined />}
</Button>
)

if (whoAmI && !whoAmI.is_shareable) {
button = (
<Tooltip title={t('user_profile.session.revoke_unavailable_tooltip')}>
{button}
</Tooltip>
)
}

return <>{button}</>
}

function ShareSessionButton() {
const ctx = useContext(UserProfileContext)

Expand Down Expand Up @@ -143,11 +185,6 @@ function ShareSessionButton() {
width={600}
>
<ReactMarkdown>{t('user_profile.share_session.text')}</ReactMarkdown>
<Alert
message={t('user_profile.share_session.warning')}
type="warning"
showIcon
/>
<Divider />
<Form
layout="vertical"
Expand Down Expand Up @@ -216,6 +253,8 @@ export function SessionForm() {
return (
<Space>
<ShareSessionButton />
{/* only available for v8.4.0+, v6.5.11+ */}
<RevokeSessionButton />
<Button danger onClick={handleLogout}>
<LogoutOutlined /> {t('user_profile.session.sign_out')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export interface IUserProfileDataSource {
options?: ReqConfig
): AxiosPromise<CodeShareResponse>

userRevokeSession(options?: ReqConfig): AxiosPromise<void>

metricsGetPromAddress(
options?: ReqConfig
): AxiosPromise<MetricsGetPromAddressConfigResponse>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,20 @@ user_profile:
sign_out: Sign Out
share: Share Current Session
share_unavailable_tooltip: Current session is not allowed to be shared
revoke: Revoke Authorization Codes
revoke_unavailable_tooltip: You have no permission to revoke the authorization codes
share_session:
text: >
You can invite others to access this {{distro.tidb}} Dashboard by sharing your
current session via an **Authorization Code**:

- The Authorization Code can be used multiple times.

- The shared session has the same privilege as your current session.

- The shared session will be invalidated after the expiry time you specified.

- The shared session has the same privilege as your current session.
warning: >
Warning: Shared session will remain valid and cannot be revoked until it is expired.
Keep the Authorization Code safe!
- The shared session can be revoked in advance by administrator.
form:
expire: Expire in
read_only: Share as read-only privilege
Expand All @@ -72,6 +73,12 @@ user_profile:
title: Authorization Code Generated
copy: Copy
copied: Copied
revoke_modal:
title: Are you sure you want to revoke all authorization codes?
content: After revoking, all authorization codes that are authorized before can't be used to login again, and this action can't undo.
ok: Revoke
cancel: Cancel
success_message: Revoke authorization codes successfully!
version:
title: Version Information
internal_version: '{{distro.tidb}} Dashboard Internal Version'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,19 @@ user_profile:
sign_out: 登出
share: 分享当前会话
share_unavailable_tooltip: 当前会话被禁止分享
revoke: 撤消授权码
revoke_unavailable_tooltip: 你没有权限撤消授权码
share_session:
text: >
您可以生成一个**授权码**来将您当前的会话分享给其他人邀请他们使用该 {{distro.tidb}} Dashboard:
您可以生成一个**授权码**来将您当前的会话分享给其他人邀请他们使用该 {{distro.tidb}} Dashboard:

- 授权码可以被重复使用。

- 分享的会话和您当前会话具有相同权限。

- 分享的会话将在您指定的有效时间后过期。

- 分享的会话和您当前会话具有相同权限。
warning: >
警告:已分享的会话无法被提前注销,将保持有效直到有效时间过期,因此请妥善保管授权码。
- 分享的会话可以被管理员提前撤消。
form:
expire: 有效时间
read_only: 以只读权限分享
Expand All @@ -70,6 +72,12 @@ user_profile:
title: 授权码已生成
copy: 复制
copied: 已复制
revoke_modal:
title: 你确定你要撤消所有的授权码吗?
content: 撤消之后,所有之前授权的授权码都不能再用于登录,而且这个操作不能回滚。
ok: 撤消
cancel: 取消
success_message: 撤消授权码成功!
version:
title: 版本信息
internal_version: '{{distro.tidb}} Dashboard 内部版本号'
Expand Down
Loading