From 22869a1507b62c24122e6621b8f195d49fee4132 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 22:51:23 +0200 Subject: [PATCH 1/7] add role_list attribute to BaseHandler --- pype/modules/ftrack/lib/ftrack_base_handler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/modules/ftrack/lib/ftrack_base_handler.py b/pype/modules/ftrack/lib/ftrack_base_handler.py index d322fbaf231..96a8150399a 100644 --- a/pype/modules/ftrack/lib/ftrack_base_handler.py +++ b/pype/modules/ftrack/lib/ftrack_base_handler.py @@ -35,6 +35,7 @@ class BaseHandler(object): type = 'No-type' ignore_me = False preactions = [] + role_list = [] def __init__(self, session, plugins_presets=None): '''Expects a ftrack_api.Session instance''' From 14e192e72c838809b30b5a7920dcd438d7275126 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 22:52:16 +0200 Subject: [PATCH 2/7] extracted rolecheck from _preregister to separate method --- .../modules/ftrack/lib/ftrack_base_handler.py | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/pype/modules/ftrack/lib/ftrack_base_handler.py b/pype/modules/ftrack/lib/ftrack_base_handler.py index 96a8150399a..c711896c195 100644 --- a/pype/modules/ftrack/lib/ftrack_base_handler.py +++ b/pype/modules/ftrack/lib/ftrack_base_handler.py @@ -149,20 +149,27 @@ def session(self): def reset_session(self): self.session.reset() + def _register_role_check(self): + if not self.role_list or not isinstance(self.role_list, (list, tuple)): + return + + user_entity = self.session.query( + "User where username is \"{}\"".format(self.session.api_user) + ).one() + available = False + lowercase_rolelist = [ + role_name.lower() + for role_name in self.role_list + ] + for role in user_entity["user_security_roles"]: + if role["security_role"]["name"].lower() in lowercase_rolelist: + available = True + break + if available is False: + raise MissingPermision + def _preregister(self): - if hasattr(self, "role_list") and len(self.role_list) > 0: - username = self.session.api_user - user = self.session.query( - 'User where username is "{}"'.format(username) - ).one() - available = False - lowercase_rolelist = [x.lower() for x in self.role_list] - for role in user['user_security_roles']: - if role['security_role']['name'].lower() in lowercase_rolelist: - available = True - break - if available is False: - raise MissingPermision + self._register_role_check() # Custom validations result = self.preregister() From 378022003c9d6465b1704c9bb9f7ffd541f4373b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 22:52:42 +0200 Subject: [PATCH 3/7] modified preregister result check --- pype/modules/ftrack/lib/ftrack_base_handler.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pype/modules/ftrack/lib/ftrack_base_handler.py b/pype/modules/ftrack/lib/ftrack_base_handler.py index c711896c195..e928f2fb885 100644 --- a/pype/modules/ftrack/lib/ftrack_base_handler.py +++ b/pype/modules/ftrack/lib/ftrack_base_handler.py @@ -180,12 +180,11 @@ def _preregister(self): ).format(self.__class__.__name__)) return - if result is True: - return - msg = None - if isinstance(result, str): - msg = result - raise PreregisterException(msg) + if result is not True: + msg = None + if isinstance(result, str): + msg = result + raise PreregisterException(msg) def preregister(self): ''' From b96fc36aedc8a239eacbb47ea4d3d92398f0d362 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 23:02:05 +0200 Subject: [PATCH 4/7] implemented ServerAction with modified discovery and register methods --- .../ftrack/lib/ftrack_action_handler.py | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/pype/modules/ftrack/lib/ftrack_action_handler.py b/pype/modules/ftrack/lib/ftrack_action_handler.py index 76c8e414116..a550d9e7d3e 100644 --- a/pype/modules/ftrack/lib/ftrack_action_handler.py +++ b/pype/modules/ftrack/lib/ftrack_action_handler.py @@ -195,3 +195,82 @@ def _handle_result(self, result): ).format(str(type(result)))) return result + + +class ServerAction(BaseAction): + """Action class meant to be used on event server. + + Unlike the `BaseAction` roles are not checked on register but on discover. + For the same reason register is modified to not filter topics by username. + """ + + def __init__(self, *args, **kwargs): + if not self.role_list: + self.role_list = set() + else: + self.role_list = set( + role_name.lower() + for role_name in self.role_list + ) + super(ServerAction, self).__init__(*args, **kwargs) + + def _register_role_check(self): + # Skip register role check. + return + + def _discover(self, event): + """Check user discover availability.""" + if not self._check_user_discover(event): + return + return super(ServerAction, self)._discover(event) + + def _check_user_discover(self, event): + """Should be action discovered by user trying to show actions.""" + if not self.role_list: + return True + + user_entity = self._get_user_entity(event) + if not user_entity: + return False + + for role in user_entity["user_security_roles"]: + lowered_role = role["security_role"]["name"].lower() + if lowered_role in self.role_list: + return True + return False + + def _get_user_entity(self, event): + """Query user entity from event.""" + not_set = object() + + # Check if user is already stored in event data + user_entity = event["data"].get("user_entity", not_set) + if user_entity is not_set: + # Query user entity from event + user_info = event.get("source", {}).get("user", {}) + user_id = user_info.get("id") + username = user_info.get("username") + if user_id: + user_entity = self.session.query( + "User where id is {}".format(user_id) + ).first() + if not user_entity and username: + user_entity = self.session.query( + "User where username is {}".format(username) + ).first() + event["data"]["user_entity"] = user_entity + + return user_entity + + def register(self): + """Register subcription to Ftrack event hub.""" + self.session.event_hub.subscribe( + "topic=ftrack.action.discover", + self._discover, + priority=self.priority + ) + + launch_subscription = ( + "topic=ftrack.action.launch and data.actionIdentifier={0}" + ).format(self.identifier) + self.session.event_hub.subscribe(launch_subscription, self._launch) From ef5b917ff32d546186d2e35da6c3fa859d9ce876 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 23:02:23 +0200 Subject: [PATCH 5/7] extracted ServerAction to ftrack.lib --- pype/modules/ftrack/lib/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/modules/ftrack/lib/__init__.py b/pype/modules/ftrack/lib/__init__.py index d8e9c7a11cf..a52e73d10f0 100644 --- a/pype/modules/ftrack/lib/__init__.py +++ b/pype/modules/ftrack/lib/__init__.py @@ -2,7 +2,7 @@ from . import credentials from .ftrack_base_handler import BaseHandler from .ftrack_event_handler import BaseEvent -from .ftrack_action_handler import BaseAction, statics_icon +from .ftrack_action_handler import BaseAction, ServerAction, statics_icon from .ftrack_app_handler import AppAction __all__ = ( @@ -11,6 +11,7 @@ "BaseHandler", "BaseEvent", "BaseAction", + "ServerAction", "statics_icon", "AppAction" ) From 7bc975c5aa2fbad5248a06dbf7b9b87769b3d575 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 23:05:35 +0200 Subject: [PATCH 6/7] simplified server actions with new ServerAction --- .../action_push_frame_values_to_task.py | 42 ++----------------- .../ftrack/events/action_sync_to_avalon.py | 36 ++-------------- 2 files changed, 6 insertions(+), 72 deletions(-) diff --git a/pype/modules/ftrack/events/action_push_frame_values_to_task.py b/pype/modules/ftrack/events/action_push_frame_values_to_task.py index a55c1e46a63..3a538b57eb1 100644 --- a/pype/modules/ftrack/events/action_push_frame_values_to_task.py +++ b/pype/modules/ftrack/events/action_push_frame_values_to_task.py @@ -1,10 +1,10 @@ import json import collections import ftrack_api -from pype.modules.ftrack.lib import BaseAction +from pype.modules.ftrack.lib import ServerAction -class PushFrameValuesToTaskAction(BaseAction): +class PushFrameValuesToTaskAction(ServerAction): """Action for testing purpose or as base for new actions.""" # Ignore event handler by default @@ -34,50 +34,14 @@ class PushFrameValuesToTaskAction(BaseAction): "frameStart": "fstart", "frameEnd": "fend" } - discover_role_list = {"Pypeclub", "Administrator", "Project Manager"} - - def register(self): - modified_role_names = set() - for role_name in self.discover_role_list: - modified_role_names.add(role_name.lower()) - self.discover_role_list = modified_role_names - - self.session.event_hub.subscribe( - "topic=ftrack.action.discover", - self._discover, - priority=self.priority - ) - - launch_subscription = ( - "topic=ftrack.action.launch and data.actionIdentifier={0}" - ).format(self.identifier) - self.session.event_hub.subscribe(launch_subscription, self._launch) + role_list = {"Pypeclub", "Administrator", "Project Manager"} def discover(self, session, entities, event): """ Validation """ # Check if selection is valid - valid_selection = False for ent in event["data"]["selection"]: # Ignore entities that are not tasks or projects if ent["entityType"].lower() == "show": - valid_selection = True - break - - if not valid_selection: - return False - - # Get user and check his roles - user_id = event.get("source", {}).get("user", {}).get("id") - if not user_id: - return False - - user = session.query("User where id is \"{}\"".format(user_id)).first() - if not user: - return False - - for role in user["user_security_roles"]: - lowered_role = role["security_role"]["name"].lower() - if lowered_role in self.discover_role_list: return True return False diff --git a/pype/modules/ftrack/events/action_sync_to_avalon.py b/pype/modules/ftrack/events/action_sync_to_avalon.py index 4e119228c34..7192afeeb62 100644 --- a/pype/modules/ftrack/events/action_sync_to_avalon.py +++ b/pype/modules/ftrack/events/action_sync_to_avalon.py @@ -1,11 +1,11 @@ import time import traceback -from pype.modules.ftrack import BaseAction +from pype.modules.ftrack import ServerAction from pype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory -class SyncToAvalonServer(BaseAction): +class SyncToAvalonServer(ServerAction): """ Synchronizing data action - from Ftrack to Avalon DB @@ -36,48 +36,18 @@ class SyncToAvalonServer(BaseAction): variant = "- Sync To Avalon (Server)" #: Action description. description = "Send data from Ftrack to Avalon" + role_list = {"Pypeclub", "Administrator", "Project Manager"} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.entities_factory = SyncEntitiesFactory(self.log, self.session) - def register(self): - self.session.event_hub.subscribe( - "topic=ftrack.action.discover", - self._discover, - priority=self.priority - ) - - launch_subscription = ( - "topic=ftrack.action.launch and data.actionIdentifier={0}" - ).format(self.identifier) - self.session.event_hub.subscribe(launch_subscription, self._launch) - def discover(self, session, entities, event): """ Validation """ # Check if selection is valid - valid_selection = False for ent in event["data"]["selection"]: # Ignore entities that are not tasks or projects if ent["entityType"].lower() in ["show", "task"]: - valid_selection = True - break - - if not valid_selection: - return False - - # Get user and check his roles - user_id = event.get("source", {}).get("user", {}).get("id") - if not user_id: - return False - - user = session.query("User where id is \"{}\"".format(user_id)).first() - if not user: - return False - - role_list = ["Pypeclub", "Administrator", "Project Manager"] - for role in user["user_security_roles"]: - if role["security_role"]["name"] in role_list: return True return False From 2f3d164447f50cc3fd901371eba022b12772c0f9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 5 Oct 2020 23:10:13 +0200 Subject: [PATCH 7/7] extracted ServerAction to ftrack module level --- pype/modules/ftrack/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/modules/ftrack/__init__.py b/pype/modules/ftrack/__init__.py index fad771f0842..a1f0b00ce05 100644 --- a/pype/modules/ftrack/__init__.py +++ b/pype/modules/ftrack/__init__.py @@ -1,6 +1,6 @@ from . import ftrack_server from .ftrack_server import FtrackServer, check_ftrack_url -from .lib import BaseHandler, BaseEvent, BaseAction +from .lib import BaseHandler, BaseEvent, BaseAction, ServerAction __all__ = ( "ftrack_server", @@ -8,5 +8,6 @@ "check_ftrack_url", "BaseHandler", "BaseEvent", - "BaseAction" + "BaseAction", + "ServerAction" )