def test_unused(self): unused = "*****@*****.**" self.assertTrue(User.email_is_unused(unused)) user = create_user(email=unused) self.assertFalse(User.email_is_unused(unused)) user.is_active = False user.save() self.assertTrue(User.email_is_unused(unused))
def test_unused(self): unused="*****@*****.**" self.assertTrue(User.email_is_unused(unused)) user = create_user(email=unused) self.assertFalse(User.email_is_unused(unused)) user.is_active = False user.save() self.assertTrue(User.email_is_unused(unused))
def forwards(self, orm): "Write your forwards methods here." if not settings.PRODUCTION: for un in SUGGESTED_USERS: try: User.objects.get(username=un) except: u = User(username=un) u.save() u.userinfo = UserInfo() u.userinfo.save()
def user_set_profile(request, comment_id): if comment_id is None: profile_comment = None else: profile_comment = get_object_or_404(Comment, id=comment_id) request.user.userinfo.profile_image = profile_comment if request.user.userinfo.profile_image is not None: request.user.userinfo.bio_text = 'DISABLED' request.user.userinfo.save() User.avatar_by_username(request.user.username).force() return {'comment_id': comment_id}
def user_set_profile(request, comment_id): if comment_id is None: profile_comment = None else: profile_comment = get_object_or_404(Comment, id=comment_id) request.user.userinfo.profile_image = profile_comment if request.user.userinfo.profile_image is not None: request.user.userinfo.bio_text = profile_comment.reply_text request.user.userinfo.save() User.avatar_by_username(request.user.username).force() return {'comment_id': comment_id}
def enabled_for_recipient_action(cls, action, recipient, pending_notification=None, *args, **kwargs): flag = super(EmailChannel, cls).enabled_for_recipient_action(action, recipient, *args, **kwargs) flag = flag and bool(recipient.email) flag = flag and recipient.is_active flag = flag and User.validate_email(recipient.email) if settings.PROJECT == 'drawquest': from drawquest.apps.bounces.models import SuppressedEmail flag = flag and not SuppressedEmail.objects.filter( email=recipient.email).exists() if (flag and pending_notification and hasattr(pending_notification, 'comment') and hasattr(pending_notification.comment, 'thread')): # Did the user mute this thread? The email channel is the only channel # that can mute specific threads. return not pending_notification.comment.thread.op.id in recipient.redis.muted_threads return flag
def clean_new_password2(self): new_password2 = super(PasswordChangeForm, self).clean_new_password2() if not User.validate_password(new_password2): raise forms.ValidationError( 'Sorry, your password is too short. It must be at least {0} characters long.' .format(User.MINIMUM_PASSWORD_LENGTH)) return new_password2
def clean_new_password2(self): new_password2 = super(PasswordChangeForm, self).clean_new_password2() if not User.validate_password(new_password2): raise forms.ValidationError( 'Sorry, your password is too short. It must be at least {0} characters long.'.format( User.MINIMUM_PASSWORD_LENGTH)) return new_password2
def recipients(): # We use a cutoff of 48 hours ago, so that we don't retroactively send this to all existing users, # and so that there's a window large enought to ensure we don't miss a bunch of users if this ever breaks and # doesn't run for a day for whatever reason. cutoff = Services.time.today() - datetime.timedelta(days=2) return User.users_over_one_day_old(cutoff=cutoff).exclude( pk__in=WelcomeEmailRecipient.objects.all().values_list('recipient_id', flat=True))
def enabled_for_actor_action(cls, action, actor, *args, **kwargs): flag = (super(EmailChannel, cls).enabled_for_actor_action( action, actor, *args, **kwargs) and actor.email and User.validate_email(actor.email)) if settings.PROJECT == 'drawquest': from drawquest.apps.bounces.models import SuppressedEmail flag = flag and not SuppressedEmail.objects.filter( email=actor.email).exists() return flag
def avatar_url(user): """ DO NOT CALL THIS FOR ANONYMOUS POSTS. """ key = 'column' avatar, = CachedCall.multicall([ User.avatar_by_username(user.username), ]) if key in avatar: url = avatar[key]['name'] else: key = user.id if user.is_authenticated() else 0 url = _default_avatar_url(key) return url
def enabled_for_actor_action(cls, action, actor, *args, **kwargs): flag = ( super(EmailChannel, cls).enabled_for_actor_action(action, actor, *args, **kwargs) and actor.email and User.validate_email(actor.email) ) if settings.PROJECT == "drawquest": from drawquest.apps.bounces.models import SuppressedEmail flag = flag and not SuppressedEmail.objects.filter(email=actor.email).exists() return flag
def _square_avatar(username, image_type, width, height): avatar, = CachedCall.multicall([ User.avatar_by_username(username), ]) if image_type in avatar: url = avatar[image_type]['name'] size = avatar[image_type] else: key = reduce(lambda acc, x: ord(x) + acc, username, 0) url = _default_avatar_url(key) size = {'width':width, 'height':height} return _avatar(url, size, width, height, username)
def test_users_over_one_day_old(self): with override_service('time', FakeTimeProvider): beginning_count = User.users_over_one_day_old().count() def assert_count(count, cutoff=None): self.assertEqual(beginning_count + count, User.users_over_one_day_old(cutoff=cutoff).count()) assert_count(0) [create_user() for _ in xrange(2)] assert_count(0) Services.time.step(60*60*48) assert_count(2) create_user() assert_count(2) Services.time.step(60*60) assert_count(2) assert_count(0, cutoff=(Services.time.today() - datetime.timedelta(days=1)))
def enabled_for_recipient_action(cls, action, recipient, pending_notification=None, *args, **kwargs): flag = super(EmailChannel, cls).enabled_for_recipient_action(action, recipient, *args, **kwargs) flag = flag and bool(recipient.email) flag = flag and recipient.is_active flag = flag and User.validate_email(recipient.email) if settings.PROJECT == "drawquest": from drawquest.apps.bounces.models import SuppressedEmail flag = flag and not SuppressedEmail.objects.filter(email=recipient.email).exists() if ( flag and pending_notification and hasattr(pending_notification, "comment") and hasattr(pending_notification.comment, "thread") ): # Did the user mute this thread? The email channel is the only channel # that can mute specific threads. return not pending_notification.comment.thread.op.id in recipient.redis.muted_threads return flag
def test_uppercase_disallowed_chars(self): name = u'DİEL' self.assertTrue( 'Usernames can only contain' in User.validate_username(name))
def assert_count(count, cutoff=None): self.assertEqual( beginning_count + count, User.users_over_one_day_old(cutoff=cutoff).count())
def test_used(self): email = '*****@*****.**' self.signup(email=email) dupe = create_user(email=email) self.assertFalse(User.email_is_unused(email))
def user_exists(request, username): """ Returns None if the username is valid and does not exist. """ error_msg = User.validate_username(username or "") if error_msg: raise ServiceError(error_msg)
def test_malformed(self): for email in ['foo@bar', 'foobar.com', 'foo@bar@com']: self.assertFalse(User.validate_email(email))
def test_uppercase_disallowed_chars(self): name = u'DİEL' self.assertTrue('Usernames can only contain' in User.validate_username(name))
def assert_count(count, cutoff=None): self.assertEqual(beginning_count + count, User.users_over_one_day_old(cutoff=cutoff).count())
def test_basic(self): self.assertTrue(User.validate_email('*****@*****.**'))
def recipients(): # We use a cutoff of 48 hours ago, so that we don't retroactively send this to all existing users, # and so that there's a window large enought to ensure we don't miss a bunch of users if this ever breaks and # doesn't run for a day for whatever reason. cutoff = Services.time.today() - datetime.timedelta(days=2) return User.users_over_one_day_old(cutoff=cutoff).exclude(pk__in=WelcomeEmailRecipient.objects.all().values_list('recipient_id', flat=True))
def get_signup_context(request, skip_invite_code=None, template="user/signup.django.html", cookies_to_set={}, cookies_to_delete=[]): """ Returns an error context (or dict) if the signup is not successful. Returns `None` for successful signups. `cookies_to_set` and `cookies_to_delete` should be passed empty so that this functin may append to them. `cookies_to_set` is for session cookies, to tie into after_signup.py / after_signup.js. """ skip_invite_code = skip_invite_code or request.GET.get( 'skip_invite_code', '').lower() bypass_copy = settings.SHORT_CODE_COPY.get(skip_invite_code) skippable_codes = ([ 'dicksoup', 'angelgate', 'friends_and_family', 'herpderp', 'fffffat', 'buzzfeedbrews' ] + settings.SHORT_CODES) login_url = '/login' if request.REQUEST.get('next'): next = request.REQUEST['next'] params = [urllib.urlencode({'next': next})] if request.method == 'POST': next_params = request.POST.get('next_params', '') else: next_params = request.GET.copy() del next_params['next'] next_params = urllib.urlencode(next_params) if next_params: params.append(next_params) login_url = login_url + '?' + u'&'.join(params) try: fb_user, fb_api = util.get_fb_api(request) except NotLoggedIntoFacebookError: fb_user, fb_api = None, None fb_uid = fb_user.get('uid') if fb_user else None fb_invite = None if request.COOKIES.get('fb_message_id'): fb_invite = FacebookInvite.objects.get_or_none( fb_message_id=request.COOKIES.get('fb_message_id')) cookies_to_delete.append('fb_message_id') if not fb_invite and fb_uid: fb_invite = FacebookInvite.get_invite(fb_user.get('uid')) if request.method == 'GET': return locals() username = request.POST.get('username', '') password = request.POST.get('password', '') email = request.POST.get('email', '') if not fb_uid: fb_uid = request.POST.get('facebook_id', None) code = InviteCode.objects.get_or_none(code=request.POST.get('code')) def error(message, context=locals()): context['message'] = message Metrics.signup_form_invalid.record(request) return context if check_rate_limit(request, username): return error( "Too many failed signup attempts. Wait a minute and try again.") if not password: return error("Password required.") if not User.validate_password(password): return error( "Sorry, your password is too short. Please use 5 or more characters." ) error_msg = User.validate_username(username) if error_msg: return error(error_msg) if not User.validate_email(email): return error("Please enter a valid email address.") if not User.email_is_unused(email): return error( "This email address is already in use. Try <a href='/login'>signing in</a> " "or <a href='/password_reset'>resetting</a> your password if you've forgotten it." ) if fb_uid and not UserInfo.facebook_is_unused(fb_uid): return error( "This Facebook account is already in use. Try <a href='/login'>signing in</a> " "or <a href='/password_reset'>resetting</a> your password if you've forgotten it." ) try: user = User.objects.create_user(username, email, password) except IntegrityError: return error("Username taken.") if not fb_uid: fb_uid = None UserInfo(user=user, invite_bypass=skip_invite_code, facebook_id=fb_uid, enable_timeline=True).save() if code: code.invitee = user code.save() if fb_invite: fb_invite.invitee = user fb_invite.save() user = auth.authenticate(username=username, password=password) # Handle following featured groups and optionally one defined by their short code. if skip_invite_code: autofollow = settings.SHORT_CODE_AUTOFOLLOW.get(skip_invite_code) if autofollow: to_follow.append(autofollow) economy.grant_daily_free_stickers(request.user, force=True, count=knobs.SIGNUP_FREE_STICKERS) # Follow the Canvas account. try: user.redis.following.sadd( User.objects.get(username=settings.CANVAS_ACCOUNT_USERNAME).id) except User.DoesNotExist: pass # Logged-out remix? cookie_key, post_data = after_signup.get_posted_comment(request) if post_data: post_comment(request, user, post_data) cookies_to_delete.append(cookie_key) inviter_id = request.session.get('inviter') if inviter_id: user.kv.inviter = inviter_id del request.session['inviter'] inviter = User.objects.get(pk=inviter_id) user.follow(inviter) inviter.follow(user) # DEPRECATED. Use after_signup.py / after_signup.js now instead. extra_info = request.POST.get("info") if extra_info: extra_info = util.loads(extra_info) if extra_info.get('in_flow') == 'yes': fact.record('flow_signup', request, {}) # A user may have come to signup by remixing/replying, and we've got their post data to submit and send them # to. if not post_data: post_data = extra_info.get('post') if post_data: post_comment(request, user, post_data) old_session_key = request.session.session_key def _after_signup(): if fb_api: app_requests = fb_api.get_object('/me/apprequests/').get( 'data', []) for app_request in app_requests: if id in app_request: fb.delete_object(app_request['id']) Metrics.signup.record(request, old_session_key=old_session_key, username=username, email=email) if 'failed_signup' in request.session: del request.session['failed_signup'] Metrics.signup_second_try.record(request) if template == 'signup/_signup_prompt.html': Metrics.signup_prompt.record(request) else: Metrics.signup_main.record(request) bgwork.defer(_after_signup) # auth.login starts a new session and copies the session data from the old one to the new one auth.login(request, user) experiments.migrate_from_request_to_user(request, user)
def get_signup_context(request, skip_invite_code=None, template="user/signup.django.html", cookies_to_set={}, cookies_to_delete=[]): """ Returns an error context (or dict) if the signup is not successful. Returns `None` for successful signups. `cookies_to_set` and `cookies_to_delete` should be passed empty so that this functin may append to them. `cookies_to_set` is for session cookies, to tie into after_signup.py / after_signup.js. """ skip_invite_code = skip_invite_code or request.GET.get('skip_invite_code', '').lower() bypass_copy = settings.SHORT_CODE_COPY.get(skip_invite_code) skippable_codes = (['dicksoup', 'angelgate', 'friends_and_family', 'herpderp', 'fffffat', 'buzzfeedbrews'] + settings.SHORT_CODES) login_url = '/login' if request.REQUEST.get('next'): next = request.REQUEST['next'] params = [urllib.urlencode({'next': next})] if request.method == 'POST': next_params = request.POST.get('next_params', '') else: next_params = request.GET.copy() del next_params['next'] next_params = urllib.urlencode(next_params) if next_params: params.append(next_params) login_url = login_url + '?' + u'&'.join(params) try: fb_user, fb_api = util.get_fb_api(request) except NotLoggedIntoFacebookError: fb_user, fb_api = None, None fb_uid = fb_user.get('uid') if fb_user else None fb_invite = None if request.COOKIES.get('fb_message_id'): fb_invite = FacebookInvite.objects.get_or_none(fb_message_id=request.COOKIES.get('fb_message_id')) cookies_to_delete.append('fb_message_id') if not fb_invite and fb_uid: fb_invite = FacebookInvite.get_invite(fb_user.get('uid')) if request.method == 'GET': return locals() username = request.POST.get('username', '') password = request.POST.get('password', '') email = request.POST.get('email', '') if not fb_uid: fb_uid = request.POST.get('facebook_id', None) def error(message, context=locals()): context['message'] = message Metrics.signup_form_invalid.record(request) return context if check_rate_limit(request, username): return error("Too many failed signup attempts. Wait a minute and try again.") if not password: return error("Password required.") if not User.validate_password(password): return error("Sorry, your password is too short. Please use 5 or more characters.") error_msg = User.validate_username(username) if error_msg: return error(error_msg) if not User.validate_email(email): return error("Please enter a valid email address.") if not User.email_is_unused(email): return error("This email address is already in use. Try <a href='/login'>signing in</a> " "or <a href='/password_reset'>resetting</a> your password if you've forgotten it.") if fb_uid and not UserInfo.facebook_is_unused(fb_uid): return error("This Facebook account is already in use. Try <a href='/login'>signing in</a> " "or <a href='/password_reset'>resetting</a> your password if you've forgotten it.") try: user = User.objects.create_user(username, email, password) except IntegrityError: return error("Username taken.") if not fb_uid: fb_uid = None UserInfo(user=user, invite_bypass=skip_invite_code, facebook_id=fb_uid, enable_timeline=True).save() if fb_invite: fb_invite.invitee = user fb_invite.save() user = auth.authenticate(username=username, password=password) # Handle following featured groups and optionally one defined by their short code. if skip_invite_code: autofollow = settings.SHORT_CODE_AUTOFOLLOW.get(skip_invite_code) if autofollow: to_follow.append(autofollow) economy.grant_daily_free_stickers(request.user, force=True, count=knobs.SIGNUP_FREE_STICKERS) # Follow the Canvas account. try: user.redis.following.sadd(User.objects.get(username=settings.CANVAS_ACCOUNT_USERNAME).id) except User.DoesNotExist: pass # Logged-out remix? cookie_key, post_data = after_signup.get_posted_comment(request) if post_data: post_comment(request, user, post_data) cookies_to_delete.append(cookie_key) inviter_id = request.session.get('inviter') if inviter_id: user.kv.inviter = inviter_id del request.session['inviter'] inviter = User.objects.get(pk=inviter_id) user.follow(inviter) inviter.follow(user) # DEPRECATED. Use after_signup.py / after_signup.js now instead. extra_info = request.POST.get("info") if extra_info: extra_info = util.loads(extra_info) if extra_info.get('in_flow') == 'yes': fact.record('flow_signup', request, {}) # A user may have come to signup by remixing/replying, and we've got their post data to submit and send them # to. if not post_data: post_data = extra_info.get('post') if post_data: post_comment(request, user, post_data) old_session_key = request.session.session_key def _after_signup(): if fb_api: app_requests = fb_api.get_object('/me/apprequests/').get('data', []) for app_request in app_requests: if id in app_request: fb.delete_object(app_request['id']) Metrics.signup.record(request, old_session_key=old_session_key, username=username, email=email) if 'failed_signup' in request.session: del request.session['failed_signup'] Metrics.signup_second_try.record(request) if template == 'signup/_signup_prompt.html': Metrics.signup_prompt.record(request) else: Metrics.signup_main.record(request) bgwork.defer(_after_signup) # auth.login starts a new session and copies the session data from the old one to the new one auth.login(request, user) experiments.migrate_from_request_to_user(request, user)