Skip to content

Commit

Permalink
remove is_within from scopes and has_capability from capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
haakonvt committed Nov 17, 2023
1 parent d39175b commit 223221e
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 60 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Changes are grouped as follows
### Fixed
- The new compare methods for capabilities in major version 7, `IAMAPI.verify_capabilities` and `IAMAPI.compare_capabilities`
now works correctly for rawAcl with database scope ("all tables").
### Removed
- Capability scopes no longer have the `is_within` method, and capabilities no longer have `has_capability`. Use the more
general `IAMAPI.compare_capabilities` instead.

## [7.2.0] - 2023-11-16
### Added
Expand Down
61 changes: 1 addition & 60 deletions cognite/client/data_classes/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ def as_tuples(self) -> set[tuple]:
# Basic implementation for all simple Scopes (e.g. all or currentuser)
return {(self._scope_name,)}

def is_within(self, other: Self) -> bool:
raise NotImplementedError

@classmethod
def from_tuple(cls, tpl: tuple) -> Self:
acl_name, action, scope_name, *scope_params = tpl
Expand All @@ -115,7 +112,7 @@ def from_tuple(cls, tpl: tuple) -> Self:
db, tbl = scope_params
scope = scope_cls({db: [tbl] if tbl else []}) # type: ignore [call-arg]
else:
raise ValueError(f"tuple not understood as capability ({tpl})")
raise ValueError(f"tuple not understood as capability: {tpl}")

return cast(Self, capability_cls(actions=[capability_cls.Action(action)], scope=scope))

Expand Down Expand Up @@ -162,13 +159,6 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]:
capability_name = self._capability_name
return {to_camel_case(capability_name) if camel_case else to_snake_case(capability_name): data}

def has_capability(self, other: Capability) -> bool:
if not isinstance(self, type(other)):
return False
if not other.scope.is_within(self.scope):
return False
return not set(other.actions) - set(self.actions)

def as_tuples(self) -> set[tuple]:
return set(
(acl, action, *scope_tpl)
Expand Down Expand Up @@ -262,17 +252,11 @@ def as_tuples(self, project: str | None = None) -> set[tuple]:
class AllScope(Capability.Scope):
_scope_name = "all"

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope)


@dataclass(frozen=True)
class CurrentUserScope(Capability.Scope):
_scope_name = "currentuserscope"

def is_within(self, other: Self) -> bool:
return isinstance(other, (AllScope, CurrentUserScope))


@dataclass(frozen=True)
class IDScope(Capability.Scope):
Expand All @@ -285,9 +269,6 @@ def __post_init__(self) -> None:
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, i) for i in self.ids}

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope) or type(self) is type(other) and set(self.ids).issubset(other.ids)


@dataclass(frozen=True)
class IDScopeLowerCase(Capability.Scope):
Expand All @@ -302,9 +283,6 @@ def __post_init__(self) -> None:
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, i) for i in self.ids}

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope) or type(self) is type(other) and set(self.ids).issubset(other.ids)


@dataclass(frozen=True)
class ExtractionPipelineScope(Capability.Scope):
Expand All @@ -317,9 +295,6 @@ def __post_init__(self) -> None:
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, i) for i in self.ids}

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope) or type(self) is type(other) and set(self.ids).issubset(other.ids)


@dataclass(frozen=True)
class DataSetScope(Capability.Scope):
Expand All @@ -332,9 +307,6 @@ def __post_init__(self) -> None:
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, i) for i in self.ids}

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope) or type(self) is type(other) and set(self.ids).issubset(other.ids)


@dataclass(frozen=True)
class TableScope(Capability.Scope):
Expand All @@ -361,19 +333,6 @@ def as_tuples(self) -> set[tuple]:
# character, we represent this internally with the empty string:
return {(self._scope_name, db, tbl) for db, tables in self.dbs_to_tables.items() for tbl in tables or [""]}

def is_within(self, other: Self) -> bool:
if isinstance(other, AllScope):
return True
if not isinstance(other, TableScope):
return False

for db_name, tables in self.dbs_to_tables.items():
if (other_tables := other.dbs_to_tables.get(db_name)) is None:
return False
if not set(tables).issubset(other_tables):
return False
return True


@dataclass(frozen=True)
class AssetRootIDScope(Capability.Scope):
Expand All @@ -386,9 +345,6 @@ def __post_init__(self) -> None:
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, i) for i in self.root_ids}

def is_within(self, other: Self) -> bool:
return isinstance(other, AllScope) or type(self) is type(other) and set(self.root_ids).issubset(other.root_ids)


@dataclass(frozen=True)
class ExperimentsScope(Capability.Scope):
Expand All @@ -398,13 +354,6 @@ class ExperimentsScope(Capability.Scope):
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, s) for s in self.experiments}

def is_within(self, other: Self) -> bool:
return (
isinstance(other, AllScope)
or type(self) is type(other)
and set(self.experiments).issubset(other.experiments)
)


@dataclass(frozen=True)
class SpaceIDScope(Capability.Scope):
Expand All @@ -414,11 +363,6 @@ class SpaceIDScope(Capability.Scope):
def as_tuples(self) -> set[tuple]:
return {(self._scope_name, s) for s in self.space_ids}

def is_within(self, other: Self) -> bool:
return (
isinstance(other, AllScope) or type(self) is type(other) and set(self.space_ids).issubset(other.space_ids)
)


@dataclass(frozen=True)
class UnknownScope(Capability.Scope):
Expand All @@ -436,9 +380,6 @@ def __getitem__(self, item: str) -> Any:
def as_tuples(self) -> set[tuple]:
raise NotImplementedError("Unknown scope cannot be converted to tuples (needed for comparisons)")

def is_within(self, other: Self) -> bool:
raise NotImplementedError("Unknown scope cannot be compared")


_SCOPE_CLASS_BY_NAME: MappingProxyType[str, type[Capability.Scope]] = MappingProxyType(
{c._scope_name: c for c in Capability.Scope.__subclasses__() if not issubclass(c, UnknownScope)}
Expand Down

0 comments on commit 223221e

Please sign in to comment.