From 54c39416083f66916ca3f3bcb27d0b15f3fb45e4 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Tue, 27 Aug 2024 18:01:29 +0530 Subject: [PATCH 1/9] Add initial publisher changes for subscription validation disabling --- .../Details/NewOverview/Configuration.jsx | 70 +++++++++++- .../Details/NewOverview/CustomizedStepper.jsx | 100 +++++++++-------- .../Apis/Details/NewOverview/MetaData.jsx | 2 +- .../Apis/Details/NewOverview/Policies.jsx | 39 +++++-- .../SubscriptionPoliciesManage.jsx | 47 +++++--- .../Details/Subscriptions/Subscriptions.jsx | 102 +++++++++++++++++- .../webapp/source/src/app/data/Constants.js | 3 +- 7 files changed, 286 insertions(+), 77 deletions(-) diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx index f742ad11f6f..85a9c64cd65 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx @@ -26,6 +26,7 @@ import Tooltip from '@mui/material/Tooltip'; import HelpOutline from '@mui/icons-material/HelpOutline'; import Box from '@mui/material/Box'; import API from 'AppData/api'; +import CONSTS from 'AppData/Constants'; import { capitalizeFirstLetter, upperCaseString, lowerCaseString } from 'AppData/stringFormatter'; import APIContext from '../components/ApiContext'; import Policies from './Policies'; @@ -45,6 +46,8 @@ const HUMAN_READABLE_SCHEMES = { function Configuration(props) { const { parentClasses } = props; const { api } = useContext(APIContext); + const isSubValidationDisabled = api.policies + && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; return ( <> @@ -280,7 +283,12 @@ function Configuration(props) { {/* Visibility */} - + )} + + + + + + + )} + > + + + + + + + {isSubValidationDisabled ? + + + + : + + + + } + + diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx index 75697f0eb6a..5eb2274617d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx @@ -19,6 +19,7 @@ import CircularProgress from '@mui/material/CircularProgress'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import AuthManager from 'AppData/AuthManager'; +import CONSTS from 'AppData/Constants'; import Typography from '@mui/material/Typography'; import LinkIcon from '@mui/icons-material/Link'; import API from 'AppData/api'; @@ -171,6 +172,8 @@ export default function CustomizedStepper() { const securityScheme = [...api.securityScheme]; const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') && securityScheme.includes('mutualssl_mandatory'); + const isSubValidationDisabled = api.policies + && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; let devportalUrl = settings ? `${settings.devportalUrl}/apis/${api.id}/overview` : ''; const intl = useIntl(); // TODO: tmkasun need to handle is loading @@ -521,50 +524,6 @@ export default function CustomizedStepper() { )} - {(api.gatewayVendor === 'wso2') && ( - - - - {isTierAvailable ? ( - - ) : ( - - )} - - - - - - - - - - - - - - - - )} )} {label === 'Deploy' && ( @@ -662,9 +621,56 @@ export default function CustomizedStepper() { )} {label === 'Publish' && ( - <> - {finalLifecycleState(lifecycleState)} - +
+ {(api.gatewayVendor === 'wso2') && !isSubValidationDisabled && ( + + + + {isTierAvailable ? ( + + ) : ( + + )} + + + + + + + + + + + + + + + + )} + <> + {finalLifecycleState(lifecycleState)} + +
)} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/MetaData.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/MetaData.jsx index 4ceeccb8bf0..61494e5f7bc 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/MetaData.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/MetaData.jsx @@ -52,7 +52,7 @@ function MetaData(props) { ) : ( )} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx index 55bf969fbbd..34721fcd050 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx @@ -22,6 +22,7 @@ import PropTypes from 'prop-types'; import Typography from '@mui/material/Typography'; import Grid from '@mui/material/Grid'; import { withAPI } from 'AppComponents/Apis/Details/components/ApiContext'; +import CONSTS from 'AppData/Constants'; /** * @@ -31,6 +32,8 @@ import { withAPI } from 'AppComponents/Apis/Details/components/ApiContext'; */ function Policies(props) { const { parentClasses, api } = props; + const isSubValidationDisabled = api.policies + && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; return ( <> @@ -44,15 +47,33 @@ function Policies(props) { {/* Throttling Policies */} - {api.policies - && api.policies.length !== 0 - && api.policies.map((item, index) => ( - - {item} - {api.policies.length !== index + 1 && ', '} - {' '} - - ))} + {api.policies && api.policies.length > 0 ? ( + (() => { + // Filter out "Default_Subscriptionless" if there's more than one policy + const filteredPolicies = api.policies.filter((policy) => + policy !== CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + + // Check if the only policy is "Default_Subscriptionless" + if (isSubValidationDisabled) { + return -; + } + + // Render filtered policies + return filteredPolicies.length > 0 ? ( + filteredPolicies.map((item, index) => ( + + {item} + {filteredPolicies.length !== index + 1 && ', '} + {' '} + + )) + ) : ( + - // Default case if no policies to show + ); + })() + ) : ( + - // Case when there are no policies at all + )} diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx index fcfcb92a485..073eaa7c8b6 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx @@ -30,6 +30,7 @@ import Paper from '@mui/material/Paper'; import API from 'AppData/api'; import { isRestricted } from 'AppData/AuthManager'; import Configurations from 'Config'; +import CONSTS from 'AppData/Constants'; const PREFIX = 'SubscriptionPoliciesManage'; @@ -72,6 +73,7 @@ class SubscriptionPoliciesManage extends Component { super(props); this.state = { subscriptionPolicies: {}, + isMutualSslOnly: false, }; this.handleChange = this.handleChange.bind(this); } @@ -79,6 +81,10 @@ class SubscriptionPoliciesManage extends Component { componentDidMount() { const { api } = this.props; const isAsyncAPI = (api.type === 'WS' || api.type === 'WEBSUB' || api.type === 'SSE' || api.type === 'ASYNC'); + const securityScheme = [...api.securityScheme]; + const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') + && securityScheme.includes('mutualssl_mandatory'); + this.setState({ isMutualSslOnly }); const limit = Configurations.app.subscriptionPolicyLimit; let policyPromise; if (isAsyncAPI) { @@ -107,11 +113,15 @@ class SubscriptionPoliciesManage extends Component { handleChange(event) { const { name, checked } = event.target; const { setPolices, policies } = this.props; + const { isMutualSslOnly } = this.state; let newSelectedPolicies = [...policies]; if (checked) { newSelectedPolicies.push(name); } else { newSelectedPolicies = policies.filter((policy) => policy !== name); + if (!isMutualSslOnly && newSelectedPolicies.length === 0) { + newSelectedPolicies.push(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + } } setPolices(newSelectedPolicies); } @@ -166,22 +176,27 @@ class SubscriptionPoliciesManage extends Component { - { subscriptionPolicies && Object.entries(subscriptionPolicies).map((value) => ( - this.handleChange(e)} - name={value[1].displayName} - /> - )} - label={value[1].displayName + ' : ' + value[1].description} - /> - ))} + { subscriptionPolicies && Object.entries(subscriptionPolicies).map((value) => { + if (value[1].displayName === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) { + return null; // Skip rendering for "Default" + } + return ( + this.handleChange(e)} + name={value[1].displayName} + /> + )} + label={value[1].displayName + ' : ' + value[1].description} + /> + ); + })} { migratedCase && ( diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx index d59b4ba0934..641c87dceb2 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx @@ -18,10 +18,16 @@ import React, { useEffect, useState } from 'react'; import { styled } from '@mui/material/styles'; -import { CircularProgress, Grid } from '@mui/material'; +import { AlertTitle, Box, CircularProgress, Grid, Alert as MUIAlert } from '@mui/material'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import Typography from '@mui/material/Typography'; import Alert from 'AppComponents/Shared/Alert'; import { useAPI } from 'AppComponents/Apis/Details/components/ApiContext'; import API from 'AppData/api'; @@ -70,11 +76,15 @@ function Subscriptions(props) { const restApi = new API(); const [tenants, setTenants] = useState(null); const [policies, setPolices] = useState({}); + const [originalPolicies, setOriginalPolicies] = useState({}); const [availability, setAvailability] = useState({ subscriptionAvailability: api.subscriptionAvailability }); const [tenantList, setTenantList] = useState(api.subscriptionAvailableTenants); const [subscriptions, setSubscriptions] = useState(null); const [updateInProgress, setUpdateInProgress] = useState(false); + const [isOpen, setIsOpen] = useState(false); const { settings } = useAppContext(); + const isSubValidationDisabled = api.policies && api.policies.length === 1 + && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; /** * Save subscription information (policies, subscriptionAvailability, subscriptionAvailableTenants) @@ -118,8 +128,27 @@ function Subscriptions(props) { setSubscriptions(result.body.count); }); setPolices([...api.policies]); + setOriginalPolicies([...api.policies]); }, []); + const handleSubscriptionSave = () => { + if (!isSubValidationDisabled && policies.length === 1 && policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) { + setIsOpen(true); + } else { + saveAPI(); + } + }; + + const handleDialogYes = () => { + setIsOpen(false); + saveAPI(); + }; + + const handleDialogNo = () => { + setIsOpen(false); + setPolices(originalPolicies); + }; + if (typeof tenants !== 'number' || typeof subscriptions !== 'number') { return ( @@ -135,6 +164,18 @@ function Subscriptions(props) { (api.gatewayType === 'wso2/synapse' || api.apiType === API.CONSTS.APIProduct) && ()} + {isSubValidationDisabled && ( + + + + + + + + )} {tenants !== 0 && settings.crossTenantSubscriptionEnabled && (api.gatewayType === 'wso2/synapse' || api.apiType === API.CONSTS.APIProduct) && ( @@ -163,7 +204,7 @@ function Subscriptions(props) { variant='contained' color='primary' disabled={api.isRevision || isRestricted(['apim:api_create', 'apim:api_publish'], api)} - onClick={() => saveAPI()} + onClick={() => handleSubscriptionSave()} id='subscriptions-save-btn' > )} + setIsOpen(false)} + aria-labelledby='alert-dialog-title' + aria-describedby='alert-dialog-description' + > + + + + + + + + + + + + + + + + + + + + ) ); } diff --git a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js index 5495c2f5a60..fac3c53d12c 100644 --- a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js +++ b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js @@ -57,7 +57,8 @@ const CONSTS = { PATH_TEMPLATES: { COMMON_POLICIES: '/policies', COMMON_POLICY_CREATE: '/policies/create', - } + }, + DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', }; export default CONSTS; From 32c721333a6b14c5c82a50c0656d0cd1fe8d838c Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Fri, 30 Aug 2024 10:05:28 +0530 Subject: [PATCH 2/9] Add sub validation disable changes for async APIs --- .../Apis/Details/NewOverview/Configuration.jsx | 2 +- .../Apis/Details/NewOverview/CustomizedStepper.jsx | 2 +- .../components/Apis/Details/NewOverview/Policies.jsx | 4 ++-- .../Subscriptions/SubscriptionPoliciesManage.jsx | 12 +++++++++--- .../Apis/Details/Subscriptions/Subscriptions.jsx | 5 +++-- .../src/main/webapp/source/src/app/data/Constants.js | 1 + 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx index 85a9c64cd65..abe09915ce9 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Configuration.jsx @@ -47,7 +47,7 @@ function Configuration(props) { const { parentClasses } = props; const { api } = useContext(APIContext); const isSubValidationDisabled = api.policies - && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; + && api.policies.length === 1 && api.policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); return ( <> diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx index 5eb2274617d..f6fd068c572 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx @@ -173,7 +173,7 @@ export default function CustomizedStepper() { const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') && securityScheme.includes('mutualssl_mandatory'); const isSubValidationDisabled = api.policies - && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; + && api.policies.length === 1 && api.policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); let devportalUrl = settings ? `${settings.devportalUrl}/apis/${api.id}/overview` : ''; const intl = useIntl(); // TODO: tmkasun need to handle is loading diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx index 34721fcd050..7b8340c6189 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/Policies.jsx @@ -33,7 +33,7 @@ import CONSTS from 'AppData/Constants'; function Policies(props) { const { parentClasses, api } = props; const isSubValidationDisabled = api.policies - && api.policies.length === 1 && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; + && api.policies.length === 1 && api.policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); return ( <> @@ -51,7 +51,7 @@ function Policies(props) { (() => { // Filter out "Default_Subscriptionless" if there's more than one policy const filteredPolicies = api.policies.filter((policy) => - policy !== CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + !policy.includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)); // Check if the only policy is "Default_Subscriptionless" if (isSubValidationDisabled) { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx index 073eaa7c8b6..cb5e2e1e62f 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx @@ -74,6 +74,7 @@ class SubscriptionPoliciesManage extends Component { this.state = { subscriptionPolicies: {}, isMutualSslOnly: false, + isAsyncAPI: false, }; this.handleChange = this.handleChange.bind(this); } @@ -81,6 +82,7 @@ class SubscriptionPoliciesManage extends Component { componentDidMount() { const { api } = this.props; const isAsyncAPI = (api.type === 'WS' || api.type === 'WEBSUB' || api.type === 'SSE' || api.type === 'ASYNC'); + this.setState( {isAsyncAPI}); const securityScheme = [...api.securityScheme]; const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') && securityScheme.includes('mutualssl_mandatory'); @@ -113,14 +115,18 @@ class SubscriptionPoliciesManage extends Component { handleChange(event) { const { name, checked } = event.target; const { setPolices, policies } = this.props; - const { isMutualSslOnly } = this.state; + const { isMutualSslOnly, isAsyncAPI } = this.state; let newSelectedPolicies = [...policies]; if (checked) { newSelectedPolicies.push(name); } else { newSelectedPolicies = policies.filter((policy) => policy !== name); if (!isMutualSslOnly && newSelectedPolicies.length === 0) { - newSelectedPolicies.push(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + if (!isAsyncAPI) { + newSelectedPolicies.push(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + } else { + newSelectedPolicies.push(CONSTS.DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN); + } } } setPolices(newSelectedPolicies); @@ -177,7 +183,7 @@ class SubscriptionPoliciesManage extends Component { { subscriptionPolicies && Object.entries(subscriptionPolicies).map((value) => { - if (value[1].displayName === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) { + if (value[1].displayName.includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)) { return null; // Skip rendering for "Default" } return ( diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx index 641c87dceb2..4bbf9f928ab 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx @@ -84,7 +84,7 @@ function Subscriptions(props) { const [isOpen, setIsOpen] = useState(false); const { settings } = useAppContext(); const isSubValidationDisabled = api.policies && api.policies.length === 1 - && api.policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN; + && api.policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); /** * Save subscription information (policies, subscriptionAvailability, subscriptionAvailableTenants) @@ -132,7 +132,8 @@ function Subscriptions(props) { }, []); const handleSubscriptionSave = () => { - if (!isSubValidationDisabled && policies.length === 1 && policies[0] === CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) { + if (!isSubValidationDisabled + && policies.length === 1 && policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)) { setIsOpen(true); } else { saveAPI(); diff --git a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js index fac3c53d12c..362555219f5 100644 --- a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js +++ b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js @@ -59,6 +59,7 @@ const CONSTS = { COMMON_POLICY_CREATE: '/policies/create', }, DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', + DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'Async_Default_Subscriptionless', }; export default CONSTS; From 28db5b1d4df80eece999030eb9b559731d7c3655 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Sat, 31 Aug 2024 15:59:54 +0530 Subject: [PATCH 3/9] Add subscription validation locales --- .../src/main/webapp/site/public/locales/en.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/portals/publisher/src/main/webapp/site/public/locales/en.json b/portals/publisher/src/main/webapp/site/public/locales/en.json index 2bede92a8c8..d5804570036 100644 --- a/portals/publisher/src/main/webapp/site/public/locales/en.json +++ b/portals/publisher/src/main/webapp/site/public/locales/en.json @@ -1028,6 +1028,10 @@ "Apis.Details.NewOverview.MetaData.securityScheme.not.set": "-", "Apis.Details.NewOverview.MetaData.securityScheme.tooltip": "OAuth2 is used as the default security schema.", "Apis.Details.NewOverview.MetaData.solace.transports": "Available Protocols", + "Apis.Details.NewOverview.MetaData.subscription.validation.tooltip": "If subscription validation is disabled, API consumption does not require subscriptions", + "Apis.Details.NewOverview.MetaData.subvalidation": "Subscription Validation", + "Apis.Details.NewOverview.MetaData.subvalidation.disabled": "Disabled", + "Apis.Details.NewOverview.MetaData.subvalidation.enabled": "Enabled", "Apis.Details.NewOverview.MetaData.tags": "Tags", "Apis.Details.NewOverview.MetaData.tags.not.set": "-", "Apis.Details.NewOverview.MetaData.transport.tooltip": "HTTP is less secure than HTTPS and makes your API vulnerable to security threats.", @@ -1458,8 +1462,12 @@ "Apis.Details.Subscriptions.SubscriptionPoliciesManage.sub.migrated": "Following policies are migrated from an old version of APIM. You can uncheck and select a different policy. Note that this is an irreversible operation.", "Apis.Details.Subscriptions.Subscriptions.cancel": "Cancel", "Apis.Details.Subscriptions.Subscriptions.save": "Save", + "Apis.Details.Subscriptions.Subscriptions.subValidationDisabled.dialog.description": "Deselcting all the subscription policies will disable subscription validation for this API. This will allow anyone with a valid token to consume the API without a subscription.", + "Apis.Details.Subscriptions.Subscriptions.subValidationDisabled.dialog.description.question": "Do you want to disable subscription validation?", + "Apis.Details.Subscriptions.Subscriptions.subValidationDisabled.dialog.title": "Caution!", "Apis.Details.Subscriptions.Subscriptions.update.error": "Error occurred while updating subscription configurations", "Apis.Details.Subscriptions.Subscriptions.update.success": "Subscription configurations updated successfully", + "Apis.Details.Subscriptions.Subscriptions.validation.disabled": "Subscription validation is disabled for this API", "Apis.Details.Subscriptions.SubscriptionsTable.active.subs.state": "Active", "Apis.Details.Subscriptions.SubscriptionsTable.blocked.production.only.subs.state": "Blocked Production Only", "Apis.Details.Subscriptions.SubscriptionsTable.blocked.subs.state": "Blocked", @@ -2030,4 +2038,4 @@ "upload.image": "Click or drag the image to upload.", "upload.image.size.error": "Uploaded File is too large. Maximum file size limit to 1MB", "upload.image.size.info": "Maximum file size limit to 1MB" -} \ No newline at end of file +} From 87bbb0df36d642ffc162738f6e654017b316b8da Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Tue, 3 Sep 2024 20:18:53 +0530 Subject: [PATCH 4/9] Addd subscription validation disabling changes to Devportal --- .../main/webapp/site/public/locales/en.json | 4 + .../app/components/Apis/Details/Overview.jsx | 92 +++++--- .../src/app/components/Apis/Details/index.jsx | 4 +- .../components/Apis/Listing/APICardView.jsx | 7 +- .../Details/SubscriptionTableData.jsx | 49 ++++- .../Shared/ApiTryOut/SelectAppPanel.jsx | 205 ++++++++++++------ .../Shared/ApiTryOut/TryOutController.jsx | 87 +++++++- .../webapp/source/src/app/data/Constants.jsx | 2 + 8 files changed, 339 insertions(+), 111 deletions(-) diff --git a/portals/devportal/src/main/webapp/site/public/locales/en.json b/portals/devportal/src/main/webapp/site/public/locales/en.json index 384de1abbb7..85faa277b02 100644 --- a/portals/devportal/src/main/webapp/site/public/locales/en.json +++ b/portals/devportal/src/main/webapp/site/public/locales/en.json @@ -78,6 +78,7 @@ "Apis.Details.ApiConsole.SelectAppPanel.environment.show.more.subscription.URLs": "Subscription Gateway URLs", "Apis.Details.ApiConsole.SelectAppPanel.production.radio": "Production", "Apis.Details.ApiConsole.SelectAppPanel.sandbox.radio": "Sandbox", + "Apis.Details.ApiConsole.SelectAppPanel.select.available.application": "Available applications", "Apis.Details.ApiConsole.SelectAppPanel.select.key.type.heading": "Key Type", "Apis.Details.ApiConsole.SelectAppPanel.select.subscribed.application": "Subscribed applications", "Apis.Details.ApiConsole.TryOutController.default.km.msg.one": "The Resident Key Manager is selected for try out console.", @@ -284,6 +285,8 @@ "Apis.Details.Overview.list.version": "Version", "Apis.Details.Overview.select.env.error": "Error Selecting Environment", "Apis.Details.Overview.source": "Source", + "Apis.Details.Overview.subscriptions.not.required": "No subscriptions required", + "Apis.Details.Overview.subscriptions.not.required.content": "Provider has disabled subscription validation for this API. You can consume this without subscribing to it.", "Apis.Details.Overview.subscriptions.title": "Subscriptions", "Apis.Details.Overview.tags.title": "Tags", "Apis.Details.PubTopic.copied": "Copied", @@ -419,6 +422,7 @@ "Applications.Details.SubscriptionTableData.delete.subscription.confirmation.dialog.title": "Confirm", "Applications.Details.SubscriptionTableData.delete.text": "Delete", "Applications.Details.SubscriptionTableData.edit.text": "Edit", + "Applications.Details.SubscriptionTableData.policy.default.tooltip": "This is the default subscription policy used when subscription validation was disabled.", "Applications.Details.SubscriptionTableData.update": "Update", "Applications.Details.SubscriptionTableData.update.business.plan": "Current Business Plan :", "Applications.Details.SubscriptionTableData.update.business.plan.name": "Business Plan", diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx index ccd3e45c0aa..696e5b63330 100644 --- a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx @@ -45,8 +45,10 @@ import Social from 'AppComponents/Apis/Details/Social/Social'; import ResourceNotFound from 'AppComponents/Base/Errors/ResourceNotFound'; import AuthManager from 'AppData/AuthManager'; import Alert from 'AppComponents/Shared/Alert'; +import InlineMessage from 'AppComponents/Shared/InlineMessage'; import Progress from 'AppComponents/Shared/Progress'; import API from 'AppData/api'; +import CONSTANTS from 'AppData/Constants'; import View from 'AppComponents/Apis/Details/Documents/View'; import SolaceEndpoints from './SolaceEndpoints'; import Environments from './Environments'; @@ -240,6 +242,9 @@ function Overview() { return filteredApiPolicies && filteredApiPolicies.length > 0; }; + const isSubValidationDisabled = api.tiers && api.tiers.length === 1 + && api.tiers[0].tierName.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); + const updateSelectedEndpoint = (e) => { const selectedEnvName = e.target.value; const filteredEndpoints = api.endpointURLs.filter((ep) => ep.environmentName === selectedEnvName); @@ -531,7 +536,28 @@ function Overview() { )} - {api.gatewayVendor === 'wso2' && allPolicies && allPolicies.length > 0 && ( + {isSubValidationDisabled && ( + + + )} + > + + + + + + )} + {api.gatewayVendor === 'wso2' && allPolicies && allPolicies.length > 0 && !isSubValidationDisabled && ( <> @@ -551,36 +577,38 @@ function Overview() { textAlign='center' > {allPolicies && allPolicies.map((tier) => ( - - - - {tier.name} - - - - {tier.requestCount === 2147483647 ? 'Unlimited' : tier.requestCount} + tier.name.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) ? null : ( + + + + {tier.name} - - - - - - - - + + + {tier.requestCount === 2147483647 ? 'Unlimited' : tier.requestCount} + + + + + + + + + + ) ))} )} - {(showCredentials && subscribedApplications.length > 0) && ( + {(showCredentials && subscribedApplications.length > 0) && !isSubValidationDisabled && ( <> @@ -683,9 +711,15 @@ function Overview() { defaultMessage='Subscriptions' /> - - {api.subscriptions || 0} - + { !isSubValidationDisabled ? ( + + {api.subscriptions || 0} + + ) : ( + + N/A + + )} diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/index.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/index.jsx index 5367fbccb24..6d64406125d 100755 --- a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/index.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/index.jsx @@ -488,6 +488,8 @@ class DetailsLegacy extends React.Component { const pageUrl = new URL(window.location); const isWidget = pageUrl.searchParams.get('widget'); const isAsyncApi = this.isAsyncAPI(api); + const isSubValidationDisabled = api && api.tiers && api.tiers.length === 1 + && api.tiers[0].tierName.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); return api ? ( @@ -537,7 +539,7 @@ class DetailsLegacy extends React.Component { open={open} id='left-menu-overview' /> - {user && showCredentials && ( + {user && showCredentials && !isSubValidationDisabled && ( <> !(api.throttlingPolicies.length === 1 + && api.throttlingPolicies[0].includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN))); for (let i = 0; i < listLocal.length; i++) { + const policyList = listLocal[i].throttlingPolicies + .filter((policy) => !policy.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)); + listLocal[i].throttlingPolicies = policyList; if (!((!subscribedIds.includes(listLocal[i].id) && !listLocal[i].advertiseInfo.advertised) && listLocal[i].isSubscriptionAvailable)) { listLocal[i].throttlingPolicies = null; diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/SubscriptionTableData.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/SubscriptionTableData.jsx index 246d0abff38..c522c1ea5e5 100755 --- a/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/SubscriptionTableData.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/SubscriptionTableData.jsx @@ -21,6 +21,7 @@ import { Link } from 'react-router-dom'; import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import Icon from '@mui/material/Icon'; +import Box from '@mui/material/Box'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; @@ -29,11 +30,14 @@ import Dialog from '@mui/material/Dialog'; import Slide from '@mui/material/Slide'; import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; +import Tooltip from '@mui/material/Tooltip'; import Autocomplete from '@mui/material/Autocomplete'; +import HelpOutline from '@mui/icons-material/HelpOutline'; import { FormattedMessage } from 'react-intl'; import { ScopeValidation, resourceMethods, resourcePaths } from 'AppComponents/Shared/ScopeValidation'; import PropTypes from 'prop-types'; import Api from 'AppData/api'; +import CONSTANTS from 'AppData/Constants'; import Subscription from 'AppData/Subscription'; import { mdiOpenInNew } from '@mdi/js'; import { Icon as MDIcon } from '@mdi/react'; @@ -242,7 +246,50 @@ class SubscriptionTableData extends React.Component { {link} {apiInfo.lifeCycleStatus} - {throttlingPolicy} + {throttlingPolicy.includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN) ? ( + + {throttlingPolicy} + {' '} + + + + )} + sx={{ + backgroundColor: '#f5f5f9', + color: 'rgba(0, 0, 0, 0.87)', + maxWidth: 220, + fontSize: '12px', + border: '1px solid #dadde9', + }} + > + + + + + + ) : ( + {throttlingPolicy} + )} {status} - - + > + + + + + ) : ( + {throttlingPolicy} + )} + {status} + + + + - {throttlingPolicy} -
- {(status === 'BLOCKED') - ? ( - - ) - : (status === 'ON_HOLD') + + + + + {throttlingPolicy} +
+ {(status === 'BLOCKED') ? ( ) - : (status === 'REJECTED') + : (status === 'ON_HOLD') ? ( ) - : (status === 'TIER_UPDATE_PENDING') + : (status === 'REJECTED') ? ( ) - : ( -
- option.label ?? option} - getOptionSelected={(option, value) => option.value === value} - value={selectedTier} - onChange={(e, newValue) => this.setSelectedTier(newValue.value)} - renderInput={(params) => ( - - )} - helperText={( - - )} - margin='normal' - variant='outlined' - /> - )} + : (status === 'TIER_UPDATE_PENDING') + ? ( + - {(status === 'TIER_UPDATE_PENDING') - && ( -
- + option.label ?? option} + getOptionSelected={(option, value) => option.value === value} + value={selectedTier} + onChange={(e, newValue) => this.setSelectedTier(newValue.value)} + renderInput={(params) => ( + + )} + helperText={( + + )} + margin='normal' + variant='outlined' /> - {requestedThrottlingPolicy} -
- )} -
- )} -
-
-
- - + )} + /> + {(status === 'TIER_UPDATE_PENDING') + && ( +
+ + {requestedThrottlingPolicy} +
+ )} +
+ )} + + + + + + + +
+ - - - - - + - - - - - - - - - - - - - - - {isMonetizedAPI && ( - - )} -
- + + + + + + + + + + + + {isMonetizedAPI && ( + + )} + + + ) ); } } diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/Subscriptions.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/Subscriptions.jsx index 06e09a96cd2..22655a150cc 100755 --- a/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/Subscriptions.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Applications/Details/Subscriptions.jsx @@ -41,6 +41,7 @@ import Progress from 'AppComponents/Shared/Progress'; import Alert from 'AppComponents/Shared/Alert'; import APIList from 'AppComponents/Apis/Listing/APICardView'; import ResourceNotFound from 'AppComponents/Base/Errors/ResourceNotFound'; +import CONSTANTS from 'AppData/Constants'; import Subscription from 'AppData/Subscription'; import Api from 'AppData/api'; import { app } from 'Settings'; @@ -206,7 +207,9 @@ class Subscriptions extends React.Component { isAuthorize: true, openDialog: false, searchText: '', + pseudoSubscriptions: false, }; + this.checkSubValidationDisabled = this.checkSubValidationDisabled.bind(this); this.handleSubscriptionDelete = this.handleSubscriptionDelete.bind(this); this.handleSubscriptionUpdate = this.handleSubscriptionUpdate.bind(this); this.updateSubscriptions = this.updateSubscriptions.bind(this); @@ -233,6 +236,27 @@ class Subscriptions extends React.Component { this.setState((prevState) => ({ openDialog: !prevState.openDialog, searchText: '' })); } + /** + * + * Check if the subscription validation is disabled + * @param {*} subList Subscriptions list reponse object + * @returns + */ + checkSubValidationDisabled(subList) { + if (subList !== null && subList.length > 0) { + const pseudoList = subList.filter((sub) => (sub.apiInfo.throttlingPolicies + && sub.apiInfo.throttlingPolicies.length === 1 + && sub.apiInfo.throttlingPolicies[0].includes(CONSTANTS.DEFAULT_SUBSCRIPTIONLESS_PLAN))); + if (pseudoList.length === subList.length) { + this.setState({ pseudoSubscriptions: true }); + } else { + this.setState({ pseudoSubscriptions: false }); + } + return; + } + this.setState({ pseudoSubscriptions: false }); + } + /** * * Update subscriptions list of Application @@ -246,6 +270,7 @@ class Subscriptions extends React.Component { promisedSubscriptions .then((response) => { this.setState({ subscriptions: response.body.list }); + this.checkSubValidationDisabled(response.body.list); }) .catch((error) => { const { status } = error; @@ -303,6 +328,7 @@ class Subscriptions extends React.Component { } } this.setState({ subscriptions }); + this.checkSubValidationDisabled(subscriptions); this.props.getApplication(); }) .catch((error) => { @@ -523,7 +549,7 @@ class Subscriptions extends React.Component {
- {(subscriptions && subscriptions.length === 0) + {((subscriptions && subscriptions.length === 0) || this.state.pseudoSubscriptions) ? ( ({ margin: theme.spacing(2), diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/components/APISecurity/components/ApplicationLevel.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/components/APISecurity/components/ApplicationLevel.jsx index dce3052f9ba..f99343abfad 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/components/APISecurity/components/ApplicationLevel.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Configuration/components/APISecurity/components/ApplicationLevel.jsx @@ -37,6 +37,7 @@ import RadioGroup from '@mui/material/RadioGroup'; import FormHelperText from '@mui/material/FormHelperText'; import { FormattedMessage, useIntl } from 'react-intl'; import { isRestricted } from 'AppData/AuthManager'; +import CONSTS from 'AppData/Constants'; import { useAPI } from 'AppComponents/Apis/Details/components/ApiContext'; import KeyManager from 'AppComponents/Apis/Details/Configuration/components/KeyManager'; import Audience from 'AppComponents/Apis/Details/Configuration/components/Audience'; @@ -106,6 +107,8 @@ export default function ApplicationLevel(props) { const [apiFromContext] = useAPI(); const [oauth2Enabled, setOauth2Enabled] = useState(securityScheme.includes(DEFAULT_API_SECURITY_OAUTH2)); const intl = useIntl(); + const isSubValidationDisabled = apiFromContext.policies && apiFromContext.policies.length === 1 + && apiFromContext.policies[0].includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); let mandatoryValue = null; let hasResourceWithSecurity; if (apiFromContext.apiType === API.CONSTS.APIProduct) { @@ -237,7 +240,9 @@ export default function ApplicationLevel(props) { control={( configDispatcher({ action: 'securityScheme', event: { checked, value }, diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx index cb5e2e1e62f..4f4df996bfb 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx @@ -75,6 +75,7 @@ class SubscriptionPoliciesManage extends Component { subscriptionPolicies: {}, isMutualSslOnly: false, isAsyncAPI: false, + isApiKeyEnabled: false, }; this.handleChange = this.handleChange.bind(this); } @@ -87,6 +88,8 @@ class SubscriptionPoliciesManage extends Component { const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') && securityScheme.includes('mutualssl_mandatory'); this.setState({ isMutualSslOnly }); + const isApiKeyEnabled = securityScheme.includes('api_key'); + this.setState({ isApiKeyEnabled }); const limit = Configurations.app.subscriptionPolicyLimit; let policyPromise; if (isAsyncAPI) { @@ -115,13 +118,13 @@ class SubscriptionPoliciesManage extends Component { handleChange(event) { const { name, checked } = event.target; const { setPolices, policies } = this.props; - const { isMutualSslOnly, isAsyncAPI } = this.state; + const { isMutualSslOnly, isAsyncAPI, isApiKeyEnabled } = this.state; let newSelectedPolicies = [...policies]; if (checked) { newSelectedPolicies.push(name); } else { newSelectedPolicies = policies.filter((policy) => policy !== name); - if (!isMutualSslOnly && newSelectedPolicies.length === 0) { + if (!isMutualSslOnly && !isApiKeyEnabled && newSelectedPolicies.length === 0) { if (!isAsyncAPI) { newSelectedPolicies.push(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); } else { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx index 4bbf9f928ab..ea68edc2d6d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx @@ -179,7 +179,7 @@ function Subscriptions(props) { )} {tenants !== 0 && settings.crossTenantSubscriptionEnabled && (api.gatewayType === 'wso2/synapse' || - api.apiType === API.CONSTS.APIProduct) && ( + api.apiType === API.CONSTS.APIProduct) && !isSubValidationDisabled && ( )} - + { !isSubValidationDisabled && () } setIsOpen(false)} From 26cffa720f90daf7fc8f17b3ca28907df4f4f466 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Wed, 4 Sep 2024 22:44:52 +0530 Subject: [PATCH 6/9] Hide default policies from UI --- .../source/src/app/components/Throttling/Subscription/List.jsx | 2 ++ portals/admin/src/main/webapp/source/src/app/data/Constants.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/portals/admin/src/main/webapp/source/src/app/components/Throttling/Subscription/List.jsx b/portals/admin/src/main/webapp/source/src/app/components/Throttling/Subscription/List.jsx index a73fab70789..e080863786b 100644 --- a/portals/admin/src/main/webapp/source/src/app/components/Throttling/Subscription/List.jsx +++ b/portals/admin/src/main/webapp/source/src/app/components/Throttling/Subscription/List.jsx @@ -30,6 +30,7 @@ import Link from '@mui/material/Link'; import Configurations from 'Config'; import Delete from 'AppComponents/Throttling/Subscription/Delete'; import API from 'AppData/api'; +import CONSTS from 'AppData/Constants'; import EditIcon from '@mui/icons-material/Edit'; import { Link as RouterLink } from 'react-router-dom'; import Button from '@mui/material/Button'; @@ -290,6 +291,7 @@ export default function ListSubscriptionThrottlingPolicies() { }); subscriptionThrottlingvalues = subscriptionPolicies + .filter((policy) => !policy.policyName.includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)) .map(Object.values); return (subscriptionThrottlingvalues); }).catch((error) => { diff --git a/portals/admin/src/main/webapp/source/src/app/data/Constants.js b/portals/admin/src/main/webapp/source/src/app/data/Constants.js index 34c53cd1659..c379dca8539 100644 --- a/portals/admin/src/main/webapp/source/src/app/data/Constants.js +++ b/portals/admin/src/main/webapp/source/src/app/data/Constants.js @@ -42,6 +42,8 @@ const CONSTS = { 'apim:scope_manage', 'openid', 'apim:admin_settings', 'apim:tenantInfo', 'apim:api_provider_change', ], }, + DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', + DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'Async_Default_Subscriptionless', }; export default CONSTS; From d2e6ebb94cbef2e10682e3203751ba0e119f3122 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Fri, 6 Sep 2024 12:41:12 +0530 Subject: [PATCH 7/9] Rename internal business plans --- .../admin/src/main/webapp/source/src/app/data/Constants.js | 4 ++-- .../src/main/webapp/source/src/app/data/Constants.jsx | 4 ++-- .../src/main/webapp/source/src/app/data/Constants.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/portals/admin/src/main/webapp/source/src/app/data/Constants.js b/portals/admin/src/main/webapp/source/src/app/data/Constants.js index c379dca8539..cd8c9e9808d 100644 --- a/portals/admin/src/main/webapp/source/src/app/data/Constants.js +++ b/portals/admin/src/main/webapp/source/src/app/data/Constants.js @@ -42,8 +42,8 @@ const CONSTS = { 'apim:scope_manage', 'openid', 'apim:admin_settings', 'apim:tenantInfo', 'apim:api_provider_change', ], }, - DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', - DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'Async_Default_Subscriptionless', + DEFAULT_SUBSCRIPTIONLESS_PLAN: 'DefaultSubscriptionless', + DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'AsyncDefaultSubscriptionless', }; export default CONSTS; diff --git a/portals/devportal/src/main/webapp/source/src/app/data/Constants.jsx b/portals/devportal/src/main/webapp/source/src/app/data/Constants.jsx index 50f277bc508..5282169233d 100644 --- a/portals/devportal/src/main/webapp/source/src/app/data/Constants.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/data/Constants.jsx @@ -29,8 +29,8 @@ const CONSTS = { ASYNC: 'ASYNC', GRAPHQL: 'GRAPHQL', }, - DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', - DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'Async_Default_Subscriptionless', + DEFAULT_SUBSCRIPTIONLESS_PLAN: 'DefaultSubscriptionless', + DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'AsyncDefaultSubscriptionless', }; export default CONSTS; diff --git a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js index 362555219f5..e9663a0c9a4 100644 --- a/portals/publisher/src/main/webapp/source/src/app/data/Constants.js +++ b/portals/publisher/src/main/webapp/source/src/app/data/Constants.js @@ -58,8 +58,8 @@ const CONSTS = { COMMON_POLICIES: '/policies', COMMON_POLICY_CREATE: '/policies/create', }, - DEFAULT_SUBSCRIPTIONLESS_PLAN: 'Default_Subscriptionless', - DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'Async_Default_Subscriptionless', + DEFAULT_SUBSCRIPTIONLESS_PLAN: 'DefaultSubscriptionless', + DEFAULT_ASYNC_SUBSCRIPTIONLESS_PLAN: 'AsyncDefaultSubscriptionless', }; export default CONSTS; From dbbc17f37e30067e8d0793d5fe0a97386d825711 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Sat, 7 Sep 2024 16:20:35 +0530 Subject: [PATCH 8/9] Add changes suggested in the review for subscription validation Add tenant-conf based enabling Improve UI messages and flows --- .../src/main/webapp/site/public/locales/en.json | 2 +- .../source/src/app/components/Apis/Details/Overview.jsx | 2 +- .../Apis/Details/Environments/DeploymentOnbording.jsx | 5 ----- .../Apis/Details/Environments/Environments.jsx | 5 ----- .../Apis/Details/NewOverview/CustomizedStepper.jsx | 3 +-- .../Details/Subscriptions/SubscriptionPoliciesManage.jsx | 5 +++-- .../Apis/Details/Subscriptions/Subscriptions.jsx | 9 ++++++++- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/portals/devportal/src/main/webapp/site/public/locales/en.json b/portals/devportal/src/main/webapp/site/public/locales/en.json index 85faa277b02..3e8da1c9af2 100644 --- a/portals/devportal/src/main/webapp/site/public/locales/en.json +++ b/portals/devportal/src/main/webapp/site/public/locales/en.json @@ -286,7 +286,7 @@ "Apis.Details.Overview.select.env.error": "Error Selecting Environment", "Apis.Details.Overview.source": "Source", "Apis.Details.Overview.subscriptions.not.required": "No subscriptions required", - "Apis.Details.Overview.subscriptions.not.required.content": "Provider has disabled subscription validation for this API. You can consume this without subscribing to it.", + "Apis.Details.Overview.subscriptions.not.required.content": "Subscriptions are not required for this API. You can consume this without subscribing to it.", "Apis.Details.Overview.subscriptions.title": "Subscriptions", "Apis.Details.Overview.tags.title": "Tags", "Apis.Details.PubTopic.copied": "Copied", diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx index 696e5b63330..166bd9cf674 100644 --- a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/Overview.jsx @@ -550,7 +550,7 @@ function Overview() { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/DeploymentOnbording.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/DeploymentOnbording.jsx index 28d2f8b1842..cd22774c0eb 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/DeploymentOnbording.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/DeploymentOnbording.jsx @@ -154,14 +154,9 @@ export default function DeploymentOnboarding(props) { internalGatewaysFiltered.filter((p) => p.gatewayType.toLowerCase() === assignGateway.toLowerCase()); const externalGateways = environments.filter((p) => p.provider.toLowerCase().includes('solace')); const hasOnlyOneEnvironment = internalGateways.length === 1; - const securityScheme = [...api.securityScheme]; - const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') - && securityScheme.includes('mutualssl_mandatory'); const isEndpointAvailable = api.endpointConfig !== null; - const isTierAvailable = api.policies.length !== 0; const isDeployButtonDisabled = (((api.type !== 'WEBSUB' && !isEndpointAvailable)) - || (!isMutualSslOnly && !isTierAvailable) || api.workflowStatus === 'CREATED'); const defaultVhosts = internalGateways.map((e) => { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/Environments.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/Environments.jsx index eb0120cab2f..d29abcbcb93 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/Environments.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Environments/Environments.jsx @@ -489,14 +489,9 @@ export default function Environments() { const maxCommentLength = '255'; const intl = useIntl(); const { api, updateAPI } = useContext(APIContext); - const securityScheme = [...api.securityScheme]; - const isMutualSslOnly = securityScheme.length === 2 && securityScheme.includes('mutualssl') - && securityScheme.includes('mutualssl_mandatory'); const isEndpointAvailable = api.endpointConfig !== null; - const isTierAvailable = api.policies.length !== 0; const isDeployButtonDisabled = (((api.type !== 'WEBSUB' && !isEndpointAvailable)) - || (!isMutualSslOnly && !isTierAvailable) || api.workflowStatus === 'CREATED'); const history = useHistory(); const { data: settings, isLoading } = usePublisherSettings(); diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx index f6fd068c572..871e00701f2 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx @@ -189,7 +189,7 @@ export default function CustomizedStepper() { } let activeStep = 0; if (api && (api.type === 'WEBSUB' || isEndpointAvailable) - && (isTierAvailable || isMutualSslOnly) && !deploymentsAvailable) { + && !deploymentsAvailable) { activeStep = 1; } else if ((api && !isEndpointAvailable && api.type !== 'WEBSUB') || (api && !isMutualSslOnly && !isTierAvailable)) { @@ -429,7 +429,6 @@ export default function CustomizedStepper() { || (!isMutualSslOnly && !isTierAvailable) || (api.type !== 'HTTP' && api.type !== 'SOAP' && api.type !== 'APIPRODUCT'); const isDeployLinkDisabled = (((api.type !== 'WEBSUB' && !isEndpointAvailable)) - || (!isMutualSslOnly && !isTierAvailable) || api.workflowStatus === 'CREATED' || lifecycleState === 'RETIRED'); let deployLinkToolTipTitle = ''; if (lifecycleState === 'RETIRED') { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx index 4f4df996bfb..e86f319afc4 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx @@ -117,14 +117,15 @@ class SubscriptionPoliciesManage extends Component { */ handleChange(event) { const { name, checked } = event.target; - const { setPolices, policies } = this.props; + const { setPolices, policies, subValidationDisablingAllowed } = this.props; const { isMutualSslOnly, isAsyncAPI, isApiKeyEnabled } = this.state; let newSelectedPolicies = [...policies]; if (checked) { newSelectedPolicies.push(name); } else { newSelectedPolicies = policies.filter((policy) => policy !== name); - if (!isMutualSslOnly && !isApiKeyEnabled && newSelectedPolicies.length === 0) { + if (subValidationDisablingAllowed + && !isMutualSslOnly && !isApiKeyEnabled && newSelectedPolicies.length === 0) { if (!isAsyncAPI) { newSelectedPolicies.push(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN); } else { diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx index ea68edc2d6d..27d654c747d 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/Subscriptions/Subscriptions.jsx @@ -164,7 +164,14 @@ function Subscriptions(props) { {(api.gatewayVendor === 'wso2') && (api.gatewayType === 'wso2/synapse' || api.apiType === API.CONSTS.APIProduct) - && ()} + && ( + + )} {isSubValidationDisabled && ( From c4b7fb263f8f5fb07f2fe8d149edb6fcfcf29e24 Mon Sep 17 00:00:00 2001 From: RakhithaRR Date: Wed, 11 Sep 2024 10:10:19 +0530 Subject: [PATCH 9/9] Fix styling issues and subsctiption policy selection --- .../components/Apis/Details/NewOverview/CustomizedStepper.jsx | 2 +- .../Apis/Details/Subscriptions/SubscriptionPoliciesManage.jsx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx index 871e00701f2..45a33b05db3 100644 --- a/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx +++ b/portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx @@ -622,7 +622,7 @@ export default function CustomizedStepper() { {label === 'Publish' && (
{(api.gatewayVendor === 'wso2') && !isSubValidationDisabled && ( - + 1) { + newSelectedPolicies = newSelectedPolicies.filter((policy) => + !policy.includes(CONSTS.DEFAULT_SUBSCRIPTIONLESS_PLAN)); + } } else { newSelectedPolicies = policies.filter((policy) => policy !== name); if (subValidationDisablingAllowed