Skip to content

Commit 5b2715c

Browse files
bexsoftBenjamin Perez
andauthored
Added support validation against subpaths to hasPermission & SecureComponent (#1570)
Signed-off-by: Benjamin Perez <[email protected]> Co-authored-by: Benjamin Perez <[email protected]>
1 parent ab41157 commit 5b2715c

File tree

2 files changed

+60
-17
lines changed

2 files changed

+60
-17
lines changed

portal-ui/src/common/SecureComponent/SecureComponent.tsx

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
import React, { cloneElement } from "react";
18+
import get from "lodash/get";
1819
import { store } from "../../store";
1920
import { hasAccessToResource } from "./permissions";
2021

@@ -35,28 +36,68 @@ export const hasPermission = (
3536
let resourceGrants: string[] = [];
3637
let containsResourceGrants: string[] = [];
3738

38-
if (Array.isArray(resource)) {
39-
resources = resources.concat(resource);
40-
} else {
41-
resources.push(resource);
42-
}
43-
for (let i = 0; i < resources.length; i++) {
44-
if (resources[i]) {
45-
resourceGrants = resourceGrants.concat(
46-
sessionGrants[resources[i]] ||
47-
sessionGrants[`arn:aws:s3:::${resources[i]}/*`] ||
48-
[]
49-
);
39+
if (resource) {
40+
if (Array.isArray(resource)) {
41+
resources = [...resources, ...resource];
42+
} else {
43+
resources.push(resource);
44+
}
45+
46+
// Filter wildcard items
47+
const wildcards = Object.keys(sessionGrants).filter(
48+
(item) => item.includes("*") && item !== "arn:aws:s3:::*"
49+
);
50+
51+
const getMatchingWildcards = (path: string) => {
52+
const items = wildcards.map((element) => {
53+
const wildcardItemSection = element.split(":").slice(-1)[0];
54+
55+
const replaceWildcard = wildcardItemSection
56+
.replace("/", "\\/")
57+
.replace("\\/*", "($|(\\/.*?))");
58+
59+
const inRegExp = new RegExp(`${replaceWildcard}$`, "gm");
60+
61+
if(inRegExp.exec(path)) {
62+
return element;
63+
}
64+
65+
return null;
66+
});
67+
68+
return items.filter(itm => itm !== null);
69+
};
70+
71+
resources.forEach((rsItem) => {
72+
// Validation against inner paths & wildcards
73+
let wildcardRules =getMatchingWildcards(rsItem);
74+
75+
let wildcardGrants: string[] = [];
76+
77+
wildcardRules.forEach((rule) => {
78+
if(rule) {
79+
const wcResources = get(sessionGrants, rule, []);
80+
wildcardGrants = [...wildcardGrants, ...wcResources];
81+
}
82+
});
83+
84+
const simpleResources = get(sessionGrants, rsItem, []);
85+
const s3Resources = get(sessionGrants, `arn:aws:s3:::${rsItem}/*`, []);
86+
87+
resourceGrants = [...simpleResources, ...s3Resources, ...wildcardGrants];
88+
5089
if (containsResource) {
51-
const matchResource = `arn:aws:s3:::${resources[i]}`;
52-
for (const [key, value] of Object.entries(sessionGrants)) {
90+
const matchResource = `arn:aws:s3:::${rsItem}`;
91+
92+
Object.entries(sessionGrants).forEach(([key, value]) => {
5393
if (key.includes(matchResource)) {
54-
containsResourceGrants = containsResourceGrants.concat(value);
94+
containsResourceGrants = [...containsResourceGrants, ...value];
5595
}
56-
}
96+
});
5797
}
58-
}
98+
});
5999
}
100+
60101
return hasAccessToResource(
61102
[...resourceGrants, ...globalGrants, ...containsResourceGrants],
62103
scopes,

portal-ui/src/screens/Console/Buckets/ListBuckets/UploadFilesButton.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ const UploadFilesButton = ({
109109
horizontal: "center",
110110
}}
111111
>
112+
112113
<SecureComponent
113114
resource={uploadPath}
115+
containsResource
114116
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
115117
errorProps={{ disabled: true }}
116118
>

0 commit comments

Comments
 (0)