Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion keepercommander/commands/pam_debug/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def execute(self, params: KeeperParams, **kwargs):
if record_link.dag.has_graph is True:
print(self._h("Record Linking Graph"))
graph.do_list(params=params, gateway_context=gateway_context, graph_type="rl", debug_level=debug_level,
indent=1)
indent=1, show_data=False)

print("")
print(self._h("User to Service/Task Graph"))
Expand Down
340 changes: 264 additions & 76 deletions keepercommander/commands/pam_debug/graph.py

Large diffs are not rendered by default.

116 changes: 5 additions & 111 deletions keepercommander/commands/pam_debug/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from ...discovery_common.types import UserAcl, DiscoveryObject, ServiceEnum
from ...discovery_common.constants import PAM_USER, PAM_MACHINE, PAM_DATABASE, PAM_DIRECTORY
from ...keeper_dag import EdgeType
from .graph import PAMDebugGraphCommand
import time
import re
import json
Expand Down Expand Up @@ -170,117 +171,10 @@ def _print_field(f):
record_vertex = record_link.dag.get_vertex(record.record_uid)

if record_vertex is not None:
print(self._h("Record Linking"))

print(self._b(" Record Data (meta)"))
print(f" Raw JSON: {json.dumps(record_vertex.content_as_dict)}")
print("")

record_parent_vertices = record_vertex.belongs_to_vertices()
print(self._b(" Parent Records"))
if len(record_parent_vertices) > 0:
for record_parent_vertex in record_parent_vertices:

parent_record = load_pam_record(params,
record_parent_vertex.uid) # type: TypedRecord | None
if parent_record is None:
print(f"{bcolors.FAIL} * Parent record {record_parent_vertex.uid} "
f"does not exists.{bcolors.ENDC}")
continue

acl_edge = record_vertex.get_edge(record_parent_vertex, EdgeType.ACL)
if acl_edge is not None:
acl_content = acl_edge.content_as_object(UserAcl) # type: UserAcl
print(f" * ACL to {self._n(parent_record.record_type)}; {parent_record.title}; "
f"{record_parent_vertex.uid}")
print(f" . Raw JSON: {json.dumps(acl_edge.content_as_dict)}")
if acl_content.is_admin:
print(f" . Is {self._gr('Admin')}")
if acl_content.belongs_to:
print(f" . Belongs")
else:
print(f" . Is {self._bl('Remote user')}")

if acl_content.rotation_settings is None:
print(f"{bcolors.FAIL} . There are no rotation settings!{bcolors.ENDC}")
else:
if (acl_content.rotation_settings.schedule is None
or acl_content.rotation_settings.schedule == ""):
print(f" . No Schedule")
else:
print(f" . Schedule = {acl_content.rotation_settings.get_schedule()}")

if (acl_content.rotation_settings.pwd_complexity is None
or acl_content.rotation_settings.pwd_complexity == ""):
print(f" . No Password Complexity")
else:
key_bytes = record.record_key
print(f" . Password Complexity = "
f"{acl_content.rotation_settings.get_pwd_complexity(key_bytes)}")
print(f" . Disabled = {acl_content.rotation_settings.disabled}")
print(f" . NOOP = {acl_content.rotation_settings.noop}")
print(f" . SaaS configuration record UID = "
f"{acl_content.rotation_settings.saas_record_uid_list}")

if len(acl_content.rotation_settings.saas_record_uid_list) > 0:
if acl_content.rotation_settings.noop:
saas_config_uid = acl_content.rotation_settings.saas_record_uid_list[0]
saas_config = load_pam_record(
params,
saas_config_uid) # type: TypedRecord | None

print(f" . SaaS configuration record is {saas_config.title}")
else:
print(f"{bcolors.FAIL} . Has SaaS plugin config record, "
f"however it's not NOOP{bcolors.ENDC}")

elif record.record_type == PAM_USER:
print(f"{bcolors.FAIL} * PAM User has NO acl!!!!!!{bcolors.ENDC}")

link_edge = record_vertex.get_edge(record_parent_vertex, EdgeType.LINK)
if link_edge is not None:
print(f" * LINK to {self._n(parent_record.record_type)}; {parent_record.title}; "
f"{record_parent_vertex.uid}")
else:
# This really should not happen
print(f"{bcolors.FAIL} Record does not have a parent record.{bcolors.ENDC}")
print("")

record_child_vertices = record_vertex.has_vertices()
print(self._b(" Child Records"))
if len(record_child_vertices) > 0:
for record_child_vertex in record_child_vertices:
child_record = load_pam_record(params,
record_child_vertex.uid) # type: TypedRecord | None

if child_record is None:
print(f"{bcolors.FAIL} * Child record {record_child_vertex.uid} "
f"does not exists.{bcolors.ENDC}")
continue

acl_edge = record_child_vertex.get_edge(record_vertex, EdgeType.ACL)
link_edge = record_child_vertex.get_edge(record_vertex, EdgeType.LINK)
if acl_edge is not None:
acl_content = acl_edge.content_as_object(UserAcl)
print(f" * ACL from {self._n(child_record.record_type)}; {child_record.title}; "
f"{record_child_vertex.uid}")
if acl_content.is_admin:
print(f" . Is {self._gr('Admin')}")
if acl_content.belongs_to:
print(f" . Belongs")
else:
print(f" . Is {self._bl('Remote user')}")
elif link_edge is not None:
print(f" * LINK from {self._n(child_record.record_type)}; {child_record.title}; "
"{record_child_vertex.uid}")
else:
for edge in record_vertex.edges: # List[DAGEdge]
print(f" * {self._f(edge.edge_type)}?")

else:
# This is OK
print(f" Record does not have any children.")
print("")
print(self._h("Record Linking Graph"))
graph = PAMDebugGraphCommand()
graph.do_list(params=params, gateway_context=gateway_context, graph_type="rl", debug_level=0,
indent=1, show_data=True, record_uids=[record.record_uid])

else:
print(f"{bcolors.FAIL}Cannot find record in record linking.{bcolors.ENDC}")
Expand Down
2 changes: 1 addition & 1 deletion keepercommander/discovery_common/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.1.23'
__version__ = '1.1.25'
3 changes: 2 additions & 1 deletion keepercommander/discovery_common/record_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ def dag(self) -> DAG:
fail_on_corrupt=self.fail_on_corrupt,
log_prefix=self.log_prefix,
save_batch_count=self.save_batch_count,
agent=self.agent)
agent=self.agent,
path_aware=True)
sync_point = self._dag.load(sync_point=0)
self.logger.debug(f"the record linking sync point is {sync_point or 0}")
if not self.dag.has_graph:
Expand Down
2 changes: 2 additions & 0 deletions keepercommander/discovery_common/rm_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,12 @@ class RmMappedUser(BaseModel):
:param id: Provider identifier for the user.
:param name: Human-readable user name.
:param role_ids: Ids of the roles this user holds (references RmMappedRole.id).
:param group_ids: Ids of the groups this user belongs to (references RmMappedGroup.id).
"""
id: str
name: Optional[str] = None
role_ids: List[str] = []
group_ids: List[str] = []


class RmMappedGroup(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion keepercommander/keeper_dag/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.1.11' # pragma: no cover
__version__ = '1.2.0' # pragma: no cover
21 changes: 20 additions & 1 deletion keepercommander/keeper_dag/connection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import os
import time
import sys
import json
from enum import Enum
from pydantic import BaseModel
from typing import Optional, Union, Any, Dict, Tuple, TYPE_CHECKING
from typing import Optional, Union, Any, Dict, Tuple, List, TYPE_CHECKING
if TYPE_CHECKING: # pragma: no cover
Logger = Union[logging.RootLogger, logging.Logger]
from ..types import JitSettings, ConnectionSettingsBase, AiSettings, Meta

# What is this?
# If used with Commander, router_abbr_pb2 will interfere with router_pb2.
Expand Down Expand Up @@ -218,6 +220,8 @@ def payload_and_headers(self, payload: Any) -> Tuple[Union[str, bytes], Dict]:
self.logger.debug("payload is protobuf")
headers = {'Content-Type': 'application/octet-stream'}
payload = encrypt_aes(payload.SerializeToString(), self.transmission_key)
elif isinstance(payload, dict):
payload = json.dumps(payload)
else:
raise Exception("Cannot determine if the model is pydantic or protobuf.")

Expand Down Expand Up @@ -468,3 +472,18 @@ def get_leafs(self,
error=str(err)
)
raise DAGException(f"Could not get leafs: {err}")

def configure_resource(self,
record: Any,
configuration_record_uid: str,
connection_user_uids: List[str] = [],
admin_user_record_uid: Optional[str] = None,
connection_settings: Optional[ConnectionSettingsBase] = None,
jit_settings: Optional[JitSettings] = None,
ai_settings: Optional[AiSettings] = None,
domain_uid: Optional[str] = None,
meta: Optional[Dict] = None,
update_services: Optional[Meta] = None,
agent: Optional[str] = None):

raise Exception(f"configure_resource does not exists for {self.__class__.__name__}")
Loading