diff --git a/auth-api/src/auth_api/resources/v1/activity_log.py b/auth-api/src/auth_api/resources/v1/activity_log.py index a4b82b0af..e245de354 100644 --- a/auth-api/src/auth_api/resources/v1/activity_log.py +++ b/auth-api/src/auth_api/resources/v1/activity_log.py @@ -29,7 +29,7 @@ @bp.route("", methods=["GET", "OPTIONS"]) @cross_origin(origins="*", methods="GET") -@_jwt.has_one_of_roles([Role.SYSTEM.value, Role.STAFF.value, Role.ACCOUNT_HOLDER.value]) +@_jwt.has_one_of_roles([Role.SYSTEM.value, Role.STAFF.value, Role.ACCOUNT_HOLDER.value, Role.VIEW_ACTIVITY_LOGS.value]) def get_activities(org_id): """Fetch activities.""" try: diff --git a/auth-api/src/auth_api/resources/v1/org.py b/auth-api/src/auth_api/resources/v1/org.py index 7192cf60b..3d0c8c585 100644 --- a/auth-api/src/auth_api/resources/v1/org.py +++ b/auth-api/src/auth_api/resources/v1/org.py @@ -81,7 +81,7 @@ def search_organizations(): roles = token.get("realm_access").get("roles") # public user can only get status of orgs in search, unless they have special roles. - allowed_roles = [Role.STAFF.value, Role.SYSTEM.value, Role.ACCOUNT_IDENTITY] + allowed_roles = [Role.STAFF.value, Role.SYSTEM.value, Role.ACCOUNT_IDENTITY, Role.STAFF_VIEW_ACCOUNTS.value] if Role.PUBLIC_USER.value in roles and not set(roles).intersection(set(allowed_roles)): if response and response.get("orgs"): status = HTTPStatus.OK diff --git a/auth-api/src/auth_api/resources/v1/task.py b/auth-api/src/auth_api/resources/v1/task.py index 7304a3f30..b47738c68 100644 --- a/auth-api/src/auth_api/resources/v1/task.py +++ b/auth-api/src/auth_api/resources/v1/task.py @@ -34,7 +34,7 @@ @bp.route("", methods=["GET", "OPTIONS"]) @cross_origin(origins="*", methods=["GET"]) -@_jwt.has_one_of_roles([Role.STAFF.value]) +@_jwt.has_one_of_roles([Role.STAFF.value, Role.STAFF_TASK_SEARCH.value]) def get_tasks(): """Fetch tasks.""" try: @@ -62,7 +62,7 @@ def get_tasks(): @bp.route("/", methods=["GET", "OPTIONS"]) @cross_origin(origins="*", methods=["GET", "PUT"]) -@_jwt.has_one_of_roles([Role.STAFF.value]) +@_jwt.has_one_of_roles([Role.STAFF.value, Role.VIEW_TASK_DETAILS.value]) def get_task(task_id): """Fetch task by id.""" try: diff --git a/auth-api/src/auth_api/services/authorization.py b/auth-api/src/auth_api/services/authorization.py index c85b47305..667534ba6 100644 --- a/auth-api/src/auth_api/services/authorization.py +++ b/auth-api/src/auth_api/services/authorization.py @@ -52,8 +52,7 @@ def get_account_authorizations_for_org( auth = None token_roles = user_from_context.roles - # todo the service account level access has not been defined - if Role.STAFF.value in token_roles: + if any(role in [Role.STAFF.value, Role.CONTACT_CENTRE_STAFF.value] for role in token_roles): if expanded: # Query Authorization view by business identifier auth = AuthorizationView.find_authorization_for_admin_by_org_id(account_id) diff --git a/auth-api/src/auth_api/services/org.py b/auth-api/src/auth_api/services/org.py index 8576fb3b4..f92c8d44d 100644 --- a/auth-api/src/auth_api/services/org.py +++ b/auth-api/src/auth_api/services/org.py @@ -772,14 +772,17 @@ def get_orgs(user_id, valid_statuses=VALID_STATUSES): return MembershipModel.find_orgs_for_user(user_id, valid_statuses) @staticmethod - def search_orgs(search: OrgSearch, environment): # pylint: disable=too-many-locals + @user_context + def search_orgs(search: OrgSearch, environment, **kwargs): # pylint: disable=too-many-locals """Search for orgs based on input parameters.""" orgs_result = {"orgs": [], "page": search.page, "limit": search.limit, "total": 0} include_invitations: bool = False + user_from_context: UserContext = kwargs["user_context"] + roles = user_from_context.roles search.access_type, is_staff_admin = Org.refine_access_type(search.access_type) if search.statuses and OrgStatus.PENDING_ACTIVATION.value in search.statuses: # only staff admin can see director search accounts - if not is_staff_admin: + if not is_staff_admin and Role.VIEW_ACCOUNT_PENDING_INVITATIONS.value not in roles: raise BusinessException(Error.INVALID_USER_CREDENTIALS, None) org_models, orgs_result["total"] = OrgModel.search_pending_activation_orgs(name=search.name) include_invitations = True diff --git a/auth-api/src/auth_api/utils/roles.py b/auth-api/src/auth_api/utils/roles.py index 219413805..168d80c13 100644 --- a/auth-api/src/auth_api/utils/roles.py +++ b/auth-api/src/auth_api/utils/roles.py @@ -44,6 +44,12 @@ class Role(Enum): # Used by Business-AR to create affiliations that may already have a passcode (bypass passcode check) SKIP_AFFILIATION_AUTH = "skip_affiliation_auth" + CONTACT_CENTRE_STAFF = "contact_centre_staff" + STAFF_TASK_SEARCH = "staff_task_search" + VIEW_TASK_DETAILS = "view_task_details" + VIEW_ACCOUNT_PENDING_INVITATIONS = "view_account_pending_invitations" + VIEW_ACTIVITY_LOGS = "view_activity_logs" + # Membership types STAFF = "STAFF" diff --git a/auth-api/src/auth_api/utils/user_context.py b/auth-api/src/auth_api/utils/user_context.py index a71dbd23e..bea14bd2c 100644 --- a/auth-api/src/auth_api/utils/user_context.py +++ b/auth-api/src/auth_api/utils/user_context.py @@ -81,8 +81,8 @@ def has_role(self, role_name: str) -> bool: return role_name in self._roles def is_staff(self) -> bool: - """Return True if the user is staff user.""" - return Role.STAFF.value in self._roles if self._roles else False + """Return True if the user is staff user or contact centre staff.""" + return self._roles and any(role in [Role.STAFF.value, Role.CONTACT_CENTRE_STAFF.value] for role in self._roles) def is_staff_admin(self) -> bool: """Return True if the user is staff user."""