def confirm_change_email(request, activation_key): """Confirm the new email for the user.""" activation_key = activation_key.lower() email_change = get_object_or_404(EmailChange, activation_key=activation_key) u = email_change.user old_email = u.email # Check that this new email isn't a duplicate in the system. new_email = email_change.email duplicate = User.objects.filter(email=new_email).exists() if not duplicate: # Update user's email. u.email = new_email u.save() if settings.DEKIWIKI_ENDPOINT: DekiUserBackend.put_mindtouch_user(u) # Delete the activation profile now, we don't need it anymore. email_change.delete() return jingo.render( request, "users/change_email_complete.html", {"old_email": old_email, "new_email": new_email, "username": u.username, "duplicate": duplicate}, )
def profile_detail(request, username): user = get_object_or_404(User, username=username) profile = UserProfile.objects.get(user=user) try: # HACK: This seems like a dirty violation of the DekiWiki auth package from dekicompat.backends import DekiUserBackend backend = DekiUserBackend() deki_user = backend.get_deki_user(profile.deki_user_id) except: deki_user = None sort_order = request.GET.get('sort', 'created') queryset = Submission.objects.all_sorted(sort_order)\ .exclude(hidden=True)\ .filter(creator=user) return object_list(request, queryset, extra_context=dict( profile_user=user, profile_deki_user=deki_user ), paginate_by=25, allow_empty=True, template_loader=template_loader, template_object_name='submission', template_name='demos/profile_detail.html')
def confirm_change_email(request, activation_key): """Confirm the new email for the user.""" activation_key = activation_key.lower() email_change = get_object_or_404(EmailChange, activation_key=activation_key) u = email_change.user old_email = u.email # Check that this new email isn't a duplicate in the system. new_email = email_change.email duplicate = User.objects.filter(email=new_email).exists() if not duplicate: # Update user's email. u.email = new_email u.save() if settings.DEKIWIKI_ENDPOINT: DekiUserBackend.put_mindtouch_user(u) # Delete the activation profile now, we don't need it anymore. email_change.delete() return render( request, 'users/change_email_complete.html', { 'old_email': old_email, 'new_email': new_email, 'username': u.username, 'duplicate': duplicate })
def test_deki_only_user(self, get_current): if not settings.DEKIWIKI_ENDPOINT: # Skip, if MindTouch API unavailable raise SkipTest() get_current.return_value.domain = 'testserver.com' self.assertRaises(User.DoesNotExist, User.objects.get, username='******') if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = '*****@*****.**' user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % ( settings.DEKIWIKI_ENDPOINT, '=testaccount', settings.DEKIWIKI_APIKEY) requests.put(passwd_url, data='theplanet') r = self.client.post(reverse('users.pw_reset'), {'email': '*****@*****.**'}) eq_(302, r.status_code) eq_('http://testserver/en-US/users/pwresetsent', r['location']) eq_(1, len(mail.outbox)) assert mail.outbox[0].subject.find('Password reset') == 0 u = User.objects.get(username='******') assert mail.outbox[0].body.find('pwreset/%s' % int_to_base36(u.id)) > 0
def test_deki_only_user(self, get_current): get_current.return_value.domain = "testserver.com" self.assertRaises(User.DoesNotExist, User.objects.get, username="******") if not getattr(settings, "DEKIWIKI_MOCK", False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = "*****@*****.**" user_xml = MINDTOUCH_USER_XML % dict( username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor", ) DekiUserBackend.put_mindtouch_user(deki_user_id="=testaccount", user_xml=user_xml) passwd_url = "%s/@api/deki/users/%s/password?apikey=%s" % ( settings.DEKIWIKI_ENDPOINT, "=testaccount", settings.DEKIWIKI_APIKEY, ) requests.put(passwd_url, data="theplanet") r = self.client.post(reverse("users.pw_reset"), {"email": "*****@*****.**"}) eq_(302, r.status_code) eq_("http://testserver/en-US/users/pwresetsent", r["location"]) eq_(1, len(mail.outbox)) assert mail.outbox[0].subject.find("Password reset") == 0 u = User.objects.get(username="******") assert mail.outbox[0].body.find("pwreset/%s" % int_to_base36(u.id)) > 0
def test_get_or_create_user_already_exists(self): backend = DekiUserBackend() deki_user = DekiUser(13, 'hobo', 'Hobo McKee', '*****@*****.**', 'http://www.audienceoftwo.com/pics/upload/v1i6hobo.jpg') user = backend.get_or_create_user(deki_user) self.assertEquals(user.username, 'hobo') self.assertEquals(2, user.id) self.assertEquals(3, user.get_profile().id) self.assertEquals(13, user.get_profile().deki_user_id)
def save(self, *args, **kwargs): skip_mindtouch_put = kwargs.get("skip_mindtouch_put", False) if "skip_mindtouch_put" in kwargs: del kwargs["skip_mindtouch_put"] super(UserProfile, self).save(*args, **kwargs) if skip_mindtouch_put: return from dekicompat.backends import DekiUserBackend DekiUserBackend.put_mindtouch_user(self.user)
def test_get_or_create_user_already_exists(self): backend = DekiUserBackend() deki_user = DekiUser( 13, 'hobo', 'Hobo McKee', '*****@*****.**', 'http://www.audienceoftwo.com/pics/upload/v1i6hobo.jpg') user = backend.get_or_create_user(deki_user) self.assertEquals(user.username, 'hobo') self.assertEquals(2, user.id) self.assertEquals(3, user.get_profile().id) self.assertEquals(13, user.get_profile().deki_user_id)
def save(self, *args, **kwargs): skip_mindtouch_put = kwargs.get('skip_mindtouch_put', False) if 'skip_mindtouch_put' in kwargs: del kwargs['skip_mindtouch_put'] super(UserProfile, self).save(*args, **kwargs) if skip_mindtouch_put: return if not settings.DEKIWIKI_ENDPOINT: # Skip if the MindTouch API is unavailable return from dekicompat.backends import DekiUserBackend DekiUserBackend.put_mindtouch_user(self.user)
def save(self, *args, **kwargs): skip_mindtouch_put = kwargs.get('skip_mindtouch_put', False) if 'skip_mindtouch_put' in kwargs: del kwargs['skip_mindtouch_put'] super(UserProfile, self).save(*args, **kwargs) if skip_mindtouch_put: return if not settings.DEKIWIKI_ENDPOINT: # Skip if the MindTouch API is unavailable return from dekicompat.backends import DekiUserBackend DekiUserBackend.put_mindtouch_user(self.user)
def clean_email(self): try: return super(PasswordResetForm, self).clean_email() except forms.ValidationError as e: email = self.cleaned_data["email"] deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user is None: raise e else: user = DekiUserBackend.get_or_create_user(deki_user) self.users_cache = User.objects.filter(email__iexact=email) return user.email raise e
def test_mindtouch_creds_create_user_and_profile(self, get_current): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() get_current.return_value.domain = 'dev.mo.org' if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = '*****@*****.**' user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % ( settings.DEKIWIKI_ENDPOINT, '=testaccount', settings.DEKIWIKI_APIKEY) requests.put(passwd_url, data='theplanet') self.assertRaises(User.DoesNotExist, User.objects.get, username='******') # Try to log in as a MindTouch user response = self.client.post(reverse('users.login'), { 'username': '******', 'password': '******' }, follow=True) eq_(200, response.status_code) # Ensure there are no validation errors page = pq(response.content) eq_(0, page.find('.errorlist').length, "There should be no validation errors in login") # Login should have auto-created django user u = User.objects.get(username='******') eq_(True, u.is_active) ok_(u.get_profile()) # Login page should show welcome back doc = pq(response.content) eq_('testaccount', doc.find('ul.user-state a:first').text())
def browserid_verify(request): """Process a submitted BrowserID assertion. If valid, try to find either a Django or MindTouch user that matches the verified email address. If neither is found, we bounce to a profile creation page (ie. browserid_register).""" redirect_to = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) redirect_to_failure = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL_FAILURE', reverse('home'))) failure_resp = set_browserid_explained( HttpResponseRedirect(redirect_to_failure)) # If the form's not valid, then this is a failure. form = BrowserIDForm(data=request.POST) if not form.is_valid(): return failure_resp # If the BrowserID assersion is not valid, then this is a failure. result = _verify_browserid(form, request) if not result: return failure_resp # So far, so good: We have a verified email address. But, no user, yet. email = result['email'] user = None # Look for first most recently used Django account, use if found. user = _get_latest_user_with_email(email) # If no Django account, look for a MindTouch account by email. But, only if # there's a MindTouch API available. If found, auto-create the user. if not user and settings.DEKIWIKI_ENDPOINT: deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user: user = DekiUserBackend.get_or_create_user(deki_user) # If we got a user from either the Django or MT paths, complete login for # Django and MT and redirect. if user: user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) return set_browserid_explained( _redirect_with_mindtouch_login(redirect_to, user.username)) # Retain the verified email in a session, redirect to registration page. request.session[SESSION_VERIFIED_EMAIL] = email request.session[SESSION_REDIRECT_TO] = redirect_to return set_browserid_explained( HttpResponseRedirect(reverse('users.browserid_register')))
def browserid_verify(request): """Process a submitted BrowserID assertion. If valid, try to find either a Django or MindTouch user that matches the verified email address. If neither is found, we bounce to a profile creation page (ie. browserid_register).""" redirect_to = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) redirect_to_failure = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL_FAILURE', reverse('home'))) failure_resp = set_browserid_explained( HttpResponseRedirect(redirect_to_failure)) # If the form's not valid, then this is a failure. form = BrowserIDForm(data=request.POST) if not form.is_valid(): return failure_resp # If the BrowserID assersion is not valid, then this is a failure. result = _verify_browserid(form, request) if not result: return failure_resp # So far, so good: We have a verified email address. But, no user, yet. email = result['email'] user = None # Look for first most recently used Django account, use if found. user = _get_latest_user_with_email(email) # If no Django account, look for a MindTouch account by email. But, only if # there's a MindTouch API available. If found, auto-create the user. if not user and settings.DEKIWIKI_ENDPOINT: deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user: user = DekiUserBackend.get_or_create_user(deki_user) # If we got a user from either the Django or MT paths, complete login for # Django and MT and redirect. if user: user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) return set_browserid_explained( _redirect_with_mindtouch_login(redirect_to, user.username)) # Retain the verified email in a session, redirect to registration page. request.session[SESSION_VERIFIED_EMAIL] = email request.session[SESSION_REDIRECT_TO] = redirect_to return set_browserid_explained( HttpResponseRedirect(reverse('users.browserid_register')))
def test_valid_assertion_with_mindtouch_user(self, _verify_browserid): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() mt_email = '*****@*****.**' _verify_browserid.return_value = {'email': mt_email} # Probably overkill but let's be sure we're testing the right thing. try: User.objects.get(email=mt_email) ok_(False, "The MindTouch user shouldn't exist in Django yet.") except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) deki_user = DekiUserBackend.get_deki_user_by_email(mt_email) ok_(deki_user is not None, "The MindTouch user should exist") # Posting the fake assertion to browserid_verify should work, with the # actual verification method mocked out. resp = self.client.post( reverse('users.browserid_verify', locale='en-US'), {'assertion': 'PRETENDTHISISVALID'}) eq_(302, resp.status_code) ok_('SUCCESS' in resp['Location']) # The session should look logged in, now. ok_('_auth_user_id' in self.client.session.keys()) eq_('django_browserid.auth.BrowserIDBackend', self.client.session.get('_auth_user_backend', '')) # And, after all the above, there should be a Django user now. try: User.objects.get(email=mt_email) except User.DoesNotExist: ok_(False, "The MindTouch user should exist in Django now.")
def test_mindtouch_creds_create_user_and_profile(self, get_current): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() get_current.return_value.domain = "dev.mo.org" if not getattr(settings, "DEKIWIKI_MOCK", False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = "*****@*****.**" user_xml = MINDTOUCH_USER_XML % dict( username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor", ) DekiUserBackend.put_mindtouch_user(deki_user_id="=testaccount", user_xml=user_xml) passwd_url = "%s/@api/deki/users/%s/password?apikey=%s" % ( settings.DEKIWIKI_ENDPOINT, "=testaccount", settings.DEKIWIKI_APIKEY, ) requests.put(passwd_url, data="theplanet") self.assertRaises(User.DoesNotExist, User.objects.get, username="******") # Try to log in as a MindTouch user response = self.client.post( reverse("users.login"), {"username": "******", "password": "******"}, follow=True ) eq_(200, response.status_code) # Ensure there are no validation errors page = pq(response.content) eq_(0, page.find(".errorlist").length, "There should be no validation errors in login") # Login should have auto-created django user u = User.objects.get(username="******") eq_(True, u.is_active) ok_(u.get_profile()) # Login page should show welcome back doc = pq(response.content) eq_("testaccount", doc.find("ul.user-state a:first").text())
def clean_username(self): username = self.cleaned_data.get('username') # check deki for existing user (it needs = in front of name) deki_user = DekiUserBackend.get_deki_user('='+username) if deki_user is not None: raise forms.ValidationError(_('The username you entered already exists.')) return username
def _redirect_with_mindtouch_login(next_url, username, password=None): resp = HttpResponseRedirect(next_url) authtoken = DekiUserBackend.mindtouch_login(username, password, force=True) if authtoken: resp.set_cookie('authtoken', authtoken) return resp
def clean_email(self): try: return super(PasswordResetForm, self).clean_email() except forms.ValidationError as e: if not settings.DEKIWIKI_ENDPOINT: # Skip MindTouch API, if unavailable. raise e email = self.cleaned_data["email"] deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user is None: raise e else: user = DekiUserBackend.get_or_create_user(deki_user) self.users_cache = User.objects.filter(email__iexact=email) return user.email raise e
def clean_email(self): try: return super(PasswordResetForm, self).clean_email() except forms.ValidationError as e: if not settings.DEKIWIKI_ENDPOINT: # Skip MindTouch API, if unavailable. raise e email = self.cleaned_data["email"] deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user is None: raise e else: user = DekiUserBackend.get_or_create_user(deki_user) self.users_cache = User.objects.filter(email__iexact=email) return user.email raise e
def deki_user(self): if not self._deki_user: # Need to find the DekiUser corresponding to the ID from dekicompat.backends import DekiUserBackend self._deki_user = (DekiUserBackend().get_deki_user( self.deki_user_id)) return self._deki_user
def test_valid_assertion_with_mindtouch_user(self, _verify_browserid): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() mt_email = "*****@*****.**" _verify_browserid.return_value = {"email": mt_email} # Probably overkill but let's be sure we're testing the right thing. try: User.objects.get(email=mt_email) ok_(False, "The MindTouch user shouldn't exist in Django yet.") except User.DoesNotExist: pass if not getattr(settings, "DEKIWIKI_MOCK", False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API user_xml = MINDTOUCH_USER_XML % dict( username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor", ) DekiUserBackend.put_mindtouch_user(deki_user_id="=testaccount", user_xml=user_xml) deki_user = DekiUserBackend.get_deki_user_by_email(mt_email) ok_(deki_user is not None, "The MindTouch user should exist") # Posting the fake assertion to browserid_verify should work, with the # actual verification method mocked out. resp = self.client.post(reverse("users.browserid_verify", locale="en-US"), {"assertion": "PRETENDTHISISVALID"}) eq_(302, resp.status_code) ok_("SUCCESS" in resp["Location"]) # The session should look logged in, now. ok_("_auth_user_id" in self.client.session.keys()) eq_("django_browserid.auth.BrowserIDBackend", self.client.session.get("_auth_user_backend", "")) # And, after all the above, there should be a Django user now. try: User.objects.get(email=mt_email) except User.DoesNotExist: ok_(False, "The MindTouch user should exist in Django now.")
def _redirect_with_mindtouch_login(next_url, username, password=None): resp = HttpResponseRedirect(next_url) if not settings.DEKIWIKI_ENDPOINT: return resp authtoken = DekiUserBackend.mindtouch_login(username, password, force=True) if authtoken: resp.set_cookie('authtoken', authtoken) return resp
def _redirect_with_mindtouch_login(next_url, username, password=None): resp = HttpResponseRedirect(next_url) if not settings.DEKIWIKI_ENDPOINT: return resp authtoken = DekiUserBackend.mindtouch_login(username, password, force=True) if authtoken: resp.set_cookie("authtoken", authtoken) return resp
def clean_username(self): username = self.cleaned_data.get("username") if settings.DEKIWIKI_ENDPOINT: # Check deki for existing user (it needs = in front of name), but # only if the API is available. deki_user = DekiUserBackend.get_deki_user("=" + username) if deki_user is not None: raise forms.ValidationError(_("The username you entered" " already exists.")) return username
def deki_user(self): if not settings.DEKIWIKI_ENDPOINT: # There is no deki_user, if the MindTouch API is disabled. return None if not self._deki_user: # Need to find the DekiUser corresponding to the ID from dekicompat.backends import DekiUserBackend self._deki_user = (DekiUserBackend().get_deki_user( self.deki_user_id)) return self._deki_user
def clean_username(self): username = self.cleaned_data.get('username') if settings.DEKIWIKI_ENDPOINT: # Check deki for existing user (it needs = in front of name), but # only if the API is available. deki_user = DekiUserBackend.get_deki_user('=' + username) if deki_user is not None: raise forms.ValidationError( _('The username you entered already exists.')) return username
def test_valid_assertion_with_mindtouch_user(self, _verify_browserid): mt_email = '*****@*****.**' _verify_browserid.return_value = {'email': mt_email} # Probably overkill but let's be sure we're testing the right thing. try: User.objects.get(email=mt_email) ok_(False, "The MindTouch user shouldn't exist in Django yet.") except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) deki_user = DekiUserBackend.get_deki_user_by_email(mt_email) ok_(deki_user is not None, "The MindTouch user should exist") # Posting the fake assertion to browserid_verify should work, with the # actual verification method mocked out. resp = self.client.post(reverse('users.browserid_verify', locale='en-US'), {'assertion': 'PRETENDTHISISVALID'}) eq_(302, resp.status_code) ok_('SUCCESS' in resp['Location']) # The session should look logged in, now. ok_('_auth_user_id' in self.client.session.keys()) eq_('django_browserid.auth.BrowserIDBackend', self.client.session.get('_auth_user_backend', '')) # And, after all the above, there should be a Django user now. try: User.objects.get(email=mt_email) except User.DoesNotExist: ok_(False, "The MindTouch user should exist in Django now.")
def test_mindtouch_creds_create_user_and_profile(self, get_current): get_current.return_value.domain = 'dev.mo.org' if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = '*****@*****.**' user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % ( settings.DEKIWIKI_ENDPOINT, '=testaccount', settings.DEKIWIKI_APIKEY) requests.put(passwd_url, data='theplanet') self.assertRaises(User.DoesNotExist, User.objects.get, username='******') # Try to log in as a MindTouch user response = self.client.post(reverse('users.login'), {'username': '******', 'password': '******'}, follow=True) eq_(200, response.status_code) # Ensure there are no validation errors page = pq(response.content) eq_(0, page.find('.errorlist').length, "There should be no validation errors in login") # Login should have auto-created django user u = User.objects.get(username='******') eq_(True, u.is_active) ok_(u.get_profile()) # Login page should show welcome back doc = pq(response.content) eq_('testaccount', doc.find('ul.user-state a:first').text())
def create_inactive_user(self, username, password, email): """ Create a new, inactive ``User`` and ``Profile``, generates a ``RegistrationProfile`` and email its activation key to the ``User``, returning the new ``User``. """ new_user = User.objects.create_user(username, email, password) new_user.is_active = False new_user.save() profile = UserProfile.objects.create(user=new_user) try: deki_user = DekiUserBackend.post_mindtouch_user(new_user) except MindTouchAPIError, e: new_user.delete() raise e
def create_inactive_user(self, username, password, email): """ Create a new, inactive ``User`` and ``Profile``, generates a ``RegistrationProfile`` and email its activation key to the ``User``, returning the new ``User``. """ new_user = User.objects.create_user(username, email, password) new_user.is_active = False new_user.save() profile = UserProfile.objects.create(user=new_user) try: deki_user = DekiUserBackend.post_mindtouch_user(new_user) except MindTouchAPIError, e: new_user.delete() raise e
def get_django_user_id_for_deki_id(self, deki_user_id): """Given a Deki user ID, come up with a Django user object whether we need to migrate it first or just fetch it.""" # If we don't already have this Deki user cached, look up or migrate if deki_user_id not in self.user_ids: # Look up the user straight from the database self.cur.execute("SELECT * FROM users AS u WHERE u.user_id = %s", (deki_user_id,)) r = list(self._query_dicts(self.cur)) if not len(r): # HACK: If, for some reason the user is missing from MindTouch, # just put and use the superuser. Seems to happen mainly for # user #0, which is probably superuser anyway. return self.get_superuser_id() # Build a DekiUser object from the database record, and make sure # it's active. user = r[0] deki_user = DekiUser(id=user['user_id'], username=user['user_name'], fullname=user['user_real_name'], email=user['user_email'], gravatar='',) deki_user.is_active = True # Scan user grants for admin roles to set Django flags. self.cur.execute("""SELECT * FROM user_grants AS ug WHERE user_id = %s""", (deki_user_id,)) is_admin = False for rg in self._query_dicts(self.cur): if rg['role_id'] in self.admin_role_ids: is_admin = True deki_user.is_superuser = deki_user.is_staff = is_admin # Finally get/create Django user and cache it. user = DekiUserBackend.get_or_create_user(deki_user, sync_attrs=[]) self.user_ids[deki_user_id] = user.pk return self.user_ids[deki_user_id]
def create_inactive_user(self, username, password, email): """ Create a new, inactive ``User`` and ``Profile``, generates a ``RegistrationProfile`` and email its activation key to the ``User``, returning the new ``User``. """ new_user = User.objects.create_user(username, email, password) new_user.is_active = False new_user.save() profile = UserProfile.objects.create(user=new_user) deki_user = DekiUserBackend.post_mindtouch_user(new_user) profile.deki_user_id = deki_user.id profile.save() registration_profile = self.create_profile(new_user) self.send_confirmation_email(registration_profile) return new_user
def test_valid_assertion_with_new_account_creation(self, _verify_browserid): new_username = '******' new_email = '*****@*****.**' _verify_browserid.return_value = {'email': new_email} try: user = User.objects.get(email=new_email) ok_(False, "User for email should not yet exist") except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: When not mocking the MindTouch API, ensure that there's no # leftover user with the same name & email as what we want to # register import random rand_num = random.randint(0, 1000000) user_xml = MINDTOUCH_USER_XML % dict( username="******" % (new_username, rand_num), email="%s_%s" % (rand_num, new_email), fullname="", status="inactive", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user( deki_user_id='=%s' % new_username, user_xml=user_xml) # Sign in with a verified email, but with no existing account resp = self.client.post(reverse('users.browserid_verify', locale='en-US'), {'assertion': 'PRETENDTHISISVALID'}) eq_(302, resp.status_code) # This should be a redirect to the BrowserID registration page. redir_url = resp['Location'] reg_url = reverse('users.browserid_register', locale='en-US') ok_(reg_url in redir_url) # And, as part of the redirect, the verified email address should be in # our session now. ok_(SESSION_VERIFIED_EMAIL in self.client.session.keys()) verified_email = self.client.session[SESSION_VERIFIED_EMAIL] eq_(new_email, verified_email) # Grab the redirect, assert that there's a create_user form present resp = self.client.get(redir_url) page = pq(resp.content) form = page.find('form#create_user') eq_(1, form.length) # There should be no error lists on first load eq_(0, page.find('.errorlist').length) # Submit the create_user form, with a chosen username resp = self.client.post(redir_url, {'username': '******', 'action': 'register'}) # The submission should result in a redirect to the session's redirect # value eq_(302, resp.status_code) redir_url = resp['Location'] ok_('SUCCESS' in redir_url) # The session should look logged in, now. ok_('_auth_user_id' in self.client.session.keys()) eq_('django_browserid.auth.BrowserIDBackend', self.client.session.get('_auth_user_backend', '')) if settings.DEKIWIKI_ENDPOINT: ok_(self.client.cookies.get('authtoken'), 'Should have set ' 'authtoken cookie for ' 'MindTouch') # Ensure that the user was created, and with the submitted username and # verified email address try: user = User.objects.get(email=new_email) eq_(new_username, user.username) eq_(new_email, user.email) except User.DoesNotExist: ok_(False, "New user should have been created")
def browserid_register(request): """Handle user creation when assertion is valid, but no existing user""" statsd_waffle_incr('users.browserid_register', 'signin_metrics') redirect_to = request.session.get(SESSION_REDIRECT_TO, getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) email = request.session.get(SESSION_VERIFIED_EMAIL, None) if not email: # This is pointless without a verified email. return HttpResponseRedirect(redirect_to) # Set up the initial forms register_form = BrowserIDRegisterForm() login_form = AuthenticationForm() if request.method == 'POST': statsd_waffle_incr('users.browserid_register.POST', 'signin_metrics') # If the profile creation form was submitted... if 'register' == request.POST.get('action', None): register_form = BrowserIDRegisterForm(request.POST) if register_form.is_valid(): try: # If the registration form is valid, then create a new # Django user, a new MindTouch user, and link the two # together. # TODO: This all belongs in model classes username = register_form.cleaned_data['username'] user = User.objects.create(username=username, email=email) user.set_unusable_password() user.save() profile = UserProfile.objects.create(user=user) if settings.DEKIWIKI_ENDPOINT: deki_user = DekiUserBackend.post_mindtouch_user(user) profile.deki_user_id = deki_user.id profile.save() user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) # Bounce to the newly created profile page, since the user # might want to review & edit. statsd_waffle_incr('users.browserid_register.POST.SUCCESS', 'signin_metrics') redirect_to = request.session.get(SESSION_REDIRECT_TO, profile.get_absolute_url()) return set_browserid_explained( _redirect_with_mindtouch_login(redirect_to, user.username)) except MindTouchAPIError: if user: user.delete() return render(request, '500.html', {'error_message': "We couldn't " "register a new account at this time. " "Please try again later."}) # HACK: Pretend the session was modified. Otherwise, the data disappears # for the next request. request.session.modified = True return render(request, 'users/browserid_register.html', {'login_form': login_form, 'register_form': register_form})
def test_valid_assertion_with_new_account_creation(self, _verify_browserid): new_username = '******' new_email = '*****@*****.**' _verify_browserid.return_value = {'email': new_email} try: user = User.objects.get(email=new_email) ok_(False, "User for email should not yet exist") except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: When not mocking the MindTouch API, ensure that there's no # leftover user with the same name & email as what we want to # register import random rand_num = random.randint(0, 1000000) user_xml = MINDTOUCH_USER_XML % dict(username="******" % (new_username, rand_num), email="%s_%s" % (rand_num, new_email), fullname="", status="inactive", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=%s' % new_username, user_xml=user_xml) # Sign in with a verified email, but with no existing account resp = self.client.post( reverse('users.browserid_verify', locale='en-US'), {'assertion': 'PRETENDTHISISVALID'}) eq_(302, resp.status_code) # This should be a redirect to the BrowserID registration page. redir_url = resp['Location'] reg_url = reverse('users.browserid_register', locale='en-US') ok_(reg_url in redir_url) # And, as part of the redirect, the verified email address should be in # our session now. ok_(SESSION_VERIFIED_EMAIL in self.client.session.keys()) verified_email = self.client.session[SESSION_VERIFIED_EMAIL] eq_(new_email, verified_email) # Grab the redirect, assert that there's a create_user form present resp = self.client.get(redir_url) page = pq(resp.content) form = page.find('form#create_user') eq_(1, form.length) # There should be no error lists on first load eq_(0, page.find('.errorlist').length) # Submit the create_user form, with a chosen username resp = self.client.post(redir_url, { 'username': '******', 'action': 'register' }) # The submission should result in a redirect to the session's redirect # value eq_(302, resp.status_code) redir_url = resp['Location'] ok_('SUCCESS' in redir_url) # The session should look logged in, now. ok_('_auth_user_id' in self.client.session.keys()) eq_('django_browserid.auth.BrowserIDBackend', self.client.session.get('_auth_user_backend', '')) if settings.DEKIWIKI_ENDPOINT: ok_(self.client.cookies.get('authtoken'), 'Should have set ' 'authtoken cookie for ' 'MindTouch') # Ensure that the user was created, and with the submitted username and # verified email address try: user = User.objects.get(email=new_email) eq_(new_username, user.username) eq_(new_email, user.email) except User.DoesNotExist: ok_(False, "New user should have been created")
def test_profile_edit_language_saves_to_mindtouch(self, get_current): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() get_current.return_value.domain = 'dev.mo.org' try: user = User.objects.get(username='******') user.delete() except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = '*****@*****.**' user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % ( settings.DEKIWIKI_ENDPOINT, '=testaccount', settings.DEKIWIKI_APIKEY) requests.put(passwd_url, data='theplanet') # log in as a MindTouch user to create django user & profile response = self.client.post(reverse('users.login', locale='en-US'), {'username': '******', 'password': '******'}, follow=True) eq_(200, response.status_code) user = User.objects.get(username='******') profile = UserProfile.objects.get(user=user) ok_(profile) # use profile edit to change language url = reverse('devmo.views.profile_edit', args=(user.username,)) r = self.client.get(url, follow=True) eq_(200, r.status_code, 'Profile should be found.') doc = pq(r.content) # Scrape out the existing significant form field values. form = dict() for fn in ('email', 'fullname', 'title', 'organization', 'location', 'locale', 'timezone', 'irc_nickname', 'bio', 'interests'): form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val() # Fill out the form with websites. form.update({'locale': 'nl'}) form.update({'timezone': 'Europe/Amsterdam'}) # Submit the form, verify redirect to profile detail r = self.client.post(url, form, follow=True) doc = pq(r.content) eq_(1, doc.find('#profile-head').length) p = UserProfile.objects.get(user=user) # Verify locale saved in the profile. eq_('nl', p.locale) # Verify the saved locale appears in the editing form url = reverse('devmo.views.profile_edit', args=(user.username,)) r = self.client.get(url, follow=True) doc = pq(r.content) ok_('nl', doc.find('#profile-edit select#id_locale option[value="nl"]' '[selected="selected"]')) # TODO: Mock this part out... """
def test_unicode_mindtouch_login(self): u_str = u'\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9' authtoken = DekiUserBackend.mindtouch_login('user', u_str) eq_('authtoken_value', authtoken)
def browserid_register(request): """Handle user creation when assertion is valid, but no existing user""" statsd_waffle_incr('users.browserid_register', 'signin_metrics') redirect_to = request.session.get(SESSION_REDIRECT_TO, getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) email = request.session.get(SESSION_VERIFIED_EMAIL, None) if not email: # This is pointless without a verified email. return HttpResponseRedirect(redirect_to) # Set up the initial forms register_form = BrowserIDRegisterForm() login_form = AuthenticationForm() if request.method == 'POST': statsd_waffle_incr('users.browserid_register.POST', 'signin_metrics') # If the profile creation form was submitted... if 'register' == request.POST.get('action', None): register_form = BrowserIDRegisterForm(request.POST) if register_form.is_valid(): try: # If the registration form is valid, then create a new # Django user, a new MindTouch user, and link the two # together. # TODO: This all belongs in model classes username = register_form.cleaned_data['username'] user = User.objects.create(username=username, email=email) user.set_unusable_password() user.save() profile = UserProfile.objects.create(user=user) if settings.DEKIWIKI_ENDPOINT: deki_user = DekiUserBackend.post_mindtouch_user(user) profile.deki_user_id = deki_user.id profile.save() user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) # Bounce to the newly created profile page, since the user # might want to review & edit. statsd_waffle_incr('users.browserid_register.POST.SUCCESS', 'signin_metrics') redirect_to = request.session.get(SESSION_REDIRECT_TO, profile.get_absolute_url()) return set_browserid_explained( _redirect_with_mindtouch_login(redirect_to, user.username)) except MindTouchAPIError: if user: user.delete() return jingo.render(request, '500.html', {'error_message': "We couldn't " "register a new account at this time. " "Please try again later."}) # HACK: Pretend the session was modified. Otherwise, the data disappears # for the next request. request.session.modified = True return jingo.render(request, 'users/browserid_register.html', {'login_form': login_form, 'register_form': register_form})
def test_profile_edit_language_saves_to_mindtouch(self, get_current): if not settings.DEKIWIKI_ENDPOINT: # Don't even bother with this test, if there's no MindTouch API raise SkipTest() get_current.return_value.domain = 'dev.mo.org' try: user = User.objects.get(username='******') user.delete() except User.DoesNotExist: pass if not getattr(settings, 'DEKIWIKI_MOCK', False): # HACK: Ensure that expected user details are in MindTouch when not # mocking the API mt_email = '*****@*****.**' user_xml = MINDTOUCH_USER_XML % dict(username="******", email=mt_email, fullname="None", status="active", language="", timezone="-08:00", role="Contributor") DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount', user_xml=user_xml) passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % ( settings.DEKIWIKI_ENDPOINT, '=testaccount', settings.DEKIWIKI_APIKEY) requests.put(passwd_url, data='theplanet') # log in as a MindTouch user to create django user & profile response = self.client.post(reverse('users.login', locale='en-US'), { 'username': '******', 'password': '******' }, follow=True) eq_(200, response.status_code) user = User.objects.get(username='******') profile = UserProfile.objects.get(user=user) ok_(profile) # use profile edit to change language url = reverse('devmo.views.profile_edit', args=(user.username, )) r = self.client.get(url, follow=True) eq_(200, r.status_code, 'Profile should be found.') doc = pq(r.content) # Scrape out the existing significant form field values. form = dict() for fn in ('email', 'fullname', 'title', 'organization', 'location', 'locale', 'timezone', 'irc_nickname', 'bio', 'interests'): form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val() # Fill out the form with websites. form.update({'locale': 'nl'}) form.update({'timezone': 'Europe/Amsterdam'}) # Submit the form, verify redirect to profile detail r = self.client.post(url, form, follow=True) doc = pq(r.content) eq_(1, doc.find('#profile-head').length) p = UserProfile.objects.get(user=user) # Verify locale saved in the profile. eq_('nl', p.locale) # Verify the saved locale appears in the editing form url = reverse('devmo.views.profile_edit', args=(user.username, )) r = self.client.get(url, follow=True) doc = pq(r.content) ok_( 'nl', doc.find('#profile-edit select#id_locale option[value="nl"]' '[selected="selected"]')) # TODO: Mock this part out... """
def browserid_verify(request): """Process a submitted BrowserID assertion. If valid, try to find either a Django or MindTouch user that matches the verified email address. If neither is found, we bounce to a profile creation page (ie. browserid_register).""" redirect_to = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) redirect_to_failure = (_clean_next_url(request) or getattr(settings, 'LOGIN_REDIRECT_URL_FAILURE', reverse('home'))) failure_resp = set_browserid_explained( HttpResponseRedirect(redirect_to_failure)) # If the form's not valid, then this is a failure. form = BrowserIDForm(data=request.POST) if not form.is_valid(): return failure_resp # If the BrowserID assersion is not valid, then this is a failure. result = _verify_browserid(form, request) if not result: return failure_resp # So far, so good: We have a verified email address. But, no user, yet. email = result['email'] user = None # TODO: This user lookup and create stuff probably belongs in the model: # If user is authenticated, change their email if request.user.is_authenticated(): user = _get_latest_user_with_email(email) # If a user with the email already exists, don't change if user and user != request.user: messages.error(request, 'That email already belongs to another ' 'user.') return set_browserid_explained( HttpResponseRedirect(reverse('users.change_email'))) else: user = request.user user.email = email user.save() redirect_to = reverse('devmo_profile_edit', args=[user.username, ]) else: # Look for first most recently used Django account, use if found. user = _get_latest_user_with_email(email) # If no Django account, look for a MindTouch account by email. # If found, auto-create the user. if not user: deki_user = DekiUserBackend.get_deki_user_by_email(email) if deki_user: user = DekiUserBackend.get_or_create_user(deki_user) # If we got a user from either the Django or MT paths, complete login for # Django and MT and redirect. if user: user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) return set_browserid_explained( _redirect_with_mindtouch_login(redirect_to, user.username)) # Retain the verified email in a session, redirect to registration page. request.session[SESSION_VERIFIED_EMAIL] = email request.session[SESSION_REDIRECT_TO] = redirect_to return set_browserid_explained( HttpResponseRedirect(reverse('users.browserid_register')))
def test_unicode_mindtouch_login(self): u_str = u'\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9' authtoken = DekiUserBackend.mindtouch_login('user', u_str) eq_('authtoken_value', authtoken)
def test_good_mindtouch_login(self): authtoken = DekiUserBackend.mindtouch_login('user', 'pass') eq_('authtoken_value', authtoken)
def test_good_mindtouch_login(self): authtoken = DekiUserBackend.mindtouch_login('user', 'pass') eq_('authtoken_value', authtoken)
def browserid_register(request): """Handle user creation when assertion is valid, but no existing user""" redirect_to = request.session.get(SESSION_REDIRECT_TO, getattr(settings, 'LOGIN_REDIRECT_URL', reverse('home'))) email = request.session.get(SESSION_VERIFIED_EMAIL, None) if not email: # This is pointless without a verified email. return HttpResponseRedirect(redirect_to) # Set up the initial forms register_form = BrowserIDRegisterForm() login_form = AuthenticationForm() if request.method == 'POST': # If the profile creation form was submitted... if 'register' == request.POST.get('action', None): register_form = BrowserIDRegisterForm(request.POST) if register_form.is_valid(): # If the registration form is valid, then create a new Django # user, a new MindTouch user, and link the two together. # TODO: This all belongs in model classes username = register_form.cleaned_data['username'] user = User.objects.create(username=username, email=email) user.set_unusable_password() user.save() profile = UserProfile.objects.create(user=user) deki_user = DekiUserBackend.post_mindtouch_user(user) profile.deki_user_id = deki_user.id profile.save() user.backend = 'django_browserid.auth.BrowserIDBackend' auth.login(request, user) # Bounce to the newly created profile page, since the user # might want to review & edit. return HttpResponseRedirect(profile.get_absolute_url()) else: # If login was valid, then set to the verified email login_form = handle_login(request) if login_form.is_valid(): if request.user.is_authenticated(): # Change email to new verified email, for next time user = request.user user.email = email user.save() return _redirect_with_mindtouch_login(redirect_to, login_form.cleaned_data.get('username'), login_form.cleaned_data.get('password')) # HACK: Pretend the session was modified. Otherwise, the data disappears # for the next request. request.session.modified = True return jingo.render(request, 'users/browserid_register.html', {'login_form': login_form, 'register_form': register_form})
def save(self, *args, **kwargs): super(UserProfile, self).save(*args, **kwargs) from dekicompat.backends import DekiUserBackend DekiUserBackend.put_mindtouch_user(self.user)