Skip to content

Commit 4286e35

Browse files
committed
Add scope validation for service catalog
1 parent e786d2a commit 4286e35

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
@@ -29,7 +29,9 @@ import { injectIntl, FormattedMessage } from 'react-intl';
2929
import Typography from '@material-ui/core/Typography';
3030
import API from 'AppData/api';
3131
import { CircularProgress } from '@material-ui/core';
32-
import { ScopeValidation, resourceMethod, resourcePath } from 'AppData/ScopeValidation';
32+
import {
33+
ScopeValidation, resourceMethod, resourcePath, client,
34+
} from 'AppData/ScopeValidation';
3335
import Alert from 'AppComponents/Shared/Alert';
3436
import Banner from 'AppComponents/Shared/Banner';
3537
import LaunchIcon from '@material-ui/icons/Launch';
@@ -318,7 +320,11 @@ class LifeCycleUpdate extends Component {
318320
))}
319321
</FormGroup>
320322
)}
321-
<ScopeValidation resourcePath={resourcePath.API_CHANGE_LC} resourceMethod={resourceMethod.POST}>
323+
<ScopeValidation
324+
resourcePath={resourcePath.API_CHANGE_LC}
325+
resourceMethod={resourceMethod.POST}
326+
client={client.API_CLIENT}
327+
>
322328
<div className={classes.buttonsWrapper}>
323329
{!isWorkflowPending
324330
&& 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';
@@ -187,7 +189,11 @@ class DeleteApiButton extends React.Component {
187189
return (
188190
<>
189191
{/* allowing delete based on scopes */}
190-
<ScopeValidation resourceMethod={resourceMethod.DELETE} resourcePath={path}>
192+
<ScopeValidation
193+
resourceMethod={resourceMethod.DELETE}
194+
resourcePath={path}
195+
client={client.API_CLIENT}
196+
>
191197
<Box
192198
className={classNames({ [classes.inlineBlock]: updateData, [classes.flexBox]: !updateData })}
193199
>

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
@@ -17,6 +17,9 @@ import Chip from '@material-ui/core/Chip';
1717
import CreateAPIButton from 'AppComponents/ServiceCatalog/CreateApi';
1818
import DeleteServiceButton from 'AppComponents/ServiceCatalog/Listing/Delete';
1919
import LetterGenerator from 'AppComponents/Apis/Listing/components/ImageGenerator/LetterGenerator';
20+
import {
21+
ScopeValidation, resourceMethod, resourcePath, client,
22+
} from 'AppData/ScopeValidation';
2023

2124

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

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
@@ -28,6 +28,9 @@ import CreateApi from 'AppComponents/ServiceCatalog/CreateApi';
2828
import MUIDataTable from 'mui-datatables';
2929
import moment from 'moment';
3030
import { FormattedMessage } from 'react-intl';
31+
import {
32+
ScopeValidation, resourceMethod, resourcePath, client,
33+
} from 'AppData/ScopeValidation';
3134

3235
const useStyles = makeStyles((theme) => ({
3336
contentInside: {
@@ -287,11 +290,18 @@ function ServicesTableView(props) {
287290
serviceUrl={serviceUrl}
288291
usage={usage}
289292
/>
290-
<Delete
291-
serviceDisplayName={name}
292-
serviceId={id}
293-
onDelete={onDelete}
294-
/>
293+
{/* allowing delete service based on scopes */}
294+
<ScopeValidation
295+
resourcePath={resourcePath.SINGLE_SERVICE}
296+
resourceMethod={resourceMethod.DELETE}
297+
client={client.SERVICE_CATALOG_CLIENT}
298+
>
299+
<Delete
300+
serviceDisplayName={name}
301+
serviceId={id}
302+
onDelete={onDelete}
303+
/>
304+
</ScopeValidation>
295305
</Box>
296306
</>
297307
);

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)