(request, username, password, channel_id)
| 641 | @api_view(["GET"]) |
| 642 | @permission_classes([AllowAny]) |
| 643 | def stream_xc(request, username, password, channel_id): |
| 644 | user = get_object_or_404(User, username=username) |
| 645 | |
| 646 | extension = pathlib.Path(channel_id).suffix |
| 647 | channel_id = pathlib.Path(channel_id).stem |
| 648 | |
| 649 | if not network_access_allowed(request, 'STREAMS', user): |
| 650 | return Response({"error": "Forbidden"}, status=403) |
| 651 | |
| 652 | custom_properties = user.custom_properties or {} |
| 653 | |
| 654 | if "xc_password" not in custom_properties: |
| 655 | return Response({"error": "Invalid credentials"}, status=401) |
| 656 | |
| 657 | if custom_properties["xc_password"] != password: |
| 658 | return Response({"error": "Invalid credentials"}, status=401) |
| 659 | |
| 660 | if user.user_level < 10: |
| 661 | user_profile_count = user.channel_profiles.count() |
| 662 | |
| 663 | # If user has ALL profiles or NO profiles, give unrestricted access |
| 664 | if user_profile_count == 0: |
| 665 | # No profile filtering - user sees all channels based on user_level |
| 666 | filters = { |
| 667 | "id": int(channel_id), |
| 668 | "user_level__lte": user.user_level |
| 669 | } |
| 670 | channel = Channel.objects.filter(**filters).first() |
| 671 | else: |
| 672 | # User has specific limited profiles assigned |
| 673 | filters = { |
| 674 | "id": int(channel_id), |
| 675 | "channelprofilemembership__enabled": True, |
| 676 | "user_level__lte": user.user_level, |
| 677 | "channelprofilemembership__channel_profile__in": user.channel_profiles.all() |
| 678 | } |
| 679 | channel = Channel.objects.filter(**filters).distinct().first() |
| 680 | |
| 681 | if not channel: |
| 682 | return JsonResponse({"error": "Not found"}, status=404) |
| 683 | else: |
| 684 | channel = get_object_or_404(Channel, id=channel_id) |
| 685 | |
| 686 | if extension.lower() == '.mp4': |
| 687 | force_format = 'fmp4' |
| 688 | elif extension.lower() == '.ts': |
| 689 | force_format = 'mpegts' |
| 690 | else: |
| 691 | force_format = None |
| 692 | return stream_ts(request._request, str(channel.uuid), user, force_output_format=force_format) |
| 693 | |
| 694 | |
| 695 | @csrf_exempt |
nothing calls this directly
no test coverage detected