fix: IAM resource type permissions (#3138)

Problem:
Suppose we want to give POST permission for all log streams. Then we use
orgId as entity, as we give permission for all log streams in that org.
If orgId and stream name are same. For eg. default log stream in default
org. The permission object for post permission on single "default" (name
of stream) log stream and Post permission on all log streams in
"default" org, both are same. And this creates a conflict

Solution:
While giving all resources permission on any of resource type, we prefix
orgId with `_all_` and this will not conflict with any resource

---------

Co-authored-by: oasisk <ashish.j.kolhe@gmail.com>
This commit is contained in:
Omkar Kesarkhane 2024-04-03 09:44:03 +05:30 committed by GitHub
parent 5002f08927
commit 7148b33916
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 366 additions and 74 deletions

284
Cargo.lock generated
View File

@ -1412,6 +1412,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"
[[package]]
name = "base16ct"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.12.3"
@ -2424,6 +2430,18 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-bigint"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
dependencies = [
"generic-array",
"rand_core",
"subtle",
"zeroize",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -2494,6 +2512,7 @@ dependencies = [
"platforms",
"rustc_version",
"subtle",
"zeroize",
]
[[package]]
@ -2979,12 +2998,27 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d"
[[package]]
name = "ecdsa"
version = "0.16.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
"digest",
"elliptic-curve",
"rfc6979",
"signature",
"spki",
]
[[package]]
name = "ed25519"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
"pkcs8",
"signature",
]
@ -2996,9 +3030,11 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
dependencies = [
"curve25519-dalek",
"ed25519",
"serde",
"sha2",
"signature",
"subtle",
"zeroize",
]
[[package]]
@ -3010,6 +3046,27 @@ dependencies = [
"serde",
]
[[package]]
name = "elliptic-curve"
version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
"digest",
"ff",
"generic-array",
"group",
"hkdf",
"pem-rfc7468",
"pkcs8",
"rand_core",
"sec1",
"subtle",
"zeroize",
]
[[package]]
name = "email-encoding"
version = "0.2.0"
@ -3195,6 +3252,16 @@ dependencies = [
"simdutf8",
]
[[package]]
name = "ff"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
dependencies = [
"rand_core",
"subtle",
]
[[package]]
name = "fiat-crypto"
version = "0.2.7"
@ -3547,6 +3614,17 @@ dependencies = [
"onig",
]
[[package]]
name = "group"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
dependencies = [
"ff",
"rand_core",
"subtle",
]
[[package]]
name = "gxhash"
version = "3.0.0"
@ -3858,6 +3936,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
"serde",
]
[[package]]
@ -4836,6 +4915,56 @@ dependencies = [
"syn 2.0.48",
]
[[package]]
name = "o2_enterprise"
version = "0.1.0"
dependencies = [
"ahash 0.8.7",
"anyhow",
"base64 0.21.7",
"byteorder",
"bytes",
"chrono",
"config",
"dashmap",
"dotenv_config",
"dotenvy",
"env_logger",
"infra",
"log",
"once_cell",
"openfga-sdk",
"openidconnect",
"rand",
"regex",
"reqwest",
"serde",
"serde_json",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "oauth2"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f"
dependencies = [
"base64 0.13.1",
"chrono",
"getrandom",
"http 0.2.11",
"rand",
"reqwest",
"serde",
"serde_json",
"serde_path_to_error",
"sha2",
"thiserror",
"url",
]
[[package]]
name = "objc"
version = "0.2.7"
@ -4933,6 +5062,51 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openfga-sdk"
version = "1.0.1"
source = "git+https://github.com/openobserve/openfga-sdk?rev=dee71467b750a742488451f7bde31391d823b873#dee71467b750a742488451f7bde31391d823b873"
dependencies = [
"reqwest",
"serde",
"serde_derive",
"serde_json",
"url",
"uuid",
]
[[package]]
name = "openidconnect"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f47e80a9cfae4462dd29c41e987edd228971d6565553fbc14b8a11e666d91590"
dependencies = [
"base64 0.13.1",
"chrono",
"dyn-clone",
"ed25519-dalek",
"hmac",
"http 0.2.11",
"itertools 0.10.5",
"log",
"oauth2",
"p256",
"p384",
"rand",
"rsa",
"serde",
"serde-value",
"serde_derive",
"serde_json",
"serde_path_to_error",
"serde_plain",
"serde_with",
"sha2",
"subtle",
"thiserror",
"url",
]
[[package]]
name = "openobserve"
version = "0.9.1"
@ -4988,6 +5162,7 @@ dependencies = [
"maxminddb",
"memory-stats",
"mimalloc",
"o2_enterprise",
"object_store",
"once_cell",
"opentelemetry",
@ -5191,6 +5366,30 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "p256"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
dependencies = [
"ecdsa",
"elliptic-curve",
"primeorder",
"sha2",
]
[[package]]
name = "p384"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209"
dependencies = [
"ecdsa",
"elliptic-curve",
"primeorder",
"sha2",
]
[[package]]
name = "packedvec"
version = "1.2.4"
@ -5608,6 +5807,15 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "primeorder"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
dependencies = [
"elliptic-curve",
]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@ -6108,6 +6316,7 @@ dependencies = [
"js-sys",
"log",
"mime",
"mime_guess",
"once_cell",
"percent-encoding",
"pin-project-lite",
@ -6132,6 +6341,16 @@ dependencies = [
"winreg 0.50.0",
]
[[package]]
name = "rfc6979"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
dependencies = [
"hmac",
"subtle",
]
[[package]]
name = "ring"
version = "0.16.20"
@ -6538,6 +6757,20 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "sec1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
dependencies = [
"base16ct",
"der",
"generic-array",
"pkcs8",
"subtle",
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.9.2"
@ -6596,6 +6829,16 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float 2.10.1",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.196"
@ -6640,6 +6883,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_plain"
version = "1.0.2"
@ -6672,6 +6925,36 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a"
dependencies = [
"base64 0.21.7",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.1.0",
"serde",
"serde_derive",
"serde_json",
"serde_with_macros",
"time",
]
[[package]]
name = "serde_with_macros"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "serde_yaml"
version = "0.8.26"
@ -8182,6 +8465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
"serde",
"wasm-bindgen",
]

View File

@ -204,6 +204,7 @@ impl FromRequest for AuthExtractor {
if path_columns[2].starts_with("alerts")
|| path_columns[2].starts_with("templates")
|| path_columns[2].starts_with("destinations")
|| path.ends_with("users/roles")
{
if method.eq("GET") {
method = "LIST".to_string();

View File

@ -31,6 +31,5 @@
});
window.$c = component;
component.addEventListener('finish', () => console.log('finish'));
// component.addEventListener('ui-update-progress', console.log);
</script>
</html>

View File

@ -640,30 +640,14 @@ const savePermissionHash = () => {
const updateRolePermissions = async (permissions: Permission[]) => {
let resourceMapper: { [key: string]: Resource } = {};
for (let i = 0; i < permissions.length; i++) {
let {
resource,
entity,
}: {
resource: string;
entity: string;
} = decodePermission(permissions[i].object);
if (!resourceMapper[resource]) {
resourceMapper[resource] = getResourceByName(
permissionsState.permissions,
resource
) as Resource;
}
// Added it intentionally, as to get parent resource for dashboard, before getting dashboard permissions
if (!resourceMapper[resource] && resource === "dashboard") {
if (!resourceMapper["dfolder"])
resourceMapper["dfolder"] = getResourceByName(
permissionsState.permissions,
"dfolder"
) as Resource;
await getResourceEntities(resourceMapper["dfolder"]);
try {
let {
resource,
entity,
}: {
resource: string;
entity: string;
} = decodePermission(permissions[i].object);
if (!resourceMapper[resource]) {
resourceMapper[resource] = getResourceByName(
@ -671,51 +655,71 @@ const updateRolePermissions = async (permissions: Permission[]) => {
resource
) as Resource;
}
}
if (!resourceMapper[resource]) return;
// Added it intentionally, as to get parent resource for dashboard, before getting dashboard permissions
if (!resourceMapper[resource] && resource === "dashboard") {
if (!resourceMapper["dfolder"])
resourceMapper["dfolder"] = getResourceByName(
permissionsState.permissions,
"dfolder"
) as Resource;
if (
resourceMapper[resource].parent &&
!resourceMapper[resourceMapper[resource].parent]
) {
resourceMapper[resourceMapper[resource].parent] = getResourceByName(
permissionsState.permissions,
resourceMapper[resource].parent
) as Resource;
}
await getResourceEntities(resourceMapper["dfolder"]);
if (entity === getOrgId()) {
resourceMapper[resource].permission[permissions[i].permission].value =
true;
if (!resourceMapper[resource]) {
resourceMapper[resource] = getResourceByName(
permissionsState.permissions,
resource
) as Resource;
}
}
continue;
}
if (!resourceMapper[resource]) continue;
if (resourceMapper[resource].parent)
await getResourceEntities(
resourceMapper[resourceMapper[resource].parent]
);
if (
resourceMapper[resource].parent &&
!resourceMapper[resourceMapper[resource].parent]
) {
resourceMapper[resourceMapper[resource].parent] = getResourceByName(
permissionsState.permissions,
resourceMapper[resource].parent
) as Resource;
}
// This is just to handle dashboard permissions, need to fix this
if (resource === "dashboard") {
const [folderId, dashboardId] = entity.split("/");
if (entity === "_all_" + getOrgId()) {
resourceMapper[resource].permission[permissions[i].permission].value =
true;
const dashResource = resourceMapper["dfolder"].entities.find(
(e: Entity) => e.name === folderId
);
await getResourceEntities(dashResource as Entity);
} else if (
resource === "logs" ||
resource === "metrics" ||
resource === "traces"
) {
const streamResource = resourceMapper["stream"].entities.find(
(e: Entity) => e.name === resource
);
await getResourceEntities(streamResource as Entity);
} else {
await getResourceEntities(resourceMapper[resource]);
continue;
}
if (resourceMapper[resource].parent)
await getResourceEntities(
resourceMapper[resourceMapper[resource].parent]
);
// This is just to handle dashboard permissions, need to fix this
if (resource === "dashboard") {
const [folderId, dashboardId] = entity.split("/");
const dashResource = resourceMapper["dfolder"].entities.find(
(e: Entity) => e.name === folderId
);
await getResourceEntities(dashResource as Entity);
} else if (
resource === "logs" ||
resource === "metrics" ||
resource === "traces"
) {
const streamResource = resourceMapper["stream"].entities.find(
(e: Entity) => e.name === resource
);
await getResourceEntities(streamResource as Entity);
} else {
await getResourceEntities(resourceMapper[resource]);
}
} catch (err) {
console.log(err);
}
}
@ -739,12 +743,16 @@ const handlePermissionChange = (row: any, permission: string) => {
let entity = "";
let resourceName = row.resourceName;
if (row.type === "Type") entity = store.state.selectedOrganization.identifier;
// As there can be conflict in resource name and org id, as they can be same.
// So we are adding _all_ prefix to org id to differentiate between org id and resource name
if (row.type === "Type")
entity = "_all_" + store.state.selectedOrganization.identifier;
else entity = row.name;
if (row.type === "Resource" && row.top_level) {
resourceName = row.name;
entity = store.state.selectedOrganization.identifier;
entity = "_all_" + store.state.selectedOrganization.identifier;
}
const permissionHash = `${resourceName}:${entity}:${permission}`;
@ -870,7 +878,7 @@ const updateJsonInTable = () => {
resourceDetails = resourceMapper.value["dfolder"].entities.find(
(e: Entity) => e.name === folderId
) as Entity;
} else if (entity === getOrgId()) {
} else if (entity === "_all_" + getOrgId()) {
resourceDetails.permission[permission.permission as "AllowAll"].value =
selectedPermissionsHash.value.has(
getPermissionHash(resource, permission.permission, entity)
@ -915,7 +923,7 @@ const updateJsonInTable = () => {
resourceDetails = resourceMapper.value["dfolder"].entities.find(
(e: Entity) => e.name === folderId
) as Entity;
} else if (entity === getOrgId()) {
} else if (entity === "_all_" + getOrgId()) {
resourceDetails.permission[permission.permission as "AllowAll"].value =
selectedPermissionsHash.value.has(
getPermissionHash(resource, permission.permission, entity)
@ -1207,7 +1215,7 @@ const getPermissionHash = (
permission: string,
entity?: string
) => {
if (!entity) entity = store.state.selectedOrganization.identifier;
if (!entity) entity = "_all_" + store.state.selectedOrganization.identifier;
return `${resourceName}:${entity}:${permission}`;
};
@ -1703,7 +1711,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowAll",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: true,
@ -1713,7 +1721,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowGet",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: true,
@ -1723,7 +1731,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowDelete",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: true,
@ -1733,7 +1741,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowPut",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: true,
@ -1743,7 +1751,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowList",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: hasEntities,
@ -1753,7 +1761,7 @@ const updateResourceResource = (
getPermissionHash(
resourceName,
"AllowPost",
store.state.selectedOrganization.identifier
"_all_" + store.state.selectedOrganization.identifier
)
),
show: hasEntities,