mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	Support email changes for !avatar syntax.
Significantly modified by tabbott to avoid calling get_user_profile_by_email in bugdown, and have 100% test coverage of the views code. Fixes #2041.
This commit is contained in:
		@@ -37,7 +37,7 @@ from zerver.lib.timeout import timeout, TimeoutExpired
 | 
			
		||||
from zerver.lib.cache import (
 | 
			
		||||
    cache_with_key, cache_get_many, cache_set_many, NotFoundInCache)
 | 
			
		||||
from zerver.lib.url_preview import preview as link_preview
 | 
			
		||||
from zerver.models import Message, Realm
 | 
			
		||||
from zerver.models import Message, Realm, UserProfile, get_user_profile_by_email
 | 
			
		||||
import zerver.lib.alert_words as alert_words
 | 
			
		||||
import zerver.lib.mention as mention
 | 
			
		||||
from zerver.lib.str_utils import force_text, force_str
 | 
			
		||||
@@ -635,10 +635,18 @@ class Avatar(markdown.inlinepatterns.Pattern):
 | 
			
		||||
        # type: (Match[Text]) -> Optional[Element]
 | 
			
		||||
        img = markdown.util.etree.Element('img')
 | 
			
		||||
        email_address = match.group('email')
 | 
			
		||||
        email = email_address.strip().lower()
 | 
			
		||||
        profile_id = None
 | 
			
		||||
 | 
			
		||||
        if db_data is not None:
 | 
			
		||||
            user_dict = db_data['by_email'].get(email)
 | 
			
		||||
            if user_dict is not None:
 | 
			
		||||
                profile_id = user_dict['id']
 | 
			
		||||
 | 
			
		||||
        img.set('class', 'message_body_gravatar')
 | 
			
		||||
        img.set('src', '/avatar/%s?s=30' % (email_address,))
 | 
			
		||||
        img.set('title', email_address)
 | 
			
		||||
        img.set('alt', email_address)
 | 
			
		||||
        img.set('src', '/avatar/{0}?s=30'.format(profile_id or email))
 | 
			
		||||
        img.set('title', email)
 | 
			
		||||
        img.set('alt', email)
 | 
			
		||||
        return img
 | 
			
		||||
 | 
			
		||||
emoji_tree = os.path.join(settings.STATIC_ROOT, "generated", "emoji", "images", "emoji")
 | 
			
		||||
@@ -1350,6 +1358,7 @@ def do_convert(content, message=None, message_realm=None, possible_words=None, s
 | 
			
		||||
        db_data = {'possible_words': possible_words,
 | 
			
		||||
                   'full_names': dict((user['full_name'].lower(), user) for user in realm_users),
 | 
			
		||||
                   'short_names': dict((user['short_name'].lower(), user) for user in realm_users),
 | 
			
		||||
                   'by_email': dict((user['email'].lower(), user) for user in realm_users),
 | 
			
		||||
                   'emoji': message_realm.get_emoji(),
 | 
			
		||||
                   'sent_by_bot': sent_by_bot,
 | 
			
		||||
                   'stream_names': dict((stream['name'], stream) for stream in realm_streams)}
 | 
			
		||||
 
 | 
			
		||||
@@ -896,3 +896,30 @@ class BugdownErrorTests(ZulipTestCase):
 | 
			
		||||
            # handle i18n properly here on some systems.
 | 
			
		||||
            with self.assertRaises(JsonableError):
 | 
			
		||||
                self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, message)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BugdownAvatarTestCase(ZulipTestCase):
 | 
			
		||||
    def test_avatar_with_id(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        sender_user_profile = get_user_profile_by_email("othello@zulip.com")
 | 
			
		||||
        message = Message(sender=sender_user_profile, sending_client=get_client("test"))
 | 
			
		||||
 | 
			
		||||
        user_profile = get_user_profile_by_email("hamlet@zulip.com")
 | 
			
		||||
        msg = '!avatar({0})'.format(user_profile.email)
 | 
			
		||||
        converted = bugdown.convert(msg, message=message)
 | 
			
		||||
        values = {'email': user_profile.email, 'id': user_profile.id}
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            converted,
 | 
			
		||||
            '<p><img alt="{email}" class="message_body_gravatar" src="/avatar/{id}?s=30" title="{email}"></p>'.format(**values))
 | 
			
		||||
 | 
			
		||||
    def test_avatar_of_unregistered_user(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        sender_user_profile = get_user_profile_by_email("othello@zulip.com")
 | 
			
		||||
        message = Message(sender=sender_user_profile, sending_client=get_client("test"))
 | 
			
		||||
 | 
			
		||||
        email = 'fakeuser@example.com'
 | 
			
		||||
        msg = '!avatar({0})'.format(email)
 | 
			
		||||
        converted = bugdown.convert(msg, message=message)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            converted,
 | 
			
		||||
            '<p><img alt="{0}" class="message_body_gravatar" src="/avatar/{0}?s=30" title="{0}"></p>'.format(email))
 | 
			
		||||
 
 | 
			
		||||
@@ -381,6 +381,10 @@ class AvatarTest(UploadSerializeMixin, ZulipTestCase):
 | 
			
		||||
        redirect_url = response['Location']
 | 
			
		||||
        self.assertTrue(redirect_url.endswith(avatar_url(cordelia) + '&foo=bar'))
 | 
			
		||||
 | 
			
		||||
        response = self.client_get("/avatar/%s?foo=bar" % (cordelia.id))
 | 
			
		||||
        redirect_url = response['Location']
 | 
			
		||||
        self.assertTrue(redirect_url.endswith(avatar_url(cordelia) + '&foo=bar'))
 | 
			
		||||
 | 
			
		||||
    def test_non_valid_user_avatar(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ from zerver.lib.validator import check_bool, check_string
 | 
			
		||||
from zerver.lib.users import check_change_full_name, check_full_name
 | 
			
		||||
from zerver.lib.utils import generate_random_token
 | 
			
		||||
from zerver.models import UserProfile, Stream, Realm, Message, get_user_profile_by_email, \
 | 
			
		||||
    email_allowed_for_realm
 | 
			
		||||
    email_allowed_for_realm, get_user_profile_by_id
 | 
			
		||||
from zproject.jinja2 import render_to_response
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -112,12 +112,26 @@ def update_user_backend(request, user_profile, email,
 | 
			
		||||
 | 
			
		||||
    return json_success()
 | 
			
		||||
 | 
			
		||||
def avatar(request, email):
 | 
			
		||||
# TODO: Since eventually we want to support using the same email with
 | 
			
		||||
# different organizations, we'll eventually want this to be a
 | 
			
		||||
# logged-in endpoint so that we can access the realm_id.
 | 
			
		||||
def avatar(request, email_or_id):
 | 
			
		||||
    # type: (HttpRequest, str) -> HttpResponse
 | 
			
		||||
    """Accepts an email address or user ID and returns the avatar"""
 | 
			
		||||
    try:
 | 
			
		||||
        user_profile = get_user_profile_by_email(email)
 | 
			
		||||
        int(email_or_id)
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        get_user_func = get_user_profile_by_email
 | 
			
		||||
    else:
 | 
			
		||||
        get_user_func = get_user_profile_by_id
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        # If there is a valid user account passed in, use its avatar
 | 
			
		||||
        user_profile = get_user_func(email_or_id)
 | 
			
		||||
        url = avatar_url(user_profile)
 | 
			
		||||
    except UserProfile.DoesNotExist:
 | 
			
		||||
        # If there is no such user, treat it as a new gravatar
 | 
			
		||||
        email = email_or_id
 | 
			
		||||
        avatar_source = 'G'
 | 
			
		||||
        avatar_version = 1
 | 
			
		||||
        url = get_avatar_url(avatar_source, email, avatar_version)
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@ i18n_urls = [
 | 
			
		||||
        {'template_name': 'zerver/reset_done.html'}),
 | 
			
		||||
 | 
			
		||||
    # Avatar
 | 
			
		||||
    url(r'^avatar/(?P<email>[\S]+)?', zerver.views.users.avatar, name='zerver.views.users.avatar'),
 | 
			
		||||
    url(r'^avatar/(?P<email_or_id>[\S]+)?', zerver.views.users.avatar, name='zerver.views.users.avatar'),
 | 
			
		||||
 | 
			
		||||
    # Registration views, require a confirmation ID.
 | 
			
		||||
    url(r'^accounts/home/', zerver.views.registration.accounts_home,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user