Skip to content

Commit

Permalink
Added support validation against subpaths to hasPermission & SecureCo…
Browse files Browse the repository at this point in the history
…mponent (#1570)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
  • Loading branch information
bexsoft and Benjamin Perez committed Feb 15, 2022
1 parent ab41157 commit 5b2715c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 17 deletions.
75 changes: 58 additions & 17 deletions portal-ui/src/common/SecureComponent/SecureComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import React, { cloneElement } from "react";
import get from "lodash/get";
import { store } from "../../store";
import { hasAccessToResource } from "./permissions";

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

if (Array.isArray(resource)) {
resources = resources.concat(resource);
} else {
resources.push(resource);
}
for (let i = 0; i < resources.length; i++) {
if (resources[i]) {
resourceGrants = resourceGrants.concat(
sessionGrants[resources[i]] ||
sessionGrants[`arn:aws:s3:::${resources[i]}/*`] ||
[]
);
if (resource) {
if (Array.isArray(resource)) {
resources = [...resources, ...resource];
} else {
resources.push(resource);
}

// Filter wildcard items
const wildcards = Object.keys(sessionGrants).filter(
(item) => item.includes("*") && item !== "arn:aws:s3:::*"
);

const getMatchingWildcards = (path: string) => {
const items = wildcards.map((element) => {
const wildcardItemSection = element.split(":").slice(-1)[0];

const replaceWildcard = wildcardItemSection
.replace("/", "\\/")
.replace("\\/*", "($|(\\/.*?))");

const inRegExp = new RegExp(`${replaceWildcard}$`, "gm");

if(inRegExp.exec(path)) {
return element;
}

return null;
});

return items.filter(itm => itm !== null);
};

resources.forEach((rsItem) => {
// Validation against inner paths & wildcards
let wildcardRules =getMatchingWildcards(rsItem);

let wildcardGrants: string[] = [];

wildcardRules.forEach((rule) => {
if(rule) {
const wcResources = get(sessionGrants, rule, []);
wildcardGrants = [...wildcardGrants, ...wcResources];
}
});

const simpleResources = get(sessionGrants, rsItem, []);
const s3Resources = get(sessionGrants, `arn:aws:s3:::${rsItem}/*`, []);

resourceGrants = [...simpleResources, ...s3Resources, ...wildcardGrants];

if (containsResource) {
const matchResource = `arn:aws:s3:::${resources[i]}`;
for (const [key, value] of Object.entries(sessionGrants)) {
const matchResource = `arn:aws:s3:::${rsItem}`;

Object.entries(sessionGrants).forEach(([key, value]) => {
if (key.includes(matchResource)) {
containsResourceGrants = containsResourceGrants.concat(value);
containsResourceGrants = [...containsResourceGrants, ...value];
}
}
});
}
}
});
}

return hasAccessToResource(
[...resourceGrants, ...globalGrants, ...containsResourceGrants],
scopes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ const UploadFilesButton = ({
horizontal: "center",
}}
>

<SecureComponent
resource={uploadPath}
containsResource
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
errorProps={{ disabled: true }}
>
Expand Down

0 comments on commit 5b2715c

Please sign in to comment.