Ejemplo n.º 1
0
 def create_comment(self, comment: Comment) -> Result[Comment, str]:
     if self.get_comment(comment.comment_id):
         return Err(f"Comment {comment} already exists")
     elif not self.get_meeting(comment.meeting_id):
         return Err(f"Meeting {comment.meeting_id} does not exist")
     else:
         c = self.connection.cursor()
         if isinstance(comment.author, Instructor):
             term = (
                 str(comment.comment_id),
                 str(comment.meeting_id),
                 comment.author.user_name,
                 None,
                 comment.time_stamp,
                 comment.content_text,
             )
         else:
             term = (
                 str(comment.comment_id),
                 str(comment.meeting_id),
                 None,
                 comment.author.student_number,
                 comment.time_stamp,
                 comment.content_text,
             )
         c.execute(
             "INSERT INTO comments(comment_id, meeting_id, author_if_instructor,"
             " author_if_student, time_stamp, content_text) "
             "VALUES (%s, %s, %s, %s, %s, %s)",
             term,
         )
         self.connection.commit()
         return Ok(comment)
Ejemplo n.º 2
0
def test_create_note(schema, success):
    note = next(fake_note())
    error = Err(fake.pystr())
    context = MagicMock()
    context.api.meeting_api.create_note.return_value = Ok(
        note) if success else error
    query = """
    mutation createNote($meetingId: UUID!, $contentText: String!) {
        createNote(meetingId: $meetingId, contentText: $contentText) {
            noteId
            meetingId
            timeStamp
            contentText
        }
    }
    """
    variables = {
        "meetingId": str(note.meeting_id),
        "contentText": note.content_text
    }
    result = schema.execute(query, context=context, variables=variables)
    if success:
        assert not result.errors
        for attr, val in result.data["createNote"].items():
            expected = getattr(note, to_snake_case(attr))
            if isinstance(expected, UUID):
                expected = str(expected)
            assert expected == val
    else:
        assert error.unwrap_err() in str(result.errors)
    context.api.meeting_api.create_note.assert_called_once_with(
        note.meeting_id, context.user, note.content_text)
Ejemplo n.º 3
0
def test_delete_note(schema, success):
    context = MagicMock()
    note_id = uuid4()
    error = Err(fake.pystr())
    context.user = fake_instructor()
    context.api.meeting_api.delete_note.return_value = Ok(
        note_id) if success else error
    query = """
    mutation deleteNote($noteId: UUID!) {
        deleteNote(noteId: $noteId) {
            noteId
        }
    }
    """

    result = schema.execute(query,
                            context=context,
                            variables={"noteId": str(note_id)})
    if success:
        assert not result.errors
        assert result.data["deleteNote"] == {"noteId": str(note_id)}
    else:
        assert error.unwrap_err() in str(result.errors)
    context.api.meeting_api.delete_note.assert_called_once_with(
        note_id, context.user)
Ejemplo n.º 4
0
 def _check_meeting_user(self, meeting_id: UUID, user: User,
                         error_msg: str) -> Result[None, str]:
     meeting_result = self.meeting_persistence.get_meeting(meeting_id)
     if not meeting_result:
         return Err(f"Meeting with ID: '{meeting_id}' does not exist")
     meeting = meeting_result.unwrap()
     if user not in (meeting.instructor, meeting.student):
         return Err(error_msg)
     return Ok(None)
Ejemplo n.º 5
0
 def verify_student_by_token(self, token: str) -> Result[Student, str]:
     payload_result = self.jwt_authenticator.verify_token(token)
     if payload_result.is_err:
         return payload_result
     payload = payload_result.unwrap()
     student_number = payload.get("id")
     if not student_number:
         return Err("Invalid token")
     return self.get_student(student_number).map_or(
         Ok, (Err("Could not get student")))
Ejemplo n.º 6
0
 def verify_instructor_by_token(self,
                                token: str) -> Result[Instructor, str]:
     payload_result = self.jwt_authenticator.verify_token(token)
     if payload_result.is_err:
         return payload_result
     payload = payload_result.unwrap()
     user_name = payload.get("id")
     if not user_name:
         return Err("Invalid token")
     return self.get_instructor(user_name).map_or(
         Ok, (Err("Could not get instructor")))
Ejemplo n.º 7
0
def get_profile(user_id) -> Result[User, HttpError]:
    parsed_id = validate_int(user_id)
    if not parsed_id:
        return Err(HttpError(400, f'{user_id} is not a valid user ID'))
    user_id = parsed_id.value

    try:
        found_user = User.objects.get(id=user_id)
    except (User.DoesNotExist, OverflowError):
        return Err(HttpError(404, f'User with ID {user_id} does not exist'))

    return Ok(found_user)
Ejemplo n.º 8
0
def delete_request(request_id, user):
    parsed_id = validate_int(request_id)
    if not parsed_id:
        return Err(HttpError(400, f'{parsed_id} is not a valid request ID'))
    try:
        request_to_del = Request.objects.get(id=parsed_id.unwrap())
    except (Request.DoesNotExist, OverflowError):
        return Err(HttpError(404, f'Request with ID {request_id} does not exist'))
    if request_to_del.customer != user:
        return Err(HttpError(403, 'Cannot delete someone else\'s request'))
    Request.objects.delete_request(request_to_del)
    return Ok({})
Ejemplo n.º 9
0
def create_response(valid_data: Dict, user: User):
    request_id = valid_data['request_id']
    try:
        request = Request.objects.get(id=request_id)
    except (Request.DoesNotExist, OverflowError):
        return Err(HttpError(404, f'Request with ID {request_id} does not exist'))
    if user == request.customer:
        return Err(HttpError(400, 'You cannot respond to your own request'))
    if request.response_set.filter(worker=user).exists():
        return Err(HttpError(400, f'You already responded to request with ID {request_id}'))
    response = Response(request=request, worker=user, comment=valid_data['comment'])
    response.save()
    return Ok(request)
Ejemplo n.º 10
0
def test_create_comment(schema, author, success):
    context = MagicMock()
    comment = next(fake_comment())
    error = Err(fake.pystr())
    query = """
    mutation createComment($meetingId: UUID!, $contentText: String!) {
        createComment(meetingId: $meetingId, contentText: $contentText) {
            commentId
            meetingId
            author {
                ... on Instructor {
                    userName
                }
                ... on Student {
                    studentNumber
                }
            }
            timeStamp
            contentText
        }
    }
    """
    context.api.meeting_api.create_comment.return_value = (Ok(comment) if
                                                           success else error)
    variables = {
        "meetingId": str(comment.meeting_id),
        "contentText": comment.content_text,
    }
    result = schema.execute(query, context=context, variables=variables)
    if success:
        assert not result.errors
        for key, val in result.data["createComment"].items():
            if key == "author":
                if isinstance(comment.author, Instructor):
                    assert val["userName"] == comment.author.user_name
                else:
                    assert val[
                        "studentNumber"] == comment.author.student_number
            else:
                expected = getattr(comment, to_snake_case(key))
                if isinstance(expected, UUID):
                    expected = str(expected)
                assert expected == val
    else:
        assert result.errors
        assert error.unwrap_err() in str(result.errors)
    context.api.meeting_api.create_comment.assert_called_once_with(
        comment.meeting_id, context.user, comment.content_text)
Ejemplo n.º 11
0
def create_request(valid_data: Dict, user: User):
    try:
        request = Request.objects.create_request(user, **valid_data)
    except ValidationError as e:
        return Err(HttpError(400, '\n'.join(e.messages)))
    else:
        return Ok(request)
Ejemplo n.º 12
0
def test_create_meeting(meeting_api, success):
    meeting = next(fake_meeting())
    error = Err(fake.pystr())

    def assert_called_correctly(_meeting):
        assert meeting.meeting_id != _meeting.meeting_id
        for attr in (
                "office_hour_id",
                "index",
                "instructor",
                "student",
                "notes",
                "comments",
                "start_time",
        ):
            assert getattr(meeting, attr) == getattr(_meeting, attr)
        return Ok(meeting) if success else error

    meeting_api.meeting_persistence.create_meeting.side_effect = assert_called_correctly
    result = meeting_api.create_meeting(
        meeting.instructor,
        meeting.student,
        meeting.office_hour_id,
        meeting.index,
        meeting.start_time,
    )
    if success:
        assert result.unwrap() == meeting
    else:
        assert result == error
    meeting_api.meeting_persistence.create_meeting.assert_called_once()
Ejemplo n.º 13
0
def find_worker(request_id, user: User):
    parsed_id = validate_int(request_id)
    if not parsed_id:
        return Err(HttpError(400, f'{request_id} is not a valid request ID'))
    request_id = parsed_id.value
    try:
        request = Request.objects.get(id=request_id)
    except (OverflowError, Request.DoesNotExist):
        return Err(HttpError(404, f'Request with {request_id} does not exist'))

    if request.customer != user:
        return Err(HttpError(403, 'You cannot find a worker for another customer\'s request'))
    worker = Request.objects.find_worker(request)
    if worker:
        return Ok(user_converter.to_dict(worker.value))
    return Ok(None)
Ejemplo n.º 14
0
 def delete_meeting(self, meeting_id: uuid.UUID) -> Result[uuid.UUID, str]:
     if not self.get_meeting(meeting_id):
         return Err(f"Meeting {meeting_id} does not exist")
     c = self.connection.cursor()
     c.execute("DELETE FROM meetings WHERE meeting_id=%s", (str(meeting_id),))
     self.connection.commit()
     return Ok(meeting_id)
Ejemplo n.º 15
0
 def delete_course(self, course_code: str) -> Result[str, str]:
     if not self.get_course(course_code):
         return Err(f"Course {course_code} does not exist")
     c = self.connection.cursor()
     c.execute("DELETE FROM courses WHERE course_code=%s", (course_code,))
     self.connection.commit()
     return Ok(course_code)
Ejemplo n.º 16
0
def parse_auth_token(request: Request) -> Result[str, str]:
    """
    Parse a Bearer token from a request header
    Args:
        request:  The HTTP request

    Returns:
        The parsed token
    """
    auth_header = request.headers.get("Authorization")
    if not auth_header:
        return Err("No 'Authorization' header")
    token_list = auth_header.split(" ")
    if len(token_list) != 2 or token_list[0] != "Bearer":
        return Err("Wrong Authorization header format (Bearer TOKEN)")
    return Ok(token_list[1])
Ejemplo n.º 17
0
def test(host="1.1.1.1", port=53, timeout=3) -> Result[None, str]:
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return Ok(None)
    except OSError err:
        return Err(f'No internet connection availiable. {err.strerror} ({err.errno})')
Ejemplo n.º 18
0
 def test_fail(self, mock_course_presistence):
     course_api = CourseApi(mock_course_presistence)
     course = fake_course()
     err = Err(fake.pystr())
     mock_course_presistence.create_course = MagicMock(return_value=err)
     assert course_api.create_course(course.course_code) == err
     mock_course_presistence.create_course.assert_called_once_with(course)
Ejemplo n.º 19
0
 def delete_note(self, note_id: uuid.UUID) -> Result[uuid.UUID, str]:
     if not self.get_note(note_id):
         return Err(f"Note {note_id} does not exist")
     c = self.connection.cursor()
     c.execute("DELETE FROM notes WHERE note_id=%s", (str(note_id),))
     self.connection.commit()
     return Ok(note_id)
Ejemplo n.º 20
0
def validate_json_string(string: AnyStr, schema: Dict, *args,
                         **kwargs) -> Result[Json, str]:
    """Parse a JSON string and validate it"""
    parsed_json = load_json(string)
    if not parsed_json:
        return Err(f'{string} is not a valid json string')
    return validate_json(parsed_json.value, schema, *args, **kwargs)
Ejemplo n.º 21
0
 def delete_comment(self, comment_id: uuid.UUID) -> Result[uuid.UUID, str]:
     if not self.get_comment(comment_id):
         return Err(f"Comment {comment_id} does not exist")
     c = self.connection.cursor()
     c.execute("DELETE FROM comments WHERE comment_id=%s", (str(comment_id),))
     self.connection.commit()
     return Ok(comment_id)
Ejemplo n.º 22
0
def validate_json(json_data: Json, schema: Dict, *args,
                  **kwargs) -> Result[Json, str]:
    """Validate a JSON value"""
    try:
        validate(json_data, schema, *args, **kwargs)
    except ValidationError as e:
        return Err(e.message)
    return Ok(json_data)
Ejemplo n.º 23
0
 def create_course(self, course: Course) -> Result[Course, str]:
     if self.get_course(course.course_code):
         return Err(f"Course {course} already exists")
     c = self.connection.cursor()
     term = (course.course_code,)
     c.execute("INSERT INTO courses VALUES (%s)", term)
     self.connection.commit()
     return Ok(course)
 def delete_student(self, student: Student) -> Result[Student, str]:
     if not self.get_student(student.student_number):
         return Err(f"Student {student} does not exist")
     c = self.connection.cursor()
     term = (student.student_number, )
     c.execute("DELETE FROM students WHERE student_number=%s", term)
     self.connection.commit()
     return Ok(student)
Ejemplo n.º 25
0
    def delete_note(self, note_id: UUID,
                    author: Instructor) -> Result[UUID, str]:
        """
        Deletes note of <note_id>.

        Returns:
            note_id on success
        """
        note_result = self.meeting_persistence.get_note(note_id)
        if not note_result:
            return Err(f"Note with ID: '{note_id}' does not exist")
        meeting_id = note_result.unwrap().meeting_id
        meeting_result = self.meeting_persistence.get_meeting(meeting_id)
        if not meeting_result:
            return Err(f"Meeting with ID: '{meeting_id}' does not exist")
        if author != meeting_result.unwrap().instructor:
            return Err("Cannot delete a note that does not belong to you")
        return self.meeting_persistence.delete_note(note_id)
Ejemplo n.º 26
0
def test_verify_password_fail_at_persistence(password_authenticator):
    user_id, password = fake.pystr(), fake.pystr()
    error = Err(fake.pystr())
    password_authenticator.authentication_persistence.get_password_hash = MagicMock(
        return_value=error)
    assert password_authenticator.verify_password(user_id, password) == error
    password_authenticator.crypto_context.verify_and_update.assert_not_called()
    password_authenticator.authentication_persistence.update_password_hash.assert_not_called(
    )
Ejemplo n.º 27
0
 def delete_instructor(self,
                       instructor: Instructor) -> Result[Instructor, str]:
     if not self.get_instructor(instructor.user_name):
         return Err(f"Instructor {instructor} does not exist")
     c = self.connection.cursor()
     term = (instructor.user_name, )
     c.execute("DELETE FROM instructors WHERE user_name=%s", term)
     self.connection.commit()
     return Ok(instructor)
Ejemplo n.º 28
0
def test_delete_meeting_fail_user_check(meeting_api, user):
    meeting = next(fake_meeting())
    error = Err(fake.pystr())
    meeting_api._check_meeting_user = MagicMock(return_value=error)
    assert meeting_api.delete_meeting(meeting.meeting_id, user) == error
    meeting_api.meeting_persistence.delete_meeting.assert_not_called()
    meeting_api._check_meeting_user.assert_called_once_with(
        meeting.meeting_id, user,
        "Cannot delete meeting that you are not a part of")
Ejemplo n.º 29
0
 def delete_officehour(self, office_hour_id: UUID,
                       mp: MeetingPersistence) -> Result[UUID, str]:
     if not self.get_officehour(office_hour_id, mp):
         return Err(f"OfficeHour {office_hour_id} does not exist")
     c = self.connection.cursor()
     c.execute("DELETE FROM officehours WHERE office_hour_id=%s",
               (office_hour_id, ))
     self.connection.commit()
     return Ok(office_hour_id)
Ejemplo n.º 30
0
 def get_password_hash(self, user_identity: str) -> Result[str, str]:
     c = self.connection.cursor()
     term = (user_identity, )
     c.execute("SELECT * FROM instructors WHERE user_name=%s", term)
     res = c.fetchone()
     if res:
         pass_hash = res[2]
         return Ok(pass_hash)
     else:
         return Err(f"Instructor {user_identity} does not exist")