def test_encode_decode(self): objects = ( ('a', 'tuple'), 'a string', u'a unicode string \u2019', {'a': 'dictionary'}, ) for o in objects: self.assert_(o != signed.dumps(o)) self.assertEqual(o, signed.loads(signed.dumps(o)))
def bestpic(request): if request.user.is_anonymous(): species = utils.random_species_with_multiple_photos() else: species = utils.random_species_with_multiple_photos(request.user) photo1, photo2 = utils.random_photos_for_species(species) # We use a token to ensure any given form we serve up can only be # submitted once. Used tokens are stored in Redis for 6 minutes. Forms # are time-stamped, and a submission from a form older than five minutes # (or one with a token within the 6 minute cache) will silently be # discarded. token = utils.generate_token() context = { 'species': species, 'photo1': photo1, 'photo2': photo2, 'options': signed.dumps({ 'species': species.pk, 'contestants': [photo1.pk, photo2.pk], 'token': token, 'time': int(time.time()), }), 'request_path': request.path, } if request.method == 'POST': context.update(process_submission(request)) return render(request, 'bestpic/index.html', context)
def test_decode_detects_tampering(self): transforms = (lambda s: s.upper(), lambda s: s + "a", lambda s: "a" + s[1:], lambda s: s.replace(".", "")) value = {"foo": "bar", "baz": 1} encoded = signed.dumps(value) self.assertEqual(value, signed.loads(encoded)) for transform in transforms: self.assertRaises(signed.BadSignature, signed.loads, transform(encoded))
def show_associate(self, request, openid=None): "Screen that offers to associate an OpenID with a user's account" if not request.user.is_authenticated(): return self.need_authenticated_user(request) try: next = signed.loads(request.REQUEST.get('next', ''), extra_salt=self.salt_next) except ValueError: next = '' return self.render( request, 'django_openid/associate.html', { 'action': urlparse.urljoin(request.path, '../associate/'), 'user': request.user, 'specific_openid': openid, 'next': next and request.REQUEST.get('next', '') or None, 'openid_token': signed.dumps( # Use user.id as part of extra_salt to prevent attackers from # creating their own openid_token for use in CSRF attack openid, extra_salt=self.associate_salt + str(request.user.id)), })
def persist_openid(self, request, response, openid_object): response.set_cookie( key = self.cookie_key, value = signed.dumps( openid_object, compress = True, extra_key = self.extra_salt ), max_age = self.cookie_max_age, expires = self.cookie_expires, path = self.cookie_path, domain = self.cookie_domain, secure = self.cookie_secure, )
def persist_openid(self, request, response, openid_object): response.set_cookie( key=self.cookie_key, value=signed.dumps(openid_object, compress=True, extra_salt=self.extra_salt), max_age=self.cookie_max_age, expires=self.cookie_expires, path=self.cookie_path, domain=self.cookie_domain, secure=self.cookie_secure, )
def test_decode_detects_tampering(self): transforms = ( lambda s: s.upper(), lambda s: s + 'a', lambda s: 'a' + s[1:], lambda s: s.replace('.', ''), ) value = {'foo': 'bar', 'baz': 1} encoded = signed.dumps(value) self.assertEqual(value, signed.loads(encoded)) for transform in transforms: self.assertRaises(signed.BadSignature, signed.loads, transform(encoded))
def show_decide(self, request, orequest): """ Called after the user is confirmed as logged-in and owning the requested openid """ # They are logged in - ask if they want to trust this root return self.render(request, self.decide_template, { 'trust_root': orequest.trust_root, 'identity': orequest.identity, 'orequest': signed.dumps(orequest, self.secret_key), 'action': request.path, 'save_trusted_roots': self.save_trusted_roots })
def test_decode_detects_tampering(self): transforms = ( lambda s: s.upper(), lambda s: s + 'a', lambda s: 'a' + s[1:], lambda s: s.replace('.', ''), ) value = {'foo': 'bar', 'baz': 1} encoded = signed.dumps(value) self.assertEqual(value, signed.loads(encoded)) for transform in transforms: self.assertRaises( signed.BadSignature, signed.loads, transform(encoded) )
def show_associate(self, request, openid=None): "Screen that offers to associate an OpenID with a user's account" if not request.user.is_authenticated(): return self.need_authenticated_user(request) return self.render(request, self.show_associate_template, { 'action': urljoin(request.path, '../associate/'), 'user': request.user, 'specific_openid': openid, 'openid_token': signed.dumps( # Use user.id as part of extra_key to prevent attackers from # creating their own openid_token for use in CSRF attack openid, extra_key = self.associate_salt + str(request.user.id) ), })
def set_user_session(self, request, response, user_session): if user_session: response.set_cookie( key=self.cookie_user_session_key, value=signed.dumps(user_session, compress=True), path=self.cookie_user_session_path, domain=self.cookie_user_session_domain, secure=self.cookie_user_session_secure, ) else: response.delete_cookie( key=self.cookie_user_session_key, path=self.cookie_user_session_path, domain=self.cookie_user_session_domain, )
def set_user_session(self, request, response, user_session): if user_session: response.set_cookie( key = self.cookie_user_session_key, value = signed.dumps(user_session, compress = True), path = self.cookie_user_session_path, domain = self.cookie_user_session_domain, secure = self.cookie_user_session_secure, ) else: response.delete_cookie( key = self.cookie_user_session_key, path = self.cookie_user_session_path, domain = self.cookie_user_session_domain, )
def do_associations(self, request): "Interface for managing your account's associated OpenIDs" if not request.user.is_authenticated(): return self.need_authenticated_user(request) message = None if request.method == 'POST': if 'todelete' in request.POST: # Something needs deleting; find out what try: todelete = signed.loads( request.POST['todelete'], extra_key=self.associate_delete_salt) if todelete['user_id'] != request.user.id: message = self.associate_tampering_message else: # It matches! Delete the OpenID relationship request.user.openids.filter( pk=todelete['association_id']).delete() message = self.association_deleted_message % ( todelete['openid']) except signed.BadSignature: message = self.associate_tampering_message # We construct a button to delete each existing association openids = [] for association in request.user.openids.all(): openids.append({ 'openid': association.openid, 'button': signed.dumps( { 'user_id': request.user.id, 'association_id': association.id, 'openid': association.openid, }, extra_key=self.associate_delete_salt), }) return self.render( request, self.associations_template, { 'openids': openids, 'user': request.user, 'action': request.path, 'logo': self.logo_path or (request.path + '../logo/'), 'message': message, 'action_new': '../', 'associate_next': self.sign_next(request.path), })
def do_associations(self, request): "Interface for managing your account's associated OpenIDs" if not request.user.is_authenticated(): return self.need_authenticated_user(request) message = None if request.method == 'POST': if 'todelete' in request.POST: # Something needs deleting; find out what try: todelete = signed.loads( request.POST['todelete'], extra_key = self.associate_delete_salt ) if todelete['user_id'] != request.user.id: message = self.associate_tampering_message else: # It matches! Delete the OpenID relationship request.user.openids.filter( pk = todelete['association_id'] ).delete() message = self.association_deleted_message % ( todelete['openid'] ) except signed.BadSignature: message = self.associate_tampering_message # We construct a button to delete each existing association openids = [] for association in request.user.openids.all(): openids.append({ 'openid': association.openid, 'button': signed.dumps({ 'user_id': request.user.id, 'association_id': association.id, 'openid': association.openid, }, extra_key = self.associate_delete_salt), }) return self.render(request, self.associations_template, { 'openids': openids, 'user': request.user, 'action': request.path, 'logo': self.logo_path or (request.path + '../logo/'), 'message': message, 'action_new': '../', 'associate_next': self.sign_next(request.path), })
def show_decide(self, request, orequest): # If user is logged in, ask if they want to trust this trust_root # If they are NOT logged in, show the landing page: if not self.user_is_logged_in(request): return self.show_landing_page(request, orequest) # Check that the user owns the requested identity if not self.user_owns_openid(request, orequest.identity): return self.show_error(request, self.not_your_openid_message) # They are logged in - ask if they want to trust this root return self.render(request, self.decide_template, { 'trust_root': orequest.trust_root, 'identity': orequest.identity, 'orequest': signed.dumps(orequest, self.secret_key), 'action': request.path, 'save_trusted_roots': self.save_trusted_roots })
def show_associate(self, request, openid=None): "Screen that offers to associate an OpenID with a user's account" if not request.user.is_authenticated(): return self.need_authenticated_user(request) return self.render( request, self.show_associate_template, { 'action': urljoin(request.path, '../associate/'), 'user': request.user, 'specific_openid': openid, 'openid_token': signed.dumps( # Use user.id as part of extra_key to prevent attackers from # creating their own openid_token for use in CSRF attack openid, extra_key=self.associate_salt + str(request.user.id)), })
def show_associate(self, request, openid=None): "Screen that offers to associate an OpenID with a user's account" if not request.user.is_authenticated(): return self.need_authenticated_user(request) try: next = signed.loads( request.REQUEST.get('next', ''), extra_salt=self.salt_next ) except ValueError: next = '' return self.render(request, self.show_associate_template, { 'action': urljoin(request.path, '../associate/'), 'user': request.user, 'specific_openid': openid, 'next': next and request.REQUEST.get('next', '') or None, 'openid_token': signed.dumps( # Use user.id as part of extra_salt to prevent attackers from # creating their own openid_token for use in CSRF attack openid, extra_salt = self.associate_salt + str(request.user.id) ), })
def photo_picker(request, photos, title, extra_context=None,set_details=None): # Enhance each photo with a signed dict for the checkbox field, so if # they DO select that photo we won't have to do another API call to look # up its details on Flickr photo_ids = [photo['id'] for photo in photos] already_imported_ids = set(Photo.objects.filter( flickr_id__in = photo_ids ).values_list('flickr_id', flat=True)) enable_button = False for photo in photos: photo_info = { 'id': photo['photo_id'], 'farm': photo['farm'], 'secret': photo['secret'], 'server': photo['server'], 'title': photo['title'], 'taken_at': photo['datetaken'], 'width_m': photo['width_m'], 'height_m': photo['height_m'], } if set_details: photo_info.update(set_details) photo['signed'] = signed.dumps(photo_info) already_imported = photo['photo_id'] in already_imported_ids photo['already_imported'] = already_imported if not already_imported: enable_button = True context = { 'title': title, 'photos': photos, 'enable_button': enable_button, } if extra_context is not None: context.update(extra_context) return render(request, 'flickr/photo_picker.html', context)
def test_encode_decode(self): objects = (("a", "tuple"), "a string", u"a unicode string \u2019", {"a": "dictionary"}) for o in objects: self.assert_(o != signed.dumps(o)) self.assertEqual(o, signed.loads(signed.dumps(o)))
def stash_incomplete_orequest(self, request, response, orequest): response.set_cookie( self.incomplete_orequest_cookie_key, signed.dumps( orequest, extra_salt = self.orequest_salt ) )
def sign_next(self, url): return signed.dumps(url, extra_key = self.salt_next)
def sign_next(self, url): if self.sign_next_param: return signed.dumps(url, extra_key = self.salt_next) else: return url
def sign_next(self, url): if self.sign_next_param: return signed.dumps(url, extra_key=self.salt_next) else: return url
def sign_done(self, url): return signed.dumps(url, extra_salt = self.salt_next)
def sign_next(self, url): return signed.dumps(url, extra_salt=self.salt_next)