From 1aae05ff5d117c34ea78b0764ae7100c73853c38 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:30:56 -0500 Subject: [PATCH 01/53] New User Model --- brewtils/models.py | 141 +++++++++++++++++++++------------- brewtils/rest/easy_client.py | 8 +- brewtils/schema_parser.py | 37 ++++----- brewtils/schemas.py | 69 ++++++----------- brewtils/test/comparable.py | 15 ++-- brewtils/test/fixtures.py | 48 +++++++----- test/models_test.py | 35 +++++---- test/rest/easy_client_test.py | 6 +- test/schema_parser_test.py | 74 +++++++++--------- test/schema_test.py | 91 ---------------------- 10 files changed, 220 insertions(+), 304 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index c60c794a..9084218b 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -21,8 +21,6 @@ "Event", "Events", "Queue", - "Principal", - "LegacyRole", "RefreshToken", "Job", "RequestFile", @@ -37,6 +35,8 @@ "Garden", "Operation", "Resolvable", + "Role", + "User", ] @@ -1103,58 +1103,6 @@ def __repr__(self): return "" % (self.name, self.size) -class Principal(BaseModel): - schema = "PrincipalSchema" - - def __init__( - self, - id=None, # noqa # shadows built-in - username=None, - roles=None, - permissions=None, - preferences=None, - metadata=None, - ): - self.id = id - self.username = username - self.roles = roles - self.permissions = permissions - self.preferences = preferences - self.metadata = metadata - - def __str__(self): - return "%s" % self.username - - def __repr__(self): - return "" % ( - self.username, - self.roles, - self.permissions, - ) - - -class LegacyRole(BaseModel): - schema = "LegacyRoleSchema" - - def __init__( - self, - id=None, # noqa # shadows built-in - name=None, - description=None, - permissions=None, - ): - self.id = id - self.name = name - self.description = description - self.permissions = permissions - - def __str__(self): - return "%s" % self.name - - def __repr__(self): - return "" % (self.name, self.permissions) - - class RefreshToken(BaseModel): schema = "RefreshTokenSchema" @@ -1649,3 +1597,88 @@ def __repr__(self): self.storage, self.details, ) + + +class User(BaseModel): + schema = "UserSchema" + + def __init__( + self, + username, + password=None, + roles=None, + assigned_roles=None, + is_remote=False, + metadata=None, + ): + self.username = username + self.password = password + self.roles = roles or [] + self.assigned_roles = assigned_roles or [] + self.is_remote = is_remote + self.metadata = metadata + + def __str__(self): + return "%s: %s" % (self.username, self.roles) + + def __repr__(self): + return "" % ( + self.username, + self.roles, + ) + + +class Role(BaseModel): + schema = "RoleSchema" + + PERMISSION_TYPES = { + "ADMIN", + "OPERATOR", + "READ_ONLY", # Default value if not role is provided + } + + def __init__( + self, + name, + permission=None, + description=None, + id=None, + is_remote=False, + scope_gardens=None, + scope_namespaces=None, + scope_systems=None, + scope_instances=None, + scope_verisons=None, + scope_commands=None, + ): + self.permission = permission or "READ_ONLY" + self.description = description + self.id = id + self.name = name + self.is_remote = is_remote + self.scope_gardens = scope_gardens or [] + self.scope_namespaces = scope_namespaces or [] + self.scope_systems = scope_systems or [] + self.scope_instances = scope_instances or [] + self.scope_verisons = scope_verisons or [] + self.scope_commands = scope_commands or [] + + def __str__(self): + return "%s" % (self.name) + + def __repr__(self): + return ( + "" + ) % ( + self.id, + self.name, + self.permission, + self.is_remote, + self.scope_gardens, + self.scope_namespaces, + self.scope_systems, + self.scope_instances, + self.scope_verisons, + self.scope_commands, + ) diff --git a/brewtils/rest/easy_client.py b/brewtils/rest/easy_client.py index 575d728a..ba515916 100644 --- a/brewtils/rest/easy_client.py +++ b/brewtils/rest/easy_client.py @@ -1088,9 +1088,7 @@ def forward(self, operation, **kwargs): SchemaParser.serialize_operation(operation), **kwargs ) - @wrap_response( - parse_method="parse_principal", parse_many=False, default_exc=FetchError - ) + @wrap_response(parse_method="parse_user", parse_many=False, default_exc=FetchError) def get_user(self, user_identifier): """Find a user @@ -1098,7 +1096,7 @@ def get_user(self, user_identifier): user_identifier (str): User ID or username Returns: - Principal: The User + User: The User """ return self.client.get_user(user_identifier) @@ -1107,7 +1105,7 @@ def who_am_i(self): """Find user using the current set of credentials Returns: - Principal: The User + User: The User """ return self.get_user(self.client.username or "anonymous") diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 98598ada..514ae696 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -37,7 +37,7 @@ class SchemaParser(object): "QueueSchema": brewtils.models.Queue, "ParameterSchema": brewtils.models.Parameter, "PatchSchema": brewtils.models.PatchOperation, - "PrincipalSchema": brewtils.models.Principal, + "UserSchema": brewtils.models.User, "RefreshTokenSchema": brewtils.models.RefreshToken, "RequestSchema": brewtils.models.Request, "RequestFileSchema": brewtils.models.RequestFile, @@ -45,11 +45,12 @@ class SchemaParser(object): "FileChunkSchema": brewtils.models.FileChunk, "FileStatusSchema": brewtils.models.FileStatus, "RequestTemplateSchema": brewtils.models.RequestTemplate, - "LegacyRoleSchema": brewtils.models.LegacyRole, "SystemSchema": brewtils.models.System, "OperationSchema": brewtils.models.Operation, "RunnerSchema": brewtils.models.Runner, "ResolvableSchema": brewtils.models.Resolvable, + "RoleSchema": brewtils.models.Role, + "UserSchema": brewtils.models.User, } logger = logging.getLogger(__name__) @@ -253,20 +254,18 @@ def parse_queue(cls, queue, from_string=False, **kwargs): ) @classmethod - def parse_principal(cls, principal, from_string=False, **kwargs): - """Convert raw JSON string or dictionary to a principal model object + def parse_user(cls, user, from_string=False, **kwargs): + """Convert raw JSON string or dictionary to a user model object Args: - principal: The raw input + user: The raw input from_string: True if input is a JSON string, False if a dictionary **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) Returns: - A Principal object + A User object """ - return cls.parse( - principal, brewtils.models.Principal, from_string=from_string, **kwargs - ) + return cls.parse(user, brewtils.models.User, from_string=from_string, **kwargs) @classmethod def parse_role(cls, role, from_string=False, **kwargs): @@ -280,9 +279,7 @@ def parse_role(cls, role, from_string=False, **kwargs): Returns: A Role object """ - return cls.parse( - role, brewtils.models.LegacyRole, from_string=from_string, **kwargs - ) + return cls.parse(role, brewtils.models.Role, from_string=from_string, **kwargs) @classmethod def parse_refresh_token(cls, refresh_token, from_string=False, **kwargs): @@ -674,11 +671,11 @@ def serialize_queue(cls, queue, to_string=True, **kwargs): ) @classmethod - def serialize_principal(cls, principal, to_string=True, **kwargs): - """Convert a principal model into serialized form + def serialize_user(cls, user, to_string=True, **kwargs): + """Convert a user model into serialized form Args: - principal: The principal object(s) to be serialized + user: The user object(s) to be serialized to_string: True to generate a JSON-formatted string, False to generate a dictionary **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) @@ -687,10 +684,7 @@ def serialize_principal(cls, principal, to_string=True, **kwargs): Serialized representation """ return cls.serialize( - principal, - to_string=to_string, - schema_name=brewtils.models.Principal.schema, - **kwargs + user, to_string=to_string, schema_name=brewtils.models.User.schema, **kwargs ) @classmethod @@ -707,10 +701,7 @@ def serialize_role(cls, role, to_string=True, **kwargs): Serialized representation """ return cls.serialize( - role, - to_string=to_string, - schema_name=brewtils.models.LegacyRole.schema, - **kwargs + role, to_string=to_string, schema_name=brewtils.models.Role.schema, **kwargs ) @classmethod diff --git a/brewtils/schemas.py b/brewtils/schemas.py index e734f13a..f038ec82 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -24,8 +24,6 @@ "LoggingConfigSchema", "EventSchema", "QueueSchema", - "PrincipalSchema", - "LegacyRoleSchema", "RefreshTokenSchema", "JobSchema", "JobExportSchema", @@ -42,8 +40,6 @@ "UserCreateSchema", "UserListSchema", "RoleSchema", - "RoleAssignmentSchema", - "RoleAssignmentDomainSchema", "GardenDomainIdentifierSchema", "SystemDomainIdentifierSchema", ] @@ -425,23 +421,6 @@ class QueueSchema(BaseSchema): size = fields.Integer(allow_none=True) -class PrincipalSchema(BaseSchema): - id = fields.Str(allow_none=True) - username = fields.Str(allow_none=True) - roles = fields.Nested("LegacyRoleSchema", many=True, allow_none=True) - permissions = fields.List(fields.Str(), allow_none=True) - preferences = fields.Dict(allow_none=True) - metadata = fields.Dict(allow_none=True) - - -class LegacyRoleSchema(BaseSchema): - id = fields.Str(allow_none=True) - name = fields.Str(allow_none=True) - description = fields.Str(allow_none=True) - roles = fields.Nested("self", many=True, allow_none=True) - permissions = fields.List(fields.Str(), allow_none=True) - - class RefreshTokenSchema(BaseSchema): id = fields.Str(allow_none=True) issued = DateTime(allow_none=True, format="epoch", example="1500065932000") @@ -604,40 +583,36 @@ class ResolvableSchema(BaseSchema): class RoleSchema(BaseSchema): - id = fields.Str() + id = fields.Str(allow_none=True) name = fields.Str() description = fields.Str(allow_none=True) - permissions = fields.List(fields.Str()) - - -class RoleAssignmentDomainSchema(BaseSchema): - scope = fields.Str() - identifiers = PolyField( - serialization_schema_selector=_domain_identifier_schema_selector, - deserialization_schema_selector=_domain_identifier_schema_selector, - required=False, - ) - - -class RoleAssignmentSchema(BaseSchema): - domain = fields.Nested(RoleAssignmentDomainSchema, required=True) - role = fields.Nested(RoleSchema()) + permission = fields.Str() + is_remote = fields.Boolean(allow_none=True) + scope_gardens = fields.List(fields.Str(), allow_none=True) + scope_namespaces = fields.List(fields.Str(), allow_none=True) + scope_systems = fields.List(fields.Str(), allow_none=True) + scope_instances = fields.List(fields.Str(), allow_none=True) + scope_verisons = fields.List(fields.Str(), allow_none=True) + scope_commands = fields.List(fields.Str(), allow_none=True) class UserSchema(BaseSchema): - id = fields.Str() + id = fields.Str(allow_none=True) username = fields.Str() - role_assignments = fields.List(fields.Nested(RoleAssignmentSchema())) - permissions = fields.Dict() + password = fields.Str() + roles = fields.List(fields.Str(), allow_none=True) + assigned_roles = fields.List(fields.Nested(RoleSchema())) + is_remote = fields.Boolean(allow_none=True) + metadata = fields.Dict(allow_none=True) -class UserCreateSchema(BaseSchema): - username = fields.Str(required=True) - password = fields.Str(required=True, load_only=True) +# class UserCreateSchema(BaseSchema): +# username = fields.Str(required=True) +# password = fields.Str(required=True, load_only=True) -class UserListSchema(BaseSchema): - users = fields.List(fields.Nested(UserSchema())) +# class UserListSchema(BaseSchema): +# users = fields.List(fields.Nested(UserSchema())) model_schema_map.update( @@ -658,7 +633,6 @@ class UserListSchema(BaseSchema): "Queue": QueueSchema, "Parameter": ParameterSchema, "PatchOperation": PatchSchema, - "Principal": PrincipalSchema, "RefreshToken": RefreshTokenSchema, "Request": RequestSchema, "RequestFile": RequestFileSchema, @@ -666,11 +640,12 @@ class UserListSchema(BaseSchema): "FileChunk": FileChunkSchema, "FileStatus": FileStatusSchema, "RequestTemplate": RequestTemplateSchema, - "LegacyRole": LegacyRoleSchema, "System": SystemSchema, "Operation": OperationSchema, "Runner": RunnerSchema, "Resolvable": ResolvableSchema, + "Role": RoleSchema, + "User": UserSchema, # Compatibility for the Job trigger types "interval": IntervalTriggerSchema, "date": DateTriggerSchema, diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 2003a7c8..8b320c30 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -24,12 +24,12 @@ Instance, IntervalTrigger, Job, - LegacyRole, + Role, LoggingConfig, Operation, Parameter, PatchOperation, - Principal, + User, Queue, Request, RequestFile, @@ -50,7 +50,7 @@ "assert_trigger_equal", "assert_command_equal", "assert_parameter_equal", - "assert_principal_equal", + "assert_user_equal", "assert_request_equal", "assert_role_equal", "assert_system_equal", @@ -236,12 +236,12 @@ def assert_event_equal(obj1, obj2, do_raise=False): ) -def assert_principal_equal(obj1, obj2, do_raise=False): +def assert_user_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, obj2, - expected_type=Principal, - deep_fields={"roles": partial(assert_role_equal, do_raise=True)}, + expected_type=User, + deep_fields={"assigned_roles": partial(assert_role_equal, do_raise=True)}, do_raise=do_raise, ) @@ -298,8 +298,7 @@ def assert_role_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, obj2, - expected_type=LegacyRole, - deep_fields={"roles": partial(assert_role_equal, do_raise=True)}, + expected_type=Role, do_raise=do_raise, ) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index cef700d8..d0c9c28f 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -17,12 +17,10 @@ Instance, IntervalTrigger, Job, - LegacyRole, LoggingConfig, Operation, Parameter, PatchOperation, - Principal, Queue, Request, RequestFile, @@ -30,6 +28,8 @@ Resolvable, Runner, System, + User, + Role, ) @@ -528,38 +528,44 @@ def bg_queue(queue_dict): @pytest.fixture -def principal_dict(legacy_role_dict): +def role_dict(): return { - "id": "58542eb571afd47ead90d24f", - "username": "admin", - "roles": [legacy_role_dict], - "permissions": ["bg-all"], - "preferences": {"theme": "dark"}, - "metadata": {"foo": "bar"}, + "permission": "ADMIN", + "description": "ADMIN ROLE", + "id": "1", + "name": "ADMIN_ROLE", + "is_remote": False, + "scope_gardens": ["FOO"], + "scope_namespaces": [], + "scope_systems": [], + "scope_instances": [], + "scope_verisons": [], + "scope_commands": [], } @pytest.fixture -def bg_principal(principal_dict, bg_role): - dict_copy = copy.deepcopy(principal_dict) - dict_copy["roles"] = [bg_role] - return Principal(**dict_copy) +def bg_role(role_dict): + return Role(**role_dict) @pytest.fixture -def legacy_role_dict(): +def user_dict(role_dict): return { - "id": "58542eb571afd47ead90d26f", - "name": "bg-admin", - "description": "The admin role", - "permissions": ["bg-all"], + "username": "USERNAME", + "password": "HASH", + "roles": ["ADMIN_ROLE"], + "assigned_roles": [role_dict], + "is_remote": False, + "metadata": {}, } @pytest.fixture -def bg_role(legacy_role_dict): - dict_copy = copy.deepcopy(legacy_role_dict) - return LegacyRole(**dict_copy) +def bg_user(user_dict, bg_role): + dict_copy = copy.deepcopy(user_dict) + dict_copy["assigned_roles"] = [bg_role] + return User(**dict_copy) @pytest.fixture diff --git a/test/models_test.py b/test/models_test.py index b64bafb1..64c22cb3 100644 --- a/test/models_test.py +++ b/test/models_test.py @@ -13,12 +13,12 @@ LoggingConfig, Parameter, PatchOperation, - Principal, + User, Queue, Request, RequestFile, RequestTemplate, - LegacyRole, + Role, ) from pytest_lazyfixture import lazy_fixture @@ -529,31 +529,36 @@ def test_repr(self, queue): assert repr(queue) == "" -class TestPrincipal(object): +class TestUser(object): @pytest.fixture - def principal(self): - return Principal(username="admin", roles=["bg-admin"], permissions=["bg-all"]) + def user(self): + return User( + username="admin", + roles=["bg-admin"], + assigned_roles=[Role(name="foo", permission="ADMIN")], + ) - def test_str(self, principal): - assert str(principal) == "admin" + def test_str(self, user): + assert str(user) == "admin: ['bg-admin']" - def test_repr(self, principal): - assert ( - repr(principal) - == "" - ) + def test_repr(self, user): + assert repr(user) == "" -class TestLegacyRole(object): +class TestRole(object): @pytest.fixture def role(self): - return LegacyRole(name="bg-admin", permissions=["bg-all"]) + return Role(name="bg-admin", permission="ADMIN") def test_str(self, role): assert str(role) == "bg-admin" def test_repr(self, role): - assert repr(role) == "" + assert repr(role) == ( + "" + ) class TestDateTrigger(object): diff --git a/test/rest/easy_client_test.py b/test/rest/easy_client_test.py index 488bb27c..9ccf8533 100644 --- a/test/rest/easy_client_test.py +++ b/test/rest/easy_client_test.py @@ -515,11 +515,11 @@ def test_forward(client, rest_client, success, bg_operation): assert rest_client.post_forward.called is True -def test_get_user(client, rest_client, success, bg_principal): +def test_get_user(client, rest_client, success, bg_user): rest_client.get_user.return_value = success - client.get_user(bg_principal.username) - rest_client.get_user.assert_called_once_with(bg_principal.username) + client.get_user(bg_user.username) + rest_client.get_user.assert_called_once_with(bg_user.username) class TestWhoAmI(object): diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index cbeee083..aea91843 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -21,7 +21,7 @@ assert_operation_equal, assert_parameter_equal, assert_patch_equal, - assert_principal_equal, + assert_user_equal, assert_queue_equal, assert_request_equal, assert_request_file_equal, @@ -121,14 +121,14 @@ def test_no_modify(self, system_dict): lazy_fixture("bg_queue"), ), ( - brewtils.models.Principal, - lazy_fixture("principal_dict"), - assert_principal_equal, - lazy_fixture("bg_principal"), + brewtils.models.User, + lazy_fixture("user_dict"), + assert_user_equal, + lazy_fixture("bg_user"), ), ( - brewtils.models.LegacyRole, - lazy_fixture("legacy_role_dict"), + brewtils.models.Role, + lazy_fixture("role_dict"), assert_role_equal, lazy_fixture("bg_role"), ), @@ -249,14 +249,14 @@ def test_single_from_string(self): lazy_fixture("bg_queue"), ), ( - "parse_principal", - lazy_fixture("principal_dict"), - assert_principal_equal, - lazy_fixture("bg_principal"), + "parse_user", + lazy_fixture("user_dict"), + assert_user_equal, + lazy_fixture("bg_user"), ), ( "parse_role", - lazy_fixture("legacy_role_dict"), + lazy_fixture("role_dict"), assert_role_equal, lazy_fixture("bg_role"), ), @@ -382,14 +382,14 @@ def test_single_specific_from_string(self): lazy_fixture("bg_queue"), ), ( - brewtils.models.Principal, - lazy_fixture("principal_dict"), - assert_principal_equal, - lazy_fixture("bg_principal"), + brewtils.models.User, + lazy_fixture("user_dict"), + assert_user_equal, + lazy_fixture("bg_user"), ), ( - brewtils.models.LegacyRole, - lazy_fixture("legacy_role_dict"), + brewtils.models.Role, + lazy_fixture("role_dict"), assert_role_equal, lazy_fixture("bg_role"), ), @@ -508,14 +508,14 @@ def test_many(self, model, data, assertion, expected): lazy_fixture("bg_queue"), ), ( - "parse_principal", - lazy_fixture("principal_dict"), - assert_principal_equal, - lazy_fixture("bg_principal"), + "parse_user", + lazy_fixture("user_dict"), + assert_user_equal, + lazy_fixture("bg_user"), ), ( "parse_role", - lazy_fixture("legacy_role_dict"), + lazy_fixture("role_dict"), assert_role_equal, lazy_fixture("bg_role"), ), @@ -605,8 +605,8 @@ class TestSerialize(object): (lazy_fixture("bg_logging_config"), lazy_fixture("logging_config_dict")), (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), - (lazy_fixture("bg_principal"), lazy_fixture("principal_dict")), - (lazy_fixture("bg_role"), lazy_fixture("legacy_role_dict")), + (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -665,14 +665,14 @@ def test_single(self, model, expected): ("serialize_event", lazy_fixture("bg_event"), lazy_fixture("event_dict")), ("serialize_queue", lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), ( - "serialize_principal", - lazy_fixture("bg_principal"), - lazy_fixture("principal_dict"), + "serialize_user", + lazy_fixture("bg_user"), + lazy_fixture("user_dict"), ), ( "serialize_role", lazy_fixture("bg_role"), - lazy_fixture("legacy_role_dict"), + lazy_fixture("role_dict"), ), ("serialize_job", lazy_fixture("bg_job"), lazy_fixture("job_dict")), ( @@ -734,8 +734,8 @@ def test_single_specific(self, method, data, expected): (lazy_fixture("bg_logging_config"), lazy_fixture("logging_config_dict")), (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), - (lazy_fixture("bg_principal"), lazy_fixture("principal_dict")), - (lazy_fixture("bg_role"), lazy_fixture("legacy_role_dict")), + (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -811,11 +811,11 @@ class TestRoundTrip(object): (brewtils.models.Event, assert_event_equal, lazy_fixture("bg_event")), (brewtils.models.Queue, assert_queue_equal, lazy_fixture("bg_queue")), ( - brewtils.models.Principal, - assert_principal_equal, - lazy_fixture("bg_principal"), + brewtils.models.User, + assert_user_equal, + lazy_fixture("bg_user"), ), - (brewtils.models.LegacyRole, assert_role_equal, lazy_fixture("bg_role")), + (brewtils.models.Role, assert_role_equal, lazy_fixture("bg_role")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_cron_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_interval_job")), @@ -853,8 +853,8 @@ def test_parsed_start(self, model, assertion, data): (brewtils.models.LoggingConfig, lazy_fixture("logging_config_dict")), (brewtils.models.Event, lazy_fixture("event_dict")), (brewtils.models.Queue, lazy_fixture("queue_dict")), - (brewtils.models.Principal, lazy_fixture("principal_dict")), - (brewtils.models.LegacyRole, lazy_fixture("legacy_role_dict")), + (brewtils.models.User, lazy_fixture("user_dict")), + (brewtils.models.Role, lazy_fixture("role_dict")), (brewtils.models.Job, lazy_fixture("job_dict")), (brewtils.models.Job, lazy_fixture("cron_job_dict")), (brewtils.models.Job, lazy_fixture("interval_job_dict")), diff --git a/test/schema_test.py b/test/schema_test.py index f032780b..da25bd61 100644 --- a/test/schema_test.py +++ b/test/schema_test.py @@ -9,7 +9,6 @@ from brewtils.schemas import ( BaseSchema, DateTime, - RoleAssignmentSchema, SystemSchema, _deserialize_model, _serialize_model, @@ -96,93 +95,3 @@ def test_deserialize_mapping(self): assert len(models) == len( SchemaParser._models ), "Missing mapped schema for deserialization" - - -class TestRoleAssignmentSchema(object): - @pytest.fixture - def schema(self): - yield RoleAssignmentSchema() - - @pytest.fixture - def role_assignment_garden_scope(self): - role = {"name": "myrole", "permissions": ["perm1"]} - domain = {"scope": "Garden", "identifiers": {"name": "mygarden"}} - role_assignment = {"role": role, "domain": domain} - - yield role_assignment - - @pytest.fixture - def role_assignment_system_scope(self): - role = {"name": "myrole", "permissions": ["perm1"]} - domain = { - "scope": "System", - "identifiers": {"name": "mysystem", "namespace": "mygarden"}, - } - role_assignment = {"role": role, "domain": domain} - - yield role_assignment - - @pytest.fixture - def role_assignment_global_scope(self): - role = {"name": "myrole", "permissions": ["perm1"]} - domain = {"scope": "Global"} - role_assignment = {"role": role, "domain": domain} - - yield role_assignment - - def test_role_assignment_domain_schema_can_deserialize_garden_scope( - self, schema, role_assignment_garden_scope - ): - assert ( - schema.load(role_assignment_garden_scope).data - == role_assignment_garden_scope - ) - - def test_role_assignment_domain_schema_can_deserialize_system_scope( - self, schema, role_assignment_system_scope - ): - assert ( - schema.load(role_assignment_system_scope).data - == role_assignment_system_scope - ) - - def test_role_assignment_domain_schema_can_deserialize_global_scope( - self, schema, role_assignment_global_scope - ): - assert ( - schema.load(role_assignment_global_scope).data - == role_assignment_global_scope - ) - - def test_role_assignment_domain_schema_can_serialize( - self, schema, role_assignment_garden_scope - ): - assert ( - schema.dump(role_assignment_garden_scope).data - == role_assignment_garden_scope - ) - - def test_role_assignment_domain_schema_can_serialize_global_scope( - self, schema, role_assignment_global_scope - ): - assert ( - schema.dump(role_assignment_global_scope).data - == role_assignment_global_scope - ) - - def test_role_assignment_domain_schema_validates_identifiers( - self, schema, role_assignment_system_scope - ): - # Remove one of the required identifier fields - del role_assignment_system_scope["domain"]["identifiers"]["namespace"] - - with pytest.raises(ValidationError): - schema.load(role_assignment_system_scope) - - def test_role_assignment_domain_schema_raises_error_on_invalid_scope( - self, schema, role_assignment_system_scope - ): - role_assignment_system_scope["domain"]["scope"] = "Unsupported" - - with pytest.raises(ValidationError): - schema.load(role_assignment_system_scope) From 504d4232c1e0c6113591d2018484a4615c827d52 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:19:53 -0500 Subject: [PATCH 02/53] code cleanup --- brewtils/models.py | 5 +++-- brewtils/schema_parser.py | 1 - brewtils/schemas.py | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9084218b..a2853f61 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1668,8 +1668,9 @@ def __str__(self): def __repr__(self): return ( - "" + "" ) % ( self.id, self.name, diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 514ae696..2a6b3783 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -37,7 +37,6 @@ class SchemaParser(object): "QueueSchema": brewtils.models.Queue, "ParameterSchema": brewtils.models.Parameter, "PatchSchema": brewtils.models.PatchOperation, - "UserSchema": brewtils.models.User, "RefreshTokenSchema": brewtils.models.RefreshToken, "RequestSchema": brewtils.models.Request, "RequestFileSchema": brewtils.models.RequestFile, diff --git a/brewtils/schemas.py b/brewtils/schemas.py index f038ec82..743950a8 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -37,8 +37,6 @@ "GardenSchema", "OperationSchema", "UserSchema", - "UserCreateSchema", - "UserListSchema", "RoleSchema", "GardenDomainIdentifierSchema", "SystemDomainIdentifierSchema", From 7705412b7400e09224506e03f6d7e39d01f26c5a Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:44:42 -0500 Subject: [PATCH 03/53] Expanding to support remote user mappings --- brewtils/models.py | 19 ++++++++++----- brewtils/schema_parser.py | 40 ++++++++++++++++++++++++++++++++ brewtils/schemas.py | 46 ++++++++----------------------------- brewtils/test/comparable.py | 8 ++++++- brewtils/test/fixtures.py | 25 ++++++++++++++++---- test/models_test.py | 6 ++--- test/schema_parser_test.py | 37 +++++++++++++++++++++++++++++ 7 files changed, 129 insertions(+), 52 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index a2853f61..628ce829 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1607,15 +1607,17 @@ def __init__( username, password=None, roles=None, - assigned_roles=None, + remote_roles=None, is_remote=False, + remote_user_mapping=None, metadata=None, ): self.username = username self.password = password self.roles = roles or [] - self.assigned_roles = assigned_roles or [] + self.remote_roles = remote_roles or [] self.is_remote = is_remote + self.remote_user_mapping = remote_user_mapping or [] self.metadata = metadata def __str__(self): @@ -1643,7 +1645,6 @@ def __init__( permission=None, description=None, id=None, - is_remote=False, scope_gardens=None, scope_namespaces=None, scope_systems=None, @@ -1655,7 +1656,6 @@ def __init__( self.description = description self.id = id self.name = name - self.is_remote = is_remote self.scope_gardens = scope_gardens or [] self.scope_namespaces = scope_namespaces or [] self.scope_systems = scope_systems or [] @@ -1668,14 +1668,13 @@ def __str__(self): def __repr__(self): return ( - "" ) % ( self.id, self.name, self.permission, - self.is_remote, self.scope_gardens, self.scope_namespaces, self.scope_systems, @@ -1683,3 +1682,11 @@ def __repr__(self): self.scope_verisons, self.scope_commands, ) + + +class RemoteUserMap(BaseModel): + schema = "RemoteUserMapSchema" + + def __init__(self, target_garden, username): + self.target_garden = target_garden + self.username = username diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 2a6b3783..7462c243 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -50,6 +50,7 @@ class SchemaParser(object): "ResolvableSchema": brewtils.models.Resolvable, "RoleSchema": brewtils.models.Role, "UserSchema": brewtils.models.User, + "RemoteUserMapSchema": brewtils.models.RemoteUserMap, } logger = logging.getLogger(__name__) @@ -280,6 +281,25 @@ def parse_role(cls, role, from_string=False, **kwargs): """ return cls.parse(role, brewtils.models.Role, from_string=from_string, **kwargs) + @classmethod + def parse_remote_user_map(cls, remote_user_map, from_string=False, **kwargs): + """Convert raw JSON string or dictionary to a RemoteUserMap model object + + Args: + role: The raw input + from_string: True if input is a JSON string, False if a dictionary + **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) + + Returns: + A RemoteUserMap object + """ + return cls.parse( + remote_user_map, + brewtils.models.RemoteUserMap, + from_string=from_string, + **kwargs + ) + @classmethod def parse_refresh_token(cls, refresh_token, from_string=False, **kwargs): """Convert raw JSON string or dictionary to a refresh token object @@ -703,6 +723,26 @@ def serialize_role(cls, role, to_string=True, **kwargs): role, to_string=to_string, schema_name=brewtils.models.Role.schema, **kwargs ) + @classmethod + def serialize_remote_user_map(cls, remote_user_map, to_string=True, **kwargs): + """Convert a RemoteUserMap model into serialized form + + Args: + RemoteUserMap: The RemoteUserMap object(s) to be serialized + to_string: True to generate a JSON-formatted string, False to generate a + dictionary + **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) + + Returns: + Serialized representation + """ + return cls.serialize( + remote_user_map, + to_string=to_string, + schema_name=brewtils.models.RemoteUserMap.schema, + **kwargs + ) + @classmethod def serialize_refresh_token(cls, refresh_token, to_string=True, **kwargs): """Convert a role model into serialized form diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 743950a8..9ea8ca42 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -38,8 +38,7 @@ "OperationSchema", "UserSchema", "RoleSchema", - "GardenDomainIdentifierSchema", - "SystemDomainIdentifierSchema", + "RemoteUserMapSchema", ] # This will be updated after all the schema classes are defined @@ -68,26 +67,6 @@ def _deserialize_model(_, data, type_field=None, allowed_types=None): return model_schema_map.get(data[type_field])() -def _domain_identifier_schema_selector(_, role_assignment_domain): - scope_schema_map = { - "Garden": GardenDomainIdentifierSchema, - "System": SystemDomainIdentifierSchema, - "Global": Schema, - } - - if isinstance(role_assignment_domain, dict): - scope = role_assignment_domain.get("scope") - else: - scope = role_assignment_domain.scope - - schema = scope_schema_map.get(scope) - - if schema is None: - raise TypeError("Invalid scope: %s" % scope) - - return schema() - - class ModelField(PolyField): """Field representing a Brewtils model @@ -495,10 +474,6 @@ class GardenSchema(BaseSchema): metadata = fields.Dict(allow_none=True) -class GardenDomainIdentifierSchema(BaseSchema): - name = fields.Str(required=True) - - class JobSchema(BaseSchema): id = fields.Str(allow_none=True) name = fields.Str(allow_none=True) @@ -585,7 +560,6 @@ class RoleSchema(BaseSchema): name = fields.Str() description = fields.Str(allow_none=True) permission = fields.Str() - is_remote = fields.Boolean(allow_none=True) scope_gardens = fields.List(fields.Str(), allow_none=True) scope_namespaces = fields.List(fields.Str(), allow_none=True) scope_systems = fields.List(fields.Str(), allow_none=True) @@ -594,25 +568,22 @@ class RoleSchema(BaseSchema): scope_commands = fields.List(fields.Str(), allow_none=True) +class RemoteUserMapSchema(BaseSchema): + target_garden = fields.Str() + username = fields.Str() + + class UserSchema(BaseSchema): id = fields.Str(allow_none=True) username = fields.Str() password = fields.Str() roles = fields.List(fields.Str(), allow_none=True) - assigned_roles = fields.List(fields.Nested(RoleSchema())) + remote_roles = fields.List(fields.Nested(RoleSchema())) + remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) -# class UserCreateSchema(BaseSchema): -# username = fields.Str(required=True) -# password = fields.Str(required=True, load_only=True) - - -# class UserListSchema(BaseSchema): -# users = fields.List(fields.Nested(UserSchema())) - - model_schema_map.update( { "Choices": ChoicesSchema, @@ -644,6 +615,7 @@ class UserSchema(BaseSchema): "Resolvable": ResolvableSchema, "Role": RoleSchema, "User": UserSchema, + "RemoteUserMap": RemoteUserMapSchema, # Compatibility for the Job trigger types "interval": IntervalTriggerSchema, "date": DateTriggerSchema, diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 8b320c30..f1197ed6 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -31,6 +31,7 @@ PatchOperation, User, Queue, + RemoteUserMap, Request, RequestFile, RequestTemplate, @@ -51,6 +52,7 @@ "assert_command_equal", "assert_parameter_equal", "assert_user_equal", + "assert_remote_user_map_equal", "assert_request_equal", "assert_role_equal", "assert_system_equal", @@ -193,6 +195,7 @@ def _assert_wrapper(obj1, obj2, expected_type=None, do_raise=False, **kwargs): assert_runner_equal = partial(_assert_wrapper, expected_type=Runner) assert_resolvable_equal = partial(_assert_wrapper, expected_type=Resolvable) assert_connection_equal = partial(_assert_wrapper, expected_type=Connection) +assert_remote_user_map_equal = partial(_assert_wrapper, expected_type=RemoteUserMap) def assert_command_equal(obj1, obj2, do_raise=False): @@ -241,7 +244,10 @@ def assert_user_equal(obj1, obj2, do_raise=False): obj1, obj2, expected_type=User, - deep_fields={"assigned_roles": partial(assert_role_equal, do_raise=True)}, + deep_fields={ + "remote_roles": partial(assert_role_equal, do_raise=True), + "remote_user_mapping": partial(assert_remote_user_map_equal, do_raise=True), + }, do_raise=do_raise, ) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index d0c9c28f..5fe6c2c4 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -22,6 +22,7 @@ Parameter, PatchOperation, Queue, + RemoteUserMap, Request, RequestFile, RequestTemplate, @@ -527,6 +528,19 @@ def bg_queue(queue_dict): return Queue(**queue_dict) +@pytest.fixture +def remote_user_map_dict(): + return { + "target_garden": "test", + "username": "user", + } + + +@pytest.fixture +def bg_remote_user_map(remote_user_map_dict): + return RemoteUserMap(**remote_user_map_dict) + + @pytest.fixture def role_dict(): return { @@ -534,7 +548,6 @@ def role_dict(): "description": "ADMIN ROLE", "id": "1", "name": "ADMIN_ROLE", - "is_remote": False, "scope_gardens": ["FOO"], "scope_namespaces": [], "scope_systems": [], @@ -550,21 +563,23 @@ def bg_role(role_dict): @pytest.fixture -def user_dict(role_dict): +def user_dict(role_dict, remote_user_map_dict): return { "username": "USERNAME", "password": "HASH", "roles": ["ADMIN_ROLE"], - "assigned_roles": [role_dict], + "remote_roles": [role_dict], + "remote_user_mapping": [remote_user_map_dict], "is_remote": False, "metadata": {}, } @pytest.fixture -def bg_user(user_dict, bg_role): +def bg_user(user_dict, bg_role, bg_remote_user_map): dict_copy = copy.deepcopy(user_dict) - dict_copy["assigned_roles"] = [bg_role] + dict_copy["remote_roles"] = [bg_role] + dict_copy["remote_user_mapping"] = [bg_remote_user_map] return User(**dict_copy) diff --git a/test/models_test.py b/test/models_test.py index 64c22cb3..6b136600 100644 --- a/test/models_test.py +++ b/test/models_test.py @@ -535,7 +535,7 @@ def user(self): return User( username="admin", roles=["bg-admin"], - assigned_roles=[Role(name="foo", permission="ADMIN")], + remote_roles=[Role(name="foo", permission="ADMIN")], ) def test_str(self, user): @@ -556,8 +556,8 @@ def test_str(self, role): def test_repr(self, role): assert repr(role) == ( "" + "scope_garden=[], scope_namespaces=[], scope_systems=[], " + "scope_instances=[], scope_versions=[], scope_commands=[]>" ) diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index aea91843..ab9dab8d 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -23,6 +23,7 @@ assert_patch_equal, assert_user_equal, assert_queue_equal, + assert_remote_user_map_equal, assert_request_equal, assert_request_file_equal, assert_resolvable_equal, @@ -126,6 +127,12 @@ def test_no_modify(self, system_dict): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.RemoteUserMap, + lazy_fixture("remote_user_map_dict"), + assert_remote_user_map_equal, + lazy_fixture("bg_remote_user_map"), + ), ( brewtils.models.Role, lazy_fixture("role_dict"), @@ -254,6 +261,12 @@ def test_single_from_string(self): assert_user_equal, lazy_fixture("bg_user"), ), + ( + "parse_remote_user_map", + lazy_fixture("remote_user_map_dict"), + assert_remote_user_map_equal, + lazy_fixture("bg_remote_user_map"), + ), ( "parse_role", lazy_fixture("role_dict"), @@ -387,6 +400,12 @@ def test_single_specific_from_string(self): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.RemoteUserMap, + lazy_fixture("remote_user_map_dict"), + assert_remote_user_map_equal, + lazy_fixture("bg_remote_user_map"), + ), ( brewtils.models.Role, lazy_fixture("role_dict"), @@ -513,6 +532,12 @@ def test_many(self, model, data, assertion, expected): assert_user_equal, lazy_fixture("bg_user"), ), + ( + "parse_remote_user_map", + lazy_fixture("remote_user_map_dict"), + assert_remote_user_map_equal, + lazy_fixture("bg_remote_user_map"), + ), ( "parse_role", lazy_fixture("role_dict"), @@ -606,6 +631,7 @@ class TestSerialize(object): (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), @@ -669,6 +695,11 @@ def test_single(self, model, expected): lazy_fixture("bg_user"), lazy_fixture("user_dict"), ), + ( + "serialize_remote_user_map", + lazy_fixture("bg_remote_user_map"), + lazy_fixture("remote_user_map_dict"), + ), ( "serialize_role", lazy_fixture("bg_role"), @@ -735,6 +766,7 @@ def test_single_specific(self, method, data, expected): (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), @@ -815,6 +847,11 @@ class TestRoundTrip(object): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.RemoteUserMap, + assert_remote_user_map_equal, + lazy_fixture("bg_remote_user_map"), + ), (brewtils.models.Role, assert_role_equal, lazy_fixture("bg_role")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_cron_job")), From 13114cc8609bff62be0d1ea566fa0c3a505c98f5 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:29:26 +0000 Subject: [PATCH 04/53] Replace Refresh with User Token --- brewtils/models.py | 8 ++++---- brewtils/schema_parser.py | 20 ++++++++++---------- brewtils/schemas.py | 10 +++++----- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 628ce829..60e6f2f3 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -21,7 +21,7 @@ "Event", "Events", "Queue", - "RefreshToken", + "UserToken", "Job", "RequestFile", "File", @@ -1103,8 +1103,8 @@ def __repr__(self): return "" % (self.name, self.size) -class RefreshToken(BaseModel): - schema = "RefreshTokenSchema" +class UserToken(BaseModel): + schema = "UserTokenSchema" def __init__( self, @@ -1122,7 +1122,7 @@ def __str__(self): return "%s" % self.payload def __repr__(self): - return "" % ( + return "" % ( self.issued, self.expires, self.payload, diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 7462c243..74830a57 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -37,7 +37,7 @@ class SchemaParser(object): "QueueSchema": brewtils.models.Queue, "ParameterSchema": brewtils.models.Parameter, "PatchSchema": brewtils.models.PatchOperation, - "RefreshTokenSchema": brewtils.models.RefreshToken, + "UserTokenSchema": brewtils.models.UserToken, "RequestSchema": brewtils.models.Request, "RequestFileSchema": brewtils.models.RequestFile, "FileSchema": brewtils.models.File, @@ -301,20 +301,20 @@ def parse_remote_user_map(cls, remote_user_map, from_string=False, **kwargs): ) @classmethod - def parse_refresh_token(cls, refresh_token, from_string=False, **kwargs): - """Convert raw JSON string or dictionary to a refresh token object + def parse_user_token(cls, user_token, from_string=False, **kwargs): + """Convert raw JSON string or dictionary to a user token object Args: - refresh_token: The raw input + user_token: The raw input from_string: True if input is a JSON string, False if a dictionary **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) Returns: - A RefreshToken object + A UserToken object """ return cls.parse( refresh_token, - brewtils.models.RefreshToken, + brewtils.models.UserToken, from_string=from_string, **kwargs ) @@ -744,11 +744,11 @@ def serialize_remote_user_map(cls, remote_user_map, to_string=True, **kwargs): ) @classmethod - def serialize_refresh_token(cls, refresh_token, to_string=True, **kwargs): + def serialize_user_token(cls, user_token, to_string=True, **kwargs): """Convert a role model into serialized form Args: - refresh_token: The token object(s) to be serialized + user_token: The token object(s) to be serialized to_string: True to generate a JSON-formatted string, False to generate a dictionary **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) @@ -757,9 +757,9 @@ def serialize_refresh_token(cls, refresh_token, to_string=True, **kwargs): Serialized representation """ return cls.serialize( - refresh_token, + user_token, to_string=to_string, - schema_name=brewtils.models.RefreshToken.schema, + schema_name=brewtils.models.UserToken.schema, **kwargs ) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 9ea8ca42..0657eb87 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -24,7 +24,7 @@ "LoggingConfigSchema", "EventSchema", "QueueSchema", - "RefreshTokenSchema", + "UserTokenSchema", "JobSchema", "JobExportSchema", "JobExportInputSchema", @@ -398,11 +398,11 @@ class QueueSchema(BaseSchema): size = fields.Integer(allow_none=True) -class RefreshTokenSchema(BaseSchema): - id = fields.Str(allow_none=True) +class UserTokenSchema(BaseSchema): + uuid = fields.Str(allow_none=True) issued = DateTime(allow_none=True, format="epoch", example="1500065932000") expires = DateTime(allow_none=True, format="epoch", example="1500065932000") - payload = fields.Dict(allow_none=True) + user = fields.Nested("UserSchema") class DateTriggerSchema(BaseSchema): @@ -602,7 +602,7 @@ class UserSchema(BaseSchema): "Queue": QueueSchema, "Parameter": ParameterSchema, "PatchOperation": PatchSchema, - "RefreshToken": RefreshTokenSchema, + "UserToken": UserTokenSchema, "Request": RequestSchema, "RequestFile": RequestFileSchema, "File": FileSchema, From c3942df74b1d1789a991acd8a5784cafef34fd8b Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:04:42 +0000 Subject: [PATCH 05/53] fixed typo --- brewtils/models.py | 6 +++--- brewtils/schemas.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 60e6f2f3..9d73fecf 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1649,7 +1649,7 @@ def __init__( scope_namespaces=None, scope_systems=None, scope_instances=None, - scope_verisons=None, + scope_versions=None, scope_commands=None, ): self.permission = permission or "READ_ONLY" @@ -1660,7 +1660,7 @@ def __init__( self.scope_namespaces = scope_namespaces or [] self.scope_systems = scope_systems or [] self.scope_instances = scope_instances or [] - self.scope_verisons = scope_verisons or [] + self.scope_versions = scope_versions or [] self.scope_commands = scope_commands or [] def __str__(self): @@ -1679,7 +1679,7 @@ def __repr__(self): self.scope_namespaces, self.scope_systems, self.scope_instances, - self.scope_verisons, + self.scope_versions, self.scope_commands, ) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 0657eb87..84c54e40 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -564,7 +564,7 @@ class RoleSchema(BaseSchema): scope_namespaces = fields.List(fields.Str(), allow_none=True) scope_systems = fields.List(fields.Str(), allow_none=True) scope_instances = fields.List(fields.Str(), allow_none=True) - scope_verisons = fields.List(fields.Str(), allow_none=True) + scope_versions = fields.List(fields.Str(), allow_none=True) scope_commands = fields.List(fields.Str(), allow_none=True) From bb6e025d7c152123ef425a934f7fabbe84fa192d Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 28 Feb 2024 19:06:31 +0000 Subject: [PATCH 06/53] model updates --- brewtils/models.py | 5 +++++ brewtils/schemas.py | 2 ++ brewtils/test/fixtures.py | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9d73fecf..032b924d 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1412,6 +1412,8 @@ def __init__( parent=None, children=None, metadata=None, + default_user=None, + shared_users=None ): self.id = id self.name = name @@ -1429,6 +1431,9 @@ def __init__( self.children = children self.metadata = metadata or {} + self.default_user = default_user + self.shared_users = shared_users + def __str__(self): return "%s" % self.name diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 84c54e40..8b45a24f 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -472,6 +472,8 @@ class GardenSchema(BaseSchema): "self", exclude=("parent"), many=True, default=None, allow_none=True ) metadata = fields.Dict(allow_none=True) + default_user = fields.Bool(allow_none=True) + shared_users = fields.Bool(allow_none=True) class JobSchema(BaseSchema): diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 5fe6c2c4..09b1beb3 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -552,7 +552,7 @@ def role_dict(): "scope_namespaces": [], "scope_systems": [], "scope_instances": [], - "scope_verisons": [], + "scope_versions": [], "scope_commands": [], } @@ -837,6 +837,8 @@ def garden_dict(ts_epoch, system_dict, connection_dict, connection_publishing_di "has_parent": False, "children": [], "metadata": {}, + "default_user": None, + "shared_users":True, } From c660498e35df6084569800a17595f91235118dbc Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:18:42 +0000 Subject: [PATCH 07/53] Add Local Roles to users --- brewtils/models.py | 2 ++ brewtils/schemas.py | 1 + brewtils/test/fixtures.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 032b924d..1ab0944a 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1612,6 +1612,7 @@ def __init__( username, password=None, roles=None, + local_roles=None, remote_roles=None, is_remote=False, remote_user_mapping=None, @@ -1620,6 +1621,7 @@ def __init__( self.username = username self.password = password self.roles = roles or [] + self.local_roles = local_roles or [] self.remote_roles = remote_roles or [] self.is_remote = is_remote self.remote_user_mapping = remote_user_mapping or [] diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 8b45a24f..6d282e73 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -580,6 +580,7 @@ class UserSchema(BaseSchema): username = fields.Str() password = fields.Str() roles = fields.List(fields.Str(), allow_none=True) + local_roles = fields.List(fields.Nested(RoleSchema())) remote_roles = fields.List(fields.Nested(RoleSchema())) remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 09b1beb3..8be66441 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -568,6 +568,7 @@ def user_dict(role_dict, remote_user_map_dict): "username": "USERNAME", "password": "HASH", "roles": ["ADMIN_ROLE"], + "local_roles": [role_dict], "remote_roles": [role_dict], "remote_user_mapping": [remote_user_map_dict], "is_remote": False, @@ -579,6 +580,7 @@ def user_dict(role_dict, remote_user_map_dict): def bg_user(user_dict, bg_role, bg_remote_user_map): dict_copy = copy.deepcopy(user_dict) dict_copy["remote_roles"] = [bg_role] + dict_copy["local_roles"] = [bg_role] dict_copy["remote_user_mapping"] = [bg_remote_user_map] return User(**dict_copy) From eb5ddc1b356e4e3034c4c9f6220fd573d58d8c9f Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:43:58 +0000 Subject: [PATCH 08/53] Cleaning up models --- brewtils/models.py | 2 -- brewtils/schemas.py | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 1ab0944a..648433a2 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1413,7 +1413,6 @@ def __init__( children=None, metadata=None, default_user=None, - shared_users=None ): self.id = id self.name = name @@ -1432,7 +1431,6 @@ def __init__( self.metadata = metadata or {} self.default_user = default_user - self.shared_users = shared_users def __str__(self): return "%s" % self.name diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 6d282e73..b062851b 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -472,8 +472,7 @@ class GardenSchema(BaseSchema): "self", exclude=("parent"), many=True, default=None, allow_none=True ) metadata = fields.Dict(allow_none=True) - default_user = fields.Bool(allow_none=True) - shared_users = fields.Bool(allow_none=True) + default_user = fields.Str(allow_none=True) class JobSchema(BaseSchema): From fbbedb62a95c08b6ce3bf879470199779ea4f0d1 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 8 Mar 2024 10:58:09 -0500 Subject: [PATCH 09/53] Update fixtures.py --- brewtils/test/fixtures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 8be66441..22c60089 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -840,7 +840,6 @@ def garden_dict(ts_epoch, system_dict, connection_dict, connection_publishing_di "children": [], "metadata": {}, "default_user": None, - "shared_users":True, } From 9aeb929368c77260b57010e031b8918a58e16cbb Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:29:30 -0500 Subject: [PATCH 10/53] added back shared users --- brewtils/models.py | 2 ++ brewtils/test/fixtures.py | 1 + 2 files changed, 3 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 648433a2..71b19d6c 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1413,6 +1413,7 @@ def __init__( children=None, metadata=None, default_user=None, + shared_users=None, ): self.id = id self.name = name @@ -1431,6 +1432,7 @@ def __init__( self.metadata = metadata or {} self.default_user = default_user + self.shared_users = shared_users def __str__(self): return "%s" % self.name diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 22c60089..38908834 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -840,6 +840,7 @@ def garden_dict(ts_epoch, system_dict, connection_dict, connection_publishing_di "children": [], "metadata": {}, "default_user": None, + "shared_users": True, } From ddd06fdb49a9b9fc03f617f3b7b3366769858440 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:31:57 -0500 Subject: [PATCH 11/53] updated schema --- brewtils/schemas.py | 1 + 1 file changed, 1 insertion(+) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index b062851b..b43a1e2a 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -473,6 +473,7 @@ class GardenSchema(BaseSchema): ) metadata = fields.Dict(allow_none=True) default_user = fields.Str(allow_none=True) + shared_users = fields.Bool(allow_none=True) class JobSchema(BaseSchema): From 69c6eeabf0c5414ad833159e2a5358b4977dd07f Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:39:46 -0400 Subject: [PATCH 12/53] Updating Admin roles --- brewtils/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 71b19d6c..8e85d440 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1641,7 +1641,8 @@ class Role(BaseModel): schema = "RoleSchema" PERMISSION_TYPES = { - "ADMIN", + "GARDEN_ADMIN", + "PLUGIN_ADMIN", "OPERATOR", "READ_ONLY", # Default value if not role is provided } From f7bd06fd3fdb1105b9ae99acf6e5140b92cd92a2 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:40:45 -0400 Subject: [PATCH 13/53] updating fixtures --- brewtils/test/fixtures.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 38908834..8ce5a37e 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -544,10 +544,10 @@ def bg_remote_user_map(remote_user_map_dict): @pytest.fixture def role_dict(): return { - "permission": "ADMIN", - "description": "ADMIN ROLE", + "permission": "PLUGIN_ADMIN", + "description": "PLUGIN ADMIN ROLE", "id": "1", - "name": "ADMIN_ROLE", + "name": "PLUGIN_ADMIN_ROLE", "scope_gardens": ["FOO"], "scope_namespaces": [], "scope_systems": [], From af9e8a673e4875bbe94535725e76c4c98dc097a8 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:43:28 -0400 Subject: [PATCH 14/53] updating fixtures --- brewtils/test/fixtures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 8ce5a37e..8083adfb 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -567,7 +567,7 @@ def user_dict(role_dict, remote_user_map_dict): return { "username": "USERNAME", "password": "HASH", - "roles": ["ADMIN_ROLE"], + "roles": ["PLUGIN_ADMIN_ROLE"], "local_roles": [role_dict], "remote_roles": [role_dict], "remote_user_mapping": [remote_user_map_dict], From da29301f6b8d90fda8327ba31e7ec5d405a80196 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 12 Mar 2024 06:35:34 -0400 Subject: [PATCH 15/53] fixed testing --- brewtils/models.py | 3 ++- brewtils/schemas.py | 4 ++-- brewtils/test/comparable.py | 1 + test/models_test.py | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 8e85d440..3bf80e9c 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1676,12 +1676,13 @@ def __str__(self): def __repr__(self): return ( - "" ) % ( self.id, self.name, + self.description, self.permission, self.scope_gardens, self.scope_namespaces, diff --git a/brewtils/schemas.py b/brewtils/schemas.py index b43a1e2a..991f7391 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -558,10 +558,10 @@ class ResolvableSchema(BaseSchema): class RoleSchema(BaseSchema): + permission = fields.Str() + description = fields.Str(allow_none=True) id = fields.Str(allow_none=True) name = fields.Str() - description = fields.Str(allow_none=True) - permission = fields.Str() scope_gardens = fields.List(fields.Str(), allow_none=True) scope_namespaces = fields.List(fields.Str(), allow_none=True) scope_systems = fields.List(fields.Str(), allow_none=True) diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index f1197ed6..377720ec 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -245,6 +245,7 @@ def assert_user_equal(obj1, obj2, do_raise=False): obj2, expected_type=User, deep_fields={ + "local_roles": partial(assert_role_equal, do_raise=True), "remote_roles": partial(assert_role_equal, do_raise=True), "remote_user_mapping": partial(assert_remote_user_map_equal, do_raise=True), }, diff --git a/test/models_test.py b/test/models_test.py index 6b136600..76744edf 100644 --- a/test/models_test.py +++ b/test/models_test.py @@ -548,14 +548,14 @@ def test_repr(self, user): class TestRole(object): @pytest.fixture def role(self): - return Role(name="bg-admin", permission="ADMIN") + return Role(name="bg-admin", permission="PLUGIN_ADMIN") def test_str(self, role): assert str(role) == "bg-admin" def test_repr(self, role): assert repr(role) == ( - "" ) From 6296b726b73480c34f17cec376b8fa7f391905c7 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:50:10 +0000 Subject: [PATCH 16/53] UserToken update --- brewtils/models.py | 19 +++++++++++-------- brewtils/schema_parser.py | 2 +- brewtils/schemas.py | 3 ++- brewtils/test/comparable.py | 14 +++++++++++++- brewtils/test/fixtures.py | 20 +++++++++++++++++++ test/schema_parser_test.py | 38 +++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 11 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 3bf80e9c..096db57a 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1109,23 +1109,26 @@ class UserToken(BaseModel): def __init__( self, id=None, # noqa # shadows built-in + uuid=None, issued=None, - expires=None, - payload=None, + expires_at=None, + user=None, ): self.id = id + self.uuid = uuid self.issued = issued - self.expires = expires - self.payload = payload or {} + self.expires_at = expires_at + self.user = user or {} def __str__(self): - return "%s" % self.payload + return "%s" % self.user def __repr__(self): - return "" % ( + return "" % ( + self.uuid, self.issued, - self.expires, - self.payload, + self.expires_at, + self.user, ) diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 74830a57..03268295 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -313,7 +313,7 @@ def parse_user_token(cls, user_token, from_string=False, **kwargs): A UserToken object """ return cls.parse( - refresh_token, + user_token, brewtils.models.UserToken, from_string=from_string, **kwargs diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 991f7391..2f1739da 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -399,9 +399,10 @@ class QueueSchema(BaseSchema): class UserTokenSchema(BaseSchema): + id = fields.Str(allow_none=True) uuid = fields.Str(allow_none=True) issued = DateTime(allow_none=True, format="epoch", example="1500065932000") - expires = DateTime(allow_none=True, format="epoch", example="1500065932000") + expires_at = DateTime(allow_none=True, format="epoch", example="1500065932000") user = fields.Nested("UserSchema") diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 377720ec..911622fc 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -30,6 +30,7 @@ Parameter, PatchOperation, User, + UserToken, Queue, RemoteUserMap, Request, @@ -51,6 +52,7 @@ "assert_trigger_equal", "assert_command_equal", "assert_parameter_equal", + "assert_user_token_equal", "assert_user_equal", "assert_remote_user_map_equal", "assert_request_equal", @@ -238,7 +240,6 @@ def assert_event_equal(obj1, obj2, do_raise=False): do_raise=do_raise, ) - def assert_user_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, @@ -252,6 +253,17 @@ def assert_user_equal(obj1, obj2, do_raise=False): do_raise=do_raise, ) +def assert_user_token_equal(obj1, obj2, do_raise=False): + return _assert_wrapper( + obj1, + obj2, + expected_type=UserToken, + deep_fields={ + "user": partial(assert_user_equal, do_raise=True), + }, + do_raise=do_raise, + ) + def assert_request_equal(obj1, obj2, do_raise=False): """Assert that two requests are 'equal'. diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 8083adfb..359db929 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -30,6 +30,7 @@ Runner, System, User, + UserToken, Role, ) @@ -540,6 +541,25 @@ def remote_user_map_dict(): def bg_remote_user_map(remote_user_map_dict): return RemoteUserMap(**remote_user_map_dict) +@pytest.fixture +def user_token_dict(user_dict, ts_epoch): + return { + "id": "1", + "uuid": "11111111-2222-4444-5555-66666666666", + "issued": ts_epoch, + "expires_at": ts_epoch, + "user": user_dict, + } + + +@pytest.fixture +def bg_user_token(user_token_dict, bg_user, ts_dt): + dict_copy = copy.deepcopy(user_token_dict) + dict_copy["user"] = bg_user + dict_copy["issued"] = ts_dt + dict_copy["expires_at"] = ts_dt + return UserToken(**dict_copy) + @pytest.fixture def role_dict(): diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index ab9dab8d..2552b814 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -22,6 +22,7 @@ assert_parameter_equal, assert_patch_equal, assert_user_equal, + assert_user_token_equal, assert_queue_equal, assert_remote_user_map_equal, assert_request_equal, @@ -127,6 +128,12 @@ def test_no_modify(self, system_dict): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.UserToken, + lazy_fixture("user_token_dict"), + assert_user_token_equal, + lazy_fixture("bg_user_token"), + ), ( brewtils.models.RemoteUserMap, lazy_fixture("remote_user_map_dict"), @@ -261,6 +268,12 @@ def test_single_from_string(self): assert_user_equal, lazy_fixture("bg_user"), ), + ( + "parse_user_token", + lazy_fixture("user_token_dict"), + assert_user_token_equal, + lazy_fixture("bg_user_token"), + ), ( "parse_remote_user_map", lazy_fixture("remote_user_map_dict"), @@ -400,6 +413,12 @@ def test_single_specific_from_string(self): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.UserToken, + lazy_fixture("user_token_dict"), + assert_user_token_equal, + lazy_fixture("bg_user_token"), + ), ( brewtils.models.RemoteUserMap, lazy_fixture("remote_user_map_dict"), @@ -532,6 +551,12 @@ def test_many(self, model, data, assertion, expected): assert_user_equal, lazy_fixture("bg_user"), ), + ( + "parse_user_token", + lazy_fixture("user_token_dict"), + assert_user_token_equal, + lazy_fixture("bg_user_token"), + ), ( "parse_remote_user_map", lazy_fixture("remote_user_map_dict"), @@ -631,6 +656,7 @@ class TestSerialize(object): (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), @@ -695,6 +721,11 @@ def test_single(self, model, expected): lazy_fixture("bg_user"), lazy_fixture("user_dict"), ), + ( + "serialize_user_token", + lazy_fixture("bg_user_token"), + lazy_fixture("user_token_dict"), + ), ( "serialize_remote_user_map", lazy_fixture("bg_remote_user_map"), @@ -766,6 +797,7 @@ def test_single_specific(self, method, data, expected): (lazy_fixture("bg_event"), lazy_fixture("event_dict")), (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), + (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), @@ -847,6 +879,11 @@ class TestRoundTrip(object): assert_user_equal, lazy_fixture("bg_user"), ), + ( + brewtils.models.UserToken, + assert_user_token_equal, + lazy_fixture("bg_user_token"), + ), ( brewtils.models.RemoteUserMap, assert_remote_user_map_equal, @@ -891,6 +928,7 @@ def test_parsed_start(self, model, assertion, data): (brewtils.models.Event, lazy_fixture("event_dict")), (brewtils.models.Queue, lazy_fixture("queue_dict")), (brewtils.models.User, lazy_fixture("user_dict")), + (brewtils.models.UserToken, lazy_fixture("user_token_dict")), (brewtils.models.Role, lazy_fixture("role_dict")), (brewtils.models.Job, lazy_fixture("job_dict")), (brewtils.models.Job, lazy_fixture("cron_job_dict")), From 7c49af0b74306d1f89f43f1bbd085ed7a1d64a68 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:51:59 -0400 Subject: [PATCH 17/53] Updated UserToken --- brewtils/models.py | 2 +- brewtils/schemas.py | 2 +- brewtils/test/fixtures.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 096db57a..e9ea318b 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1116,7 +1116,7 @@ def __init__( ): self.id = id self.uuid = uuid - self.issued = issued + self.issued_at = issued self.expires_at = expires_at self.user = user or {} diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 2f1739da..009955b9 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -401,7 +401,7 @@ class QueueSchema(BaseSchema): class UserTokenSchema(BaseSchema): id = fields.Str(allow_none=True) uuid = fields.Str(allow_none=True) - issued = DateTime(allow_none=True, format="epoch", example="1500065932000") + issued_at = DateTime(allow_none=True, format="epoch", example="1500065932000") expires_at = DateTime(allow_none=True, format="epoch", example="1500065932000") user = fields.Nested("UserSchema") diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 359db929..8a0c4e68 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -546,7 +546,7 @@ def user_token_dict(user_dict, ts_epoch): return { "id": "1", "uuid": "11111111-2222-4444-5555-66666666666", - "issued": ts_epoch, + "issued_at": ts_epoch, "expires_at": ts_epoch, "user": user_dict, } @@ -556,7 +556,7 @@ def user_token_dict(user_dict, ts_epoch): def bg_user_token(user_token_dict, bg_user, ts_dt): dict_copy = copy.deepcopy(user_token_dict) dict_copy["user"] = bg_user - dict_copy["issued"] = ts_dt + dict_copy["issued_at"] = ts_dt dict_copy["expires_at"] = ts_dt return UserToken(**dict_copy) From f84eead0ef6b7ad83799cc00c88ab428ab805aed Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:53:37 -0400 Subject: [PATCH 18/53] Fixed model --- brewtils/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index e9ea318b..9d999d19 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1110,7 +1110,7 @@ def __init__( self, id=None, # noqa # shadows built-in uuid=None, - issued=None, + issued_at=None, expires_at=None, user=None, ): From 6f0cbeed3b345be129713aaa1f54c8e194d93411 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:55:02 -0400 Subject: [PATCH 19/53] Fixed Models --- brewtils/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9d999d19..3f23e81f 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1124,9 +1124,9 @@ def __str__(self): return "%s" % self.user def __repr__(self): - return "" % ( + return "" % ( self.uuid, - self.issued, + self.issued_at, self.expires_at, self.user, ) From 14d02765782c42dce10c55ddfd22d02efe348a21 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:58:39 +0000 Subject: [PATCH 20/53] Fixed model --- brewtils/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 3f23e81f..0968adba 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1116,7 +1116,7 @@ def __init__( ): self.id = id self.uuid = uuid - self.issued_at = issued + self.issued_at = issued_at self.expires_at = expires_at self.user = user or {} From 11a4772de2484bbcab122d3a9573e995226b8747 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:28:14 -0400 Subject: [PATCH 21/53] User ID field --- brewtils/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 0968adba..194453b0 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1612,6 +1612,7 @@ class User(BaseModel): def __init__( self, + id, username, password=None, roles=None, @@ -1621,6 +1622,7 @@ def __init__( remote_user_mapping=None, metadata=None, ): + self.id = id self.username = username self.password = password self.roles = roles or [] From 562f8b7e75f6aca47bc24dde37d12a3da3f6e463 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:32:31 -0400 Subject: [PATCH 22/53] fixed user id --- brewtils/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 194453b0..9cc1f6aa 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1612,8 +1612,8 @@ class User(BaseModel): def __init__( self, - id, username, + id = None, password=None, roles=None, local_roles=None, From d26a394876225ee892c38a928c275e1281ec6d31 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 20 Mar 2024 12:41:53 -0400 Subject: [PATCH 23/53] All none on Users --- brewtils/models.py | 2 +- brewtils/schemas.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9cc1f6aa..9f9f0417 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1612,7 +1612,7 @@ class User(BaseModel): def __init__( self, - username, + username = None, id = None, password=None, roles=None, diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 009955b9..3f8cfe05 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -578,8 +578,8 @@ class RemoteUserMapSchema(BaseSchema): class UserSchema(BaseSchema): id = fields.Str(allow_none=True) - username = fields.Str() - password = fields.Str() + username = fields.Str(allow_none=True) + password = fields.Str(allow_none=True) roles = fields.List(fields.Str(), allow_none=True) local_roles = fields.List(fields.Nested(RoleSchema())) remote_roles = fields.List(fields.Nested(RoleSchema())) From 9e7be7006db01c08ea647a6b2ba32456ce48ffc9 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:31:36 -0400 Subject: [PATCH 24/53] Usertoken stores username --- brewtils/models.py | 10 +++++----- brewtils/schemas.py | 2 +- brewtils/test/fixtures.py | 5 ++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9f9f0417..88bf76d1 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1112,23 +1112,23 @@ def __init__( uuid=None, issued_at=None, expires_at=None, - user=None, + username=None, ): self.id = id self.uuid = uuid self.issued_at = issued_at self.expires_at = expires_at - self.user = user or {} + self.username = username def __str__(self): - return "%s" % self.user + return "%s" % self.username def __repr__(self): - return "" % ( + return "" % ( self.uuid, self.issued_at, self.expires_at, - self.user, + self.username, ) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 3f8cfe05..351d2bdb 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -403,7 +403,7 @@ class UserTokenSchema(BaseSchema): uuid = fields.Str(allow_none=True) issued_at = DateTime(allow_none=True, format="epoch", example="1500065932000") expires_at = DateTime(allow_none=True, format="epoch", example="1500065932000") - user = fields.Nested("UserSchema") + username = fields.Str(allow_none=True) class DateTriggerSchema(BaseSchema): diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 8a0c4e68..79c7a047 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -548,14 +548,13 @@ def user_token_dict(user_dict, ts_epoch): "uuid": "11111111-2222-4444-5555-66666666666", "issued_at": ts_epoch, "expires_at": ts_epoch, - "user": user_dict, + "username": "USERNAME", } @pytest.fixture -def bg_user_token(user_token_dict, bg_user, ts_dt): +def bg_user_token(user_token_dict, ts_dt): dict_copy = copy.deepcopy(user_token_dict) - dict_copy["user"] = bg_user dict_copy["issued_at"] = ts_dt dict_copy["expires_at"] = ts_dt return UserToken(**dict_copy) From 02d0d128d35f23ab340ce68fb48e1a02204d3a1b Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:25:42 -0400 Subject: [PATCH 25/53] Allow none on roles --- brewtils/schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 351d2bdb..015e9d0e 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -581,8 +581,8 @@ class UserSchema(BaseSchema): username = fields.Str(allow_none=True) password = fields.Str(allow_none=True) roles = fields.List(fields.Str(), allow_none=True) - local_roles = fields.List(fields.Nested(RoleSchema())) - remote_roles = fields.List(fields.Nested(RoleSchema())) + local_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) + remote_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) From e1f44d774561ff7366734b0114a861dbf0294e86 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:46:47 -0400 Subject: [PATCH 26/53] Adding Remote Roles --- brewtils/models.py | 2 ++ brewtils/schemas.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 88bf76d1..ba2bcf10 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1697,6 +1697,8 @@ def __repr__(self): self.scope_commands, ) +class RemoteRole(Role): + pass class RemoteUserMap(BaseModel): schema = "RemoteUserMapSchema" diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 015e9d0e..8736a20a 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -587,6 +587,9 @@ class UserSchema(BaseSchema): is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) +class RemoteUserSchema(UserSchema): + pass + model_schema_map.update( { @@ -618,6 +621,7 @@ class UserSchema(BaseSchema): "Runner": RunnerSchema, "Resolvable": ResolvableSchema, "Role": RoleSchema, + "RemoteRole": RemoteRoleSchema, "User": UserSchema, "RemoteUserMap": RemoteUserMapSchema, # Compatibility for the Job trigger types From 282669751a60855c0d07c09158fb3f461dcd2527 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Thu, 21 Mar 2024 09:58:39 -0400 Subject: [PATCH 27/53] Fixed schemas --- brewtils/schemas.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 8736a20a..530343a4 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -570,6 +570,8 @@ class RoleSchema(BaseSchema): scope_versions = fields.List(fields.Str(), allow_none=True) scope_commands = fields.List(fields.Str(), allow_none=True) +class RemoteRoleSchema(RoleSchema): + pass class RemoteUserMapSchema(BaseSchema): target_garden = fields.Str() @@ -582,13 +584,12 @@ class UserSchema(BaseSchema): password = fields.Str(allow_none=True) roles = fields.List(fields.Str(), allow_none=True) local_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) - remote_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) + remote_roles = fields.List(fields.Nested(RemoteRoleSchema()), allow_none=True) remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) -class RemoteUserSchema(UserSchema): - pass + model_schema_map.update( From 181557bb63ddcdf0236309d73221838a5ed3e87f Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:49:13 -0400 Subject: [PATCH 28/53] Add Remote Role Schema parsing --- brewtils/schema_parser.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 03268295..3de95c74 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -49,6 +49,7 @@ class SchemaParser(object): "RunnerSchema": brewtils.models.Runner, "ResolvableSchema": brewtils.models.Resolvable, "RoleSchema": brewtils.models.Role, + "RemoteRoleSchema": brewtils.models.RemoteRole, "UserSchema": brewtils.models.User, "RemoteUserMapSchema": brewtils.models.RemoteUserMap, } @@ -280,6 +281,20 @@ def parse_role(cls, role, from_string=False, **kwargs): A Role object """ return cls.parse(role, brewtils.models.Role, from_string=from_string, **kwargs) + + @classmethod + def parse_remote_role(cls, role, from_string=False, **kwargs): + """Convert raw JSON string or dictionary to a role model object + + Args: + role: The raw input + from_string: True if input is a JSON string, False if a dictionary + **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) + + Returns: + A Role object + """ + return cls.parse(role, brewtils.models.RemoteRole, from_string=from_string, **kwargs) @classmethod def parse_remote_user_map(cls, remote_user_map, from_string=False, **kwargs): @@ -722,6 +737,23 @@ def serialize_role(cls, role, to_string=True, **kwargs): return cls.serialize( role, to_string=to_string, schema_name=brewtils.models.Role.schema, **kwargs ) + + @classmethod + def serialize_remote_role(cls, role, to_string=True, **kwargs): + """Convert a role model into serialized form + + Args: + role: The role object(s) to be serialized + to_string: True to generate a JSON-formatted string, False to generate a + dictionary + **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) + + Returns: + Serialized representation + """ + return cls.serialize( + role, to_string=to_string, schema_name=brewtils.models.RemoteRole.schema, **kwargs + ) @classmethod def serialize_remote_user_map(cls, remote_user_map, to_string=True, **kwargs): From e591cd646ac98e2e3c207a76be15a6187b0ade04 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:00:47 -0400 Subject: [PATCH 29/53] Updating testing --- brewtils/schemas.py | 12 +++++++++++- brewtils/test/comparable.py | 11 ++++++++++- brewtils/test/fixtures.py | 30 ++++++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index e724f959..0c769d01 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -573,7 +573,17 @@ class RoleSchema(BaseSchema): scope_commands = fields.List(fields.Str(), allow_none=True) class RemoteRoleSchema(RoleSchema): - pass + permission = fields.Str() + description = fields.Str(allow_none=True) + id = fields.Str(allow_none=True) + name = fields.Str() + scope_gardens = fields.List(fields.Str(), allow_none=True) + scope_namespaces = fields.List(fields.Str(), allow_none=True) + scope_systems = fields.List(fields.Str(), allow_none=True) + scope_instances = fields.List(fields.Str(), allow_none=True) + scope_versions = fields.List(fields.Str(), allow_none=True) + scope_commands = fields.List(fields.Str(), allow_none=True) + class RemoteUserMapSchema(BaseSchema): target_garden = fields.Str() diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 2123b2f2..43a4add7 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -33,6 +33,7 @@ UserToken, Queue, RemoteUserMap, + RemoteRole, Request, RequestFile, RequestTemplate, @@ -252,7 +253,7 @@ def assert_user_equal(obj1, obj2, do_raise=False): expected_type=User, deep_fields={ "local_roles": partial(assert_role_equal, do_raise=True), - "remote_roles": partial(assert_role_equal, do_raise=True), + "remote_roles": partial(assert_remote_role_equal, do_raise=True), "remote_user_mapping": partial(assert_remote_user_map_equal, do_raise=True), }, do_raise=do_raise, @@ -326,6 +327,14 @@ def assert_role_equal(obj1, obj2, do_raise=False): do_raise=do_raise, ) +def assert_remote_role_equal(obj1, obj2, do_raise=False): + return _assert_wrapper( + obj1, + obj2, + expected_type=RemoteRole, + do_raise=do_raise, + ) + def assert_system_equal(obj1, obj2, do_raise=False): return _assert_wrapper( diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 6b4b2a9a..6eb113b3 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -23,6 +23,7 @@ PatchOperation, Queue, RemoteUserMap, + RemoteRole, Request, RequestFile, RequestTemplate, @@ -578,19 +579,40 @@ def role_dict(): } +@pytest.fixture +def bg_remote_role(role_dict): + return RemoteRole(**role_dict) + +@pytest.fixture +def remote_role_dict(): + return { + "permission": "PLUGIN_ADMIN", + "description": "PLUGIN ADMIN ROLE", + "id": "1", + "name": "PLUGIN_ADMIN_ROLE", + "scope_gardens": ["FOO"], + "scope_namespaces": [], + "scope_systems": [], + "scope_instances": [], + "scope_versions": [], + "scope_commands": [], + } + + @pytest.fixture def bg_role(role_dict): return Role(**role_dict) @pytest.fixture -def user_dict(role_dict, remote_user_map_dict): +def user_dict(role_dict, remote_role_dict, remote_user_map_dict): return { + "id": "1", "username": "USERNAME", "password": "HASH", "roles": ["PLUGIN_ADMIN_ROLE"], "local_roles": [role_dict], - "remote_roles": [role_dict], + "remote_roles": [remote_role_dict], "remote_user_mapping": [remote_user_map_dict], "is_remote": False, "metadata": {}, @@ -598,9 +620,9 @@ def user_dict(role_dict, remote_user_map_dict): @pytest.fixture -def bg_user(user_dict, bg_role, bg_remote_user_map): +def bg_user(user_dict, bg_role, bg_remote_role, bg_remote_user_map): dict_copy = copy.deepcopy(user_dict) - dict_copy["remote_roles"] = [bg_role] + dict_copy["remote_roles"] = [bg_remote_role] dict_copy["local_roles"] = [bg_role] dict_copy["remote_user_mapping"] = [bg_remote_user_map] return User(**dict_copy) From 121d7c487336f5617da83ce576e3fff5db342ce2 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:14:05 -0400 Subject: [PATCH 30/53] Updating more testing --- brewtils/models.py | 2 +- test/schema_parser_test.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index f74ea152..8a5b70d7 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1703,7 +1703,7 @@ def __repr__(self): ) class RemoteRole(Role): - pass + schema = "RemoteRoleSchema" class RemoteUserMap(BaseModel): schema = "RemoteUserMapSchema" diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index 59b899f7..d575980b 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -25,6 +25,7 @@ assert_user_token_equal, assert_queue_equal, assert_remote_user_map_equal, + assert_remote_role_equal, assert_request_equal, assert_request_file_equal, assert_resolvable_equal, @@ -148,6 +149,12 @@ def test_no_modify(self, system_dict): assert_role_equal, lazy_fixture("bg_role"), ), + ( + brewtils.models.RemoteRole, + lazy_fixture("remote_role_dict"), + assert_remote_role_equal, + lazy_fixture("bg_remote_role"), + ), ( brewtils.models.Job, lazy_fixture("job_dict"), @@ -300,6 +307,12 @@ def test_single_from_string(self): assert_role_equal, lazy_fixture("bg_role"), ), + ( + "parse_remote_role", + lazy_fixture("remote_role_dict"), + assert_remote_role_equal, + lazy_fixture("bg_remote_role"), + ), ( "parse_job", lazy_fixture("job_dict"), @@ -457,6 +470,12 @@ def test_single_specific_from_string(self): assert_role_equal, lazy_fixture("bg_role"), ), + ( + brewtils.models.RemoteRole, + lazy_fixture("remote_role_dict"), + assert_remote_role_equal, + lazy_fixture("bg_remote_role"), + ), ( brewtils.models.Job, lazy_fixture("job_dict"), @@ -607,6 +626,12 @@ def test_many(self, model, data, assertion, expected): assert_role_equal, lazy_fixture("bg_role"), ), + ( + "parse_remote_role", + lazy_fixture("remote_role_dict"), + assert_remote_role_equal, + lazy_fixture("bg_remote_role"), + ), ( "parse_job", lazy_fixture("job_dict"), @@ -709,6 +734,7 @@ class TestSerialize(object): (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), + (lazy_fixture("bg_remote_role"), lazy_fixture("remote_role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -788,6 +814,11 @@ def test_single(self, model, expected): lazy_fixture("bg_role"), lazy_fixture("role_dict"), ), + ( + "serialize_remote_role", + lazy_fixture("bg_remote_role"), + lazy_fixture("remote_role_dict"), + ), ("serialize_job", lazy_fixture("bg_job"), lazy_fixture("job_dict")), ( "serialize_job", @@ -862,6 +893,7 @@ def test_single_specific(self, method, data, expected): (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), + (lazy_fixture("bg_remote_role"), lazy_fixture("remote_role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -954,6 +986,7 @@ class TestRoundTrip(object): lazy_fixture("bg_remote_user_map"), ), (brewtils.models.Role, assert_role_equal, lazy_fixture("bg_role")), + (brewtils.models.RemoteRole, assert_remote_role_equal, lazy_fixture("bg_remote_role")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_cron_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_interval_job")), @@ -1000,6 +1033,7 @@ def test_parsed_start(self, model, assertion, data): (brewtils.models.User, lazy_fixture("user_dict")), (brewtils.models.UserToken, lazy_fixture("user_token_dict")), (brewtils.models.Role, lazy_fixture("role_dict")), + (brewtils.models.RemoteRole, lazy_fixture("remote_role_dict")), (brewtils.models.Job, lazy_fixture("job_dict")), (brewtils.models.Job, lazy_fixture("cron_job_dict")), (brewtils.models.Job, lazy_fixture("interval_job_dict")), From 3503afdedd1f4fbdb42399e9b2a54d639a45339d Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:51:41 -0400 Subject: [PATCH 31/53] combining roles schemas --- brewtils/schemas.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 0c769d01..b2262559 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -573,16 +573,7 @@ class RoleSchema(BaseSchema): scope_commands = fields.List(fields.Str(), allow_none=True) class RemoteRoleSchema(RoleSchema): - permission = fields.Str() - description = fields.Str(allow_none=True) - id = fields.Str(allow_none=True) - name = fields.Str() - scope_gardens = fields.List(fields.Str(), allow_none=True) - scope_namespaces = fields.List(fields.Str(), allow_none=True) - scope_systems = fields.List(fields.Str(), allow_none=True) - scope_instances = fields.List(fields.Str(), allow_none=True) - scope_versions = fields.List(fields.Str(), allow_none=True) - scope_commands = fields.List(fields.Str(), allow_none=True) + pass class RemoteUserMapSchema(BaseSchema): From ed9319900731323135afe2fed6744cfa3f63fb14 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Thu, 18 Apr 2024 14:46:03 -0400 Subject: [PATCH 32/53] Add protected to roles --- brewtils/models.py | 2 ++ brewtils/schemas.py | 1 + brewtils/test/fixtures.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 8a5b70d7..2eb861d6 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1669,6 +1669,7 @@ def __init__( scope_instances=None, scope_versions=None, scope_commands=None, + protected=False, ): self.permission = permission or "READ_ONLY" self.description = description @@ -1680,6 +1681,7 @@ def __init__( self.scope_instances = scope_instances or [] self.scope_versions = scope_versions or [] self.scope_commands = scope_commands or [] + self.protected = protected def __str__(self): return "%s" % (self.name) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index b2262559..0aaafedc 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -571,6 +571,7 @@ class RoleSchema(BaseSchema): scope_instances = fields.List(fields.Str(), allow_none=True) scope_versions = fields.List(fields.Str(), allow_none=True) scope_commands = fields.List(fields.Str(), allow_none=True) + protected = fields.Boolean(allow_none=True) class RemoteRoleSchema(RoleSchema): pass diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 6eb113b3..3cc919d8 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -576,6 +576,7 @@ def role_dict(): "scope_instances": [], "scope_versions": [], "scope_commands": [], + "protected": False, } @@ -596,6 +597,7 @@ def remote_role_dict(): "scope_instances": [], "scope_versions": [], "scope_commands": [], + "protected": False, } From 014cba49de83bec3716cf87d5242063cc7c08bbd Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 3 Jun 2024 08:39:39 -0400 Subject: [PATCH 33/53] Adding is protected to user accounts --- brewtils/models.py | 2 ++ brewtils/schemas.py | 1 + brewtils/test/fixtures.py | 1 + 3 files changed, 4 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 2eb861d6..ebd673c7 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1626,6 +1626,7 @@ def __init__( is_remote=False, remote_user_mapping=None, metadata=None, + is_protected=False, ): self.id = id self.username = username @@ -1636,6 +1637,7 @@ def __init__( self.is_remote = is_remote self.remote_user_mapping = remote_user_mapping or [] self.metadata = metadata + self.is_protected = is_protected def __str__(self): return "%s: %s" % (self.username, self.roles) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 0aaafedc..d93a066e 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -606,6 +606,7 @@ class UserSchema(BaseSchema): remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) + is_protected = fields.Boolean(allow_none=True) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 3cc919d8..afd920f8 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -618,6 +618,7 @@ def user_dict(role_dict, remote_role_dict, remote_user_map_dict): "remote_user_mapping": [remote_user_map_dict], "is_remote": False, "metadata": {}, + "is_protected": False, } From 3865bd7341716aeed21eec0aaea564046daa6bbd Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 3 Jun 2024 08:42:18 -0400 Subject: [PATCH 34/53] Changed is_protected to protected --- brewtils/models.py | 4 ++-- brewtils/schemas.py | 2 +- brewtils/test/fixtures.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index ebd673c7..66c55190 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1626,7 +1626,7 @@ def __init__( is_remote=False, remote_user_mapping=None, metadata=None, - is_protected=False, + protected=False, ): self.id = id self.username = username @@ -1637,7 +1637,7 @@ def __init__( self.is_remote = is_remote self.remote_user_mapping = remote_user_mapping or [] self.metadata = metadata - self.is_protected = is_protected + self.protected = is_protected def __str__(self): return "%s: %s" % (self.username, self.roles) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index d93a066e..f4d3269f 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -606,7 +606,7 @@ class UserSchema(BaseSchema): remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) - is_protected = fields.Boolean(allow_none=True) + protected = fields.Boolean(allow_none=True) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index afd920f8..09a845b1 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -618,7 +618,7 @@ def user_dict(role_dict, remote_role_dict, remote_user_map_dict): "remote_user_mapping": [remote_user_map_dict], "is_remote": False, "metadata": {}, - "is_protected": False, + "protected": False, } From 4aae1dc1e8b8578715334782120c9a8b4cd06ec7 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:03:03 -0400 Subject: [PATCH 35/53] fixed model --- brewtils/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 66c55190..b7ac64fb 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1637,7 +1637,7 @@ def __init__( self.is_remote = is_remote self.remote_user_mapping = remote_user_mapping or [] self.metadata = metadata - self.protected = is_protected + self.protected = protected def __str__(self): return "%s: %s" % (self.username, self.roles) From 198380b83cbfd6c0257dbcb5e465bd5e07db5f5e Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:01:13 -0400 Subject: [PATCH 36/53] Update Requester on child requests --- brewtils/request_handling.py | 1 + brewtils/rest/system_client.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/brewtils/request_handling.py b/brewtils/request_handling.py index 259f2c0b..7ec877d4 100644 --- a/brewtils/request_handling.py +++ b/brewtils/request_handling.py @@ -61,6 +61,7 @@ def process_command(self, request): if parent_request: request.parent = Request(id=str(parent_request.id)) + request.requester = parent_request.requester request.has_parent = True # check for kwargs on the target command diff --git a/brewtils/rest/system_client.py b/brewtils/rest/system_client.py index 7b7a0064..75569a6d 100644 --- a/brewtils/rest/system_client.py +++ b/brewtils/rest/system_client.py @@ -535,6 +535,10 @@ def _wait_for_request(self, request, raise_on_error, timeout): brewtils.plugin.request_context, "current_request", None ) request.has_parent = request.parent is not None + if request.has_parent: + request.requester = getattr( + brewtils.plugin.request_context.current_request, "requester", None + ) ec = EasyClient( bg_host=brewtils.plugin.CONFIG.bg_host, bg_port=brewtils.plugin.CONFIG.bg_port, From f31dc469f0f49acf95bdd0cfc67b8898f37e3751 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:22:01 -0400 Subject: [PATCH 37/53] Set requester from parent --- brewtils/rest/system_client.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/brewtils/rest/system_client.py b/brewtils/rest/system_client.py index 75569a6d..d48b99bb 100644 --- a/brewtils/rest/system_client.py +++ b/brewtils/rest/system_client.py @@ -535,10 +535,7 @@ def _wait_for_request(self, request, raise_on_error, timeout): brewtils.plugin.request_context, "current_request", None ) request.has_parent = request.parent is not None - if request.has_parent: - request.requester = getattr( - brewtils.plugin.request_context.current_request, "requester", None - ) + ec = EasyClient( bg_host=brewtils.plugin.CONFIG.bg_host, bg_port=brewtils.plugin.CONFIG.bg_port, @@ -586,6 +583,11 @@ def _construct_bg_request(self, **kwargs): topic = kwargs.pop("_topic", None) propagate = kwargs.pop("_propagate", None) + if parent: + requester = getattr(brewtils.plugin.request_context.current_request, "requester", None) + else: + requester = None + if system_display: metadata["system_display_name"] = system_display if publish: @@ -616,6 +618,7 @@ def _construct_bg_request(self, **kwargs): parent=parent, metadata=metadata, parameters=kwargs, + requester=requester, ) request.parameters = self._resolve_parameters(command, request) From 5fb7344f9716f8b22504850ec8d152f15e7f8e85 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:33:00 -0400 Subject: [PATCH 38/53] add file generated flag --- brewtils/models.py | 8 ++++++-- brewtils/schemas.py | 2 ++ brewtils/test/fixtures.py | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index b7ac64fb..afafa7b1 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1622,11 +1622,12 @@ def __init__( password=None, roles=None, local_roles=None, - remote_roles=None, - is_remote=False, + remote_roles=None, remote_user_mapping=None, metadata=None, + is_remote=False, protected=False, + file_generated=False, ): self.id = id self.username = username @@ -1638,6 +1639,7 @@ def __init__( self.remote_user_mapping = remote_user_mapping or [] self.metadata = metadata self.protected = protected + self.file_generated = file_generated def __str__(self): return "%s: %s" % (self.username, self.roles) @@ -1672,6 +1674,7 @@ def __init__( scope_versions=None, scope_commands=None, protected=False, + file_generated=False, ): self.permission = permission or "READ_ONLY" self.description = description @@ -1684,6 +1687,7 @@ def __init__( self.scope_versions = scope_versions or [] self.scope_commands = scope_commands or [] self.protected = protected + self.file_generated = file_generated def __str__(self): return "%s" % (self.name) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index f4d3269f..470f07b3 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -572,6 +572,7 @@ class RoleSchema(BaseSchema): scope_versions = fields.List(fields.Str(), allow_none=True) scope_commands = fields.List(fields.Str(), allow_none=True) protected = fields.Boolean(allow_none=True) + file_generated = fields.Boolean(allow_none=True) class RemoteRoleSchema(RoleSchema): pass @@ -607,6 +608,7 @@ class UserSchema(BaseSchema): is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) protected = fields.Boolean(allow_none=True) + file_generated = fields.Boolean(allow_none=True) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 09a845b1..85b89937 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -577,6 +577,7 @@ def role_dict(): "scope_versions": [], "scope_commands": [], "protected": False, + "file_generated": False, } @@ -598,6 +599,7 @@ def remote_role_dict(): "scope_versions": [], "scope_commands": [], "protected": False, + "file_generated": False, } @@ -619,6 +621,7 @@ def user_dict(role_dict, remote_role_dict, remote_user_map_dict): "is_remote": False, "metadata": {}, "protected": False, + "file_generated": False, } From fdb17e39f147bd2df8e7261dad9d2bde6486b31a Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:51:45 -0400 Subject: [PATCH 39/53] Load Tokens first if configured --- brewtils/rest/client.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/brewtils/rest/client.py b/brewtils/rest/client.py index 39b530bc..b9e348ee 100644 --- a/brewtils/rest/client.py +++ b/brewtils/rest/client.py @@ -23,12 +23,17 @@ def enable_auth(method): @functools.wraps(method) def wrapper(self, *args, **kwargs): + + # Load Token initially if authentication settings are provided + if not self.session.headers.get("Authorization") and ((self.username and self.password) or self.client_cert): + self.get_tokens() + original_response = method(self, *args, **kwargs) if original_response.status_code != 401: return original_response - # Try to use credentials + # Refresh Token if expired and caused 401 if (self.username and self.password) or self.client_cert: credential_response = self.get_tokens() From 3949c61194732eebe14f1b2943900454c66e4444 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:49:17 -0400 Subject: [PATCH 40/53] User metadata defaults --- brewtils/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index afafa7b1..d22bf768 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1637,7 +1637,7 @@ def __init__( self.remote_roles = remote_roles or [] self.is_remote = is_remote self.remote_user_mapping = remote_user_mapping or [] - self.metadata = metadata + self.metadata = metadata or {} self.protected = protected self.file_generated = file_generated From 64f81e37c0ab5bf5db182593a4b8d94264b36456 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:07:38 +0000 Subject: [PATCH 41/53] changing to upstream and alias --- brewtils/models.py | 23 ++++---- brewtils/schema_parser.py | 46 ++++++++------- brewtils/schemas.py | 16 ++--- brewtils/test/comparable.py | 27 +++++---- brewtils/test/fixtures.py | 40 +++++++------ test/schema_parser_test.py | 113 +++++++++++++++++++----------------- 6 files changed, 140 insertions(+), 125 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index d22bf768..ad42ccc7 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1617,13 +1617,13 @@ class User(BaseModel): def __init__( self, - username = None, - id = None, + username=None, + id=None, password=None, roles=None, local_roles=None, - remote_roles=None, - remote_user_mapping=None, + upstream_roles=None, + alias_user_mapping=None, metadata=None, is_remote=False, protected=False, @@ -1634,9 +1634,9 @@ def __init__( self.password = password self.roles = roles or [] self.local_roles = local_roles or [] - self.remote_roles = remote_roles or [] + self.upstream_roles = upstream_roles or [] self.is_remote = is_remote - self.remote_user_mapping = remote_user_mapping or [] + self.alias_user_mapping = alias_user_mapping or [] self.metadata = metadata or {} self.protected = protected self.file_generated = file_generated @@ -1710,16 +1710,19 @@ def __repr__(self): self.scope_commands, ) -class RemoteRole(Role): - schema = "RemoteRoleSchema" -class RemoteUserMap(BaseModel): - schema = "RemoteUserMapSchema" +class UpstreamRole(Role): + schema = "UpstreamRoleSchema" + + +class AliasUserMap(BaseModel): + schema = "AliasUserMapSchema" def __init__(self, target_garden, username): self.target_garden = target_garden self.username = username + class Subscriber(BaseModel): schema = "SubscriberSchema" diff --git a/brewtils/schema_parser.py b/brewtils/schema_parser.py index 4f302e2d..abe523aa 100644 --- a/brewtils/schema_parser.py +++ b/brewtils/schema_parser.py @@ -49,9 +49,9 @@ class SchemaParser(object): "RunnerSchema": brewtils.models.Runner, "ResolvableSchema": brewtils.models.Resolvable, "RoleSchema": brewtils.models.Role, - "RemoteRoleSchema": brewtils.models.RemoteRole, + "UpstreamRoleSchema": brewtils.models.UpstreamRole, "UserSchema": brewtils.models.User, - "RemoteUserMapSchema": brewtils.models.RemoteUserMap, + "AliasUserMapSchema": brewtils.models.AliasUserMap, "SubscriberSchema": brewtils.models.Subscriber, "TopicSchema": brewtils.models.Topic, } @@ -283,9 +283,9 @@ def parse_role(cls, role, from_string=False, **kwargs): A Role object """ return cls.parse(role, brewtils.models.Role, from_string=from_string, **kwargs) - + @classmethod - def parse_remote_role(cls, role, from_string=False, **kwargs): + def parse_upstream_role(cls, role, from_string=False, **kwargs): """Convert raw JSON string or dictionary to a role model object Args: @@ -296,11 +296,13 @@ def parse_remote_role(cls, role, from_string=False, **kwargs): Returns: A Role object """ - return cls.parse(role, brewtils.models.RemoteRole, from_string=from_string, **kwargs) + return cls.parse( + role, brewtils.models.UpstreamRole, from_string=from_string, **kwargs + ) @classmethod - def parse_remote_user_map(cls, remote_user_map, from_string=False, **kwargs): - """Convert raw JSON string or dictionary to a RemoteUserMap model object + def parse_alias_user_map(cls, alias_user_map, from_string=False, **kwargs): + """Convert raw JSON string or dictionary to a AliasUserMap model object Args: role: The raw input @@ -308,11 +310,11 @@ def parse_remote_user_map(cls, remote_user_map, from_string=False, **kwargs): **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) Returns: - A RemoteUserMap object + A AliasUserMap object """ return cls.parse( - remote_user_map, - brewtils.models.RemoteUserMap, + alias_user_map, + brewtils.models.AliasUserMap, from_string=from_string, **kwargs ) @@ -330,10 +332,7 @@ def parse_user_token(cls, user_token, from_string=False, **kwargs): A UserToken object """ return cls.parse( - user_token, - brewtils.models.UserToken, - from_string=from_string, - **kwargs + user_token, brewtils.models.UserToken, from_string=from_string, **kwargs ) @classmethod @@ -771,9 +770,9 @@ def serialize_role(cls, role, to_string=True, **kwargs): return cls.serialize( role, to_string=to_string, schema_name=brewtils.models.Role.schema, **kwargs ) - + @classmethod - def serialize_remote_role(cls, role, to_string=True, **kwargs): + def serialize_upstream_role(cls, role, to_string=True, **kwargs): """Convert a role model into serialized form Args: @@ -786,15 +785,18 @@ def serialize_remote_role(cls, role, to_string=True, **kwargs): Serialized representation """ return cls.serialize( - role, to_string=to_string, schema_name=brewtils.models.RemoteRole.schema, **kwargs + role, + to_string=to_string, + schema_name=brewtils.models.UpstreamRole.schema, + **kwargs ) @classmethod - def serialize_remote_user_map(cls, remote_user_map, to_string=True, **kwargs): - """Convert a RemoteUserMap model into serialized form + def serialize_alias_user_map(cls, alias_user_map, to_string=True, **kwargs): + """Convert a AliasUserMap model into serialized form Args: - RemoteUserMap: The RemoteUserMap object(s) to be serialized + AliasUserMap: The AliasUserMap object(s) to be serialized to_string: True to generate a JSON-formatted string, False to generate a dictionary **kwargs: Additional parameters to be passed to the Schema (e.g. many=True) @@ -803,9 +805,9 @@ def serialize_remote_user_map(cls, remote_user_map, to_string=True, **kwargs): Serialized representation """ return cls.serialize( - remote_user_map, + alias_user_map, to_string=to_string, - schema_name=brewtils.models.RemoteUserMap.schema, + schema_name=brewtils.models.AliasUserMap.schema, **kwargs ) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 470f07b3..885a290f 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -574,14 +574,16 @@ class RoleSchema(BaseSchema): protected = fields.Boolean(allow_none=True) file_generated = fields.Boolean(allow_none=True) -class RemoteRoleSchema(RoleSchema): + +class UpstreamRoleSchema(RoleSchema): pass -class RemoteUserMapSchema(BaseSchema): +class AliasUserMapSchema(BaseSchema): target_garden = fields.Str() username = fields.Str() + class SubscriberSchema(BaseSchema): garden = fields.Str(allow_none=True) namespace = fields.Str(allow_none=True) @@ -603,16 +605,14 @@ class UserSchema(BaseSchema): password = fields.Str(allow_none=True) roles = fields.List(fields.Str(), allow_none=True) local_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) - remote_roles = fields.List(fields.Nested(RemoteRoleSchema()), allow_none=True) - remote_user_mapping = fields.List(fields.Nested(RemoteUserMapSchema())) + upstream_roles = fields.List(fields.Nested(UpstreamRoleSchema()), allow_none=True) + alias_user_mapping = fields.List(fields.Nested(AliasUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) protected = fields.Boolean(allow_none=True) file_generated = fields.Boolean(allow_none=True) - - model_schema_map.update( { "Choices": ChoicesSchema, @@ -643,9 +643,9 @@ class UserSchema(BaseSchema): "Runner": RunnerSchema, "Resolvable": ResolvableSchema, "Role": RoleSchema, - "RemoteRole": RemoteRoleSchema, + "UpstreamRole": UpstreamRoleSchema, "User": UserSchema, - "RemoteUserMap": RemoteUserMapSchema, + "AliasUserMap": AliasUserMapSchema, "Subscriber": SubscriberSchema, "Topic": TopicSchema, # Compatibility for the Job trigger types diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 43a4add7..1874906b 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -14,6 +14,7 @@ import brewtils.test from brewtils.models import ( + AliasUserMap, Choices, Command, Connection, @@ -24,24 +25,23 @@ Instance, IntervalTrigger, Job, - Role, LoggingConfig, Operation, Parameter, PatchOperation, - User, - UserToken, Queue, - RemoteUserMap, - RemoteRole, Request, RequestFile, RequestTemplate, Resolvable, + Role, Runner, - System, Subscriber, + System, Topic, + UpstreamRole, + User, + UserToken, ) __all__ = [ @@ -57,7 +57,7 @@ "assert_parameter_equal", "assert_user_token_equal", "assert_user_equal", - "assert_remote_user_map_equal", + "assert_alias_user_map_equal", "assert_request_equal", "assert_role_equal", "assert_system_equal", @@ -202,7 +202,7 @@ def _assert_wrapper(obj1, obj2, expected_type=None, do_raise=False, **kwargs): assert_runner_equal = partial(_assert_wrapper, expected_type=Runner) assert_resolvable_equal = partial(_assert_wrapper, expected_type=Resolvable) assert_connection_equal = partial(_assert_wrapper, expected_type=Connection) -assert_remote_user_map_equal = partial(_assert_wrapper, expected_type=RemoteUserMap) +assert_alias_user_map_equal = partial(_assert_wrapper, expected_type=AliasUserMap) assert_subscriber_equal = partial(_assert_wrapper, expected_type=Subscriber) @@ -246,6 +246,7 @@ def assert_event_equal(obj1, obj2, do_raise=False): do_raise=do_raise, ) + def assert_user_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, @@ -253,12 +254,13 @@ def assert_user_equal(obj1, obj2, do_raise=False): expected_type=User, deep_fields={ "local_roles": partial(assert_role_equal, do_raise=True), - "remote_roles": partial(assert_remote_role_equal, do_raise=True), - "remote_user_mapping": partial(assert_remote_user_map_equal, do_raise=True), + "upstream_roles": partial(assert_upstream_role_equal, do_raise=True), + "alias_user_mapping": partial(assert_alias_user_map_equal, do_raise=True), }, do_raise=do_raise, ) + def assert_user_token_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, @@ -327,11 +329,12 @@ def assert_role_equal(obj1, obj2, do_raise=False): do_raise=do_raise, ) -def assert_remote_role_equal(obj1, obj2, do_raise=False): + +def assert_upstream_role_equal(obj1, obj2, do_raise=False): return _assert_wrapper( obj1, obj2, - expected_type=RemoteRole, + expected_type=UpstreamRole, do_raise=do_raise, ) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 85b89937..11cfdf0f 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -7,6 +7,7 @@ import pytz from brewtils.models import ( + AliasUserMap, Choices, Command, Connection, @@ -22,19 +23,18 @@ Parameter, PatchOperation, Queue, - RemoteUserMap, - RemoteRole, Request, RequestFile, RequestTemplate, Resolvable, + Role, Runner, + Subscriber, System, + Topic, + UpstreamRole, User, UserToken, - Role, - Subscriber, - Topic, ) @@ -533,7 +533,7 @@ def bg_queue(queue_dict): @pytest.fixture -def remote_user_map_dict(): +def alias_user_map_dict(): return { "target_garden": "test", "username": "user", @@ -541,8 +541,9 @@ def remote_user_map_dict(): @pytest.fixture -def bg_remote_user_map(remote_user_map_dict): - return RemoteUserMap(**remote_user_map_dict) +def bg_alias_user_map(alias_user_map_dict): + return AliasUserMap(**alias_user_map_dict) + @pytest.fixture def user_token_dict(user_dict, ts_epoch): @@ -582,11 +583,12 @@ def role_dict(): @pytest.fixture -def bg_remote_role(role_dict): - return RemoteRole(**role_dict) +def bg_role(role_dict): + return Role(**role_dict) + @pytest.fixture -def remote_role_dict(): +def upstream_role_dict(): return { "permission": "PLUGIN_ADMIN", "description": "PLUGIN ADMIN ROLE", @@ -604,20 +606,20 @@ def remote_role_dict(): @pytest.fixture -def bg_role(role_dict): - return Role(**role_dict) +def bg_upstream_role(upstream_role_dict): + return UpstreamRole(**upstream_role_dict) @pytest.fixture -def user_dict(role_dict, remote_role_dict, remote_user_map_dict): +def user_dict(role_dict, upstream_role_dict, alias_user_map_dict): return { "id": "1", "username": "USERNAME", "password": "HASH", "roles": ["PLUGIN_ADMIN_ROLE"], "local_roles": [role_dict], - "remote_roles": [remote_role_dict], - "remote_user_mapping": [remote_user_map_dict], + "upstream_roles": [upstream_role_dict], + "alias_user_mapping": [alias_user_map_dict], "is_remote": False, "metadata": {}, "protected": False, @@ -626,11 +628,11 @@ def user_dict(role_dict, remote_role_dict, remote_user_map_dict): @pytest.fixture -def bg_user(user_dict, bg_role, bg_remote_role, bg_remote_user_map): +def bg_user(user_dict, bg_role, bg_upstream_role, bg_alias_user_map): dict_copy = copy.deepcopy(user_dict) - dict_copy["remote_roles"] = [bg_remote_role] + dict_copy["upstream_roles"] = [bg_upstream_role] dict_copy["local_roles"] = [bg_role] - dict_copy["remote_user_mapping"] = [bg_remote_user_map] + dict_copy["alias_user_mapping"] = [bg_alias_user_map] return User(**dict_copy) diff --git a/test/schema_parser_test.py b/test/schema_parser_test.py index d575980b..94fa1cc2 100644 --- a/test/schema_parser_test.py +++ b/test/schema_parser_test.py @@ -5,11 +5,15 @@ import copy -import brewtils.models import pytest +from marshmallow.exceptions import MarshmallowError +from pytest_lazyfixture import lazy_fixture + +import brewtils.models from brewtils.models import System from brewtils.schema_parser import SchemaParser from brewtils.test.comparable import ( + assert_alias_user_map_equal, assert_command_equal, assert_connection_equal, assert_event_equal, @@ -21,11 +25,7 @@ assert_operation_equal, assert_parameter_equal, assert_patch_equal, - assert_user_equal, - assert_user_token_equal, assert_queue_equal, - assert_remote_user_map_equal, - assert_remote_role_equal, assert_request_equal, assert_request_file_equal, assert_resolvable_equal, @@ -34,9 +34,10 @@ assert_subscriber_equal, assert_system_equal, assert_topic_equal, + assert_upstream_role_equal, + assert_user_equal, + assert_user_token_equal, ) -from marshmallow.exceptions import MarshmallowError -from pytest_lazyfixture import lazy_fixture class TestParse(object): @@ -138,10 +139,10 @@ def test_no_modify(self, system_dict): lazy_fixture("bg_user_token"), ), ( - brewtils.models.RemoteUserMap, - lazy_fixture("remote_user_map_dict"), - assert_remote_user_map_equal, - lazy_fixture("bg_remote_user_map"), + brewtils.models.AliasUserMap, + lazy_fixture("alias_user_map_dict"), + assert_alias_user_map_equal, + lazy_fixture("bg_alias_user_map"), ), ( brewtils.models.Role, @@ -150,10 +151,10 @@ def test_no_modify(self, system_dict): lazy_fixture("bg_role"), ), ( - brewtils.models.RemoteRole, - lazy_fixture("remote_role_dict"), - assert_remote_role_equal, - lazy_fixture("bg_remote_role"), + brewtils.models.UpstreamRole, + lazy_fixture("upstream_role_dict"), + assert_upstream_role_equal, + lazy_fixture("bg_upstream_role"), ), ( brewtils.models.Job, @@ -296,10 +297,10 @@ def test_single_from_string(self): lazy_fixture("bg_user_token"), ), ( - "parse_remote_user_map", - lazy_fixture("remote_user_map_dict"), - assert_remote_user_map_equal, - lazy_fixture("bg_remote_user_map"), + "parse_alias_user_map", + lazy_fixture("alias_user_map_dict"), + assert_alias_user_map_equal, + lazy_fixture("bg_alias_user_map"), ), ( "parse_role", @@ -308,10 +309,10 @@ def test_single_from_string(self): lazy_fixture("bg_role"), ), ( - "parse_remote_role", - lazy_fixture("remote_role_dict"), - assert_remote_role_equal, - lazy_fixture("bg_remote_role"), + "parse_upstream_role", + lazy_fixture("upstream_role_dict"), + assert_upstream_role_equal, + lazy_fixture("bg_upstream_role"), ), ( "parse_job", @@ -459,10 +460,10 @@ def test_single_specific_from_string(self): lazy_fixture("bg_user_token"), ), ( - brewtils.models.RemoteUserMap, - lazy_fixture("remote_user_map_dict"), - assert_remote_user_map_equal, - lazy_fixture("bg_remote_user_map"), + brewtils.models.AliasUserMap, + lazy_fixture("alias_user_map_dict"), + assert_alias_user_map_equal, + lazy_fixture("bg_alias_user_map"), ), ( brewtils.models.Role, @@ -471,10 +472,10 @@ def test_single_specific_from_string(self): lazy_fixture("bg_role"), ), ( - brewtils.models.RemoteRole, - lazy_fixture("remote_role_dict"), - assert_remote_role_equal, - lazy_fixture("bg_remote_role"), + brewtils.models.UpstreamRole, + lazy_fixture("upstream_role_dict"), + assert_upstream_role_equal, + lazy_fixture("bg_upstream_role"), ), ( brewtils.models.Job, @@ -615,10 +616,10 @@ def test_many(self, model, data, assertion, expected): lazy_fixture("bg_user_token"), ), ( - "parse_remote_user_map", - lazy_fixture("remote_user_map_dict"), - assert_remote_user_map_equal, - lazy_fixture("bg_remote_user_map"), + "parse_alias_user_map", + lazy_fixture("alias_user_map_dict"), + assert_alias_user_map_equal, + lazy_fixture("bg_alias_user_map"), ), ( "parse_role", @@ -627,10 +628,10 @@ def test_many(self, model, data, assertion, expected): lazy_fixture("bg_role"), ), ( - "parse_remote_role", - lazy_fixture("remote_role_dict"), - assert_remote_role_equal, - lazy_fixture("bg_remote_role"), + "parse_upstream_role", + lazy_fixture("upstream_role_dict"), + assert_upstream_role_equal, + lazy_fixture("bg_upstream_role"), ), ( "parse_job", @@ -732,9 +733,9 @@ class TestSerialize(object): (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), - (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), + (lazy_fixture("bg_alias_user_map"), lazy_fixture("alias_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), - (lazy_fixture("bg_remote_role"), lazy_fixture("remote_role_dict")), + (lazy_fixture("bg_upstream_role"), lazy_fixture("upstream_role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -805,9 +806,9 @@ def test_single(self, model, expected): lazy_fixture("user_token_dict"), ), ( - "serialize_remote_user_map", - lazy_fixture("bg_remote_user_map"), - lazy_fixture("remote_user_map_dict"), + "serialize_alias_user_map", + lazy_fixture("bg_alias_user_map"), + lazy_fixture("alias_user_map_dict"), ), ( "serialize_role", @@ -815,9 +816,9 @@ def test_single(self, model, expected): lazy_fixture("role_dict"), ), ( - "serialize_remote_role", - lazy_fixture("bg_remote_role"), - lazy_fixture("remote_role_dict"), + "serialize_upstream_role", + lazy_fixture("bg_upstream_role"), + lazy_fixture("upstream_role_dict"), ), ("serialize_job", lazy_fixture("bg_job"), lazy_fixture("job_dict")), ( @@ -891,9 +892,9 @@ def test_single_specific(self, method, data, expected): (lazy_fixture("bg_queue"), lazy_fixture("queue_dict")), (lazy_fixture("bg_user"), lazy_fixture("user_dict")), (lazy_fixture("bg_user_token"), lazy_fixture("user_token_dict")), - (lazy_fixture("bg_remote_user_map"), lazy_fixture("remote_user_map_dict")), + (lazy_fixture("bg_alias_user_map"), lazy_fixture("alias_user_map_dict")), (lazy_fixture("bg_role"), lazy_fixture("role_dict")), - (lazy_fixture("bg_remote_role"), lazy_fixture("remote_role_dict")), + (lazy_fixture("bg_upstream_role"), lazy_fixture("upstream_role_dict")), (lazy_fixture("bg_job"), lazy_fixture("job_dict")), (lazy_fixture("bg_cron_job"), lazy_fixture("cron_job_dict")), (lazy_fixture("bg_interval_job"), lazy_fixture("interval_job_dict")), @@ -981,12 +982,16 @@ class TestRoundTrip(object): lazy_fixture("bg_user_token"), ), ( - brewtils.models.RemoteUserMap, - assert_remote_user_map_equal, - lazy_fixture("bg_remote_user_map"), + brewtils.models.AliasUserMap, + assert_alias_user_map_equal, + lazy_fixture("bg_alias_user_map"), ), (brewtils.models.Role, assert_role_equal, lazy_fixture("bg_role")), - (brewtils.models.RemoteRole, assert_remote_role_equal, lazy_fixture("bg_remote_role")), + ( + brewtils.models.UpstreamRole, + assert_upstream_role_equal, + lazy_fixture("bg_upstream_role"), + ), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_cron_job")), (brewtils.models.Job, assert_job_equal, lazy_fixture("bg_interval_job")), @@ -1033,7 +1038,7 @@ def test_parsed_start(self, model, assertion, data): (brewtils.models.User, lazy_fixture("user_dict")), (brewtils.models.UserToken, lazy_fixture("user_token_dict")), (brewtils.models.Role, lazy_fixture("role_dict")), - (brewtils.models.RemoteRole, lazy_fixture("remote_role_dict")), + (brewtils.models.UpstreamRole, lazy_fixture("upstream_role_dict")), (brewtils.models.Job, lazy_fixture("job_dict")), (brewtils.models.Job, lazy_fixture("cron_job_dict")), (brewtils.models.Job, lazy_fixture("interval_job_dict")), From 8c961d2d6377a2e866658edf244b0f20f75bde0a Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:09:09 +0000 Subject: [PATCH 42/53] fixing testing --- test/models_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models_test.py b/test/models_test.py index 2e2c1e47..cb1d8b39 100644 --- a/test/models_test.py +++ b/test/models_test.py @@ -537,7 +537,7 @@ def user(self): return User( username="admin", roles=["bg-admin"], - remote_roles=[Role(name="foo", permission="ADMIN")], + upstream_roles=[Role(name="foo", permission="ADMIN")], ) def test_str(self, user): From ce072b2f0c0345d7c918effe7e8ee246f49ba3fd Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:12:04 +0000 Subject: [PATCH 43/53] formatting --- brewtils/rest/client.py | 4 +++- brewtils/schemas.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/brewtils/rest/client.py b/brewtils/rest/client.py index b9e348ee..ad7cfacc 100644 --- a/brewtils/rest/client.py +++ b/brewtils/rest/client.py @@ -25,7 +25,9 @@ def enable_auth(method): def wrapper(self, *args, **kwargs): # Load Token initially if authentication settings are provided - if not self.session.headers.get("Authorization") and ((self.username and self.password) or self.client_cert): + if not self.session.headers.get("Authorization") and ( + (self.username and self.password) or self.client_cert + ): self.get_tokens() original_response = method(self, *args, **kwargs) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 885a290f..65b98fef 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -38,7 +38,7 @@ "OperationSchema", "UserSchema", "RoleSchema", - "RemoteUserMapSchema", + "AliasUserMapSchema", "SubscriberSchema", "TopicSchema", ] From 4daaf21b9ce2c06236ef907ddc64805ac138289d Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:13:24 +0000 Subject: [PATCH 44/53] formatting --- brewtils/rest/system_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brewtils/rest/system_client.py b/brewtils/rest/system_client.py index 6d78fc1b..bfcd216b 100644 --- a/brewtils/rest/system_client.py +++ b/brewtils/rest/system_client.py @@ -597,7 +597,9 @@ def _construct_bg_request(self, **kwargs): propagate = kwargs.pop("_propagate", None) if parent: - requester = getattr(brewtils.plugin.request_context.current_request, "requester", None) + requester = getattr( + brewtils.plugin.request_context.current_request, "requester", None + ) else: requester = None From c97d4ce02dfa1bdf2b7d52915641c88080dcd4c2 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Thu, 13 Jun 2024 06:44:40 -0400 Subject: [PATCH 45/53] Roles Equals func --- brewtils/models.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index ad42ccc7..be5216b3 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1710,6 +1710,22 @@ def __repr__(self): self.scope_commands, ) + def __eq__(self, other): + if not isinstance(other, Role): + # don't attempt to compare against unrelated types + return NotImplemented + + return ( + self.name == other.name + and self.description == other.description + and self.scope_gardens == other.scope_gardens + and self.scope_namespaces == other.scope_namespaces + and self.scope_systems == other.scope_systems + and self.scope_instances == other.scope_instances + and self.scope_versions == other.scope_versions + and self.scope_commands == other.scope_commands + ) + class UpstreamRole(Role): schema = "UpstreamRoleSchema" From 92aa21032f4fa90b91c2be1dcd7b038bd599ac3d Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:51:27 -0400 Subject: [PATCH 46/53] Update Events Roles --- brewtils/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index be5216b3..35e463bf 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -91,8 +91,8 @@ class Events(Enum): JOB_EXECUTED = 43 USER_UPDATED = 44 USERS_IMPORTED = 45 - ROLE_UPDATED = 46 - ROLES_IMPORTED = 47 + ROLE_DELETED = 46 + ROLE_UPDATED = 47 COMMAND_PUBLISHING_BLOCKLIST_SYNC = 48 COMMAND_PUBLISHING_BLOCKLIST_REMOVE = 49 COMMAND_PUBLISHING_BLOCKLIST_UPDATE = 50 From d1142175906550ee6bb32d0119ce2a61eda4b2bf Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:25:14 +0000 Subject: [PATCH 47/53] User Model Equals --- brewtils/models.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/brewtils/models.py b/brewtils/models.py index 35e463bf..81eedb7e 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1649,6 +1649,21 @@ def __repr__(self): self.username, self.roles, ) + + def __eq__(self, other): + if not isinstance(other, User): + # don't attempt to compare against unrelated types + return NotImplemented + + return ( + self.username == other.username + and self.roles == other.roles + and self.upstream_roles == other.upstream_roles + and self.is_remote == other.is_remote + and self.alias_user_mapping == other.alias_user_mapping + and self.protected == other.protected + and self.file_generated == other.file_generated + ) class Role(BaseModel): From cd47aadf57adc1774e4470652d485e3c8c71e2e1 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 19 Jun 2024 06:26:47 -0400 Subject: [PATCH 48/53] Formatting --- brewtils/auto_decorator.py | 1 - brewtils/models.py | 2 +- brewtils/request_handling.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/brewtils/auto_decorator.py b/brewtils/auto_decorator.py index 0ddd3049..ef3742b0 100644 --- a/brewtils/auto_decorator.py +++ b/brewtils/auto_decorator.py @@ -1,7 +1,6 @@ from inspect import Parameter as InspectParameter # noqa from inspect import signature - from brewtils.models import Command, Parameter diff --git a/brewtils/models.py b/brewtils/models.py index 81eedb7e..53c53796 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1649,7 +1649,7 @@ def __repr__(self): self.username, self.roles, ) - + def __eq__(self, other): if not isinstance(other, User): # don't attempt to compare against unrelated types diff --git a/brewtils/request_handling.py b/brewtils/request_handling.py index 7ec877d4..fad8e647 100644 --- a/brewtils/request_handling.py +++ b/brewtils/request_handling.py @@ -10,8 +10,8 @@ import six from requests import ConnectionError as RequestsConnectionError -from brewtils.decorators import _parse_method import brewtils.plugin +from brewtils.decorators import _parse_method from brewtils.errors import ( BGGivesUpError, DiscardMessageException, From 078681288883ebaf30d5b766b1bc2e176130b78a Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 19 Jun 2024 08:50:05 -0400 Subject: [PATCH 49/53] Change Log Updates --- CHANGELOG.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 16ea25b6..31d665ed 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ Brewtils Changelog ================== +3.27.0 +------ +TBD + +- New Models for User, UserToken, Role, and AliasUserMap +- Must upgrade to a minimum version of Beer Garden 3.27.0 to support new authentication models. If authentication is not enabled, upgrade + is not required. +- Removed 2.0 Legacy support for Principle and LegacyRole models +- Fixed bug in SystemClient to properly assign requester field from parent request + 3.26.2 ------ 6/6/20 From c5c8521e7f0e9d0823b919b80082df402db4e202 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:36:16 +0000 Subject: [PATCH 50/53] update to user_alias_mapping --- brewtils/models.py | 6 +++--- brewtils/schemas.py | 2 +- brewtils/test/comparable.py | 2 +- brewtils/test/fixtures.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index 53c53796..a044c939 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -1623,7 +1623,7 @@ def __init__( roles=None, local_roles=None, upstream_roles=None, - alias_user_mapping=None, + user_alias_mapping=None, metadata=None, is_remote=False, protected=False, @@ -1636,7 +1636,7 @@ def __init__( self.local_roles = local_roles or [] self.upstream_roles = upstream_roles or [] self.is_remote = is_remote - self.alias_user_mapping = alias_user_mapping or [] + self.user_alias_mapping = user_alias_mapping or [] self.metadata = metadata or {} self.protected = protected self.file_generated = file_generated @@ -1660,7 +1660,7 @@ def __eq__(self, other): and self.roles == other.roles and self.upstream_roles == other.upstream_roles and self.is_remote == other.is_remote - and self.alias_user_mapping == other.alias_user_mapping + and self.user_alias_mapping == other.user_alias_mapping and self.protected == other.protected and self.file_generated == other.file_generated ) diff --git a/brewtils/schemas.py b/brewtils/schemas.py index 65b98fef..77496931 100644 --- a/brewtils/schemas.py +++ b/brewtils/schemas.py @@ -606,7 +606,7 @@ class UserSchema(BaseSchema): roles = fields.List(fields.Str(), allow_none=True) local_roles = fields.List(fields.Nested(RoleSchema()), allow_none=True) upstream_roles = fields.List(fields.Nested(UpstreamRoleSchema()), allow_none=True) - alias_user_mapping = fields.List(fields.Nested(AliasUserMapSchema())) + user_alias_mapping = fields.List(fields.Nested(AliasUserMapSchema())) is_remote = fields.Boolean(allow_none=True) metadata = fields.Dict(allow_none=True) protected = fields.Boolean(allow_none=True) diff --git a/brewtils/test/comparable.py b/brewtils/test/comparable.py index 1874906b..c2fc68de 100644 --- a/brewtils/test/comparable.py +++ b/brewtils/test/comparable.py @@ -255,7 +255,7 @@ def assert_user_equal(obj1, obj2, do_raise=False): deep_fields={ "local_roles": partial(assert_role_equal, do_raise=True), "upstream_roles": partial(assert_upstream_role_equal, do_raise=True), - "alias_user_mapping": partial(assert_alias_user_map_equal, do_raise=True), + "user_alias_mapping": partial(assert_alias_user_map_equal, do_raise=True), }, do_raise=do_raise, ) diff --git a/brewtils/test/fixtures.py b/brewtils/test/fixtures.py index 11cfdf0f..98afa338 100644 --- a/brewtils/test/fixtures.py +++ b/brewtils/test/fixtures.py @@ -619,7 +619,7 @@ def user_dict(role_dict, upstream_role_dict, alias_user_map_dict): "roles": ["PLUGIN_ADMIN_ROLE"], "local_roles": [role_dict], "upstream_roles": [upstream_role_dict], - "alias_user_mapping": [alias_user_map_dict], + "user_alias_mapping": [alias_user_map_dict], "is_remote": False, "metadata": {}, "protected": False, @@ -632,7 +632,7 @@ def bg_user(user_dict, bg_role, bg_upstream_role, bg_alias_user_map): dict_copy = copy.deepcopy(user_dict) dict_copy["upstream_roles"] = [bg_upstream_role] dict_copy["local_roles"] = [bg_role] - dict_copy["alias_user_mapping"] = [bg_alias_user_map] + dict_copy["user_alias_mapping"] = [bg_alias_user_map] return User(**dict_copy) From adb189be66cd50244c83d9dcde4697fc18577ecb Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:08:57 -0400 Subject: [PATCH 51/53] PR Requested Changes --- brewtils/models.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/brewtils/models.py b/brewtils/models.py index a044c939..9f327de1 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -91,8 +91,8 @@ class Events(Enum): JOB_EXECUTED = 43 USER_UPDATED = 44 USERS_IMPORTED = 45 - ROLE_DELETED = 46 - ROLE_UPDATED = 47 + ROLE_UPDATED = 46 + ROLE_DELETED = 47 COMMAND_PUBLISHING_BLOCKLIST_SYNC = 48 COMMAND_PUBLISHING_BLOCKLIST_REMOVE = 49 COMMAND_PUBLISHING_BLOCKLIST_UPDATE = 50 @@ -1629,8 +1629,8 @@ def __init__( protected=False, file_generated=False, ): - self.id = id self.username = username + self.id = id self.password = password self.roles = roles or [] self.local_roles = local_roles or [] @@ -1691,10 +1691,10 @@ def __init__( protected=False, file_generated=False, ): + self.name = name self.permission = permission or "READ_ONLY" self.description = description - self.id = id - self.name = name + self.id = id self.scope_gardens = scope_gardens or [] self.scope_namespaces = scope_namespaces or [] self.scope_systems = scope_systems or [] @@ -1733,6 +1733,7 @@ def __eq__(self, other): return ( self.name == other.name and self.description == other.description + and self.permission == other.permission and self.scope_gardens == other.scope_gardens and self.scope_namespaces == other.scope_namespaces and self.scope_systems == other.scope_systems From 350474ed95027c3491a84c5aca197cd35247cee7 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:11:45 -0400 Subject: [PATCH 52/53] Add Permissions Enum --- brewtils/models.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 9f327de1..71a421fc 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -102,6 +102,11 @@ class Events(Enum): # Next: 57 +class Permissions(Enum): + READ_ONLY = 1 + OPERATOR = 2 + PLUGIN_ADMIN = 3 + GARDEN_ADMIN = 4 class BaseModel(object): schema = None @@ -1669,6 +1674,7 @@ def __eq__(self, other): class Role(BaseModel): schema = "RoleSchema" + # TODO: REMOVE after DB model Updated with Permissions enum PERMISSION_TYPES = { "GARDEN_ADMIN", "PLUGIN_ADMIN", @@ -1692,7 +1698,7 @@ def __init__( file_generated=False, ): self.name = name - self.permission = permission or "READ_ONLY" + self.permission = permission or Permissions.READ_ONLY.name self.description = description self.id = id self.scope_gardens = scope_gardens or [] From b78ee1f76195473d0d169a1a243cb91666df73ca Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Fri, 28 Jun 2024 08:34:14 -0400 Subject: [PATCH 53/53] Linting --- brewtils/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brewtils/models.py b/brewtils/models.py index 71a421fc..a651fb12 100644 --- a/brewtils/models.py +++ b/brewtils/models.py @@ -102,12 +102,14 @@ class Events(Enum): # Next: 57 + class Permissions(Enum): READ_ONLY = 1 OPERATOR = 2 PLUGIN_ADMIN = 3 GARDEN_ADMIN = 4 + class BaseModel(object): schema = None @@ -1700,7 +1702,7 @@ def __init__( self.name = name self.permission = permission or Permissions.READ_ONLY.name self.description = description - self.id = id + self.id = id self.scope_gardens = scope_gardens or [] self.scope_namespaces = scope_namespaces or [] self.scope_systems = scope_systems or []