def test_get_user_by_id_in_realm_including_cross_realm(self) -> None: realm = get_realm('zulip') hamlet = self.example_user('hamlet') othello = self.example_user('othello') bot = self.example_user('welcome_bot') # Pass in the ID of a cross-realm bot and a valid realm cross_realm_bot = get_user_by_id_in_realm_including_cross_realm( bot.id, realm) self.assertEqual(cross_realm_bot.email, bot.email) self.assertEqual(cross_realm_bot.id, bot.id) # Pass in the ID of a cross-realm bot but with a invalid realm, # note that the realm should be irrelevant here cross_realm_bot = get_user_by_id_in_realm_including_cross_realm( bot.id, get_realm('invalid')) self.assertEqual(cross_realm_bot.email, bot.email) self.assertEqual(cross_realm_bot.id, bot.id) # Pass in the ID of a non-cross-realm user with a realm user_profile = get_user_by_id_in_realm_including_cross_realm( othello.id, realm) self.assertEqual(user_profile.email, othello.email) self.assertEqual(user_profile.id, othello.id) # If the realm doesn't match, or if the ID is not that of a # cross-realm bot, UserProfile.DoesNotExist is raised with self.assertRaises(UserProfile.DoesNotExist): get_user_by_id_in_realm_including_cross_realm( hamlet.id, get_realm('invalid'))
def test_get_user_by_id_in_realm_including_cross_realm(self) -> None: realm = get_realm('zulip') hamlet = self.example_user('hamlet') othello = self.example_user('othello') bot = self.example_user('welcome_bot') # Pass in the ID of a cross-realm bot and a valid realm cross_realm_bot = get_user_by_id_in_realm_including_cross_realm( bot.id, realm) self.assertEqual(cross_realm_bot.email, bot.email) self.assertEqual(cross_realm_bot.id, bot.id) # Pass in the ID of a cross-realm bot but with a invalid realm, # note that the realm should be irrelevant here cross_realm_bot = get_user_by_id_in_realm_including_cross_realm( bot.id, None) self.assertEqual(cross_realm_bot.email, bot.email) self.assertEqual(cross_realm_bot.id, bot.id) # Pass in the ID of a non-cross-realm user with a realm user_profile = get_user_by_id_in_realm_including_cross_realm( othello.id, realm) self.assertEqual(user_profile.email, othello.email) self.assertEqual(user_profile.id, othello.id) # If the realm doesn't match, or if the ID is not that of a # cross-realm bot, UserProfile.DoesNotExist is raised with self.assertRaises(UserProfile.DoesNotExist): get_user_by_id_in_realm_including_cross_realm(hamlet.id, None)
def by_group_pm_with(self, query: Query, operand: Union[str, int], maybe_negate: ConditionTransform) -> Query: try: if isinstance(operand, str): narrow_profile = get_user_including_cross_realm(operand, self.user_realm) else: narrow_profile = get_user_by_id_in_realm_including_cross_realm(operand, self.user_realm) except UserProfile.DoesNotExist: raise BadNarrowOperator('unknown user ' + str(operand)) self_recipient_ids = [ recipient_tuple['recipient_id'] for recipient_tuple in Subscription.objects.filter( user_profile=self.user_profile, recipient__type=Recipient.HUDDLE, ).values("recipient_id")] narrow_recipient_ids = [ recipient_tuple['recipient_id'] for recipient_tuple in Subscription.objects.filter( user_profile=narrow_profile, recipient__type=Recipient.HUDDLE, ).values("recipient_id")] recipient_ids = set(self_recipient_ids) & set(narrow_recipient_ids) cond = column("recipient_id").in_(recipient_ids) return query.where(maybe_negate(cond))
def avatar(request: HttpRequest, user_profile: UserProfile, email_or_id: str, medium: bool = False) -> HttpResponse: """Accepts an email address or user ID and returns the avatar""" is_email = False try: int(email_or_id) except ValueError: is_email = True try: realm = user_profile.realm if is_email: avatar_user_profile = get_user_including_cross_realm( email_or_id, realm) else: avatar_user_profile = get_user_by_id_in_realm_including_cross_realm( int(email_or_id), realm) # If there is a valid user account passed in, use its avatar url = avatar_url(avatar_user_profile, medium=medium) except UserProfile.DoesNotExist: # If there is no such user, treat it as a new gravatar email = email_or_id avatar_version = 1 url = get_gravatar_url(email, avatar_version, medium) # We can rely on the url already having query parameters. Because # our templates depend on being able to use the ampersand to # add query parameters to our url, get_avatar_url does '?x=x' # hacks to prevent us from having to jump through decode/encode hoops. assert url is not None assert '?' in url url += '&' + request.META['QUERY_STRING'] return redirect(url)
def avatar(request: HttpRequest, user_profile: UserProfile, email_or_id: str, medium: bool=False) -> HttpResponse: """Accepts an email address or user ID and returns the avatar""" is_email = False try: int(email_or_id) except ValueError: is_email = True try: realm = user_profile.realm if is_email: avatar_user_profile = get_user_including_cross_realm(email_or_id, realm) else: avatar_user_profile = get_user_by_id_in_realm_including_cross_realm(int(email_or_id), realm) # If there is a valid user account passed in, use its avatar url = avatar_url(avatar_user_profile, medium=medium) except UserProfile.DoesNotExist: # If there is no such user, treat it as a new gravatar email = email_or_id avatar_version = 1 url = get_gravatar_url(email, avatar_version, medium) # We can rely on the url already having query parameters. Because # our templates depend on being able to use the ampersand to # add query parameters to our url, get_avatar_url does '?x=x' # hacks to prevent us from having to jump through decode/encode hoops. assert url is not None assert '?' in url url += '&' + request.META['QUERY_STRING'] return redirect(url)
def check_send_typing_notification(sender: UserProfile, user_ids: List[int], operator: str) -> None: realm = sender.realm if sender.id not in user_ids: user_ids.append(sender.id) # If any of the user_ids being sent in are invalid, we will # just reject the whole request, since a partial list of user_ids # can create confusion related to huddles. Plus it's a good # sign that a client is confused (or possibly even malicious) if # we get bad user_ids. user_profiles = [] for user_id in user_ids: try: # We include cross-bot realms as possible recipients, # so that clients can know which huddle conversation # is relevant here. user_profile = get_user_by_id_in_realm_including_cross_realm( user_id, sender.realm) except UserProfile.DoesNotExist: raise JsonableError(_("Invalid user ID {}").format(user_id)) user_profiles.append(user_profile) do_send_typing_notification( realm=realm, sender=sender, recipient_user_profiles=user_profiles, operator=operator, )
def get_user_profiles_by_ids(user_ids: Iterable[int], realm: Realm) -> List[UserProfile]: user_profiles = [] # type: List[UserProfile] for user_id in user_ids: try: user_profile = get_user_by_id_in_realm_including_cross_realm(user_id, realm) except UserProfile.DoesNotExist: raise JsonableError(_("Invalid user ID {}").format(user_id)) user_profiles.append(user_profile) return user_profiles
def get_user_profiles_by_ids(user_ids: Iterable[int], realm: Realm) -> List[UserProfile]: user_profiles = [] # type: List[UserProfile] for user_id in user_ids: try: user_profile = get_user_by_id_in_realm_including_cross_realm(user_id, realm) except UserProfile.DoesNotExist: raise JsonableError(_("Invalid user ID {}".format(user_id))) user_profiles.append(user_profile) return user_profiles
def by_sender(self, query: Query, operand: Union[str, int], maybe_negate: ConditionTransform) -> Query: try: if isinstance(operand, str): sender = get_user_including_cross_realm(operand, self.user_realm) else: sender = get_user_by_id_in_realm_including_cross_realm(operand, self.user_realm) except UserProfile.DoesNotExist: raise BadNarrowOperator('unknown user ' + str(operand)) cond = column("sender_id") == literal(sender.id) return query.where(maybe_negate(cond))
def avatar( request: HttpRequest, maybe_user_profile: Union[UserProfile, AnonymousUser], email_or_id: str, medium: bool = False, ) -> HttpResponse: """Accepts an email address or user ID and returns the avatar""" is_email = False try: int(email_or_id) except ValueError: is_email = True if not maybe_user_profile.is_authenticated: # Allow anonynous access to avatars only if spectators are # enabled in the organization. realm = get_valid_realm_from_request(request) # TODO: Replace with realm.allow_web_public_streams_access() # when the method is available. if not realm.has_web_public_streams(): raise MissingAuthenticationError() # We only allow the ID format for accessing a user's avatar # for spectators. This is mainly for defense in depth, since # email_address_visibility should mean spectators only # interact with fake email addresses anyway. if is_email: raise MissingAuthenticationError() else: realm = maybe_user_profile.realm try: if is_email: avatar_user_profile = get_user_including_cross_realm( email_or_id, realm) else: avatar_user_profile = get_user_by_id_in_realm_including_cross_realm( int(email_or_id), realm) # If there is a valid user account passed in, use its avatar url = avatar_url(avatar_user_profile, medium=medium) except UserProfile.DoesNotExist: # If there is no such user, treat it as a new gravatar email = email_or_id avatar_version = 1 url = get_gravatar_url(email, avatar_version, medium) # We can rely on the URL already having query parameters. Because # our templates depend on being able to use the ampersand to # add query parameters to our url, get_avatar_url does '?x=x' # hacks to prevent us from having to jump through decode/encode hoops. assert url is not None url = append_url_query_string(url, request.META["QUERY_STRING"]) return redirect(url)