def test_can_stop_users_from_proceeding_if_not_logged_in(self): """ Several routes depend on a method to get the session user that will throw if no request user is logged in. """ request = self.request_factory.get("/") SessionMiddleware().process_request(request) AuthenticationMiddleware().process_request(request) with self.assertRaises(AuthenticationRequiredException): IdentityService.get_required_session_user(request)
def test_newly_authenticated_user_is_authenticated(self): """ This exists to catch an edge case where a user would be created but could not be authenticated against. Using User.objects.create(...) instead of User.objects.create_user(...) will not throw an error, but the created user can't be authenticated against. Who knows what Django does internally that's different from manually adding a user? Just don't delete this test. """ email = "*****@*****.**" # Django does not include middleware in tests, so add it manually # The request can be nondescript because it's just to satisfy Django request = self.request_factory.get("/") SessionMiddleware().process_request(request) AuthenticationMiddleware().process_request(request) user = IdentityService.sign_up(request, email, "hunter2", "John", "Doe") self.assertTrue(user is not None) self.assertEqual(user.email, email)
def get_team_by_id(self, request): """ Get a team by their ID. """ user = IdentityService.get_required_session_user(request) team_id = re.match(r"/api/teams/([0-9]*)", request.path)[1] team = TeamService.get(team_id) return JsonResponse({"team": serialize_team(team)}, status=200)
def whoami(self, request): """ Return information about the session user, or an empty object if there is no user """ user = IdentityService.get_session_user(request) if user is None: return JsonResponse({}, status=200) return JsonResponse({"user": serialize_user(user)}, status=201)
def get_teams_of_user(self, request): """ Get the teams of which the session user is a member. """ user = IdentityService.get_required_session_user(request) teams = TeamService.get_teams_of_user_with_id(user.id) return JsonResponse( {"teams": [serialize_team(team) for team in teams]}, status=200)
def sign_in(self, request): """ Attempt to initiate an authenticated session """ credentials = re.fullmatch(r"Basic (.*)", request.META["HTTP_AUTHORIZATION"])[1] email, password = base64.b64decode( credentials.encode()).decode().split(":") user = IdentityService.sign_in(request, email=email, password=password) return JsonResponse({"user": serialize_user(user)}, status=200)
def create_team(self, request): """ Create a new team, with the session user as a member. If roles are implemented, this may also include asssigning them as an 'owner'-like role. """ user = IdentityService.get_required_session_user(request) body = json.loads(request.body.decode("utf-8")) name = body["name"] website = body["website"] team = TeamService.create_team_with_user_as_owner(user, name, website) return JsonResponse({"team": serialize_team(team)}, status=201)
def sign_up(self, request): """ Create a new user and start an authenticated session with them """ credentials = re.fullmatch(r"Basic (.*)", request.META["HTTP_AUTHORIZATION"])[1] email, password = base64.b64decode( credentials.encode()).decode().split(":") body = json.loads(request.body.decode("utf-8")) first_name = body["firstName"] if "firstName" in body else "" last_name = body["lastName"] if "lastName" in body else "" user = IdentityService.sign_up(request, email, password, first_name, last_name) return JsonResponse({"user": serialize_user(user)}, status=201)
def get_meetings_of_team(self, request): """ Gets the meetings of a given team. """ user = IdentityService.get_required_session_user(request) team_id = re.match(r"/api/teams/([0-9]*)/meetings", request.path)[1] if not PermissionsService.can_read_meetings_of_team(user.id, team_id): raise ForbiddenException( "You are not allowed to view this team's meetings") meetings = MeetingService.get_meetings_of_team_with_id(team_id) return JsonResponse( {"meetings": [serialize_meeting(meeting) for meeting in meetings]}, status=200, )
def get_items_of_meeting(self, request): """ Obtains the items of a meeting """ user = IdentityService.get_required_session_user(request) meeting_id = int( re.match(r"/api/meetings/([0-9]*)/items", request.path)[1]) meeting = MeetingService.get(meeting_id) if not PermissionsService.can_write_meetings_of_team( user.id, meeting.team.id): raise ForbiddenException( "You are not allowed to view the items of this meeting") items = ItemService.get_items_of_meeting_with_id(meeting_id) return JsonResponse( {"items": [serialize_item(item) for item in items]}, status=200)
def create_meeting_for_team(self, request): """ Creates a meeting for the given team. """ user = IdentityService.get_required_session_user(request) team_id = re.match(r"/api/teams/([0-9]*)/meetings", request.path)[1] body = json.loads(request.body.decode("utf-8")) name = body["name"] venue = body["venue"] if "venue" in body else "" if not PermissionsService.can_write_meetings_of_team(user.id, team_id): raise ForbiddenException( "You are not allowed to create a meeting for this team") meeting = MeetingService.create(team_id, name, venue) return JsonResponse({"meeting": serialize_meeting(meeting)}, status=201)
def post_item_to_meeting(self, request): """ Creates an item within a meeting. """ user = IdentityService.get_required_session_user(request) meeting_id = int( re.match(r"/api/meetings/([0-9]*)/items", request.path)[1]) body = json.loads(request.body.decode("utf-8")) name = body["name"] description = body["description"] meeting = MeetingService.get(meeting_id) if not PermissionsService.can_write_meetings_of_team( user.id, meeting.team.id): raise ForbiddenException( "You are not allowed to create items for this meeting") item = ItemService.create(meeting.id, name, description) return JsonResponse({"item": serialize_item(item)}, status=201)
def get_meeting_by_id(self, request): """ Returns a given meeting and the team that held it, requires the session user be a member of said team. To check team membership (and thus permission to read meetings), it's fine to get the team ID from the meeting itself for now, as retreiving meetings is not a particularly expensive operation. """ user = IdentityService.get_required_session_user(request) meeting_id = int(re.match(r"/api/meetings/([0-9]*)", request.path)[1]) meeting = MeetingService.get(meeting_id) if not PermissionsService.can_read_meetings_of_team( user.id, meeting.team.id): raise ForbiddenException( "You are not allowed to view this meeting") return JsonResponse({"meeting": serialize_meeting(meeting)}, status=200)
def sign_out(self, request): """ End the current session, succeeding even if one does not exist """ IdentityService.sign_out(request) return JsonResponse({}, status=200)