This is page 1 of 7. Use http://codebase.md/higress-group/himarket?page={x} to view the full context. # Directory Structure ``` ├── .cursor │ └── rules │ ├── api-style.mdc │ └── project-architecture.mdc ├── .gitignore ├── build.sh ├── deploy │ ├── docker │ │ ├── docker-compose.yml │ │ └── Docker部署说明.md │ └── helm │ ├── Chart.yaml │ ├── Helm部署说明.md │ ├── templates │ │ ├── _helpers.tpl │ │ ├── himarket-admin-cm.yaml │ │ ├── himarket-admin-deployment.yaml │ │ ├── himarket-admin-service.yaml │ │ ├── himarket-frontend-cm.yaml │ │ ├── himarket-frontend-deployment.yaml │ │ ├── himarket-frontend-service.yaml │ │ ├── himarket-server-cm.yaml │ │ ├── himarket-server-deployment.yaml │ │ ├── himarket-server-service.yaml │ │ ├── mysql.yaml │ │ └── serviceaccount.yaml │ └── values.yaml ├── LICENSE ├── NOTICE ├── pom.xml ├── portal-bootstrap │ ├── Dockerfile │ ├── pom.xml │ └── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── alibaba │ │ │ └── apiopenplatform │ │ │ ├── config │ │ │ │ ├── AsyncConfig.java │ │ │ │ ├── FilterConfig.java │ │ │ │ ├── PageConfig.java │ │ │ │ ├── RestTemplateConfig.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── SwaggerConfig.java │ │ │ ├── filter │ │ │ │ └── PortalResolvingFilter.java │ │ │ └── PortalApplication.java │ │ └── resources │ │ └── application.yaml │ └── test │ └── java │ └── com │ └── alibaba │ └── apiopenplatform │ └── integration │ └── AdministratorAuthIntegrationTest.java ├── portal-dal │ ├── pom.xml │ └── src │ └── main │ └── java │ └── com │ └── alibaba │ └── apiopenplatform │ ├── converter │ │ ├── AdpAIGatewayConfigConverter.java │ │ ├── APIGConfigConverter.java │ │ ├── APIGRefConfigConverter.java │ │ ├── ApiKeyConfigConverter.java │ │ ├── ConsumerAuthConfigConverter.java │ │ ├── GatewayConfigConverter.java │ │ ├── HigressConfigConverter.java │ │ ├── HigressRefConfigConverter.java │ │ ├── HmacConfigConverter.java │ │ ├── JsonConverter.java │ │ ├── JwtConfigConverter.java │ │ ├── NacosRefConfigConverter.java │ │ ├── PortalSettingConfigConverter.java │ │ ├── PortalUiConfigConverter.java │ │ └── ProductIconConverter.java │ ├── entity │ │ ├── Administrator.java │ │ ├── BaseEntity.java │ │ ├── Consumer.java │ │ ├── ConsumerCredential.java │ │ ├── ConsumerRef.java │ │ ├── Developer.java │ │ ├── DeveloperExternalIdentity.java │ │ ├── Gateway.java │ │ ├── NacosInstance.java │ │ ├── Portal.java │ │ ├── PortalDomain.java │ │ ├── Product.java │ │ ├── ProductPublication.java │ │ ├── ProductRef.java │ │ └── ProductSubscription.java │ ├── repository │ │ ├── AdministratorRepository.java │ │ ├── BaseRepository.java │ │ ├── ConsumerCredentialRepository.java │ │ ├── ConsumerRefRepository.java │ │ ├── ConsumerRepository.java │ │ ├── DeveloperExternalIdentityRepository.java │ │ ├── DeveloperRepository.java │ │ ├── GatewayRepository.java │ │ ├── NacosInstanceRepository.java │ │ ├── PortalDomainRepository.java │ │ ├── PortalRepository.java │ │ ├── ProductPublicationRepository.java │ │ ├── ProductRefRepository.java │ │ ├── ProductRepository.java │ │ └── SubscriptionRepository.java │ └── support │ ├── common │ │ ├── Encrypted.java │ │ ├── Encryptor.java │ │ └── User.java │ ├── consumer │ │ ├── AdpAIAuthConfig.java │ │ ├── APIGAuthConfig.java │ │ ├── ApiKeyConfig.java │ │ ├── ConsumerAuthConfig.java │ │ ├── HigressAuthConfig.java │ │ ├── HmacConfig.java │ │ └── JwtConfig.java │ ├── enums │ │ ├── APIGAPIType.java │ │ ├── ConsumerAuthType.java │ │ ├── ConsumerStatus.java │ │ ├── CredentialMode.java │ │ ├── DeveloperAuthType.java │ │ ├── DeveloperStatus.java │ │ ├── DomainType.java │ │ ├── GatewayType.java │ │ ├── GrantType.java │ │ ├── HigressAPIType.java │ │ ├── JwtAlgorithm.java │ │ ├── ProductIconType.java │ │ ├── ProductStatus.java │ │ ├── ProductType.java │ │ ├── ProtocolType.java │ │ ├── PublicKeyFormat.java │ │ ├── SourceType.java │ │ ├── SubscriptionStatus.java │ │ └── UserType.java │ ├── gateway │ │ ├── AdpAIGatewayConfig.java │ │ ├── APIGConfig.java │ │ ├── GatewayConfig.java │ │ └── HigressConfig.java │ ├── portal │ │ ├── AuthCodeConfig.java │ │ ├── IdentityMapping.java │ │ ├── JwtBearerConfig.java │ │ ├── OAuth2Config.java │ │ ├── OidcConfig.java │ │ ├── PortalSettingConfig.java │ │ ├── PortalUiConfig.java │ │ └── PublicKeyConfig.java │ └── product │ ├── APIGRefConfig.java │ ├── HigressRefConfig.java │ ├── NacosRefConfig.java │ └── ProductIcon.java ├── portal-server │ ├── pom.xml │ └── src │ └── main │ └── java │ └── com │ └── alibaba │ └── apiopenplatform │ ├── controller │ │ ├── AdministratorController.java │ │ ├── ConsumerController.java │ │ ├── DeveloperController.java │ │ ├── GatewayController.java │ │ ├── NacosController.java │ │ ├── OAuth2Controller.java │ │ ├── OidcController.java │ │ ├── PortalController.java │ │ └── ProductController.java │ ├── core │ │ ├── advice │ │ │ ├── ExceptionAdvice.java │ │ │ └── ResponseAdvice.java │ │ ├── annotation │ │ │ ├── AdminAuth.java │ │ │ ├── AdminOrDeveloperAuth.java │ │ │ └── DeveloperAuth.java │ │ ├── constant │ │ │ ├── CommonConstants.java │ │ │ ├── IdpConstants.java │ │ │ ├── JwtConstants.java │ │ │ └── Resources.java │ │ ├── event │ │ │ ├── DeveloperDeletingEvent.java │ │ │ ├── PortalDeletingEvent.java │ │ │ └── ProductDeletingEvent.java │ │ ├── exception │ │ │ ├── BusinessException.java │ │ │ └── ErrorCode.java │ │ ├── response │ │ │ └── Response.java │ │ ├── security │ │ │ ├── ContextHolder.java │ │ │ ├── DeveloperAuthenticationProvider.java │ │ │ └── JwtAuthenticationFilter.java │ │ └── utils │ │ ├── IdGenerator.java │ │ ├── PasswordHasher.java │ │ └── TokenUtil.java │ ├── dto │ │ ├── converter │ │ │ ├── InputConverter.java │ │ │ ├── NacosToGatewayToolsConverter.java │ │ │ └── OutputConverter.java │ │ ├── params │ │ │ ├── admin │ │ │ │ ├── AdminCreateParam.java │ │ │ │ ├── AdminLoginParam.java │ │ │ │ └── ResetPasswordParam.java │ │ │ ├── consumer │ │ │ │ ├── CreateConsumerParam.java │ │ │ │ ├── CreateCredentialParam.java │ │ │ │ ├── CreateSubscriptionParam.java │ │ │ │ ├── QueryConsumerParam.java │ │ │ │ ├── QuerySubscriptionParam.java │ │ │ │ └── UpdateCredentialParam.java │ │ │ ├── developer │ │ │ │ ├── CreateDeveloperParam.java │ │ │ │ ├── CreateExternalDeveloperParam.java │ │ │ │ ├── DeveloperLoginParam.java │ │ │ │ ├── QueryDeveloperParam.java │ │ │ │ ├── UnbindExternalIdentityParam.java │ │ │ │ ├── UpdateDeveloperParam.java │ │ │ │ └── UpdateDeveloperStatusParam.java │ │ │ ├── gateway │ │ │ │ ├── ImportGatewayParam.java │ │ │ │ ├── QueryAdpAIGatewayParam.java │ │ │ │ ├── QueryAPIGParam.java │ │ │ │ └── QueryGatewayParam.java │ │ │ ├── nacos │ │ │ │ ├── CreateNacosParam.java │ │ │ │ ├── QueryNacosNamespaceParam.java │ │ │ │ ├── QueryNacosParam.java │ │ │ │ └── UpdateNacosParam.java │ │ │ ├── portal │ │ │ │ ├── BindDomainParam.java │ │ │ │ ├── CreatePortalParam.java │ │ │ │ └── UpdatePortalParam.java │ │ │ └── product │ │ │ ├── CreateProductParam.java │ │ │ ├── CreateProductRefParam.java │ │ │ ├── PublishProductParam.java │ │ │ ├── QueryProductParam.java │ │ │ ├── QueryProductSubscriptionParam.java │ │ │ ├── UnPublishProductParam.java │ │ │ └── UpdateProductParam.java │ │ └── result │ │ ├── AdminResult.java │ │ ├── AdpGatewayInstanceResult.java │ │ ├── AdpMcpServerListResult.java │ │ ├── AdpMCPServerResult.java │ │ ├── APIConfigResult.java │ │ ├── APIGMCPServerResult.java │ │ ├── APIResult.java │ │ ├── AuthResult.java │ │ ├── ConsumerCredentialResult.java │ │ ├── ConsumerResult.java │ │ ├── DeveloperResult.java │ │ ├── GatewayMCPServerResult.java │ │ ├── GatewayResult.java │ │ ├── HigressMCPServerResult.java │ │ ├── IdpResult.java │ │ ├── IdpState.java │ │ ├── IdpTokenResult.java │ │ ├── MCPConfigResult.java │ │ ├── MCPServerResult.java │ │ ├── MseNacosResult.java │ │ ├── NacosMCPServerResult.java │ │ ├── NacosNamespaceResult.java │ │ ├── NacosResult.java │ │ ├── PageResult.java │ │ ├── PortalResult.java │ │ ├── ProductPublicationResult.java │ │ ├── ProductRefResult.java │ │ ├── ProductResult.java │ │ └── SubscriptionResult.java │ └── service │ ├── AdministratorService.java │ ├── AdpAIGatewayService.java │ ├── ConsumerService.java │ ├── DeveloperService.java │ ├── gateway │ │ ├── AdpAIGatewayOperator.java │ │ ├── AIGatewayOperator.java │ │ ├── APIGOperator.java │ │ ├── client │ │ │ ├── AdpAIGatewayClient.java │ │ │ ├── APIGClient.java │ │ │ ├── GatewayClient.java │ │ │ ├── HigressClient.java │ │ │ ├── PopGatewayClient.java │ │ │ └── SLSClient.java │ │ ├── factory │ │ │ └── HTTPClientFactory.java │ │ ├── GatewayOperator.java │ │ └── HigressOperator.java │ ├── GatewayService.java │ ├── IdpService.java │ ├── impl │ │ ├── AdministratorServiceImpl.java │ │ ├── ConsumerServiceImpl.java │ │ ├── DeveloperServiceImpl.java │ │ ├── GatewayServiceImpl.java │ │ ├── IdpServiceImpl.java │ │ ├── NacosServiceImpl.java │ │ ├── OAuth2ServiceImpl.java │ │ ├── OidcServiceImpl.java │ │ ├── PortalServiceImpl.java │ │ └── ProductServiceImpl.java │ ├── NacosService.java │ ├── OAuth2Service.java │ ├── OidcService.java │ ├── PortalService.java │ └── ProductService.java ├── portal-web │ ├── api-portal-admin │ │ ├── .env │ │ ├── .gitignore │ │ ├── bin │ │ │ ├── replace_var.py │ │ │ └── start.sh │ │ ├── Dockerfile │ │ ├── eslint.config.js │ │ ├── index.html │ │ ├── nginx.conf │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── proxy.conf │ │ ├── public │ │ │ ├── logo.png │ │ │ └── vite.svg │ │ ├── README.md │ │ ├── src │ │ │ ├── aliyunThemeToken.ts │ │ │ ├── App.css │ │ │ ├── App.tsx │ │ │ ├── assets │ │ │ │ └── react.svg │ │ │ ├── components │ │ │ │ ├── api-product │ │ │ │ │ ├── ApiProductApiDocs.tsx │ │ │ │ │ ├── ApiProductDashboard.tsx │ │ │ │ │ ├── ApiProductFormModal.tsx │ │ │ │ │ ├── ApiProductLinkApi.tsx │ │ │ │ │ ├── ApiProductOverview.tsx │ │ │ │ │ ├── ApiProductPolicy.tsx │ │ │ │ │ ├── ApiProductPortal.tsx │ │ │ │ │ ├── ApiProductUsageGuide.tsx │ │ │ │ │ ├── SwaggerUIWrapper.css │ │ │ │ │ └── SwaggerUIWrapper.tsx │ │ │ │ ├── common │ │ │ │ │ ├── AdvancedSearch.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── console │ │ │ │ │ ├── GatewayTypeSelector.tsx │ │ │ │ │ ├── ImportGatewayModal.tsx │ │ │ │ │ ├── ImportHigressModal.tsx │ │ │ │ │ ├── ImportMseNacosModal.tsx │ │ │ │ │ └── NacosTypeSelector.tsx │ │ │ │ ├── icons │ │ │ │ │ └── McpServerIcon.tsx │ │ │ │ ├── Layout.tsx │ │ │ │ ├── LayoutWrapper.tsx │ │ │ │ ├── portal │ │ │ │ │ ├── PortalConsumers.tsx │ │ │ │ │ ├── PortalDashboard.tsx │ │ │ │ │ ├── PortalDevelopers.tsx │ │ │ │ │ ├── PortalDomain.tsx │ │ │ │ │ ├── PortalFormModal.tsx │ │ │ │ │ ├── PortalOverview.tsx │ │ │ │ │ ├── PortalPublishedApis.tsx │ │ │ │ │ ├── PortalSecurity.tsx │ │ │ │ │ ├── PortalSettings.tsx │ │ │ │ │ ├── PublicKeyManager.tsx │ │ │ │ │ └── ThirdPartyAuthManager.tsx │ │ │ │ └── subscription │ │ │ │ └── SubscriptionListModal.tsx │ │ │ ├── contexts │ │ │ │ └── LoadingContext.tsx │ │ │ ├── index.css │ │ │ ├── lib │ │ │ │ ├── api.ts │ │ │ │ ├── constant.ts │ │ │ │ └── utils.ts │ │ │ ├── main.tsx │ │ │ ├── pages │ │ │ │ ├── ApiProductDetail.tsx │ │ │ │ ├── ApiProducts.tsx │ │ │ │ ├── Dashboard.tsx │ │ │ │ ├── GatewayConsoles.tsx │ │ │ │ ├── Login.tsx │ │ │ │ ├── NacosConsoles.tsx │ │ │ │ ├── PortalDetail.tsx │ │ │ │ ├── Portals.tsx │ │ │ │ └── Register.tsx │ │ │ ├── routes │ │ │ │ └── index.tsx │ │ │ ├── types │ │ │ │ ├── api-product.ts │ │ │ │ ├── consumer.ts │ │ │ │ ├── gateway.ts │ │ │ │ ├── index.ts │ │ │ │ ├── portal.ts │ │ │ │ ├── shims-js-yaml.d.ts │ │ │ │ └── subscription.ts │ │ │ └── vite-env.d.ts │ │ ├── tailwind.config.js │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts │ └── api-portal-frontend │ ├── .env │ ├── .gitignore │ ├── .husky │ │ └── pre-commit │ ├── bin │ │ ├── replace_var.py │ │ └── start.sh │ ├── Dockerfile │ ├── eslint.config.js │ ├── index.html │ ├── nginx.conf │ ├── package.json │ ├── postcss.config.js │ ├── proxy.conf │ ├── public │ │ ├── favicon.ico │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── MCP.png │ │ ├── MCP.svg │ │ └── vite.svg │ ├── README.md │ ├── src │ │ ├── aliyunThemeToken.ts │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ ├── aliyun.png │ │ │ ├── github.png │ │ │ ├── google.png │ │ │ └── react.svg │ │ ├── components │ │ │ ├── consumer │ │ │ │ ├── ConsumerBasicInfo.tsx │ │ │ │ ├── CredentialManager.tsx │ │ │ │ ├── index.ts │ │ │ │ └── SubscriptionManager.tsx │ │ │ ├── Layout.tsx │ │ │ ├── Navigation.tsx │ │ │ ├── ProductHeader.tsx │ │ │ ├── SwaggerUIWrapper.css │ │ │ ├── SwaggerUIWrapper.tsx │ │ │ └── UserInfo.tsx │ │ ├── index.css │ │ ├── lib │ │ │ ├── api.ts │ │ │ ├── statusUtils.ts │ │ │ └── utils.ts │ │ ├── main.tsx │ │ ├── pages │ │ │ ├── ApiDetail.tsx │ │ │ ├── Apis.tsx │ │ │ ├── Callback.tsx │ │ │ ├── ConsumerDetail.tsx │ │ │ ├── Consumers.tsx │ │ │ ├── GettingStarted.tsx │ │ │ ├── Home.tsx │ │ │ ├── Login.tsx │ │ │ ├── Mcp.tsx │ │ │ ├── McpDetail.tsx │ │ │ ├── OidcCallback.tsx │ │ │ ├── Profile.tsx │ │ │ ├── Register.tsx │ │ │ └── Test.css │ │ ├── router.tsx │ │ ├── types │ │ │ ├── consumer.ts │ │ │ └── index.ts │ │ └── vite-env.d.ts │ ├── tailwind.config.js │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts └── README.md ``` # Files -------------------------------------------------------------------------------- /portal-web/api-portal-admin/.env: -------------------------------------------------------------------------------- ``` VITE_API_BASE_URL=/api/v1 ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/.env: -------------------------------------------------------------------------------- ``` VITE_API_BASE_URL=/api/v1 ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/.gitignore: -------------------------------------------------------------------------------- ``` # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? image-push.sh ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/.gitignore: -------------------------------------------------------------------------------- ``` # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? image-push.sh ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` target/ !.mvn/wrapper/maven-wrapper.jar !**/src/main/**/target/ !**/src/test/**/target/ ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### Eclipse ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ build/ !**/src/main/**/build/ !**/src/test/**/build/ ### VS Code ### .vscode/ ### Mac OS ### .DS_Store /front-auth-app package-lock.json ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/vite-env.d.ts: -------------------------------------------------------------------------------- ```typescript /// <reference types="vite/client" /> ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/vite-env.d.ts: -------------------------------------------------------------------------------- ```typescript /// <reference types="vite/client" /> ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/postcss.config.js: -------------------------------------------------------------------------------- ```javascript export default { plugins: { tailwindcss: {}, autoprefixer: {}, }, } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/postcss.config.js: -------------------------------------------------------------------------------- ```javascript export default { plugins: { tailwindcss: {}, autoprefixer: {}, }, } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/types/shims-js-yaml.d.ts: -------------------------------------------------------------------------------- ```typescript declare module 'js-yaml' { export function load(str: string, opts?: unknown): unknown; } ``` -------------------------------------------------------------------------------- /deploy/helm/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "himarket.serviceAccountName" . }} ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/components/common/index.ts: -------------------------------------------------------------------------------- ```typescript export { AdvancedSearch } from './AdvancedSearch'; export type { SearchParam } from './AdvancedSearch'; ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/PublicKeyFormat.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.enums; public enum PublicKeyFormat { PEM, JWK, ; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/tsconfig.json: -------------------------------------------------------------------------------- ```json { "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ProductIconType.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.enums; /** * @author zh */ public enum ProductIconType { URL, BASE64, ; } ``` -------------------------------------------------------------------------------- /deploy/helm/templates/himarket-admin-cm.yaml: -------------------------------------------------------------------------------- ```yaml kind: ConfigMap apiVersion: v1 metadata: labels: app: himarket-admin name: himarket-admin data: HIMARKET_SERVER: "http://himarket-server" ``` -------------------------------------------------------------------------------- /deploy/helm/templates/himarket-frontend-cm.yaml: -------------------------------------------------------------------------------- ```yaml kind: ConfigMap apiVersion: v1 metadata: labels: app: himarket-frontend name: himarket-frontend data: HIMARKET_SERVER: "http://himarket-server" ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/components/consumer/index.ts: -------------------------------------------------------------------------------- ```typescript export { ConsumerBasicInfo } from './ConsumerBasicInfo'; export { CredentialManager } from './CredentialManager'; export { SubscriptionManager } from './SubscriptionManager'; ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/JwtAlgorithm.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.enums; /** * @author zh */ public enum JwtAlgorithm { RS256, RS384, RS512, ES256, ES384, ES512, ; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/tailwind.config.js: -------------------------------------------------------------------------------- ```javascript /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/main.tsx: -------------------------------------------------------------------------------- ```typescript import { createRoot } from 'react-dom/client' import 'antd/dist/reset.css' import './index.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( <App /> ) ``` -------------------------------------------------------------------------------- /portal-bootstrap/Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM docker.m.daocloud.io/openjdk:8-jdk-slim WORKDIR /app COPY target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar", "--logging.file.name=/app/logs/himarket-server.log"] ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/tsconfig.node.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM docker.m.daocloud.io/nginx:1.24-alpine COPY nginx.conf /etc/nginx/nginx.conf COPY proxy.conf /etc/nginx/default.d/proxy.conf COPY bin /home/admin/bin WORKDIR /app COPY dist/ /app CMD ["/bin/sh", "/home/admin/bin/start.sh"] ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/Dockerfile: -------------------------------------------------------------------------------- ```dockerfile FROM docker.m.daocloud.io/nginx:1.24-alpine COPY nginx.conf /etc/nginx/nginx.conf COPY proxy.conf /etc/nginx/default.d/proxy.conf COPY bin /home/admin/bin WORKDIR /app COPY dist/ /app CMD ["/bin/sh", "/home/admin/bin/start.sh"] ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/JwtBearerConfig.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.portal; import lombok.Data; import java.util.List; /** * @author zh */ @Data public class JwtBearerConfig { /** * JWT公钥 */ private List<PublicKeyConfig> publicKeys; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/HigressAuthConfig.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.consumer; import lombok.Builder; import lombok.Data; /** * @author zh */ @Data @Builder public class HigressAuthConfig { private String resourceType; private String resourceName; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/APIGAuthConfig.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.consumer; import lombok.Builder; import lombok.Data; import java.util.List; /** * @author zh */ @Data @Builder public class APIGAuthConfig { private List<String> authorizationRuleIds; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/gateway/QueryGatewayParam.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.dto.params.gateway; import com.alibaba.apiopenplatform.support.enums.GatewayType; import lombok.Data; /** * @author zh */ @Data public class QueryGatewayParam { private GatewayType gatewayType; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/product/ProductIcon.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.product; import com.alibaba.apiopenplatform.support.enums.ProductIconType; import lombok.Data; /** * @author zh */ @Data public class ProductIcon { private ProductIconType type; private String value; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/bin/start.sh: -------------------------------------------------------------------------------- ```bash #!/bin/sh if [ -z "$HIMARKET_SERVER" ]; then echo "HIMARKET_SERVER not set" exit 1 fi sed -i "s|{{ HIMARKET_SERVER }}|${HIMARKET_SERVER}|g" /etc/nginx/default.d/proxy.conf nginx echo "HiMarket Admin started successfully" tail -f /var/log/nginx/access.log ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/bin/start.sh: -------------------------------------------------------------------------------- ```bash #!/bin/sh if [ -z "$HIMARKET_SERVER" ]; then echo "HIMARKET_SERVER not set" exit 1 fi sed -i "s|{{ HIMARKET_SERVER }}|${HIMARKET_SERVER}|g" /etc/nginx/default.d/proxy.conf nginx echo "HiMarket Frontend started successfully" tail -f /var/log/nginx/access.log ``` -------------------------------------------------------------------------------- /deploy/helm/templates/himarket-admin-service.yaml: -------------------------------------------------------------------------------- ```yaml apiVersion: v1 kind: Service metadata: name: himarket-admin labels: app: himarket-admin spec: type: {{ .Values.admin.service.type }} ports: - port: {{ .Values.admin.service.port }} targetPort: http protocol: TCP name: http selector: app: himarket-admin ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/QueryProductSubscriptionParam.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.dto.params.product; import com.alibaba.apiopenplatform.support.enums.SubscriptionStatus; import lombok.Data; /** * @author zh */ @Data public class QueryProductSubscriptionParam { private SubscriptionStatus status; private String consumerName; } ``` -------------------------------------------------------------------------------- /deploy/helm/templates/himarket-server-service.yaml: -------------------------------------------------------------------------------- ```yaml apiVersion: v1 kind: Service metadata: name: himarket-server labels: app: himarket-server spec: type: {{ .Values.server.service.type }} ports: - port: {{ .Values.server.service.port }} targetPort: http protocol: TCP name: http selector: app: himarket-server ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/DeveloperAuthType.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.enums; /** * @author zh */ public enum DeveloperAuthType { @Deprecated LOCAL, BUILTIN, @Deprecated EXTERNAL, OIDC, OAUTH2, ; public boolean isBuiltIn() { return this == BUILTIN || this == LOCAL; } } ``` -------------------------------------------------------------------------------- /deploy/helm/templates/himarket-frontend-service.yaml: -------------------------------------------------------------------------------- ```yaml apiVersion: v1 kind: Service metadata: name: himarket-frontend labels: app: himarket-frontend spec: type: {{ .Values.frontend.service.type }} ports: - port: {{ .Values.frontend.service.port }} targetPort: http protocol: TCP name: http selector: app: himarket-frontend ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/service/OAuth2Service.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.service; import com.alibaba.apiopenplatform.dto.result.AuthResult; /** * @author zh */ public interface OAuth2Service { /** * JWT Bearer认证 * * @param grantType * @param jwtToken * @return */ AuthResult authenticate(String grantType, String jwtToken); } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ProductIconConverter.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.product.ProductIcon; import javax.persistence.Converter; /** * @author zh */ @Converter(autoApply = true) public class ProductIconConverter extends JsonConverter<ProductIcon> { protected ProductIconConverter() { super(ProductIcon.class); } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/index.html: -------------------------------------------------------------------------------- ```html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/logo.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>HiMarket</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body> </html> ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/index.html: -------------------------------------------------------------------------------- ```html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/logo.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>HiMarket</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body> </html> ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/AdpAIGatewayConfigConverter.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.gateway.AdpAIGatewayConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class AdpAIGatewayConfigConverter extends JsonConverter<AdpAIGatewayConfig> { public AdpAIGatewayConfigConverter() { super(AdpAIGatewayConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/main.tsx: -------------------------------------------------------------------------------- ```typescript import React from 'react' import ReactDOM from 'react-dom/client' // import { RouterProvider } from 'react-router-dom' import App from './App.tsx' import './index.css' const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( <React.StrictMode> <App /> </React.StrictMode>, ) ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/proxy.conf: -------------------------------------------------------------------------------- ``` location ^~ /api/v1 { proxy_http_version 1.1; proxy_set_header Connection ""; rewrite ^/api/v1/(.*)$ /$1 break; proxy_pass {{ HIMARKET_SERVER }}; } location ~ .*\.(js|css|gif|jpg|jpeg|png|svg|json|otf|ico)$ { root /app; } location / { try_files $uri $uri/ /index.html; root /app; index index.html index.htm; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/GrantType.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.enums; import lombok.Getter; /** * @author zh */ @Getter public enum GrantType { /** * 授权码模式 */ AUTHORIZATION_CODE("authorization_code"), /** * JWT断言,OAuth2.0标准拓展 */ JWT_BEARER("urn:ietf:params:oauth:grant-type:jwt-bearer"), ; private final String type; GrantType(String type) { this.type = type; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/service/AdpAIGatewayService.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.service; import com.alibaba.apiopenplatform.dto.params.gateway.QueryAdpAIGatewayParam; import com.alibaba.apiopenplatform.dto.result.GatewayResult; import com.alibaba.apiopenplatform.dto.result.PageResult; import org.springframework.data.domain.Pageable; public interface AdpAIGatewayService { PageResult<GatewayResult> fetchGateways(QueryAdpAIGatewayParam param, int page, int size); } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/types/subscription.ts: -------------------------------------------------------------------------------- ```typescript export interface Subscription { subscriptionId: string; consumerId: string; productId: string; status: 'PENDING' | 'APPROVED'; createAt: string; updatedAt: string; productName: string; productType: string; } export interface Product { productId: string; name: string; description?: string; type: string; } export interface SubscriptionModalProps { visible: boolean; consumerId: string; consumerName: string; onCancel: () => void; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/App.tsx: -------------------------------------------------------------------------------- ```typescript import { BrowserRouter } from "react-router-dom"; import { Router } from "./router"; import { ConfigProvider } from 'antd'; import zhCN from 'antd/locale/zh_CN'; import './App.css' import aliyunThemeToken from './aliyunThemeToken.ts'; function App() { return ( <ConfigProvider locale={zhCN} theme={{ token: aliyunThemeToken }} > <BrowserRouter> <Router /> </BrowserRouter> </ConfigProvider> ); } export default App; ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/tailwind.config.js: -------------------------------------------------------------------------------- ```javascript /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: { colors: { gray: { 50: '#f9fafb', 100: '#f3f4f6', 200: '#e5e7eb', 300: '#d1d5db', 400: '#9ca3af', 500: '#6b7280', 600: '#4b5563', 700: '#374151', 800: '#1f2937', 900: '#111827', } } }, }, plugins: [], } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/components/consumer/ConsumerBasicInfo.tsx: -------------------------------------------------------------------------------- ```typescript import { Card, Descriptions } from "antd"; import type { Consumer } from "../../types/consumer"; interface ConsumerBasicInfoProps { consumer: Consumer; } export function ConsumerBasicInfo({ consumer }: ConsumerBasicInfoProps) { return ( <Card title="基本信息"> <Descriptions column={2}> <Descriptions.Item label="名称">{consumer.name}</Descriptions.Item> <Descriptions.Item label="描述">{consumer.description || '-'}</Descriptions.Item> </Descriptions> </Card> ); } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/App.css: -------------------------------------------------------------------------------- ```css #root { } .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.react:hover { filter: drop-shadow(0 0 2em #61dafbaa); } @keyframes logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @media (prefers-reduced-motion: no-preference) { a:nth-of-type(2) .logo { animation: logo-spin infinite 20s linear; } } .card { padding: 2em; } .read-the-docs { color: #888; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/App.tsx: -------------------------------------------------------------------------------- ```typescript import { RouterProvider } from 'react-router-dom' import { ConfigProvider } from 'antd' import zhCN from 'antd/locale/zh_CN' import { router } from './routes' import aliyunThemeToken from './aliyunThemeToken' import { LoadingProvider } from './contexts/LoadingContext' import './App.css' function App() { return ( <LoadingProvider> <ConfigProvider locale={zhCN} theme={{ token: aliyunThemeToken, }} > <RouterProvider router={router} /> </ConfigProvider> </LoadingProvider> ) } export default App ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/CreateExternalDeveloperParam.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.dto.params.developer; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.DeveloperExternalIdentity; import com.alibaba.apiopenplatform.support.enums.DeveloperAuthType; import lombok.Builder; import lombok.Data; /** * @author zh */ @Data @Builder public class CreateExternalDeveloperParam implements InputConverter<DeveloperExternalIdentity> { private String provider; private String subject; private String displayName; private String email; private DeveloperAuthType authType; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/OAuth2Config.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.portal; import com.alibaba.apiopenplatform.support.enums.GrantType; import lombok.Data; /** * @author zh */ @Data public class OAuth2Config { /** * 提供商 */ private String provider; /** * 名称 */ private String name; /** * 是否启用 */ private boolean enabled = true; /** * 授权模式 */ private GrantType grantType; /** * JWT断言配置 */ private JwtBearerConfig jwtBearerConfig; /** * 身份映射 */ private IdentityMapping identityMapping = new IdentityMapping(); } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/eslint.config.js: -------------------------------------------------------------------------------- ```javascript import js from '@eslint/js' import globals from 'globals' import reactHooks from 'eslint-plugin-react-hooks' import reactRefresh from 'eslint-plugin-react-refresh' import tseslint from 'typescript-eslint' import { globalIgnores } from 'eslint/config' export default tseslint.config([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite, ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, }, ]) ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/tsconfig.node.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2023", "lib": ["ES2023"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["vite.config.ts"] } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/AuthCodeConfig.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.support.portal; import lombok.Data; /** * @author zh */ @Data public class AuthCodeConfig { /** * 凭证 */ private String clientId; private String clientSecret; /** * 访问范围 */ private String scopes; /** * Issuer */ private String issuer; /** * 授权端点 */ private String authorizationEndpoint; /** * 令牌端点 */ private String tokenEndpoint; /** * 用户信息端点 */ private String userInfoEndpoint; /** * JWK Set URI */ private String jwkSetUri; /** * 重定向URI */ private String redirectUri; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, /* Path mapping */ "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/types/gateway.ts: -------------------------------------------------------------------------------- ```typescript export interface Gateway { gatewayId: string gatewayName: string gatewayType: 'APIG_API' | 'HIGRESS' | 'APIG_AI' | 'ADP_AI_GATEWAY' createAt: string apigConfig?: ApigConfig higressConfig?: HigressConfig } export interface ApigConfig { region: string accessKey: string secretKey: string } export interface HigressConfig { username: string address: string password: string } export interface NacosInstance { nacosId: string nacosName: string serverUrl: string username: string password?: string accessKey?: string secretKey?: string description: string adminId: string createAt?: string | number } export type GatewayType = 'APIG_API' | 'APIG_AI' | 'HIGRESS' | 'ADP_AI_GATEWAY' ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/tsconfig.app.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "allowSyntheticDefaultImports": true }, "include": ["src"] } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/vite.config.ts: -------------------------------------------------------------------------------- ```typescript import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' // https://vite.dev/config/ const env = loadEnv(process.env.NODE_ENV || 'development', process.cwd(), '') const apiPrefix = env.VITE_API_BASE_URL export default defineConfig({ plugins: [react()], server: { host: '0.0.0.0', allowedHosts: true, port: 5173, proxy: { [apiPrefix]: { target: 'http://localhost:8080', changeOrigin: true, rewrite: (p) => p.replace(new RegExp(`^${apiPrefix}`), ''), }, }, }, optimizeDeps: { include: ['monaco-editor/esm/vs/editor/editor.api'] }, build: { rollupOptions: { external: ['monaco-editor'] } }, define: { 'process.env': {} } }) ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/eslint.config.js: -------------------------------------------------------------------------------- ```javascript import js from '@eslint/js' import globals from 'globals' import reactHooks from 'eslint-plugin-react-hooks' import reactRefresh from 'eslint-plugin-react-refresh' import { defineConfig, globalIgnores } from 'eslint/config' export default defineConfig([ globalIgnores(['dist']), { files: ['**/*.{js,jsx}'], extends: [ js.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite, ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, parserOptions: { ecmaVersion: 'latest', ecmaFeatures: { jsx: true }, sourceType: 'module', }, }, rules: { 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], }, }, ]) ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/service/IdpService.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.service; import com.alibaba.apiopenplatform.support.enums.PublicKeyFormat; import com.alibaba.apiopenplatform.support.portal.OAuth2Config; import com.alibaba.apiopenplatform.support.portal.OidcConfig; import java.security.PublicKey; import java.util.List; /** * @author zh */ public interface IdpService { /** * 验证OIDC配置 * * @param oidcConfigs */ void validateOidcConfigs(List<OidcConfig> oidcConfigs); /** * 验证OAuth2配置 * * @param oauth2Configs */ void validateOAuth2Configs(List<OAuth2Config> oauth2Configs); /** * 加载JWT公钥 * * @param format * @param publicKey * @return */ PublicKey loadPublicKey(PublicKeyFormat format, String publicKey); } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/contexts/LoadingContext.tsx: -------------------------------------------------------------------------------- ```typescript import React, { createContext, useContext, useState, ReactNode } from 'react'; interface LoadingContextType { loading: boolean; setLoading: (loading: boolean) => void; } const LoadingContext = createContext<LoadingContextType | undefined>(undefined); export const useLoading = () => { const context = useContext(LoadingContext); if (context === undefined) { throw new Error('useLoading must be used within a LoadingProvider'); } return context; }; interface LoadingProviderProps { children: ReactNode; } export const LoadingProvider: React.FC<LoadingProviderProps> = ({ children }) => { const [loading, setLoading] = useState(false); return ( <LoadingContext.Provider value={{ loading, setLoading }}> {children} </LoadingContext.Provider> ); }; ``` -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- ```bash #!/bin/bash VERSION=1.0.0 set -e # 构建 server echo "=== Building backend server ===" echo "Building with Maven..." mvn clean package -DskipTests cd portal-bootstrap echo "Building backend Docker image..." docker buildx build \ --platform linux/amd64 \ -t himarket-server:$VERSION \ --load . echo "Backend server build completed" cd .. # 构建 frontend cd portal-web/api-portal-frontend echo "=== Building frontend ===" rm -rf ./dist npm install --force npm run build docker buildx build \ -t himarket-frontend:$VERSION \ --platform linux/amd64 \ --load . # 构建 admin cd ../api-portal-admin echo "=== Building admin ===" rm -rf ./dist npm install --force npm run build docker buildx build \ -t himarket-admin:$VERSION \ --platform linux/amd64 \ --load . echo "All images have been built successfully!" ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/public/MCP.svg: -------------------------------------------------------------------------------- ``` <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet"> <g fill="#000000"> <path d="M97.7 185.2 l-8.7 -8.7 40.5 -40.5 c22.3 -22.3 40.5 -40.9 40.5 -41.5 0 -0.6 -6.8 -7.8 -15 -16 l-15 -15 -32.8 32.8 -32.7 32.7 -4.3 -4.2 -4.2 -4.3 32.7 -32.7 32.8 -32.8 -15.5 -15.5 -15.5 -15.5 -41 41 -41.1 41 -3.9 -4 -4 -4 45.3 -45.3 45.2 -45.2 43.2 43.2 43.3 43.3 -41 41 -41 41 5 5 4.9 5 -3.9 4 c-2.1 2.2 -4.2 4 -4.5 4 -0.3 0 -4.5 -3.9 -9.3 -8.8z"/> <path d="M53.7 141.2 l-23.7 -23.7 35.3 -35.3 35.3 -35.2 3.9 4 3.9 4 -30.9 31 -31 31 15.5 15.5 15.5 15.5 31 -31 31 -31 4.3 4.3 4.2 4.2 -35.3 35.3 -35.2 35.2 -23.8 -23.8z"/> </g> </svg> ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/controller/OAuth2Controller.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.controller; import com.alibaba.apiopenplatform.dto.result.AuthResult; import com.alibaba.apiopenplatform.service.OAuth2Service; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * @author zh */ @RestController @RequiredArgsConstructor @RequestMapping("/developers/oauth2") public class OAuth2Controller { private final OAuth2Service oAuth2Service; @PostMapping("/token") public AuthResult authenticate(@RequestParam("grant_type") String grantType, @RequestParam("assertion") String assertion) { return oAuth2Service.authenticate(grantType, assertion); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/JwtConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.consumer; import lombok.Data; @Data public class JwtConfig { } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ProtocolType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum ProtocolType { HTTP, HTTPS, ; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/DomainType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum DomainType { DEFAULT, CUSTOM, ; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/CredentialMode.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum CredentialMode { SYSTEM, CUSTOM, ; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ProductType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum ProductType { REST_API, HTTP_API, MCP_SERVER, } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ConsumerAuthType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum ConsumerAuthType { KEY_AUTH, HMAC, JWT, ; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/service/OidcService.java: -------------------------------------------------------------------------------- ```java package com.alibaba.apiopenplatform.service; import com.alibaba.apiopenplatform.dto.result.AuthResult; import com.alibaba.apiopenplatform.dto.result.IdpResult; import com.alibaba.apiopenplatform.support.portal.OidcConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; public interface OidcService { /** * 重定向到授权服务器 * * @param provider * @param apiPrefix * @param request * @return */ String buildAuthorizationUrl(String provider, String apiPrefix, HttpServletRequest request); /** * 授权服务器回调 * * @param code * @param state * @param request * @param response * @return */ AuthResult handleCallback(String code, String state, HttpServletRequest request, HttpServletResponse response); /** * 可用的OIDC认证列表 * * @return */ List<IdpResult> getAvailableProviders(); } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/PortalUiConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.portal; import lombok.Data; @Data public class PortalUiConfig { private String logo; private String icon; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/UserType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum UserType { /** * 管理员用户 */ ADMIN, /** * 开发者用户 */ DEVELOPER, ; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/DeveloperStatus.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum DeveloperStatus { /** * 已激活 */ APPROVED, /** * 待审核 */ PENDING, ; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/vite.config.ts: -------------------------------------------------------------------------------- ```typescript import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' import { fileURLToPath } from 'url' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const env = loadEnv(process.env.NODE_ENV || 'development', process.cwd(), '') const apiPrefix = env.VITE_API_BASE_URL || '/api/v1' // https://vite.dev/config/ export default defineConfig({ plugins: [react()], server: { host: '0.0.0.0', port: 5174, proxy: { [apiPrefix]: { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(new RegExp(`^${apiPrefix}`), ''), }, }, }, resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, build: { rollupOptions: { output: { entryFileNames: 'index.js', chunkFileNames: 'chunk-[name].js', assetFileNames: 'assets/[name].[ext]' } } }, define: { 'process.env': {} } }) ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/product/HigressRefConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.product; import lombok.Data; @Data public class HigressRefConfig { private String routeName; private String mcpServerName; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/SubscriptionStatus.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum SubscriptionStatus { /** * Pending approval */ PENDING, /** * Approved and active */ APPROVED, ; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/admin/ResetPasswordParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.admin; import lombok.Data; /** * 修改密码参数 * */ @Data public class ResetPasswordParam { private String oldPassword; private String newPassword; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/QueryConsumerParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.consumer; import lombok.Data; @Data public class QueryConsumerParam { private String portalId; private String developerId; private String name; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/product/NacosRefConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.product; import lombok.Data; /** * Nacos MCP Server 配置 */ @Data public class NacosRefConfig { private String mcpServerName; private String namespaceId; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ConsumerStatus.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum ConsumerStatus { /** * 待审核 */ PENDING, /** * 已审核 */ APPROVED, /** * 不可用,对应的网关资源已删除 */ DISABLED, ; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/UnPublishProductParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.product; import lombok.Data; import javax.validation.constraints.NotBlank; @Data public class UnPublishProductParam { @NotBlank(message = "门户ID不能为空") private String portalId; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/ProductStatus.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; public enum ProductStatus { /** * 未配置API和MCP Server */ PENDING, /** * 已配置API或MCP Server */ READY, /** * 已发布 */ PUBLISHED, ; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/common/User.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.common; import com.alibaba.apiopenplatform.support.enums.UserType; import lombok.Builder; import lombok.Data; @Data @Builder public class User { private UserType userType; private String userId; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/HigressAPIType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; import lombok.Getter; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Getter public enum HigressAPIType { ROUTE("Route"), MCP("MCP"), ; private final String type; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/UnbindExternalIdentityParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.developer; import lombok.Data; /** * 解绑外部身份参数 * */ @Data public class UnbindExternalIdentityParam { private String providerName; private String providerSubject; private String portalId; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/UpdateDeveloperStatusParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.developer; import com.alibaba.apiopenplatform.support.enums.DeveloperStatus; import lombok.Data; @Data public class UpdateDeveloperStatusParam { private String portalId; private DeveloperStatus status; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/QuerySubscriptionParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.consumer; import com.alibaba.apiopenplatform.support.enums.SubscriptionStatus; import lombok.Data; @Data public class QuerySubscriptionParam { private SubscriptionStatus status; private String productName; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/APIGAPIType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor public enum APIGAPIType { REST("Rest"), HTTP("Http"), MCP("MCP"), ; private final String type; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/components/icons/McpServerIcon.tsx: -------------------------------------------------------------------------------- ```typescript import React from 'react'; import Icon from '@ant-design/icons'; import type { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; // 基于真实的 MCP.svg 文件的图标组件 const McpSvg = () => ( <svg width="1em" height="1em" viewBox="0 0 200 200" fill="currentColor" xmlns="http://www.w3.org/2000/svg" > <g fill="currentColor"> <path d="M97.7 185.2 l-8.7 -8.7 40.5 -40.5 c22.3 -22.3 40.5 -40.9 40.5 -41.5 0 -0.6 -6.8 -7.8 -15 -16 l-15 -15 -32.8 32.8 -32.7 32.7 -4.3 -4.2 -4.2 -4.3 32.7 -32.7 32.8 -32.8 -15.5 -15.5 -15.5 -15.5 -41 41 -41.1 41 -3.9 -4 -4 -4 45.3 -45.3 45.2 -45.2 43.2 43.2 43.3 43.3 -41 41 -41 41 5 5 4.9 5 -3.9 4 c-2.1 2.2 -4.2 4 -4.5 4 -0.3 0 -4.5 -3.9 -9.3 -8.8z"/> <path d="M53.7 141.2 l-23.7 -23.7 35.3 -35.3 35.3 -35.2 3.9 4 3.9 4 -30.9 31 -31 31 15.5 15.5 15.5 15.5 31 -31 31 -31 4.3 4.3 4.2 4.2 -35.3 35.3 -35.2 35.2 -23.8 -23.8z"/> </g> </svg> ); const McpServerIcon: React.FC<Partial<CustomIconComponentProps>> = (props) => ( <Icon component={McpSvg} {...props} /> ); export default McpServerIcon; ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/QueryDeveloperParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.developer; import com.alibaba.apiopenplatform.support.enums.DeveloperStatus; import lombok.Data; @Data public class QueryDeveloperParam { private String portalId; private String username; private DeveloperStatus status; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/nacos/QueryNacosNamespaceParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.nacos; import lombok.Data; /** * 查询Nacos命名空间参数 * */ @Data public class QueryNacosNamespaceParam extends CreateNacosParam { /** * runtime namespace to query on remote Nacos (not stored on instance) */ private String namespace; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/product/APIGRefConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.product; import lombok.Data; @Data public class APIGRefConfig { private String apiId; private String apiName; /** * MCP标识信息 */ private String mcpServerId; private String mcpRouteId; private String mcpServerName; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/common/Encrypted.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.common; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Encrypted { } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/JwtConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.consumer.JwtConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class JwtConfigConverter extends JsonConverter<JwtConfig> { protected JwtConfigConverter() { super(JwtConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/NacosRefConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.product.NacosRefConfig; import javax.persistence.Converter; @Converter public class NacosRefConfigConverter extends JsonConverter<NacosRefConfig> { public NacosRefConfigConverter() { super(NacosRefConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/APIGConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.gateway.APIGConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class APIGConfigConverter extends JsonConverter<APIGConfig> { protected APIGConfigConverter() { super(APIGConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HmacConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.consumer.HmacConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class HmacConfigConverter extends JsonConverter<HmacConfig> { protected HmacConfigConverter() { super(HmacConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/DeveloperLoginParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.developer; import lombok.Data; import javax.validation.constraints.NotBlank; import lombok.NoArgsConstructor; @Data public class DeveloperLoginParam { @NotBlank(message = "用户名不能为空") private String username; @NotBlank(message = "密码不能为空") private String password; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/App.css: -------------------------------------------------------------------------------- ```css #root { } .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.react:hover { filter: drop-shadow(0 0 2em #61dafbaa); } @keyframes logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @media (prefers-reduced-motion: no-preference) { a:nth-of-type(2) .logo { animation: logo-spin infinite 20s linear; } } .card { padding: 2em; } .read-the-docs { color: #888; } /* 用户下拉菜单样式 */ .user-dropdown .ant-dropdown-menu { border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); border: 1px solid #f0f0f0; min-width: 200px; } .user-dropdown .ant-dropdown-menu-item { padding: 8px 12px; font-size: 14px; } .user-dropdown .ant-dropdown-menu-item:hover { background-color: #f5f5f5; } .user-dropdown .ant-dropdown-menu-item-disabled { cursor: default; color: inherit; background-color: transparent; } .user-dropdown .ant-dropdown-menu-item-disabled:hover { background-color: transparent; } .user-dropdown .ant-dropdown-menu-divider { margin: 4px 0; } ``` -------------------------------------------------------------------------------- /deploy/helm/Chart.yaml: -------------------------------------------------------------------------------- ```yaml apiVersion: v2 name: himarket description: HiMarket AI 开放平台 Helm Chart # A chart can be either an 'application' or a 'library' chart. # # Application charts are a collection of templates that can be packaged into versioned archives # to be deployed. # # Library charts provide useful utilities or functions for the chart developer. They're included as # a dependency of application charts to inject those utilities and functions into the rendering # pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "1.16.0" ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ApiKeyConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class ApiKeyConfigConverter extends JsonConverter<ApiKeyConfig> { protected ApiKeyConfigConverter() { super(ApiKeyConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/GatewayConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.gateway.GatewayConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class GatewayConfigConverter extends JsonConverter<GatewayConfig> { public GatewayConfigConverter() { super(GatewayConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/APIGRefConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.product.APIGRefConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class APIGRefConfigConverter extends JsonConverter<APIGRefConfig> { protected APIGRefConfigConverter() { super(APIGRefConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HigressConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.gateway.HigressConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class HigressConfigConverter extends JsonConverter<HigressConfig> { protected HigressConfigConverter() { super(HigressConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/PortalUiConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.portal.PortalUiConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class PortalUiConfigConverter extends JsonConverter<PortalUiConfig> { public PortalUiConfigConverter() { super(PortalUiConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/PortalDeletingEvent.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.event; import lombok.Getter; import org.springframework.context.ApplicationEvent; @Getter public class PortalDeletingEvent extends ApplicationEvent { private final String portalId; public PortalDeletingEvent(String portalId) { super(portalId); this.portalId = portalId; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/admin/AdminLoginParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.admin; import lombok.Data; import javax.validation.constraints.NotBlank; import lombok.NoArgsConstructor; /** * 管理员登录参数DTO * */ @Data public class AdminLoginParam { @NotBlank(message = "用户名不能为空") private String username; @NotBlank(message = "密码不能为空") private String password; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/SourceType.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.enums; /** * 数据来源类型枚举 * */ public enum SourceType { /** * 来自Gateway (Higress, APIG等) */ GATEWAY, /** * 来自Nacos注册中心 */ NACOS; public boolean isGateway() { return this == GATEWAY; } public boolean isNacos() { return this == NACOS; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/ProductDeletingEvent.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.event; import lombok.Getter; import org.springframework.context.ApplicationEvent; @Getter public class ProductDeletingEvent extends ApplicationEvent { private final String productId; public ProductDeletingEvent(String productId) { super(productId); this.productId = productId; } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HigressRefConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.product.HigressRefConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class HigressRefConfigConverter extends JsonConverter<HigressRefConfig> { protected HigressRefConfigConverter() { super(HigressRefConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/ConsumerCredentialRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.ConsumerCredential; import java.util.Optional; public interface ConsumerCredentialRepository extends BaseRepository<ConsumerCredential, Long> { Optional<ConsumerCredential> findByConsumerId(String consumerId); void deleteAllByConsumerId(String consumerId); } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ConsumerAuthConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.consumer.ConsumerAuthConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class ConsumerAuthConfigConverter extends JsonConverter<ConsumerAuthConfig> { public ConsumerAuthConfigConverter() { super(ConsumerAuthConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/AdpAIAuthConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.consumer; import lombok.Builder; import lombok.Data; /** * ADP AI网关授权配置 */ @Data @Builder public class AdpAIAuthConfig { /** * MCP Server名称 */ private String mcpServerName; /** * 消费者ID */ private String consumerId; /** * 网关实例ID */ private String gwInstanceId; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/PortalSettingConfigConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.converter; import com.alibaba.apiopenplatform.support.portal.PortalSettingConfig; import javax.persistence.Converter; @Converter(autoApply = true) public class PortalSettingConfigConverter extends JsonConverter<PortalSettingConfig> { public PortalSettingConfigConverter() { super(PortalSettingConfig.class); } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/DeveloperDeletingEvent.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.event; import lombok.Getter; import org.springframework.context.ApplicationEvent; @Getter public class DeveloperDeletingEvent extends ApplicationEvent { private final String developerId; public DeveloperDeletingEvent(String developerId) { super(developerId); this.developerId = developerId; } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/gateway/HigressConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.gateway; import com.alibaba.apiopenplatform.support.common.Encrypted; import lombok.Data; @Data public class HigressConfig { private String address; private String username; @Encrypted private String password; public String buildUniqueKey() { return String.format("%s:%s:%s", address, username, password); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/HmacConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.consumer; import com.alibaba.apiopenplatform.support.enums.CredentialMode; import lombok.Data; import java.util.List; @Data public class HmacConfig { private List<HmacCredential> credentials; @Data public static class HmacCredential { private String ak; private String sk; private CredentialMode mode; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/QueryProductParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.product; import com.alibaba.apiopenplatform.support.enums.ProductStatus; import com.alibaba.apiopenplatform.support.enums.ProductType; import lombok.Data; @Data public class QueryProductParam { private String portalId; private ProductType type; private String name; private String category; private ProductStatus status; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/proxy.conf: -------------------------------------------------------------------------------- ``` location ^~ /api/v1 { proxy_http_version 1.1; proxy_set_header Connection ""; # 保留原始host header - 这是最重要的配置 proxy_set_header Host $http_host; # 设置X-Forwarded-Host header proxy_set_header X-Forwarded-Host $http_host; # 设置真实的客户端IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置协议信息 proxy_set_header X-Forwarded-Proto $scheme; # 设置原始请求的Origin header proxy_set_header Origin $http_origin; # 设置Referer header proxy_set_header Referer $http_referer; # 设置User-Agent proxy_set_header User-Agent $http_user_agent; # 超时设置 proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; rewrite ^/api/v1/(.*)$ /$1 break; proxy_pass {{ HIMARKET_SERVER }}; } location ~ .*\.(js|css|gif|jpg|jpeg|png|svg|json|otf|ico)$ { root /app; } location / { try_files $uri $uri/ /index.html; root /app; index index.html index.htm; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/ConsumerAuthConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.consumer; import lombok.Builder; import lombok.Data; @Data @Builder public class ConsumerAuthConfig { /** * for APIG */ private APIGAuthConfig apigAuthConfig; /** * for Higress */ private HigressAuthConfig higressAuthConfig; /** * for ADP AI Gateway */ private AdpAIAuthConfig adpAIAuthConfig; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/gateway/APIGConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.gateway; import com.alibaba.apiopenplatform.support.common.Encrypted; import lombok.Data; @Data public class APIGConfig { @Encrypted private String accessKey; @Encrypted private String secretKey; private String region; public String buildUniqueKey() { return String.format("%s:%s:%s", accessKey, secretKey, region); } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/PublishProductParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.product; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.ProductPublication; import lombok.Data; import javax.validation.constraints.NotBlank; @Data public class PublishProductParam implements InputConverter<ProductPublication> { @NotBlank(message = "门户ID不能为空") private String portalId; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/MCPServerResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data @Schema( oneOf = { APIGMCPServerResult.class, HigressMCPServerResult.class, NacosMCPServerResult.class }, discriminatorProperty = "type" ) public class MCPServerResult { protected String mcpServerName; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/GatewayMCPServerResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data @Schema( oneOf = { APIGMCPServerResult.class, HigressMCPServerResult.class, AdpMCPServerResult.class }, discriminatorProperty = "type" ) public class GatewayMCPServerResult { protected String mcpServerName; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/CreateSubscriptionParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.consumer; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.ProductSubscription; import lombok.Data; import javax.validation.constraints.NotBlank; @Data public class CreateSubscriptionParam implements InputConverter<ProductSubscription> { @NotBlank(message = "Product ID不能为空") private String productId; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/GatewayRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.Gateway; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import java.util.Optional; public interface GatewayRepository extends BaseRepository<Gateway, Long> { Optional<Gateway> findByGatewayId(String gatewayId); Page<Gateway> findByAdminId(String adminId, Pageable pageable); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/AdminAuth.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.annotation; import org.springframework.security.access.prepost.PreAuthorize; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasRole('ADMIN')") public @interface AdminAuth { } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/APIConfigResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import lombok.Data; @Data public class APIConfigResult { private String spec; private APIMetadata meta; @Data public static class APIMetadata { /** * 来源 * API网关/Higress */ private String source; /** * 类型 * API网关:HTTP/REST * Higress:Route */ private String type; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/DeveloperAuth.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.annotation; import org.springframework.security.access.prepost.PreAuthorize; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasRole('DEVELOPER')") public @interface DeveloperAuth { } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ConsumerResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.Consumer; import lombok.Data; import java.time.LocalDateTime; @Data public class ConsumerResult implements OutputConverter<ConsumerResult, Consumer> { private String consumerId; private String name; private String description; private LocalDateTime createAt; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/AdministratorRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.Administrator; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; /** * 管理员数据访问接口,提供管理员相关的数据库操作 * */ public interface AdministratorRepository extends JpaRepository<Administrator, Long> { Optional<Administrator> findByAdminId(String adminId); Optional<Administrator> findByUsername(String username); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/AdminResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.Administrator; import lombok.Data; import java.time.LocalDateTime; @Data public class AdminResult implements OutputConverter<AdminResult, Administrator> { private String adminId; private String username; private LocalDateTime createAt; private LocalDateTime updatedAt; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/AdminOrDeveloperAuth.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.annotation; import org.springframework.security.access.prepost.PreAuthorize; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("hasRole('ADMIN') or hasRole('DEVELOPER')") public @interface AdminOrDeveloperAuth { } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/utils/PasswordHasher.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.utils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; public class PasswordHasher { private static final BCryptPasswordEncoder ENCODER = new BCryptPasswordEncoder(); public static String hash(String plainPassword) { return ENCODER.encode(plainPassword); } public static boolean verify(String plainPassword, String hashed) { return ENCODER.matches(plainPassword, hashed); } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/types/consumer.ts: -------------------------------------------------------------------------------- ```typescript // Consumer 相关类型定义 export interface Consumer { consumerId: string; name: string; description?: string; status?: string; createAt?: string; createdAt?: string; // 支持两种字段名 enabled?: boolean; } // Portal 开发者统计信息(之前错误命名为Consumer) export interface DeveloperStats { id: string; name: string; email: string; status: string; plan: string; joinedAt: string; lastActive: string; apiCalls: number; subscriptions: number; } // 凭据相关类型 export interface HMACCredential { ak?: string; sk?: string; } export interface APIKeyCredential { apiKey?: string; } export type ConsumerCredential = HMACCredential | APIKeyCredential; export interface ConsumerCredentialResult { apiKeyConfig?: { credentials?: Array<{ apiKey?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; source?: string; key?: string; }; hmacConfig?: { credentials?: Array<{ ak?: string; sk?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; source?: string; accessKeyId?: string; secretAccessKey?: string; }; } export interface Subscription { subscriptionId: string; productId: string; productName?: string; status: string; createdAt: string; } export interface CreateCredentialParam { credentialType: 'HMAC' | 'API_KEY'; apiKey?: string; } ``` -------------------------------------------------------------------------------- /portal-bootstrap/src/main/resources/application.yaml: -------------------------------------------------------------------------------- ```yaml spring: datasource: url: jdbc:mariadb://${db.host}:${db.port}/${db.name}?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC username: ${db.username} password: ${db.password} driver-class-name: org.mariadb.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true #db: # host: YourDBHost # port: 3306 # name: YourDBName # username: YourDBUser # password: YourDBPassword db: host: rm-uf6pc9n1jzi2478l4eo.mysql.rds.aliyuncs.com port: 3306 name: portal_db username: portal_test password: portal-Go # -Ddb.host=rm-uf6pc9n1jzi2478l4eo.mysql.rds.aliyuncs.com \ # -Ddb.port=3306 \ # -Ddb.name=portal_db \ # -Ddb.username=portal_test \ # -Ddb.password=portal-Go \ # Encryptor encryption: root-key: portalmanagement springdoc: api-docs: enabled: true path: /portal/v3/api-docs swagger-ui: path: /portal/swagger-ui.html disable-swagger-default-url: true packages-to-scan: com.alibaba.apiopenplatform.controller jwt: secret: YourJWTSecret expiration: 2h logging: pattern: console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" level: root: INFO com.alibaba.apiopenplatform: INFO ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/DeveloperResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.Developer; import lombok.Data; import java.time.LocalDateTime; @Data public class DeveloperResult implements OutputConverter<DeveloperResult, Developer> { private String developerId; private String portalId; private String username; private String status; private String avatarUrl; private LocalDateTime createAt; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/gateway/GatewayConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.gateway; import com.alibaba.apiopenplatform.entity.Gateway; import com.alibaba.apiopenplatform.support.enums.GatewayType; import lombok.Builder; import lombok.Data; @Data @Builder public class GatewayConfig { private GatewayType gatewayType; private APIGConfig apigConfig; private AdpAIGatewayConfig adpAIGatewayConfig; private HigressConfig higressConfig; /** * 网关实体引用,用于获取gatewayId等信息 */ private Gateway gateway; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ProductPublicationResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.ProductPublication; import lombok.Data; import java.time.LocalDateTime; @Data public class ProductPublicationResult implements OutputConverter<ProductPublicationResult, ProductPublication> { private String portalId; private String portalName; private Boolean autoApproveSubscriptions = false; private LocalDateTime createAt; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/NacosInstanceRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.NacosInstance; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; @Repository public interface NacosInstanceRepository extends BaseRepository<NacosInstance, Long> { Optional<NacosInstance> findByNacosId(String nacosId); Optional<NacosInstance> findByNacosName(String nacosName); } ``` -------------------------------------------------------------------------------- /portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/config/SwaggerConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.config; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { @Bean public OpenAPI openAPI() { return new OpenAPI() .info(new Info() .title("开放平台 API") .version("1.0.0") .description("API 文档描述")); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/ProductPublication.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.entity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.persistence.*; @EqualsAndHashCode(callSuper = true) @Entity @Table(name = "publication") @Data public class ProductPublication extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "portal_id", length = 64, nullable = false) private String portalId; @Column(name = "product_id", length = 64, nullable = false) private String productId; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/AdpMcpServerListResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import java.util.List; @Data public class AdpMcpServerListResult { private Integer code; private String message; private String msg; private AdpMcpServerListData data; @Data public static class AdpMcpServerListData { private List<AdpMCPServerResult> records; private Integer total; private Integer size; private Integer current; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/exception/BusinessException.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.exception; import lombok.Getter; import org.springframework.http.HttpStatus; @Getter public class BusinessException extends RuntimeException { private final HttpStatus status; private final String code; private final String message; public BusinessException(ErrorCode errorCode, Object... args) { super(errorCode.getMessage(args)); this.status = errorCode.getStatus(); this.code = errorCode.name(); this.message = errorCode.getMessage(args); } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/consumer/ApiKeyConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.consumer; import com.alibaba.apiopenplatform.support.enums.CredentialMode; import lombok.Data; import java.util.List; @Data public class ApiKeyConfig { private List<ApiKeyCredential> credentials; /** * apikey的位置 */ private String source = "Default"; /** * apikey参数名称 */ private String key = "Authorization"; @Data public static class ApiKeyCredential { private String apiKey; private CredentialMode mode = CredentialMode.SYSTEM; } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/PortalSettingConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.portal; import lombok.Data; import java.util.List; @Data public class PortalSettingConfig { /** * 内置的账号密码认证,默认开启 */ private Boolean builtinAuthEnabled = true; /** * OIDC配置 */ private List<OidcConfig> oidcConfigs; /** * 开启自动审批开发者注册 */ private Boolean autoApproveDevelopers = false; /** * 开启自动审批订阅申请 */ private Boolean autoApproveSubscriptions = true; /** * OAuth2配置 */ private List<OAuth2Config> oauth2Configs; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/admin/AdminCreateParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.admin; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.Administrator; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; /** * 管理员注册/创建参数DTO * */ @Data public class AdminCreateParam implements InputConverter<Administrator> { @NotBlank(message = "用户名不能为空") private String username; @NotBlank(message = "密码不能为空") private String password; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/PortalDomainRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.PortalDomain; import java.util.List; import java.util.Optional; public interface PortalDomainRepository extends BaseRepository<PortalDomain, Long> { Optional<PortalDomain> findByDomain(String domain); Optional<PortalDomain> findByPortalIdAndDomain(String portalId, String domain); List<PortalDomain> findAllByPortalId(String portalId); List<PortalDomain> findAllByPortalIdIn(List<String> portalIds); void deleteAllByPortalId(String portalId); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/NacosResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.NacosInstance; import lombok.Data; import java.time.LocalDateTime; @Data public class NacosResult implements OutputConverter<NacosResult, NacosInstance> { private String nacosId; private String nacosName; private String serverUrl; private String username; private String accessKey; private String description; private String adminId; private LocalDateTime createAt; } ``` -------------------------------------------------------------------------------- /portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/PortalApplication.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @EnableJpaAuditing public class PortalApplication { public static void main(String[] args) { SpringApplication.run(PortalApplication.class, args); } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/CreateConsumerParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.consumer; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.Consumer; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; @Data public class CreateConsumerParam implements InputConverter<Consumer> { @NotBlank(message = "Consumer名称不能为空") @Size(max = 50, message = "Consumer名称长度不能超过50个字符") private String name; @Size(max = 256, message = "Consumer描述长度不能超过256个字符") private String description; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/APIResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.support.enums.GatewayType; import com.aliyun.sdk.service.apig20240327.models.HttpApiApiInfo; import lombok.Data; @Data public class APIResult implements OutputConverter<APIResult, HttpApiApiInfo> { private String apiId; private String apiName; @Override public APIResult convertFrom(HttpApiApiInfo apiInfo) { setApiId(apiInfo.getHttpApiId()); setApiName(apiInfo.getName()); return this; } } ``` -------------------------------------------------------------------------------- /deploy/docker/docker-compose.yml: -------------------------------------------------------------------------------- ```yaml version: '3' services: mysql: image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/mysql:1.0.0 container_name: mysql environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=portal_db - MYSQL_USER=portal_user - MYSQL_PASSWORD=portal_pass ports: - "3306:3306" volumes: - ./mysql/data:/var/lib/mysql restart: always himarket-server: image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-server:1.0.0 container_name: himarket-server environment: - DB_HOST=mysql - DB_PORT=3306 - DB_NAME=portal_db - DB_USERNAME=portal_user - DB_PASSWORD=portal_pass ports: - "8080:8080" depends_on: - mysql restart: always himarket-admin: image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-admin:1.0.0 container_name: himarket-admin environment: - HIMARKET_SERVER=http://himarket-server:8080 ports: - "5174:8000" depends_on: - himarket-server restart: always himarket-frontend: image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-frontend:1.0.0 container_name: himarket-frontend environment: - HIMARKET_SERVER=http://himarket-server:8080 ports: - "5173:8000" depends_on: - himarket-server restart: always ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/constant/CommonConstants.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.constant; public class CommonConstants { // Token相关 public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String BEARER_PREFIX = "Bearer "; // 角色前缀 public static final String ROLE_PREFIX = "ROLE_"; public static final String USER_TYPE = "userType"; public static final String USER_ID = "userId"; // Cookie相关 public static final String AUTH_TOKEN_COOKIE = "auth_token"; // HTTP public static final Integer HTTP_PORT = 80; public static final Integer HTTPS_PORT = 443; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/UpdateCredentialParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.consumer; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.ConsumerCredential; import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig; import com.alibaba.apiopenplatform.support.consumer.HmacConfig; import com.alibaba.apiopenplatform.support.consumer.JwtConfig; import lombok.Data; @Data public class UpdateCredentialParam implements InputConverter<ConsumerCredential> { private ApiKeyConfig apiKeyConfig; private HmacConfig hmacConfig; private JwtConfig jwtConfig; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/router.tsx: -------------------------------------------------------------------------------- ```typescript import { Routes, Route } from "react-router-dom"; import Home from "./pages/Home"; import Apis from "./pages/Apis"; import ApiDetail from "./pages/ApiDetail"; import Consumers from "./pages/Consumers"; import ConsumerDetail from "./pages/ConsumerDetail"; import GettingStarted from "./pages/GettingStarted"; import Mcp from "./pages/Mcp"; import Login from "./pages/Login"; import Register from "./pages/Register"; import Profile from './pages/Profile' import McpDetail from "./pages/McpDetail"; import Callback from "./pages/Callback"; import OidcCallback from "./pages/OidcCallback"; export function Router() { return ( <Routes> <Route path="/" element={<Home />} /> <Route path="/getting-started" element={<GettingStarted />} /> <Route path="/apis" element={<Apis />} /> <Route path="/apis/:id" element={<ApiDetail />} /> <Route path="/consumers/:consumerId" element={<ConsumerDetail />} /> <Route path="/consumers" element={<Consumers />} /> <Route path="/mcp" element={<Mcp />} /> <Route path="/mcp/:mcpName" element={<McpDetail />} /> <Route path="/login" element={<Login />} /> <Route path="/register" element={<Register />} /> <Route path="/profile" element={<Profile />} /> <Route path="/callback" element={<Callback />} /> <Route path="/oidc/callback" element={<OidcCallback />} /> {/* 其他页面可继续添加 */} </Routes> ); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/converter/OutputConverter.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.converter; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; public interface OutputConverter<Target extends OutputConverter<Target, Source>, Source> { /** * 以Source更新Target * * @param source * @return */ @SuppressWarnings("unchecked") default Target convertFrom(Source source) { BeanUtil.copyProperties(source, this, configOptions()); return (Target) this; } default CopyOptions configOptions() { return CopyOptions.create().ignoreNullValue().ignoreError(); } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/routes/index.tsx: -------------------------------------------------------------------------------- ```typescript import { createBrowserRouter, Navigate } from 'react-router-dom'; import LayoutWrapper from '@/components/LayoutWrapper'; import Portals from '@/pages/Portals'; import ApiProducts from '@/pages/ApiProducts'; import GatewayConsoles from '@/pages/GatewayConsoles'; import NacosConsoles from '@/pages/NacosConsoles'; import PortalDetail from '@/pages/PortalDetail'; import ApiProductDetail from '@/pages/ApiProductDetail'; import Login from '@/pages/Login'; export const router = createBrowserRouter([ { path: '/login', element: <Login />, }, { path: '/', element: <LayoutWrapper />, children: [ { index: true, element: <Navigate to="/portals" replace />, }, { path: 'portals', element: <Portals />, }, { path: 'portals/detail', element: <PortalDetail />, }, { path: 'api-products', element: <ApiProducts />, }, { path: 'api-products/detail', element: <ApiProductDetail />, }, { path: 'consoles', element: <Navigate to="/consoles/gateway" replace />, }, { path: 'consoles/gateway', element: <GatewayConsoles />, }, { path: 'consoles/nacos', element: <NacosConsoles />, }, { path: '*', element: <Navigate to="/portals" replace />, }, ], }, ]); ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ConsumerCredentialResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.ConsumerCredential; import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig; import com.alibaba.apiopenplatform.support.consumer.HmacConfig; import com.alibaba.apiopenplatform.support.consumer.JwtConfig; import lombok.Data; @Data public class ConsumerCredentialResult implements OutputConverter<ConsumerCredentialResult, ConsumerCredential> { private JwtConfig jwtConfig; private HmacConfig hmacConfig; private ApiKeyConfig apiKeyConfig; } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/CreatePortalParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.portal; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.Portal; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; @Schema(description = "创建门户参数") @Data public class CreatePortalParam implements InputConverter<Portal> { @NotBlank(message = "门户名称不能为空") @Size(max = 50, message = "门户名称长度不能超过50个字符") private String name; @Size(max = 1024, message = "门户描述长度不能超过1024个字符") private String description; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/types/consumer.ts: -------------------------------------------------------------------------------- ```typescript import type { Product } from "./index"; export interface Consumer { consumerId: string; name: string; description?: string; status?: string; createAt?: string; enabled?: boolean; } export type ConsumerCredential = HMACCredential | APIKeyCredential; export interface HMACCredential { ak?: string; sk?: string; mode?: 'SYSTEM' | 'CUSTOM'; } export interface APIKeyCredential { apiKey?: string; mode?: 'SYSTEM' | 'CUSTOM'; } export interface ConsumerCredentialResult { apiKeyConfig?: { credentials?: Array<{ apiKey?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; source?: string; key?: string; }; hmacConfig?: { credentials?: Array<{ ak?: string; sk?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; }; jwtConfig?: Record<string, unknown>; } export interface Subscription { productId: string; consumerId: string; status: 'PENDING' | 'APPROVED'; createAt: string; updatedAt: string; productName: string; productType: 'REST_API' | 'MCP_SERVER'; consumerName?: string; product?: Product; } export interface CreateCredentialParam { apiKeyConfig?: { credentials?: Array<{ apiKey?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; source?: string; key?: string; }; hmacConfig?: { credentials?: Array<{ ak?: string; sk?: string; mode?: 'SYSTEM' | 'CUSTOM'; }>; }; jwtConfig?: Record<string, unknown>; } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/package.json: -------------------------------------------------------------------------------- ```json { "name": "portal-frontend", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview", "prepare": "husky", "serve": "npm run build && npm start", "type-check": "tsc -b" }, "dependencies": { "@ant-design/icons": "^5.2.7", "antd": "^5.15.8", "axios": "^1.10.0", "clsx": "^2.1.1", "js-yaml": "^4.1.0", "monaco-editor": "^0.52.2", "postcss": "^8.5.6", "react": "^18.0.0", "react-dom": "^18.0.0", "react-markdown": "^10.1.0", "react-markdown-editor-lite": "^1.3.4", "react-monaco-editor": "^0.59.0", "react-router-dom": "^6.23.1", "remark-gfm": "^4.0.1", "swagger-ui-react": "^5.29.0", "terser": "^5.43.1" }, "devDependencies": { "@eslint/js": "^9.30.1", "@types/js-yaml": "^4.0.9", "@types/node": "^24.3.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.3", "@types/swagger-ui-react": "^5.18.0", "@vitejs/plugin-react": "^4.6.0", "autoprefixer": "^10.4.19", "compression": "^1.8.1", "eslint": "^9.30.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "husky": "^9.1.7", "postcss": "^8.5.6", "tailwindcss": "^3.4.3", "typescript": "~5.8.3", "typescript-eslint": "^8.35.1", "vite": "^4.5.14" } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/src/index.css: -------------------------------------------------------------------------------- ```css @tailwind base; @tailwind components; @tailwind utilities; :root { --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --card: oklch(1 0 0); --card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0); --popover-foreground: oklch(0.145 0 0); --primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.205 0 0); --muted: oklch(0.97 0 0); --muted-foreground: oklch(0.556 0 0); --accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0); --destructive: oklch(0.577 0.245 27.325); --border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.708 0 0); } .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --card: oklch(0.205 0 0); --card-foreground: oklch(0.985 0 0); --popover: oklch(0.205 0 0); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.922 0 0); --primary-foreground: oklch(0.205 0 0); --secondary: oklch(0.269 0 0); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.269 0 0); --muted-foreground: oklch(0.708 0 0); --accent: oklch(0.269 0 0); --accent-foreground: oklch(0.985 0 0); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.556 0 0); } @layer base { * { @apply border-gray-200; } body { @apply bg-white text-gray-900; } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/src/index.css: -------------------------------------------------------------------------------- ```css @tailwind base; @tailwind components; @tailwind utilities; :root { --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --card: oklch(1 0 0); --card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0); --popover-foreground: oklch(0.145 0 0); --primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.205 0 0); --muted: oklch(0.97 0 0); --muted-foreground: oklch(0.556 0 0); --accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0); --destructive: oklch(0.577 0.245 27.325); --border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.708 0 0); } .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --card: oklch(0.205 0 0); --card-foreground: oklch(0.985 0 0); --popover: oklch(0.205 0 0); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.922 0 0); --primary-foreground: oklch(0.205 0 0); --secondary: oklch(0.269 0 0); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.269 0 0); --muted-foreground: oklch(0.708 0 0); --accent: oklch(0.269 0 0); --accent-foreground: oklch(0.985 0 0); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.556 0 0); } @layer base { * { @apply border-gray-200; } body { @apply bg-white text-gray-900; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/HigressMCPServerResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.service.gateway.HigressOperator.HigressMCPConfig; import lombok.Data; import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data public class HigressMCPServerResult extends GatewayMCPServerResult implements OutputConverter<HigressMCPServerResult, HigressMCPConfig> { @Override public HigressMCPServerResult convertFrom(HigressMCPConfig mcp) { HigressMCPServerResult r = OutputConverter.super.convertFrom(mcp); r.setMcpServerName(mcp.getName()); return r; } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/PortalRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.Portal; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import java.util.Optional; public interface PortalRepository extends BaseRepository<Portal, Long> { Optional<Portal> findFirstByOrderByIdAsc(); Optional<Portal> findByPortalIdAndAdminId(String portalId, String adminId); Optional<Portal> findByPortalId(String portalId); Optional<Portal> findByNameAndAdminId(String name, String adminId); Optional<Portal> findByName(String name); Page<Portal> findByAdminId(String adminId, Pageable pageable); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/SubscriptionResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.apiopenplatform.entity.ProductSubscription; import com.alibaba.apiopenplatform.support.enums.ProductType; import lombok.Data; import java.time.LocalDateTime; @Data public class SubscriptionResult implements OutputConverter<SubscriptionResult, ProductSubscription> { private String productId; private String consumerId; private String status; private ProductType productType; private String productName; private String consumerName; private LocalDateTime createAt; private LocalDateTime updatedAt; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/OidcConfig.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.support.portal; import com.alibaba.apiopenplatform.support.enums.GrantType; import lombok.Data; @Data public class OidcConfig { /** * 提供商 */ private String provider; /** * 对外的名称 */ private String name; /** * 登录按钮logo */ private String logoUrl; /** * 是否启用 */ private boolean enabled = true; /** * 授权类型,默认授权码 */ private GrantType grantType = GrantType.AUTHORIZATION_CODE; /** * 授权码模式配置 */ private AuthCodeConfig authCodeConfig; /** * 身份映射 */ private IdentityMapping identityMapping = new IdentityMapping(); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/BindDomainParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.portal; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.PortalDomain; import com.alibaba.apiopenplatform.support.enums.DomainType; import com.alibaba.apiopenplatform.support.enums.ProtocolType; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data public class BindDomainParam implements InputConverter<PortalDomain> { @NotBlank(message = "门户域名不能为空") private String domain; @NotNull(message = "域名协议不能为空") private ProtocolType protocol; private DomainType type = DomainType.CUSTOM; } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/SubscriptionRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.ProductSubscription; import java.util.List; import java.util.Optional; public interface SubscriptionRepository extends BaseRepository<ProductSubscription, Long> { Optional<ProductSubscription> findByConsumerIdAndProductId(String consumerId, String productId); List<ProductSubscription> findALlByConsumerId(String consumerId); List<ProductSubscription> findAllByProductId(String productId); void deleteAllByConsumerId(String consumerId); void deleteAllByProductId(String productId); void deleteByConsumerIdAndProductId(String consumerId, String productId); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/core/response/Response.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.core.response; import lombok.Data; import lombok.experimental.Accessors; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class Response<T> { private String code; private String message; private T data; public static <T> Response<T> ok(T data) { return new Response<T>() .setCode("SUCCESS") .setData(data); } public static <T> Response<T> fail(String code, String message) { return new Response<T>() .setCode(code) .setMessage(message); } } ``` -------------------------------------------------------------------------------- /portal-web/api-portal-admin/public/vite.svg: -------------------------------------------------------------------------------- ``` <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> ``` -------------------------------------------------------------------------------- /portal-web/api-portal-frontend/public/vite.svg: -------------------------------------------------------------------------------- ``` <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/nacos/QueryNacosParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.nacos; import lombok.Data; import javax.validation.constraints.NotBlank; import com.aliyun.teaopenapi.models.Config; /** * 查询Nacos集群参数 * */ @Data public class QueryNacosParam { @NotBlank(message = "地域不能为空") private String regionId; @NotBlank(message = "accessKey不能为空") private String accessKey; @NotBlank(message = "secretKey不能为空") private String secretKey; public Config toClientConfig() { Config config = new Config() .setAccessKeyId(this.accessKey) .setAccessKeySecret(this.secretKey) .setRegionId(this.regionId); return config; } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/service/gateway/client/GatewayClient.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.service.gateway.client; import java.net.InetSocketAddress; import java.net.Socket; public abstract class GatewayClient { public void close() { } protected String getAPIGEndpoint(String region) { String internalEndpoint = String.format("apig-vpc.%s.aliyuncs.com", region); String publicEndpoint = String.format("apig.%s.aliyuncs.com", region); // 优先尝试内网endpoint try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(internalEndpoint, 443), 1000); // 1秒超时 return internalEndpoint; } catch (Exception e) { return publicEndpoint; } } } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/NacosMCPServerResult.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.result; import com.alibaba.apiopenplatform.dto.converter.OutputConverter; import com.alibaba.nacos.api.ai.model.mcp.McpServerBasicInfo; import lombok.Data; import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) public class NacosMCPServerResult extends MCPServerResult implements OutputConverter<NacosMCPServerResult, McpServerBasicInfo> { private String version; @Override public NacosMCPServerResult convertFrom(McpServerBasicInfo basicInfo) { OutputConverter.super.convertFrom(basicInfo); setMcpServerName(basicInfo.getName()); setVersion(basicInfo.getVersion()); return this; } } ``` -------------------------------------------------------------------------------- /portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/DeveloperExternalIdentityRepository.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.repository; import com.alibaba.apiopenplatform.entity.DeveloperExternalIdentity; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; import java.util.Optional; public interface DeveloperExternalIdentityRepository extends JpaRepository<DeveloperExternalIdentity, Long> { List<DeveloperExternalIdentity> findByDeveloper_DeveloperId(String developerId); Optional<DeveloperExternalIdentity> findByProviderAndSubject(String provider, String subject); void deleteByProviderAndSubjectAndDeveloper_DeveloperId(String provider, String subject, String developerId); void deleteByDeveloper_DeveloperId(String developerId); } ``` -------------------------------------------------------------------------------- /portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/UpdatePortalParam.java: -------------------------------------------------------------------------------- ```java /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.alibaba.apiopenplatform.dto.params.portal; import com.alibaba.apiopenplatform.dto.converter.InputConverter; import com.alibaba.apiopenplatform.entity.Portal; import com.alibaba.apiopenplatform.support.portal.PortalSettingConfig; import com.alibaba.apiopenplatform.support.portal.PortalUiConfig; import lombok.Data; import javax.validation.constraints.Size; @Data public class UpdatePortalParam implements InputConverter<Portal> { @Size(max = 50, message = "门户名称长度不能超过50个字符") private String name; @Size(max = 1024, message = "门户描述长度不能超过1024个字符") private String description; private PortalSettingConfig portalSettingConfig; private PortalUiConfig portalUiConfig; } ```