Exemple #1
0
    def join(self, request, token):
        token = token.upper()
        student = get_object_or_404(Student, access_token=token)
        lesson = Room.objects.filter(group=student.group).last()
        if not lesson:
            return HttpResponseRedirect(redirect_to=limbo_url(token))

        bbb_api = BigBlueButtonAPI(lesson.server_node.hostname,
                                   lesson.server_node.api_secret)
        if not bbb_api.is_meeting_running(lesson.bbb_meeting_id):
            # TODO - soft delete?
            lesson.delete()
            return HttpResponseRedirect(redirect_to=limbo_url(token))

        try:
            # TODO - where do I take pass from?
            redirect_url = bbb_api.get_join_url(
                meeting_id=lesson.bbb_meeting_id,
                password=lesson.attendee_secret,
                join_as=student.display_name,
                assing_user_id=student.uuid,
            )
        except:
            # TODO - too broad
            return HttpResponseRedirect(redirect_to=limbo_url(token))

        return HttpResponseRedirect(redirect_to=redirect_url)
Exemple #2
0
def start_lesson(group, moderator):
    """"""
    room = get_group_active_meeting(group)

    # group does not have running meeting, create one
    if not room:
        server = ServerNode.assign_server(group=group)
        room, _ = Room.objects.get_or_create(server_node=server, group=group)

    server = room.server_node
    api = BigBlueButtonAPI(server.hostname, server.api_secret)

    try:
        bbb_room = api.create_room(
            meeting_id=room.bbb_meeting_id,
            attendee_secret=User.objects.make_random_password(),
            moderator_secret=User.objects.make_random_password(),
        )
        room.attendee_secret = bbb_room.attendeePW
        room.moderator_secret = bbb_room.moderatorPW
        room.save()
    except RoomAlreadyExistsError:
        pass

    # Connect to room
    redirect_url = api.get_join_url(
        meeting_id=room.bbb_meeting_id,
        password=room.moderator_secret,
        join_as=moderator.display_name,
        assing_user_id=moderator.uuid,
    )
    return redirect_url
def _start_lesson(group, moderator):
    room = _get_or_create_room(group)
    server = room.server_node
    api = BigBlueButtonAPI(server.hostname, server.api_secret)

    try:
        bbb_room = api.create_room(
            meeting_id=room.bbb_meeting_id,
            attendee_secret=User.objects.make_random_password(),
            moderator_secret=User.objects.make_random_password(),
        )
        room.attendee_secret = bbb_room.attendeePW
        room.moderator_secret = bbb_room.moderatorPW
        room.save()
    except RoomAlreadyExistsError:
        pass

    # Connect to room
    redirect_url = api.get_join_url(
        meeting_id=room.bbb_meeting_id,
        password=room.moderator_secret,
        # TODO - temporary, until RODO is sorted out
        join_as='Prowadzący',
        # join_as=moderator.display_name,
        assing_user_id=moderator.uuid,
    )
    logger.debug(f'Mod {moderator.id} start_lesson room {room.id} for {group.display_name}@{server.hostname}')
    return redirect_url
Exemple #4
0
def get_group_active_meeting(group):
    room = Room.objects.filter(group=group).last()
    if room:
        server = room.server_node
        api = BigBlueButtonAPI(server.hostname, server.api_secret)
        if api.is_meeting_running(room.bbb_meeting_id):
            return room

    return None
def get_student_access_url(token):
    """
    Get access url for student, perform checks.
    :param token: Student access token
    :return: redirect url for student or None
    """
    # Token & Student
    try:
        student = Student.objects.get(access_token__iexact=token)
        student.last_accessed = now()
        student.save()
    except Student.DoesNotExist:
        logger.warning(f"Token {token} has no associated student.")
        return None

    # Get meeting details
    try:
        lesson = Room.objects.filter(group=student.group).latest('id')

        bbb_api = BigBlueButtonAPI(lesson.server_node.hostname, lesson.server_node.api_secret)
        room_details, attendees = bbb_api.get_meeting_info(lesson.bbb_meeting_id)
    except Room.DoesNotExist:
        logger.warning(f"Token {token} has no associated lesson.")
        return None
    except BBBRequestFailed as e:
        logger.error(f"Unable to fetch meeting {lesson.bbb_meeting_id} info: {e}")
        return None

    # Check: meeeting not running, remove from pool
    if room_details.running != apibool(True):
        logger.error(f"Meeting {lesson.bbb_meeting_id} is not running.")
        return None

    # Check: max sessions for token
    student_sessions = [a.userID for a in attendees].count(student.uuid)
    if student_sessions >= settings.MAX_STUDENT_TOKEN_SESSIONS:
        logger.warning(
            f"Student {student.uuid} token {token} has max number of active sessions.")
        return None

    try:
        return bbb_api.get_join_url(
            meeting_id=lesson.bbb_meeting_id,
            password=lesson.attendee_secret,
            join_as=student.display_name,
            assing_user_id=student.uuid,
        )
    except BBBRequestFailed as e:
        logger.error(f"Unable to fetch redirect url {lesson.bbb_meeting_id}: {e}")
        return None
Exemple #6
0
    def register_server_node(cls, hostname, api_secret, display_name=None):
        # Verify hostname from allowed domain
        if not hostname.endswith(settings.BBB_DOMAIN_ALLOWED):
            return

        api = BigBlueButtonAPI(hostname, api_secret)
        if api.check_connection():
            try:
                server_node = ServerNode.objects.get(hostname=hostname)
            except ServerNode.DoesNotExist:
                server_node = ServerNode(hostname=hostname,
                                         display_name=display_name or hostname)

            server_node.api_secret = api_secret
            server_node.save()

            return server_node
def _get_or_create_room(group):
    """"Returns active room for a group or assigns new one."""
    room = group.last_meeting_room()

    # Room already exists, got to probe it
    if room:
        server = room.server_node
        api = BigBlueButtonAPI(server.hostname, server.api_secret)

        if api.is_meeting_running(room.bbb_meeting_id):
            logger.info(f'Meeting for group {group} already in progress.')
            return room
        else:
            # Room leftover, clean it from BBB and let assign new
            logger.info(f'Cleaning leftover room for group {group}')
            Room.objects.filter(id=room.id).delete()
            room = None

    # Room not found or not active, assign new from refreshed pool
    if not room:
        server = ServerNode.assign_server(group=group)
        room, _ = Room.objects.get_or_create(server_node=server, group=group)

    return room
Exemple #8
0
 def test_is_meeting_running_with_unreachable_server_not_rises(self):
     """Unmocked, check behavior with non-existent server."""
     api = BigBlueButtonAPI(hostname='this.hostname.is.totally.fake', api_secret='dddd')
     self.assertFalse(api.is_meeting_running('fake_meeting_id'))
Exemple #9
0
 def test_check_create_room_with_unreachable_server_rises(self):
     """Unmocked, check behavior with non-existent server."""
     api = BigBlueButtonAPI(hostname='this.hostname.is.totally.fake', api_secret='dddd')
     self.assertRaises(BBBServerUnreachable, api.create_room, meeting_id='abc', attendee_secret='def', moderator_secret='ghi')
Exemple #10
0
 def test_check_connection_with_unreachable_server_not_rises(self):
     """Unmocked, check behavior with non-existent server."""
     api = BigBlueButtonAPI(hostname='this.hostname.is.totally.fake', api_secret='dddd')
     self.assertFalse(api.check_connection())