Skip to content

Commit e26c669

Browse files
committed
Add scope validation for service catalog
1 parent 88bd55c commit e26c669

File tree

8 files changed

+126
-62
lines changed

8 files changed

+126
-62
lines changed

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/Apis/Details/LifeCycle/LifeCycleUpdate.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ import { injectIntl, FormattedMessage } from 'react-intl';
3030
import Typography from '@material-ui/core/Typography';
3131
import API from 'AppData/api';
3232
import { CircularProgress } from '@material-ui/core';
33-
import { ScopeValidation, resourceMethod, resourcePath } from 'AppData/ScopeValidation';
33+
import {
34+
ScopeValidation, resourceMethod, resourcePath, client,
35+
} from 'AppData/ScopeValidation';
3436
import Alert from 'AppComponents/Shared/Alert';
3537
import Banner from 'AppComponents/Shared/Banner';
3638
import LaunchIcon from '@material-ui/icons/Launch';
@@ -315,7 +317,11 @@ class LifeCycleUpdate extends Component {
315317
))}
316318
</FormGroup>
317319
)}
318-
<ScopeValidation resourcePath={resourcePath.API_CHANGE_LC} resourceMethod={resourceMethod.POST}>
320+
<ScopeValidation
321+
resourcePath={resourcePath.API_CHANGE_LC}
322+
resourceMethod={resourceMethod.POST}
323+
client={client.API_CLIENT}
324+
>
319325
<div className={classes.buttonsWrapper}>
320326
{!isWorkflowPending
321327
&& lifecycleButtons.map((transitionState) => {

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/Apis/Details/Subscriptions/SubscriptionsTable.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ import UserIcon from '@material-ui/icons/Person';
4444

4545
import Alert from 'AppComponents/Shared/Alert';
4646
import API from 'AppData/api';
47-
import { ScopeValidation, resourceMethod, resourcePath } from 'AppData/ScopeValidation';
47+
import {
48+
ScopeValidation, resourceMethod, resourcePath, client,
49+
} from 'AppData/ScopeValidation';
4850
import AuthManager from 'AppData/AuthManager';
4951
import Invoice from './Invoice';
5052

@@ -853,6 +855,7 @@ class SubscriptionsTable extends Component {
853855
<ScopeValidation
854856
resourceMethod={resourceMethod.POST}
855857
resourcePath={resourcePath.BLOCK_SUBSCRIPTION}
858+
client={client.API_CLIENT}
856859
>
857860
{
858861
this.getSubscriptionBlockingButtons(

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/Apis/Details/components/CreateNewVersionButton.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import { withStyles } from '@material-ui/core/styles';
2525
import Typography from '@material-ui/core/Typography';
2626
import { FormattedMessage } from 'react-intl';
2727

28-
import { resourceMethod, resourcePath, ScopeValidation } from 'AppData/ScopeValidation';
28+
import {
29+
client, resourceMethod, resourcePath, ScopeValidation,
30+
} from 'AppData/ScopeValidation';
2931
import VerticalDivider from 'AppComponents/Shared/VerticalDivider';
3032

3133
const styles = (theme) => ({
@@ -81,7 +83,11 @@ function CreateNewVersionButton(props) {
8183
return (
8284
<>
8385
{/* allowing create new version based on scopes */}
84-
<ScopeValidation resourceMethod={resourceMethod.POST} resourcePath={resourcePath.API_COPY}>
86+
<ScopeValidation
87+
resourceMethod={resourceMethod.POST}
88+
resourcePath={resourcePath.API_COPY}
89+
client={client.API_CLIENT}
90+
>
8591
<div className={classes.createNewVersionWrapper}>
8692
<VerticalDivider height={70} />
8793
<Link

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/Apis/Details/components/DeleteApiButton.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { withRouter } from 'react-router-dom';
1010
import { withStyles } from '@material-ui/core/styles';
1111
import IconButton from '@material-ui/core/IconButton';
1212
import API from 'AppData/api';
13-
import { resourceMethod, resourcePath, ScopeValidation } from 'AppData/ScopeValidation';
13+
import {
14+
client, resourceMethod, resourcePath, ScopeValidation,
15+
} from 'AppData/ScopeValidation';
1416
import Alert from 'AppComponents/Shared/Alert';
1517
import VerticalDivider from 'AppComponents/Shared/VerticalDivider';
1618
import { FormattedMessage } from 'react-intl';
@@ -190,7 +192,11 @@ class DeleteApiButton extends React.Component {
190192
return (
191193
<>
192194
{/* allowing delete based on scopes */}
193-
<ScopeValidation resourceMethod={resourceMethod.DELETE} resourcePath={path}>
195+
<ScopeValidation
196+
resourceMethod={resourceMethod.DELETE}
197+
resourcePath={path}
198+
client={client.API_CLIENT}
199+
>
194200
<Box
195201
className={classNames({ [classes.inlineBlock]: updateData, [classes.flexBox]: !updateData })}
196202
>

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/ServiceCatalog/Listing/Onboarding.jsx

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import CircularProgress from '@material-ui/core/CircularProgress';
3030
import OnboardingMenuCard from 'AppComponents/ServiceCatalog/Listing/components/OnboardingMenuCard';
3131
import Configurations from 'Config';
3232
import { getSampleServiceMeta, getSampleOpenAPI } from 'AppData/SamplePizzaShack';
33+
import {
34+
ScopeValidation, resourceMethod, resourcePath, client,
35+
} from 'AppData/ScopeValidation';
3336

3437
const useStyles = makeStyles((theme) => ({
3538
actionStyle: {
@@ -122,46 +125,53 @@ function Onboarding() {
122125
</Button>
123126
</OnboardingMenuCard>
124127
{/* Deploy Sample Service */}
125-
<OnboardingMenuCard
126-
iconSrc={
127-
Configurations.app.context + '/site/public/images/wso2-intg-service-icon.svg'
128-
}
129-
heading={(
130-
<FormattedMessage
131-
id='ServiceCatalog.Listing.Onboarding.sample.heading'
132-
defaultMessage='Add a sample'
133-
/>
134-
)}
135-
subHeading={(
136-
<FormattedMessage
137-
id='ServiceCatalog.Listing.Onboarding.sample.heading.sub'
138-
defaultMessage='Integration Service'
139-
/>
140-
)}
141-
description={(
142-
<FormattedMessage
143-
id='ServiceCatalog.Listing.Onboarding.sample.heading.text'
144-
defaultMessage={'Deploy the Sample Integration Service'
145-
+ ' already available with WSO2 API Manager and get started in one click'}
146-
/>
147-
)}
128+
{/* allowing create sample service based on scopes */}
129+
<ScopeValidation
130+
resourcePath={resourcePath.SERVICES}
131+
resourceMethod={resourceMethod.POST}
132+
client={client.SERVICE_CATALOG_CLIENT}
148133
>
149-
<Button
150-
className={classes.actionStyle}
151-
size='large'
152-
id='itest-services-landing-deploy-sample'
153-
variant='outlined'
154-
color='primary'
155-
onClick={handleOnClick}
156-
disabled={deployStatus.inprogress}
134+
<OnboardingMenuCard
135+
iconSrc={
136+
Configurations.app.context + '/site/public/images/wso2-intg-service-icon.svg'
137+
}
138+
heading={(
139+
<FormattedMessage
140+
id='ServiceCatalog.Listing.Onboarding.sample.heading'
141+
defaultMessage='Add a sample'
142+
/>
143+
)}
144+
subHeading={(
145+
<FormattedMessage
146+
id='ServiceCatalog.Listing.Onboarding.sample.heading.sub'
147+
defaultMessage='Integration Service'
148+
/>
149+
)}
150+
description={(
151+
<FormattedMessage
152+
id='ServiceCatalog.Listing.Onboarding.sample.heading.text'
153+
defaultMessage={'Deploy the Sample Integration Service'
154+
+ ' already available with WSO2 API Manager and get started in one click'}
155+
/>
156+
)}
157157
>
158-
<FormattedMessage
159-
id='ServiceCatalog.Listing.Onboarding.sample.add'
160-
defaultMessage='Add Sample Service'
161-
/>
162-
{deployStatus.inprogress && <CircularProgress size={15} />}
163-
</Button>
164-
</OnboardingMenuCard>
158+
<Button
159+
className={classes.actionStyle}
160+
size='large'
161+
id='itest-services-landing-deploy-sample'
162+
variant='outlined'
163+
color='primary'
164+
onClick={handleOnClick}
165+
disabled={deployStatus.inprogress}
166+
>
167+
<FormattedMessage
168+
id='ServiceCatalog.Listing.Onboarding.sample.add'
169+
defaultMessage='Add Sample Service'
170+
/>
171+
{deployStatus.inprogress && <CircularProgress size={15} />}
172+
</Button>
173+
</OnboardingMenuCard>
174+
</ScopeValidation>
165175
</Grid>
166176
</Box>
167177
);

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/ServiceCatalog/Listing/components/ServiceCard.jsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import Chip from '@material-ui/core/Chip';
1818
import CreateAPIButton from 'AppComponents/ServiceCatalog/CreateApi';
1919
import DeleteServiceButton from 'AppComponents/ServiceCatalog/Listing/Delete';
2020
import LetterGenerator from 'AppComponents/Apis/Listing/components/ImageGenerator/LetterGenerator';
21+
import {
22+
ScopeValidation, resourceMethod, resourcePath, client,
23+
} from 'AppData/ScopeValidation';
2124

2225

2326
const useStyles = makeStyles((theme) => ({
@@ -202,13 +205,20 @@ export default function ServiceCard(props) {
202205
serviceUrl={service.serviceUrl}
203206
usage={service.usage}
204207
/>
205-
<DeleteServiceButton
206-
id='itest-service-card-delete'
207-
serviceDisplayName={service.name}
208-
serviceId={service.id}
209-
onDelete={onDelete}
210-
isIconButton
211-
/>
208+
{/* allowing delete service based on scopes */}
209+
<ScopeValidation
210+
resourcePath={resourcePath.SINGLE_SERVICE}
211+
resourceMethod={resourceMethod.DELETE}
212+
client={client.SERVICE_CATALOG_CLIENT}
213+
>
214+
<DeleteServiceButton
215+
id='itest-service-card-delete'
216+
serviceDisplayName={service.name}
217+
serviceId={service.id}
218+
onDelete={onDelete}
219+
isIconButton
220+
/>
221+
</ScopeValidation>
212222
</Grid>
213223
)}
214224
</Grid>

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/components/ServiceCatalog/Listing/components/ServicesTableView.jsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import { isRestricted } from 'AppData/AuthManager';
2929
import MUIDataTable from 'mui-datatables';
3030
import moment from 'moment';
3131
import { FormattedMessage } from 'react-intl';
32+
import {
33+
ScopeValidation, resourceMethod, resourcePath, client,
34+
} from 'AppData/ScopeValidation';
3235

3336
const useStyles = makeStyles((theme) => ({
3437
contentInside: {
@@ -289,11 +292,18 @@ function ServicesTableView(props) {
289292
serviceUrl={serviceUrl}
290293
usage={usage}
291294
/>
292-
<Delete
293-
serviceDisplayName={name}
294-
serviceId={id}
295-
onDelete={onDelete}
296-
/>
295+
{/* allowing delete service based on scopes */}
296+
<ScopeValidation
297+
resourcePath={resourcePath.SINGLE_SERVICE}
298+
resourceMethod={resourceMethod.DELETE}
299+
client={client.SERVICE_CATALOG_CLIENT}
300+
>
301+
<Delete
302+
serviceDisplayName={name}
303+
serviceId={id}
304+
onDelete={onDelete}
305+
/>
306+
</ScopeValidation>
297307
</Box>
298308
)}
299309
</>

features/apimgt/org.wso2.carbon.apimgt.publisher.feature/src/main/resources/publisher/source/src/app/data/ScopeValidation.jsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import React from 'react';
2020
import PropTypes from 'prop-types';
2121
import APIClient from 'AppData/APIClient';
22+
import ServiceCatalogClient from 'AppData/ServiceCatalogClient';
2223
import AuthManager from 'AppData/AuthManager';
2324

2425
const resourcePath = {
@@ -68,6 +69,11 @@ const resourceMethod = {
6869
HEAD: 'head',
6970
};
7071

72+
const client = {
73+
API_CLIENT: APIClient,
74+
SERVICE_CATALOG_CLIENT: ServiceCatalogClient,
75+
};
76+
7177
/**
7278
* Show element iff user has proper scope for the view/action
7379
* @class ScopeValidation
@@ -83,9 +89,9 @@ export default class ScopeValidation extends React.Component {
8389
* @returns Boolean
8490
* @memberof AuthManager
8591
*/
86-
static hasScopes(currentResourcePath, currentResourceMethod) {
92+
static hasScopes(currentResourcePath, currentResourceMethod, currentClient) {
8793
const userScopes = AuthManager.getUser().scopes;
88-
const validScope = APIClient.getScopeForResource(currentResourcePath, currentResourceMethod);
94+
const validScope = currentClient.getScopeForResource(currentResourcePath, currentResourceMethod);
8995
return validScope.then((scopes) => {
9096
for (const scope of scopes) {
9197
if (userScopes.includes(scope)) {
@@ -111,8 +117,12 @@ export default class ScopeValidation extends React.Component {
111117
* @memberof ScopeValidation
112118
*/
113119
componentDidMount() {
114-
const { resourcePath: currentResourcePath, resourceMethod: currentResourceMethod } = this.props;
115-
const hasScope = ScopeValidation.hasScopes(currentResourcePath, currentResourceMethod);
120+
const {
121+
resourcePath: currentResourcePath,
122+
resourceMethod: currentResourceMethod,
123+
client: currentClient,
124+
} = this.props;
125+
const hasScope = ScopeValidation.hasScopes(currentResourcePath, currentResourceMethod, currentClient);
116126
hasScope.then((haveScope) => {
117127
this.setState({ haveScope });
118128
});
@@ -137,6 +147,9 @@ ScopeValidation.propTypes = {
137147
children: PropTypes.node.isRequired,
138148
resourcePath: PropTypes.string.isRequired,
139149
resourceMethod: PropTypes.string.isRequired,
150+
client: PropTypes.shape({}).isRequired,
140151
};
141152

142-
export { ScopeValidation, resourceMethod, resourcePath };
153+
export {
154+
ScopeValidation, resourceMethod, resourcePath, client,
155+
};

0 commit comments

Comments
 (0)