Browse Source

Merge pull request #882 from colinin/fix-openiddict

Fix about openiddict
pull/914/head
yx lin 2 years ago
committed by GitHub
parent
commit
40fe0d8bed
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 118
      apps/vue/src/api/openiddict/open-iddict-application/index.ts
  2. 73
      apps/vue/src/api/openiddict/open-iddict-authorization/index.ts
  3. 118
      apps/vue/src/api/openiddict/open-iddict-scope/index.ts
  4. 73
      apps/vue/src/api/openiddict/open-iddict-token/index.ts
  5. 2
      apps/vue/src/views/account/setting/SecureSetting.vue
  6. 38
      apps/vue/src/views/openiddict/applications/components/ApplicationModal.vue
  7. 6
      apps/vue/src/views/openiddict/applications/components/ApplicationScope.vue
  8. 67
      apps/vue/src/views/openiddict/applications/components/ApplicationSecretModal.vue
  9. 36
      apps/vue/src/views/openiddict/applications/components/ApplicationTable.vue
  10. 1
      apps/vue/src/views/openiddict/applications/components/PostLogoutRedirectUri.vue
  11. 1
      apps/vue/src/views/openiddict/applications/components/RedirectUri.vue
  12. 2
      apps/vue/src/views/openiddict/applications/datas/ModalData.ts
  13. 32
      apps/vue/src/views/openiddict/applications/datas/TableData.ts
  14. 34
      apps/vue/src/views/openiddict/authorizations/components/AuthorizationModal.vue
  15. 8
      apps/vue/src/views/openiddict/authorizations/components/AuthorizationTable.vue
  16. 43
      apps/vue/src/views/openiddict/authorizations/datas/ModalData.ts
  17. 3
      apps/vue/src/views/openiddict/components/DisplayNames/DisplayNameForm.vue
  18. 2
      apps/vue/src/views/openiddict/components/Properties/PropertyForm.vue
  19. 272
      apps/vue/src/views/openiddict/scopes/components/ScopeModal.vue
  20. 103
      apps/vue/src/views/openiddict/scopes/components/ScopeTable.vue
  21. 18
      apps/vue/src/views/openiddict/scopes/datas/ModalData.ts
  22. 51
      apps/vue/src/views/openiddict/scopes/datas/TableData.ts
  23. 12
      apps/vue/src/views/openiddict/scopes/types/props.ts
  24. 29
      apps/vue/src/views/openiddict/tokens/components/TokenModal.vue
  25. 6
      apps/vue/src/views/openiddict/tokens/components/TokenTable.vue
  26. 28
      apps/vue/src/views/openiddict/tokens/datas/ModalData.ts
  27. 2
      apps/vue/src/views/openiddict/tokens/datas/TableData.ts
  28. 2
      aspnet-core/LINGYUN.MicroService.All.sln
  29. 3
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationCreateOrUpdateDto.cs
  30. 1
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationDto.cs
  31. 3
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Localization/Resources/en.json
  32. 3
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Localization/Resources/zh-Hans.json
  33. 4
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Permissions/AbpOpenIddictPermissionDefinitionProvider.cs
  34. 1
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Permissions/AbpOpenIddictPermissions.cs
  35. 2
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Scopes/OpenIddictScopeCreateOrUpdateDto.cs
  36. 29
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationAppService.cs
  37. 2
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationExtensions.cs
  38. 8
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Authorizations/OpenIddictAuthorizationAppService.cs
  39. 23
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Scopes/OpenIddictScopeAppService.cs
  40. 10
      aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Tokens/OpenIddictTokenAppService.cs

118
apps/vue/src/api/openiddict/open-iddict-application/index.ts

@ -1,65 +1,99 @@
import { defAbpHttp } from '/@/utils/http/abp';
import { OpenIddictApplicationDto,OpenIddictApplicationGetListInput, OpenIddictApplicationCreateDto, OpenIddictApplicationUpdateDto, } from './model';
import {
OpenIddictApplicationDto,
OpenIddictApplicationGetListInput,
OpenIddictApplicationCreateDto,
OpenIddictApplicationUpdateDto,
} from './model';
const remoteServiceName = 'AbpOpenIddict';
const controllerName = 'OpenIddictApplication';
// export const GetAsyncById = (id: string) => {
// return defAbpHttp.request<OpenIddictApplicationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetAsync',
// uniqueName: 'GetAsyncById',
// params: {
// id: id,
// },
// });
// };
export const GetAsyncById = (id: string) => {
return defAbpHttp.request<OpenIddictApplicationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetAsync',
uniqueName: 'GetAsyncById',
params: {
id: id,
},
return defAbpHttp.get<OpenIddictApplicationDto>({
url: `/api/openiddict/applications/${id}`,
});
};
// export const GetListAsyncByInput = (input: OpenIddictApplicationGetListInput) => {
// return defAbpHttp.pagedRequest<OpenIddictApplicationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetListAsync',
// uniqueName: 'GetListAsyncByInput',
// params: {
// input: input,
// },
// });
// };
export const GetListAsyncByInput = (input: OpenIddictApplicationGetListInput) => {
return defAbpHttp.pagedRequest<OpenIddictApplicationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetListAsync',
uniqueName: 'GetListAsyncByInput',
params: {
input: input,
},
return defAbpHttp.get<PagedResultDto<OpenIddictApplicationDto>>({
url: '/api/openiddict/applications',
params: input,
});
};
// export const CreateAsyncByInput = (input: OpenIddictApplicationCreateDto) => {
// return defAbpHttp.request<OpenIddictApplicationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'CreateAsync',
// uniqueName: 'CreateAsyncByInput',
// data: input,
// });
// };
export const CreateAsyncByInput = (input: OpenIddictApplicationCreateDto) => {
return defAbpHttp.request<OpenIddictApplicationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'CreateAsync',
uniqueName: 'CreateAsyncByInput',
return defAbpHttp.post<OpenIddictApplicationDto>({
url: '/api/openiddict/applications',
data: input,
});
};
// export const UpdateAsyncByIdAndInput = (id: string, input: OpenIddictApplicationUpdateDto) => {
// return defAbpHttp.request<OpenIddictApplicationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'UpdateAsync',
// uniqueName: 'UpdateAsyncByIdAndInput',
// params: {
// id: id,
// },
// data: input,
// });
// };
export const UpdateAsyncByIdAndInput = (id: string, input: OpenIddictApplicationUpdateDto) => {
return defAbpHttp.request<OpenIddictApplicationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'UpdateAsync',
uniqueName: 'UpdateAsyncByIdAndInput',
params: {
id: id,
},
return defAbpHttp.put<OpenIddictApplicationDto>({
url: `/api/openiddict/applications/${id}`,
data: input,
});
};
// export const DeleteAsyncById = (id: string) => {
// return defAbpHttp.request<void>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'DeleteAsync',
// uniqueName: 'DeleteAsyncById',
// params: {
// id: id,
// },
// });
// };
export const DeleteAsyncById = (id: string) => {
return defAbpHttp.request<void>({
service: remoteServiceName,
controller: controllerName,
action: 'DeleteAsync',
uniqueName: 'DeleteAsyncById',
params: {
id: id,
},
return defAbpHttp.delete<void>({
url: `/api/openiddict/applications/${id}`,
});
};
};

73
apps/vue/src/api/openiddict/open-iddict-authorization/index.ts

@ -1,42 +1,57 @@
import { defAbpHttp } from '/@/utils/http/abp';
import { OpenIddictAuthorizationDto,OpenIddictAuthorizationGetListInput, } from './model';
import { OpenIddictAuthorizationDto, OpenIddictAuthorizationGetListInput, } from './model';
const remoteServiceName = 'AbpOpenIddict';
const controllerName = 'OpenIddictAuthorization';
// export const DeleteAsyncById = (id: string) => {
// return defAbpHttp.request<void>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'DeleteAsync',
// uniqueName: 'DeleteAsyncById',
// params: {
// id: id,
// },
// });
// };
export const DeleteAsyncById = (id: string) => {
return defAbpHttp.request<void>({
service: remoteServiceName,
controller: controllerName,
action: 'DeleteAsync',
uniqueName: 'DeleteAsyncById',
params: {
id: id,
},
return defAbpHttp.delete<void>({
url: `/api/openiddict/authorizations/${id}`,
});
};
// export const GetAsyncById = (id: string) => {
// return defAbpHttp.request<OpenIddictAuthorizationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetAsync',
// uniqueName: 'GetAsyncById',
// params: {
// id: id,
// },
// });
// };
export const GetAsyncById = (id: string) => {
return defAbpHttp.request<OpenIddictAuthorizationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetAsync',
uniqueName: 'GetAsyncById',
params: {
id: id,
},
return defAbpHttp.get<OpenIddictAuthorizationDto>({
url: `/api/openiddict/authorizations/${id}`,
});
};
// export const GetListAsyncByInput = (input: OpenIddictAuthorizationGetListInput) => {
// return defAbpHttp.pagedRequest<OpenIddictAuthorizationDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetListAsync',
// uniqueName: 'GetListAsyncByInput',
// params: {
// input: input,
// },
// });
// };
export const GetListAsyncByInput = (input: OpenIddictAuthorizationGetListInput) => {
return defAbpHttp.pagedRequest<OpenIddictAuthorizationDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetListAsync',
uniqueName: 'GetListAsyncByInput',
params: {
input: input,
},
return defAbpHttp.get<PagedResultDto<OpenIddictAuthorizationDto>>({
url: '/api/openiddict/authorizations',
params: input,
});
};
};

118
apps/vue/src/api/openiddict/open-iddict-scope/index.ts

@ -1,65 +1,99 @@
import { defAbpHttp } from '/@/utils/http/abp';
import { OpenIddictScopeCreateDto, OpenIddictScopeDto,OpenIddictScopeGetListInput, OpenIddictScopeUpdateDto, } from './model';
import {
OpenIddictScopeCreateDto,
OpenIddictScopeDto,
OpenIddictScopeGetListInput,
OpenIddictScopeUpdateDto,
} from './model';
const remoteServiceName = 'AbpOpenIddict';
const controllerName = 'OpenIddictScope';
// export const CreateAsyncByInput = (input: OpenIddictScopeCreateDto) => {
// return defAbpHttp.request<OpenIddictScopeDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'CreateAsync',
// uniqueName: 'CreateAsyncByInput',
// data: input,
// });
// };
export const CreateAsyncByInput = (input: OpenIddictScopeCreateDto) => {
return defAbpHttp.request<OpenIddictScopeDto>({
service: remoteServiceName,
controller: controllerName,
action: 'CreateAsync',
uniqueName: 'CreateAsyncByInput',
return defAbpHttp.post<OpenIddictScopeDto>({
url: '/api/openiddict/scopes',
data: input,
});
};
// export const DeleteAsyncById = (id: string) => {
// return defAbpHttp.request<void>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'DeleteAsync',
// uniqueName: 'DeleteAsyncById',
// params: {
// id: id,
// },
// });
// };
export const DeleteAsyncById = (id: string) => {
return defAbpHttp.request<void>({
service: remoteServiceName,
controller: controllerName,
action: 'DeleteAsync',
uniqueName: 'DeleteAsyncById',
params: {
id: id,
},
return defAbpHttp.delete<void>({
url: `/api/openiddict/scopes/${id}`
});
};
// export const GetAsyncById = (id: string) => {
// return defAbpHttp.request<OpenIddictScopeDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetAsync',
// uniqueName: 'GetAsyncById',
// params: {
// id: id,
// },
// });
// };
export const GetAsyncById = (id: string) => {
return defAbpHttp.request<OpenIddictScopeDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetAsync',
uniqueName: 'GetAsyncById',
params: {
id: id,
},
return defAbpHttp.get<OpenIddictScopeDto>({
url: `/api/openiddict/scopes/${id}`
});
};
// export const GetListAsyncByInput = (input: OpenIddictScopeGetListInput) => {
// return defAbpHttp.pagedRequest<OpenIddictScopeDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetListAsync',
// uniqueName: 'GetListAsyncByInput',
// params: {
// input: input,
// },
// });
// };
export const GetListAsyncByInput = (input: OpenIddictScopeGetListInput) => {
return defAbpHttp.pagedRequest<OpenIddictScopeDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetListAsync',
uniqueName: 'GetListAsyncByInput',
params: {
input: input,
},
return defAbpHttp.get<PagedResultDto<OpenIddictScopeDto>>({
url: '/api/openiddict/scopes',
params: input,
});
};
// export const UpdateAsyncByIdAndInput = (id: string, input: OpenIddictScopeUpdateDto) => {
// return defAbpHttp.request<OpenIddictScopeDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'UpdateAsync',
// uniqueName: 'UpdateAsyncByIdAndInput',
// params: {
// id: id,
// },
// data: input,
// });
// };
export const UpdateAsyncByIdAndInput = (id: string, input: OpenIddictScopeUpdateDto) => {
return defAbpHttp.request<OpenIddictScopeDto>({
service: remoteServiceName,
controller: controllerName,
action: 'UpdateAsync',
uniqueName: 'UpdateAsyncByIdAndInput',
params: {
id: id,
},
return defAbpHttp.put<OpenIddictScopeDto>({
url: `/api/openiddict/scopes/${id}`,
data: input,
});
};
};

73
apps/vue/src/api/openiddict/open-iddict-token/index.ts

@ -1,42 +1,57 @@
import { defAbpHttp } from '/@/utils/http/abp';
import { OpenIddictTokenDto,OpenIddictTokenGetListInput, } from './model';
import { OpenIddictTokenDto, OpenIddictTokenGetListInput, } from './model';
const remoteServiceName = 'AbpOpenIddict';
const controllerName = 'OpenIddictToken';
// export const DeleteAsyncById = (id: string) => {
// return defAbpHttp.request<void>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'DeleteAsync',
// uniqueName: 'DeleteAsyncById',
// params: {
// id: id,
// },
// });
// };
export const DeleteAsyncById = (id: string) => {
return defAbpHttp.request<void>({
service: remoteServiceName,
controller: controllerName,
action: 'DeleteAsync',
uniqueName: 'DeleteAsyncById',
params: {
id: id,
},
return defAbpHttp.delete<void>({
url: `/api/openiddict/tokens/${id}`,
});
};
// export const GetAsyncById = (id: string) => {
// return defAbpHttp.request<OpenIddictTokenDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetAsync',
// uniqueName: 'GetAsyncById',
// params: {
// id: id,
// },
// });
// };
export const GetAsyncById = (id: string) => {
return defAbpHttp.request<OpenIddictTokenDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetAsync',
uniqueName: 'GetAsyncById',
params: {
id: id,
},
return defAbpHttp.get<OpenIddictTokenDto>({
url: `/api/openiddict/tokens/${id}`,
});
};
// export const GetListAsyncByInput = (input: OpenIddictTokenGetListInput) => {
// return defAbpHttp.pagedRequest<OpenIddictTokenDto>({
// service: remoteServiceName,
// controller: controllerName,
// action: 'GetListAsync',
// uniqueName: 'GetListAsyncByInput',
// params: {
// input: input,
// },
// });
// };
export const GetListAsyncByInput = (input: OpenIddictTokenGetListInput) => {
return defAbpHttp.pagedRequest<OpenIddictTokenDto>({
service: remoteServiceName,
controller: controllerName,
action: 'GetListAsync',
uniqueName: 'GetListAsyncByInput',
params: {
input: input,
},
return defAbpHttp.get<PagedResultDto<OpenIddictTokenDto>>({
url: '/api/openiddict/tokens',
params: input,
});
};
};

2
apps/vue/src/views/account/setting/SecureSetting.vue

@ -78,7 +78,7 @@
case 'email':
sendEmailConfirmLink({
email: item.description,
appName: 'STS',
appName: 'VueVbenAdmin',
returnUrl: window.location.href,
}).finally(() => {
item.loading = false;

38
apps/vue/src/views/openiddict/applications/components/ApplicationModal.vue

@ -22,7 +22,10 @@
<Input :disabled="state.isEdit" v-model:value="state.application.clientId" />
</FormItem>
<FormItem name="type" :label="L('DisplayName:Type')">
<Input v-model:value="state.application.type" />
<Select :disabled="state.isEdit" default-value="public" :options="clientTypes" v-model:value="state.application.type" />
</FormItem>
<FormItem v-if="getShowSecret" name="clientSecret" :label="L('DisplayName:ClientSecret')">
<Input v-model:value="state.application.clientSecret" />
</FormItem>
<FormItem name="clientUri" :label="L('DisplayName:ClientUri')">
<Input v-model:value="state.application.clientUri" />
@ -36,7 +39,7 @@
:label-col="{ span: 4 }"
:wrapper-col="{ span: 20 }"
>
<Select :options="consentTypes" v-model:value="state.application.consentType" />
<Select :options="consentTypes" default-value="explicit" v-model:value="state.application.consentType" />
</FormItem>
</TabPane>
<!-- DisplayName -->
@ -157,7 +160,7 @@
const MenuItem = Menu.Item;
const emits = defineEmits(['register', 'change']);
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { ruleCreator } = useValidation();
const { createMessage, createConfirm } = useMessage();
const componentsRef = shallowRef({
@ -173,6 +176,19 @@
formRules: {
clientId: ruleCreator.fieldRequired({
name: 'ClientId',
prefix: 'DisplayName',
resourceName: 'AbpOpenIddict',
trigger: 'blur',
}),
clientSecret: ruleCreator.fieldRequired({
name: 'ClientSecret',
prefix: 'DisplayName',
resourceName: 'AbpOpenIddict',
trigger: 'blur',
}),
displayName: ruleCreator.fieldRequired({
name: 'DisplayName',
prefix: 'DisplayName',
resourceName: 'AbpOpenIddict',
trigger: 'blur',
}),
@ -191,6 +207,10 @@
deep: true,
},
);
const clientTypes = reactive([
{ label: 'public', value: 'public' },
{ label: 'confidential', value: 'confidential' },
]);
const consentTypes = reactive([
{ label: 'explicit', value: 'explicit' },
{ label: 'external', value: 'external' },
@ -205,6 +225,9 @@
{ label: 'revocation', value: 'revocation' },
{ label: 'introspection', value: 'introspection' },
]);
const getShowSecret = computed(() => {
return !state.isEdit && state.application.type === 'confidential';
});
const grantTypes = computed(() => {
if (!state.openIdConfiguration) return[];
const types = state.openIdConfiguration.grant_types_supported;
@ -293,9 +316,7 @@
return;
}
const index = state.application.postLogoutRedirectUris.findIndex(logoutUri => logoutUri === uri);
if (!index) {
state.application.postLogoutRedirectUris.splice(index);
}
index && state.application.postLogoutRedirectUris.splice(index);
}
function handleNewRedirectUri(uri: string) {
@ -311,9 +332,7 @@
return;
}
const index = state.application.redirectUris.findIndex(redirectUri => redirectUri === uri);
if (!index) {
state.application.redirectUris.splice(index);
}
index && state.application.redirectUris.splice(index);
}
function handleNewDisplayName(record) {
@ -370,7 +389,6 @@
}
function handleBeforeClose(): Promise<boolean> {
console.log(state);
return new Promise((resolve) => {
if (!state.entityChanged) {
return resolve(true);

6
apps/vue/src/views/openiddict/applications/components/ApplicationScope.vue

@ -35,7 +35,11 @@
title: scope,
}
});
supportScopes.push(...resources);
resources.forEach((resource) => {
if (!supportScopes.find((scope) => scope.key === resource.key)) {
supportScopes.push(resource);
}
});
return supportScopes;
}
return resources;

67
apps/vue/src/views/openiddict/applications/components/ApplicationSecretModal.vue

@ -0,0 +1,67 @@
<template>
<BasicModal
:title="L('ManageSecret')"
@register="registerModal"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { BasicForm, useForm } from '/@/components/Form';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { useMessage } from '/@/hooks/web/useMessage';
import { UpdateAsyncByIdAndInput } from '/@/api/openiddict/open-iddict-application';
import { OpenIddictApplicationUpdateDto } from '/@/api/openiddict/open-iddict-application/model';
const state = reactive<{
application: Recordable
}>({
application: {},
});
const emits = defineEmits(['change', 'register']);
const { createMessage } = useMessage();
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const [registerForm, { validate, resetFields }] = useForm({
layout: 'vertical',
showActionButtonGroup: false,
schemas: [
{
field: 'clientSecret',
component: 'Input',
label: L('DisplayName:ClientSecret'),
colProps: { span: 24 },
required: true,
},
],
});
const [registerModal, { changeOkLoading, closeModal }] = useModalInner((data) => {
state.application = data;
});
function handleSubmit() {
validate().then((input) => {
changeOkLoading(true);
UpdateAsyncByIdAndInput(
state.application.id,
{
...state.application as OpenIddictApplicationUpdateDto,
clientSecret: input.clientSecret
}).then((dto) => {
createMessage.success(L('Successful'));
resetFields();
emits('change', dto);
closeModal();
}).finally(() => {
changeOkLoading(false);
});
});
}
</script>
<style scoped>
</style>

36
apps/vue/src/views/openiddict/applications/components/ApplicationTable.vue

@ -35,21 +35,28 @@
label: L('ManagePermissions'),
onClick: handlePermission.bind(null, record),
},
{
//auth: 'AbpOpenIddict.Applications.ManageSecret',
label: L('GenerateSecret'),
ifShow: getShowSecret(record),
onClick: handleGenerateSecret.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<ApplicationModal @register="registerModal" @change="reload" />
<ApplicationSecretModal @register="registerSecretModal" @change="reload" />
<PermissionModal @register="registerPermissionModal" />
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { Button } from 'ant-design-vue';
import { BasicTable, TableAction, useTable } from '/@/components/Table';
import { getDataColumns } from '../datas/TableData';
import { getSearchFormProps } from '../datas/ModalData';
import { useModal } from '/@/components/Modal';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
@ -57,10 +64,12 @@
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import { PermissionModal } from '/@/components/Permission';
import ApplicationModal from './ApplicationModal.vue';
import ApplicationSecretModal from './ApplicationSecretModal.vue';
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerSecretModal, { openModal: openSecretModal }] = useModal();
const [registerPermissionModal, { openModal: openPermissionModal }] = useModal();
const [registerTable, { reload }] = useTable({
rowKey: 'id',
@ -73,7 +82,17 @@
useSearchForm: true,
showIndexColumn: false,
showTableSetting: true,
formConfig: getSearchFormProps(),
formConfig: {
labelWidth: 100,
schemas: [
{
field: 'filter',
component: 'Input',
label: L('Search'),
colProps: { span: 24 },
},
],
},
bordered: true,
canResize: true,
immediate: true,
@ -83,6 +102,11 @@
dataIndex: 'action',
},
});
const getShowSecret = computed(() => {
return (record) => {
return record.type === 'confidential';
};
});
function handleAddNew() {
openModal(true, {});
@ -92,6 +116,10 @@
openModal(true, record);
}
function handleGenerateSecret(record) {
openSecretModal(true, record);
}
function handlePermission(record) {
const props = {
providerName: 'C',
@ -106,7 +134,7 @@
title: L('AreYouSure'),
content: L('ItemWillBeDeletedMessage'),
onOk: () => {
return DeleteAsyncById(record.key).then(() => {
return DeleteAsyncById(record.id).then(() => {
createMessage.success(L('SuccessfullyDeleted'));
reload();
});

1
apps/vue/src/views/openiddict/applications/components/PostLogoutRedirectUri.vue

@ -38,7 +38,6 @@
component: 'Input',
label: 'Uri',
colProps: { span: 24 },
required: true,
},
];
const columns: BasicColumn[] = [

1
apps/vue/src/views/openiddict/applications/components/RedirectUri.vue

@ -38,7 +38,6 @@
component: 'Input',
label: 'Uri',
colProps: { span: 24 },
required: true,
},
];
const columns: BasicColumn[] = [

2
apps/vue/src/views/openiddict/applications/datas/ModalData.ts

@ -1,7 +1,7 @@
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { FormProps } from '/@/components/Form';
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
export function getSearchFormProps(): Partial<FormProps> {
return {

32
apps/vue/src/views/openiddict/applications/datas/TableData.ts

@ -13,14 +13,6 @@ export function getDataColumns(): BasicColumn[] {
sorter: true,
resizable: true,
},
{
title: L('DisplayName:ClientSecret'),
dataIndex: 'clientSecret',
align: 'left',
width: 200,
sorter: true,
resizable: true,
},
{
title: L('DisplayName:DisplayName'),
dataIndex: 'displayName',
@ -36,5 +28,29 @@ export function getDataColumns(): BasicColumn[] {
sorter: true,
resizable: true,
},
{
title: L('DisplayName:Type'),
dataIndex: 'type',
align: 'left',
width: 120,
sorter: true,
resizable: true,
},
{
title: L('DisplayName:ClientUri'),
dataIndex: 'clientUri',
align: 'left',
width: 150,
sorter: true,
resizable: true,
},
{
title: L('DisplayName:LogoUri'),
dataIndex: 'logoUri',
align: 'left',
width: 120,
sorter: true,
resizable: true,
},
];
}

34
apps/vue/src/views/openiddict/authorizations/components/AuthorizationModal.vue

@ -7,20 +7,31 @@
:width="800"
:height="500"
>
<BasicForm @register="registerForm" />
<BasicForm @register="registerForm">
<template #scopes="{ model, field }">
<Select mode="tags" :value="model[field]" :disabled="true">
<Option v-for="scope in model[field]" :key="scope" :title="scope" :value="scope" />
</Select>
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { nextTick } from 'vue';
import { Select } from 'ant-design-vue';
import { BasicForm, useForm } from '/@/components/Form';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { getModalFormSchemas } from '../datas/ModalData';
import { formatToDateTime } from '/@/utils/dateUtil';
import { GetAsyncById } from '/@/api/openiddict/open-iddict-authorization';
import { OpenIddictAuthorizationDto } from '/@/api/openiddict/open-iddict-authorization/model';
import { GetAsyncById as getAuthorization } from '/@/api/openiddict/open-iddict-authorization';
import { GetAsyncById as getApplication } from '/@/api/openiddict/open-iddict-application';
const { L } = useLocalization('AbpOpenIddict');
const Option = Select.Option;
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const [registerForm, { setFieldsValue, resetFields }] = useForm({
layout: 'vertical',
showActionButtonGroup: false,
@ -32,13 +43,22 @@
const [registerModal] = useModalInner((data) => {
nextTick(() => {
resetFields();
fetchToken(data.id);
fetchAuth(data.id);
});
});
function fetchToken(id: string) {
GetAsyncById(id).then((token) => {
setFieldsValue(token);
function fetchAuth(id: string) {
getAuthorization(id).then((dto) => {
setFieldsValue(dto);
fetchApplication(dto);
});
}
function fetchApplication(auth: OpenIddictAuthorizationDto) {
auth.applicationId && getApplication(auth.applicationId).then((dto) => {
setFieldsValue({
applicationId: `${dto.clientId}(${auth.applicationId})`,
});
});
}
</script>

8
apps/vue/src/views/openiddict/authorizations/components/AuthorizationTable.vue

@ -7,13 +7,13 @@
:stop-button-propagation="true"
:actions="[
{
//auth: 'AbpOpenIddict.Authorizations.Update',
auth: 'AbpOpenIddict.Authorizations',
label: L('Edit'),
icon: 'ant-design:edit-outlined',
onClick: handleEdit.bind(null, record),
},
{
//auth: 'AbpOpenIddict.Authorizations.Delete',
auth: 'AbpOpenIddict.Authorizations.Delete',
label: L('Delete'),
color: 'error',
icon: 'ant-design:delete-outlined',
@ -39,7 +39,7 @@
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import AuthorizationModal from './AuthorizationModal.vue';
const { L } = useLocalization('AbpOpenIddict');
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload }] = useTable({
@ -74,7 +74,7 @@
title: L('AreYouSure'),
content: L('ItemWillBeDeletedMessage'),
onOk: () => {
return DeleteAsyncById(record.key).then(() => {
return DeleteAsyncById(record.id).then(() => {
createMessage.success(L('SuccessfullyDeleted'));
reload();
});

43
apps/vue/src/views/openiddict/authorizations/datas/ModalData.ts

@ -2,7 +2,7 @@ import { useLocalization } from '/@/hooks/abp/useLocalization';
import { FormProps, FormSchema } from '/@/components/Form';
import { GetListAsyncByInput as getApplications } from '/@/api/openiddict/open-iddict-application';
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
export function getSearchFormProps(): Partial<FormProps> {
return {
@ -104,51 +104,28 @@ export function getModalFormSchemas(): FormSchema[] {
},
},
{
field: 'expirationDate',
component: 'Input',
label: L('DisplayName:ExpirationDate'),
colProps: { span: 24 },
componentProps: {
readonly: true,
},
},
{
field: 'redemptionDate',
component: 'Input',
label: L('DisplayName:RedemptionDate'),
colProps: { span: 24 },
componentProps: {
readonly: true,
},
},
{
field: 'referenceId',
field: 'status',
component: 'Input',
label: L('DisplayName:ReferenceId'),
label: L('DisplayName:Status'),
colProps: { span: 24 },
componentProps: {
readonly: true,
},
},
{
field: 'status',
component: 'Input',
label: L('DisplayName:Status'),
field: 'scopes',
component: 'Select',
label: L('DisplayName:Scopes'),
colProps: { span: 24 },
componentProps: {
readonly: true,
},
slot: 'scopes',
},
{
field: 'payload',
component: 'InputTextArea',
label: L('DisplayName:Payload'),
field: 'properties',
component: 'CodeEditorX',
label: L('DisplayName:Properties'),
colProps: { span: 24 },
componentProps: {
readonly: true,
autoSize: {
minRows: 5,
},
},
},
];

3
apps/vue/src/views/openiddict/components/DisplayNames/DisplayNameForm.vue

@ -114,9 +114,6 @@
});
function handleSubmit(input) {
if (!props.displayNames && !props.displayNames[input.culture]) {
return;
}
emits('create', input);
resetFields();
}

2
apps/vue/src/views/openiddict/components/Properties/PropertyForm.vue

@ -41,7 +41,7 @@
},
});
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const title = ref('');
const [registerForm, { validate, resetFields }] = useForm({
labelWidth: 120,

272
apps/vue/src/views/openiddict/scopes/components/ScopeModal.vue

@ -1,10 +1,272 @@
<template>
<div>
</div>
<BasicModal
@register="registerModal"
:title="L('Scopes')"
:can-fullscreen="false"
:width="800"
:height="500"
:close-func="handleBeforeClose"
@ok="handleSubmit"
>
<Form
ref="formRef"
:model="state.formModel"
:rules="state.formRules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
>
<Tabs v-model:active-key="state.activeTab">
<!-- Basic -->
<TabPane key="basic" :tab="L('BasicInfo')">
<FormItem name="name" :label="L('DisplayName:Name')">
<Input v-model:value="state.formModel.name" />
</FormItem>
</TabPane>
<!-- DisplayName -->
<TabPane key="description" :tab="L('Descriptions')">
<FormItem name="description" :label="L('DisplayName:DefaultDescription')">
<Input v-model:value="state.formModel.description" />
</FormItem>
<DisplayNameForm
:displayNames="state.formModel.descriptions"
@create="handleNewDescription"
@delete="handleDelDescription"
/>
</TabPane>
<!-- DisplayName -->
<TabPane key="displayName" :tab="L('DisplayNames')">
<FormItem name="displayName" :label="L('DisplayName:DefaultDisplayName')">
<Input v-model:value="state.formModel.displayName" />
</FormItem>
<DisplayNameForm
:displayNames="state.formModel.displayNames"
@create="handleNewDisplayName"
@delete="handleDelDisplayName"
/>
</TabPane>
<!-- Resources -->
<TabPane key="resources" :tab="L('Resources')">
<PermissionForm
:resources="getSupportResources"
:targetResources="targetResources"
@change="handleResourceChange"
/>
</TabPane>
<!-- Propertites -->
<TabPane key="propertites" :tab="L('Propertites')">
<PropertyForm
:properties="state.formModel.properties"
@create="handleNewProperty"
@delete="handleDelProperty"
/>
</TabPane>
</Tabs>
</Form>
</BasicModal>
</template>
<script lang="ts" setup>
</script>
import type { FormInstance } from 'ant-design-vue/lib/form';
import { cloneDeep } from 'lodash-es';
import { computed, nextTick, ref, unref, reactive, watch, onMounted } from 'vue';
import { Form, Input, Tabs } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { useMessage } from '/@/hooks/web/useMessage';
import { useValidation } from '/@/hooks/abp/useValidation';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { ScopeState } from '../types/props';
import { GetAsyncById, CreateAsyncByInput, UpdateAsyncByIdAndInput } from '/@/api/openiddict/open-iddict-scope';
import { OpenIddictScopeDto } from '/@/api/openiddict/open-iddict-scope/model';
import { discovery } from '/@/api/identity-server/identityServer';
import DisplayNameForm from '../../components/DisplayNames/DisplayNameForm.vue';
import PropertyForm from '../../components/Properties/PropertyForm.vue';
import PermissionForm from '../../components/Permissions/PermissionForm.vue';
const FormItem = Form.Item;
const TabPane = Tabs.TabPane;
const emits = defineEmits(['register', 'change']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { ruleCreator } = useValidation();
const { createMessage, createConfirm } = useMessage();
const formRef = ref<FormInstance>();
const state = reactive<ScopeState>({
activeTab: 'basic',
isEdit: false,
entityChanged: false,
formModel: {} as OpenIddictScopeDto,
formRules: {
name: ruleCreator.fieldRequired({
name: 'Name',
prefix: 'DisplayName',
resourceName: 'AbpOpenIddict',
trigger: 'blur',
}),
},
});
watch(
() => state.formModel,
() => {
state.entityChanged = true;
},
{
deep: true,
},
);
const targetResources = computed(() => {
if (!state.formModel.resources) return [];
const targetScopes = getSupportResources.value.filter((item) =>
state.formModel.resources?.some((scope) => scope === item.key),
);
return targetScopes.map((item) => item.key);
});
const getSupportResources = computed(() => {
if (state.openIdConfiguration?.claims_supported) {
const supportResources = state.openIdConfiguration?.claims_supported.map(claim => {
return {
key: claim,
title: claim,
}
});
return supportResources;
}
return [];
});
const [registerModal, { changeLoading, changeOkLoading, closeModal }] = useModalInner((data) => {
nextTick(() => {
fetch(data?.id);
});
});
onMounted(initOpenidDiscovery);
function initOpenidDiscovery() {
discovery().then((openIdConfiuration) => {
state.openIdConfiguration = openIdConfiuration;
});
}
function fetch(id?: string) {
state.activeTab = 'basic';
state.isEdit = false;
state.entityChanged = false;
state.formModel = {} as OpenIddictScopeDto;
const form = unref(formRef);
form?.resetFields();
if (!id) {
nextTick(() => {
state.isEdit = false;
state.entityChanged = false;
});
return;
}
changeLoading(true);
GetAsyncById(id).then((scope) => {
state.formModel = scope;
nextTick(() => {
state.isEdit = true;
state.entityChanged = false;
});
}).finally(() => {
changeLoading(false);
});
}
function handleResourceChange(_, direction, moveKeys: string[]) {
switch (direction) {
case 'left':
moveKeys.forEach((key) => {
const index = state.formModel.resources?.findIndex(r => r === key);
index && state.formModel.resources?.splice(index);
});
break;
case 'right':
state.formModel.resources ??= [];
state.formModel.resources.push(...moveKeys);
break;
}
}
<style lang="less" scoped>
</style>
function handleNewDisplayName(record) {
if (!state.formModel) {
return;
}
state.formModel.displayNames ??= {};
state.formModel.displayNames[record.culture] = record.displayName;
}
function handleDelDisplayName(record) {
if (!state.formModel || !state.formModel.displayNames) {
return;
}
delete state.formModel.displayNames[record.culture];
}
function handleNewDescription(record) {
if (!state.formModel) {
return;
}
state.formModel.descriptions ??= {};
state.formModel.descriptions[record.culture] = record.displayName;
}
function handleDelDescription(record) {
if (!state.formModel || !state.formModel.descriptions) {
return;
}
delete state.formModel.descriptions[record.culture];
}
function handleNewProperty(record) {
if (!state.formModel) {
return;
}
state.formModel.properties ??= {};
state.formModel.properties[record.key] = record.value;
}
function handleDelProperty(record) {
if (!state.formModel || !state.formModel.properties) {
return;
}
delete state.formModel.properties[record.key];
}
function handleBeforeClose(): Promise<boolean> {
return new Promise((resolve) => {
if (!state.entityChanged) {
return resolve(true);
}
createConfirm({
iconType: 'warning',
title: L('AreYouSure'),
content: L('AreYouSureYouWantToCancelEditingWarningMessage'),
onOk: () => {
resolve(true);
},
onCancel: () => {
resolve(false);
}
});
});
}
function handleSubmit() {
const form = unref(formRef);
form?.validate().then(() => {
changeOkLoading(true);
console.log(state.formModel);
const api = state.formModel.id
? UpdateAsyncByIdAndInput(state.formModel.id, cloneDeep(state.formModel))
: CreateAsyncByInput(cloneDeep(state.formModel));
api.then((res) => {
createMessage.success(L('Successful'));
emits('change', res);
closeModal();
}).finally(() => {
changeOkLoading(false);
})
});
}
</script>

103
apps/vue/src/views/openiddict/scopes/components/ScopeTable.vue

@ -1,10 +1,107 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<Button
v-auth="['AbpOpenIddict.Scopes.Create']"
type="primary"
@click="handleAddNew"
>
{{ L('Scopes:AddNew') }}
</Button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:stop-button-propagation="true"
:actions="[
{
auth: 'AbpOpenIddict.Scopes.Update',
label: L('Edit'),
icon: 'ant-design:edit-outlined',
onClick: handleEdit.bind(null, record),
},
{
auth: 'AbpOpenIddict.Scopes.Delete',
label: L('Delete'),
color: 'error',
icon: 'ant-design:delete-outlined',
onClick: handleDelete.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
<ScopeModal @register="registerModal" @change="reload" />
</div>
</template>
<script lang="ts" setup>
</script>
import { Button } from 'ant-design-vue';
import { BasicTable, TableAction, useTable } from '/@/components/Table';
import { getDataColumns } from '../datas/TableData';
import { useModal } from '/@/components/Modal';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { GetListAsyncByInput, DeleteAsyncById } from '/@/api/openiddict/open-iddict-scope';
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import ScopeModal from './ScopeModal.vue';
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload }] = useTable({
rowKey: 'id',
title: L('Scopes'),
api: GetListAsyncByInput,
columns: getDataColumns(),
beforeFetch: formatPagedRequest,
pagination: true,
striped: false,
useSearchForm: true,
showIndexColumn: false,
showTableSetting: true,
formConfig: {
labelWidth: 100,
schemas: [
{
field: 'filter',
component: 'Input',
label: L('Search'),
colProps: { span: 24 },
},
],
},
bordered: true,
canResize: true,
immediate: true,
actionColumn: {
width: 150,
title: L('Actions'),
dataIndex: 'action',
},
});
function handleAddNew() {
openModal(true, {});
}
<style lang="less" scoped>
</style>
function handleEdit(record) {
openModal(true, record);
}
function handleDelete(record) {
createConfirm({
iconType: 'warning',
title: L('AreYouSure'),
content: L('ItemWillBeDeletedMessage'),
onOk: () => {
return DeleteAsyncById(record.id).then(() => {
createMessage.success(L('SuccessfullyDeleted'));
reload();
});
},
});
}
</script>

18
apps/vue/src/views/openiddict/scopes/datas/ModalData.ts

@ -0,0 +1,18 @@
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { FormProps } from '/@/components/Form';
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
export function getSearchFormProps(): Partial<FormProps> {
return {
labelWidth: 100,
schemas: [
{
field: 'filter',
component: 'Input',
label: L('Search'),
colProps: { span: 24 },
},
],
};
}

51
apps/vue/src/views/openiddict/scopes/datas/TableData.ts

@ -0,0 +1,51 @@
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { BasicColumn } from '/@/components/Table';
import { formatToDateTime } from '/@/utils/dateUtil';
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
export function getDataColumns(): BasicColumn[] {
return [
{
title: L('DisplayName:ConcurrencyStamp'),
dataIndex: 'concurrencyStamp',
align: 'left',
width: 1,
ifShow: false,
},
{
title: L('DisplayName:Name'),
dataIndex: 'name',
align: 'left',
width: 150,
sorter: true,
resizable: true,
},
{
title: L('DisplayName:DisplayName'),
dataIndex: 'displayName',
align: 'left',
width: 180,
sorter: true,
},
{
title: L('DisplayName:Description'),
dataIndex: 'description',
align: 'left',
width: 200,
sorter: true,
resizable: true,
},
{
title: L('DisplayName:CreationDate'),
dataIndex: 'creationTime',
align: 'left',
width: 200,
sorter: true,
resizable: true,
format: (text?: string) => {
return text ? formatToDateTime(text) : '';
},
},
];
}

12
apps/vue/src/views/openiddict/scopes/types/props.ts

@ -0,0 +1,12 @@
import { Rule } from 'ant-design-vue/lib/form';
import { OpenIdConfiguration } from '/@/api/identity-server/model/basicModel';
import { OpenIddictScopeDto } from '/@/api/openiddict/open-iddict-scope/model';
export interface ScopeState {
activeTab: string;
formRules?: Dictionary<string, Rule>,
formModel: OpenIddictScopeDto;
openIdConfiguration?: OpenIdConfiguration,
entityChanged: boolean;
isEdit: boolean;
}

29
apps/vue/src/views/openiddict/tokens/components/TokenModal.vue

@ -18,9 +18,12 @@
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { getModalFormSchemas } from '../datas/ModalData';
import { formatToDateTime } from '/@/utils/dateUtil';
import { GetAsyncById } from '/@/api/openiddict/open-iddict-token';
import { OpenIddictTokenDto } from '/@/api/openiddict/open-iddict-token/model';
import { GetAsyncById as getToken } from '/@/api/openiddict/open-iddict-token';
import { GetAsyncById as getApplication } from '/@/api/openiddict/open-iddict-application';
import { GetAsyncById as getAuthorization } from '/@/api/openiddict/open-iddict-authorization';
const { L } = useLocalization('AbpOpenIddict');
const { L } = useLocalization(['AbpOpenIddict']);
const [registerForm, { setFieldsValue, resetFields }] = useForm({
layout: 'vertical',
showActionButtonGroup: false,
@ -37,8 +40,26 @@
});
function fetchToken(id: string) {
GetAsyncById(id).then((token) => {
setFieldsValue(token);
getToken(id).then((dto) => {
setFieldsValue(dto);
fetchApplication(dto);
fetchAuthorization(dto);
});
}
function fetchApplication(token: OpenIddictTokenDto) {
token.applicationId && getApplication(token.applicationId).then((dto) => {
setFieldsValue({
applicationId: `${dto.clientId}(${token.applicationId})`,
});
});
}
function fetchAuthorization(token: OpenIddictTokenDto) {
token.authorizationId && getAuthorization(token.authorizationId).then((dto) => {
setFieldsValue({
authorizationId: `${dto.subject}(${token.authorizationId})`,
});
});
}
</script>

6
apps/vue/src/views/openiddict/tokens/components/TokenTable.vue

@ -7,13 +7,13 @@
:stop-button-propagation="true"
:actions="[
{
//auth: 'AbpOpenIddict.Tokens.Update',
auth: 'AbpOpenIddict.Tokens',
label: L('Edit'),
icon: 'ant-design:edit-outlined',
onClick: handleEdit.bind(null, record),
},
{
//auth: 'AbpOpenIddict.Tokens.Delete',
auth: 'AbpOpenIddict.Tokens.Delete',
label: L('Delete'),
color: 'error',
icon: 'ant-design:delete-outlined',
@ -39,7 +39,7 @@
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import TokenModal from './TokenModal.vue';
const { L } = useLocalization('AbpOpenIddict');
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
const { createConfirm, createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload }] = useTable({

28
apps/vue/src/views/openiddict/tokens/datas/ModalData.ts

@ -1,7 +1,9 @@
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { FormProps, FormSchema } from '/@/components/Form';
import { GetListAsyncByInput as getApplications } from '/@/api/openiddict/open-iddict-application';
import { GetListAsyncByInput as getAuthorizations } from '/@/api/openiddict/open-iddict-authorization';
const { L } = useLocalization(['AbpOpenIddict']);
const { L } = useLocalization(['AbpOpenIddict', 'AbpUi']);
export function getSearchFormProps(): Partial<FormProps> {
return {
@ -13,15 +15,35 @@ export function getSearchFormProps(): Partial<FormProps> {
schemas: [
{
field: 'clientId',
component: 'Input',
component: 'ApiSelect',
label: L('DisplayName:ClientId'),
colProps: { span: 8 },
componentProps: {
api: getApplications,
params: {
skipCount: 0,
maxResultCount: 100,
},
resultField: 'items',
labelField: 'clientId',
valueField: 'id',
}
},
{
field: 'authorizationId',
component: 'Input',
component: 'ApiSelect',
label: L('DisplayName:AuthorizationId'),
colProps: { span: 8 },
componentProps: {
api: getAuthorizations,
params: {
skipCount: 0,
maxResultCount: 100,
},
resultField: 'items',
labelField: 'subject',
valueField: 'id',
}
},
{
field: 'subject',

2
apps/vue/src/views/openiddict/tokens/datas/TableData.ts

@ -2,7 +2,7 @@ import { useLocalization } from '/@/hooks/abp/useLocalization';
import { BasicColumn } from '/@/components/Table';
import { formatToDateTime } from '/@/utils/dateUtil';
const { L } = useLocalization('AbpOpenIddict');
const { L } = useLocalization(['AbpOpenIddict']);
export function getDataColumns(): BasicColumn[] {
return [

2
aspnet-core/LINGYUN.MicroService.All.sln

@ -1794,7 +1794,7 @@ Global
{5D0ED1FC-3A7C-4531-9512-832E73AD9555} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{2BF7FB73-0C62-4ECF-99F0-0583855D2777} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{6FE7E243-2D99-4567-8786-6C9283D608EF} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{685188AC-A145-4A27-BF5F-9C970A59AA9C} = {E2408063-FB1F-4513-B4A7-1FE50667C6E8}
{685188AC-A145-4A27-BF5F-9C970A59AA9C} = {672E1170-7B18-474B-85C7-1961BF2A48AE}
{6AA0785D-9B6C-4EAE-AB83-0C4CF2B6B473} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{65DE28D5-DFEA-43E5-B820-BAF09A1FC4ED} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{D3E65610-4167-4235-9C9D-1E1FAD4C0CE6} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}

3
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationCreateOrUpdateDto.cs

@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
using Volo.Abp.ObjectExtending;
using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.Validation;
@ -8,6 +8,7 @@ namespace LINGYUN.Abp.OpenIddict.Applications;
public abstract class OpenIddictApplicationCreateOrUpdateDto : ExtensibleObject
{
[DisableAuditing]
public string ClientSecret { get; set; }
[DynamicStringLength(typeof(OpenIddictApplicationConsts), nameof(OpenIddictApplicationConsts.ConsentTypeMaxLength))]

1
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationDto.cs

@ -9,7 +9,6 @@ namespace LINGYUN.Abp.OpenIddict.Applications;
public class OpenIddictApplicationDto : ExtensibleAuditedEntityDto<Guid>, IHasConcurrencyStamp
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string ConsentType { get; set; }
public string DisplayName { get; set; }
public Dictionary<string, string> DisplayNames { get; set; } = new Dictionary<string, string>();

3
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Localization/Resources/en.json

@ -49,9 +49,12 @@
"Applications:AddNew": "New Application",
"Authorizations": "Authorizations",
"Scopes": "Scopes",
"Scopes:AddNew": "New Scope",
"Tokens": "Tokens",
"ManageSecret": "Manage Secret",
"ManagePermissions": "Manage Permissions",
"BasicInfo": "Basic",
"TokenInfo": "Token",
"DisplayNames": "Display Names",
"DisplayName:AddNew": "New Display Name",
"Endpoints": "Endpoints",

3
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Localization/Resources/zh-Hans.json

@ -49,9 +49,12 @@
"Applications:AddNew": "新应用",
"Authorizations": "授权",
"Scopes": "范围",
"Scopes:AddNew": "新范围",
"Tokens": "令牌",
"ManageSecret": "管理密钥",
"ManagePermissions": "管理权限",
"BasicInfo": "基本信息",
"TokenInfo": "令牌信息",
"DisplayNames": "显示名称",
"DisplayName:AddNew": "新显示配置",
"Endpoints": "端点",

4
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Permissions/AbpOpenIddictPermissionDefinitionProvider.cs

@ -38,6 +38,10 @@ namespace LINGYUN.Abp.OpenIddict.Permissions
AbpOpenIddictPermissions.Applications.ManagePermissions,
L("Permissions:ManagePermissions"),
MultiTenancySides.Host);
applications.AddChild(
AbpOpenIddictPermissions.Applications.ManageSecret,
L("Permissions:ManageSecret"),
MultiTenancySides.Host);
var authorizations = openIddictGroup.AddPermission(
AbpOpenIddictPermissions.Authorizations.Default,

1
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Permissions/AbpOpenIddictPermissions.cs

@ -11,6 +11,7 @@
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string ManagePermissions = Default + ".ManagePermissions";
public const string ManageSecret = Default + ".ManageSecret";
}
public static class Authorizations

2
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application.Contracts/LINGYUN/Abp/OpenIddict/Scopes/OpenIddictScopeCreateOrUpdateDto.cs

@ -23,5 +23,5 @@ public abstract class OpenIddictScopeCreateOrUpdateDto : ExtensibleObject
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();
public List<string> Resources { get; set; }
public List<string> Resources { get; set; } = new List<string>();
}

29
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationAppService.cs

@ -1,6 +1,5 @@
using LINGYUN.Abp.OpenIddict.Permissions;
using Microsoft.AspNetCore.Authorization;
using OpenIddict.Abstractions;
using System;
using System.Linq;
using System.Threading.Tasks;
@ -16,14 +15,16 @@ namespace LINGYUN.Abp.OpenIddict.Applications;
public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase, IOpenIddictApplicationAppService
{
private readonly IAbpApplicationManager _applicationManager;
private readonly AbpOpenIddictIdentifierConverter _identifierConverter;
private readonly IOpenIddictApplicationRepository _applicationRepository;
public OpenIddictApplicationAppService(
IAbpApplicationManager applicationManager,
AbpOpenIddictIdentifierConverter identifierConverter,
IOpenIddictApplicationRepository applicationRepository)
{
_applicationManager = applicationManager;
_identifierConverter = identifierConverter;
_applicationRepository = applicationRepository;
}
@ -46,7 +47,7 @@ public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase,
[Authorize(AbpOpenIddictPermissions.Applications.Create)]
public async virtual Task<OpenIddictApplicationDto> CreateAsync(OpenIddictApplicationCreateDto input)
{
if (await _applicationRepository.FindByClientIdAsync(input.ClientId) != null)
if (await _applicationManager.FindByClientIdAsync(input.ClientId) != null)
{
throw new BusinessException(OpenIddictApplicationErrorCodes.Applications.ClientIdExisted)
.WithData(nameof(OpenIddictApplication.ClientId), input.ClientId);
@ -59,9 +60,9 @@ public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase,
application = input.ToEntity(application, JsonSerializer);
application = await _applicationRepository.InsertAsync(application);
await _applicationManager.CreateAsync(application.ToModel(), input.ClientSecret);
await CurrentUnitOfWork.SaveChangesAsync();
application = await _applicationRepository.FindByClientIdAsync(input.ClientId);
return application.ToDto(JsonSerializer);
}
@ -82,11 +83,16 @@ public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase,
application = input.ToEntity(application, JsonSerializer);
var cache = LazyServiceProvider.LazyGetRequiredService<IOpenIddictApplicationCache<OpenIddictApplicationModel>>();
await cache.RemoveAsync(application.ToModel(), GetCancellationToken());
if (input.ClientSecret.IsNullOrWhiteSpace())
{
await _applicationManager.UpdateAsync(application.ToModel());
}
else
{
await _applicationManager.UpdateAsync(application.ToModel(), input.ClientSecret);
}
await _applicationRepository.UpdateAsync(application);
application = await _applicationRepository.FindAsync(id);
return application.ToDto(JsonSerializer);
}
@ -94,8 +100,7 @@ public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase,
[Authorize(AbpOpenIddictPermissions.Applications.Delete)]
public async virtual Task DeleteAsync(Guid id)
{
var application = await _applicationRepository.GetAsync(id);
await _applicationManager.DeleteAsync(application.ToModel());
var application = await _applicationManager.FindByIdAsync(_identifierConverter.ToString(id));
await _applicationManager.DeleteAsync(application);
}
}

2
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Applications/OpenIddictApplicationExtensions.cs

@ -15,7 +15,6 @@ internal static class OpenIddictApplicationExtensions
Check.NotNull(dto, nameof(dto));
Check.NotNull(entity, nameof(entity));
entity.ClientSecret = dto.ClientSecret;
entity.ConsentType = dto.ConsentType;
entity.DisplayName = dto.DisplayName;
entity.DisplayNames = jsonSerializer.Serialize(dto.DisplayNames);
@ -97,7 +96,6 @@ internal static class OpenIddictApplicationExtensions
{
Id = entity.Id,
ClientId = entity.ClientId,
ClientSecret = entity.ClientSecret,
ConsentType = entity.ConsentType,
DisplayName = entity.DisplayName,
CreationTime = entity.CreationTime,

8
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Authorizations/OpenIddictAuthorizationAppService.cs

@ -7,6 +7,7 @@ using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.OpenIddict;
using Volo.Abp.OpenIddict.Authorizations;
namespace LINGYUN.Abp.OpenIddict.Authorizations;
@ -15,22 +16,25 @@ namespace LINGYUN.Abp.OpenIddict.Authorizations;
public class OpenIddictAuthorizationAppService : OpenIddictApplicationServiceBase, IOpenIddictAuthorizationAppService
{
private readonly IOpenIddictAuthorizationManager _authorizationManager;
private readonly AbpOpenIddictIdentifierConverter _identifierConverter;
private readonly IRepository<OpenIddictAuthorization, Guid> _authorizationRepository;
public OpenIddictAuthorizationAppService(
IOpenIddictAuthorizationManager authorizationManager,
AbpOpenIddictIdentifierConverter identifierConverter,
IRepository<OpenIddictAuthorization, Guid> authorizationRepository)
{
_authorizationManager = authorizationManager;
_identifierConverter = identifierConverter;
_authorizationRepository = authorizationRepository;
}
[Authorize(AbpOpenIddictPermissions.Authorizations.Delete)]
public async virtual Task DeleteAsync(Guid id)
{
var authorization = await _authorizationRepository.GetAsync(id);
var authorization = await _authorizationManager.FindByIdAsync(_identifierConverter.ToString(id));
await _authorizationManager.DeleteAsync(authorization.ToModel());
await _authorizationManager.DeleteAsync(authorization);
}
public async virtual Task<OpenIddictAuthorizationDto> GetAsync(Guid id)

23
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Scopes/OpenIddictScopeAppService.cs

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.OpenIddict;
using Volo.Abp.OpenIddict.Applications;
using Volo.Abp.OpenIddict.Scopes;
@ -16,21 +17,23 @@ namespace LINGYUN.Abp.OpenIddict.Scopes;
public class OpenIddictScopeAppService : OpenIddictApplicationServiceBase, IOpenIddictScopeAppService
{
private readonly IOpenIddictScopeManager _scopeManager;
private readonly IOpenIddictScopeRepository _scoppeRepository;
private readonly AbpOpenIddictIdentifierConverter _identifierConverter;
public OpenIddictScopeAppService(
IOpenIddictScopeManager scopeManager,
IOpenIddictScopeRepository scopeRepository)
IOpenIddictScopeRepository scopeRepository,
AbpOpenIddictIdentifierConverter identifierConverter)
{
_scopeManager = scopeManager;
_scoppeRepository = scopeRepository;
_identifierConverter = identifierConverter;
}
[Authorize(AbpOpenIddictPermissions.Scopes.Create)]
public async virtual Task<OpenIddictScopeDto> CreateAsync(OpenIddictScopeCreateDto input)
{
if (await _scoppeRepository.FindByNameAsync(input.Name) != null)
if (await _scopeManager.FindByNameAsync(input.Name) != null)
{
throw new BusinessException(OpenIddictApplicationErrorCodes.Scopes.NameExisted)
.WithData(nameof(OpenIddictScope.Name), input.Name);
@ -40,9 +43,9 @@ public class OpenIddictScopeAppService : OpenIddictApplicationServiceBase, IOpen
scope = input.ToEntity(scope, JsonSerializer);
scope = await _scoppeRepository.InsertAsync(scope);
await _scopeManager.CreateAsync(scope.ToModel());
await CurrentUnitOfWork.SaveChangesAsync();
scope = await _scoppeRepository.FindByIdAsync(scope.Id);
return scope.ToDto(JsonSerializer);
}
@ -50,9 +53,9 @@ public class OpenIddictScopeAppService : OpenIddictApplicationServiceBase, IOpen
[Authorize(AbpOpenIddictPermissions.Scopes.Delete)]
public async virtual Task DeleteAsync(Guid id)
{
var scope = await _scoppeRepository.GetAsync(id);
var scope = await _scopeManager.FindByIdAsync(_identifierConverter.ToString(id));
await _scopeManager.DeleteAsync(scope.ToModel());
await _scopeManager.DeleteAsync(scope);
}
public async virtual Task<OpenIddictScopeDto> GetAsync(Guid id)
@ -87,11 +90,9 @@ public class OpenIddictScopeAppService : OpenIddictApplicationServiceBase, IOpen
scope = input.ToEntity(scope, JsonSerializer);
var cache = LazyServiceProvider.LazyGetRequiredService<IOpenIddictScopeCache<OpenIddictScopeModel>>();
await cache.RemoveAsync(scope.ToModel(), GetCancellationToken());
await _scopeManager.UpdateAsync(scope.ToModel());
await _scoppeRepository.UpdateAsync(scope);
scope = await _scoppeRepository.GetAsync(id);
return scope.ToDto(JsonSerializer);
}

10
aspnet-core/modules/openIddict/LINGYUN.Abp.OpenIddict.Application/LINGYUN/Abp/OpenIddict/Tokens/OpenIddictTokenAppService.cs

@ -7,6 +7,7 @@ using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.OpenIddict;
using Volo.Abp.OpenIddict.Tokens;
namespace LINGYUN.Abp.OpenIddict.Tokens;
@ -16,21 +17,24 @@ public class OpenIddictTokenAppService : OpenIddictApplicationServiceBase, IOpen
{
private readonly IOpenIddictTokenManager _tokenManager;
private readonly IRepository<OpenIddictToken, Guid> _tokenRepository;
private readonly AbpOpenIddictIdentifierConverter _identifierConverter;
public OpenIddictTokenAppService(
IOpenIddictTokenManager tokenManager,
IRepository<OpenIddictToken, Guid> tokenRepository)
IRepository<OpenIddictToken, Guid> tokenRepository,
AbpOpenIddictIdentifierConverter identifierConverter)
{
_tokenManager = tokenManager;
_tokenRepository = tokenRepository;
_identifierConverter = identifierConverter;
}
[Authorize(AbpOpenIddictPermissions.Tokens.Delete)]
public async virtual Task DeleteAsync(Guid id)
{
var token = await _tokenRepository.GetAsync(id);
var token = await _tokenManager.FindByIdAsync(_identifierConverter.ToString(id));
await _tokenManager.DeleteAsync(token.ToModel());
await _tokenManager.DeleteAsync(token);
}
public async virtual Task<OpenIddictTokenDto> GetAsync(Guid id)

Loading…
Cancel
Save