""" Permission Helpers ================== Helper functions for complex permission checks beyond simple role checks. This module provides: - Content access checks (company profiles, contact info) - Feature access checks (forum, chat, classifieds) - Data visibility filters (what user can see) Usage: from utils.permissions import can_view_contact_info, filter_visible_companies if can_view_contact_info(current_user, company): show_contact_details() visible_companies = filter_visible_companies(current_user, all_companies) """ from typing import List, Optional, TYPE_CHECKING if TYPE_CHECKING: from database import User, Company, SystemRole def can_view_contact_info(user: 'User', target_company: 'Company' = None) -> bool: """ Check if user can view contact information (email, phone, address). Non-members (UNAFFILIATED) cannot see contact details. Members and above can see all contact info (respecting privacy settings). Args: user: The user requesting access target_company: The company whose info is being accessed (optional) Returns: True if user can view contact information """ if not user or not user.is_authenticated: return False return user.can_view_contacts() def can_view_company_dashboard(user: 'User', company_id: int) -> bool: """ Check if user can view a company's internal dashboard. Args: user: The user requesting access company_id: ID of the company dashboard Returns: True if user can view the dashboard """ if not user or not user.is_authenticated: return False # Admins and Office Managers can view any dashboard if user.can_access_admin_panel(): return True # User can view their own company's dashboard return user.company_id == company_id def can_invite_user_to_company(user: 'User', company_id: int) -> bool: """ Check if user can invite new users to a company. Only MANAGER role (within company) and ADMIN can invite users. Args: user: The user attempting to invite company_id: ID of the company to invite to Returns: True if user can invite users to this company """ if not user or not user.is_authenticated: return False return user.can_manage_company(company_id) def get_editable_company_fields(user: 'User', company_id: int) -> List[str]: """ Get list of company profile fields that user can edit. Access is determined by: 1. System role (OFFICE_MANAGER/ADMIN can edit everything) 2. Company role (MANAGER has full access to their company) 3. Delegated permissions (EMPLOYEE gets specific permissions from MANAGER) Args: user: The user requesting edit access company_id: ID of the company to edit Returns: List of field names user can edit """ from database import SystemRole, CompanyRole if not user or not user.is_authenticated: return [] # Not allowed to edit this company at all if not user.can_edit_company(company_id): return [] # Field categories description_fields = [ 'description_short', 'description_full', 'core_values', 'founding_history', ] services_fields = [ 'services_offered', 'technologies_used', 'operational_area', 'languages_offered', ] contact_fields = [ 'email', 'phone', 'address_street', 'address_city', 'address_postal', ] social_fields = [ 'website', # Social media handled via related tables ] admin_only_fields = [ 'name', 'legal_name', 'nip', 'regon', 'krs', 'year_established', 'employees_count', 'capital_amount', 'status', 'category_id', ] # Admins and Office Managers can edit everything if user.has_role(SystemRole.OFFICE_MANAGER): return description_fields + services_fields + contact_fields + social_fields + admin_only_fields # Check user's own company if user.company_id != company_id: return [] # Managers can edit everything except admin-only fields if user.company_role_enum >= CompanyRole.MANAGER: return description_fields + services_fields + contact_fields + social_fields # Employees get permissions based on delegation if user.company_role_enum >= CompanyRole.EMPLOYEE: fields = [] if user.can_edit_company_field('description'): fields.extend(description_fields) if user.can_edit_company_field('services'): fields.extend(services_fields) if user.can_edit_company_field('contacts'): fields.extend(contact_fields) if user.can_edit_company_field('social'): fields.extend(social_fields) return fields return [] def filter_visible_companies(user: 'User', companies: List['Company']) -> List['Company']: """ Filter companies list based on user's access level. All users can see basic company info (name, category, description). Only members can see contact details. This function doesn't filter the list - all companies are visible. Use can_view_contact_info() to determine what details to show. Args: user: The user viewing companies companies: List of companies to filter Returns: Same list (filtering happens at template level) """ # All companies are visible to everyone # Contact info visibility is handled in templates using can_view_contact_info return companies def get_chat_access_level(user: 'User') -> str: """ Get user's NordaGPT chat access level. Args: user: The user accessing chat Returns: 'full' - Full access to all features 'limited' - Basic Q&A only, no company recommendations 'none' - No access """ from database import SystemRole if not user or not user.is_authenticated: return 'none' if user.has_role(SystemRole.MEMBER): return 'full' # UNAFFILIATED users get limited access return 'limited' def can_access_b2b_classifieds(user: 'User') -> bool: """ Check if user can access B2B classifieds (tablica ogłoszeń). Requires at least MEMBER role. Args: user: The user requesting access Returns: True if user can access B2B classifieds """ from database import SystemRole if not user or not user.is_authenticated: return False return user.has_role(SystemRole.MEMBER) def can_create_classified(user: 'User') -> bool: """ Check if user can create B2B classified ads. Requires at least EMPLOYEE role (must be associated with a company). Args: user: The user attempting to create Returns: True if user can create classifieds """ from database import SystemRole if not user or not user.is_authenticated: return False # Must have a company association and be at least EMPLOYEE return user.company_id is not None and user.has_role(SystemRole.EMPLOYEE) def can_access_calendar(user: 'User') -> bool: """ Check if user can access the events calendar. Requires at least MEMBER role. Args: user: The user requesting access Returns: True if user can access calendar """ from database import SystemRole if not user or not user.is_authenticated: return False return user.has_role(SystemRole.MEMBER) def can_create_event(user: 'User') -> bool: """ Check if user can create calendar events. Requires OFFICE_MANAGER or ADMIN role. Args: user: The user attempting to create Returns: True if user can create events """ from database import SystemRole if not user or not user.is_authenticated: return False return user.has_role(SystemRole.OFFICE_MANAGER) def get_user_permissions_summary(user: 'User') -> dict: """ Get a summary of all permissions for a user. Useful for debugging and displaying in user profile. Args: user: The user to summarize Returns: Dictionary with permission flags """ from database import SystemRole if not user or not user.is_authenticated: return { 'role': None, 'company_role': None, 'can_view_contacts': False, 'can_access_forum': False, 'can_access_chat': 'none', 'can_access_admin_panel': False, 'can_manage_users': False, 'can_moderate_forum': False, 'can_edit_own_company': False, 'can_manage_own_company': False, } return { 'role': user.role, 'role_label': dict(SystemRole.choices()).get(user.system_role.value, 'Nieznany'), 'company_role': user.company_role, 'can_view_contacts': user.can_view_contacts(), 'can_access_forum': user.can_access_forum(), 'can_access_chat': get_chat_access_level(user), 'can_access_admin_panel': user.can_access_admin_panel(), 'can_manage_users': user.can_manage_users(), 'can_moderate_forum': user.can_moderate_forum(), 'can_edit_own_company': user.can_edit_company() if user.company_id else False, 'can_manage_own_company': user.can_manage_company() if user.company_id else False, }